Noob: Random LED generator help

Hey legends. Noob coder here. Appreciate your input.

I have 7 LEDs. The code below turns the LEDs HIGH and LOW in set patterns. (It's like a countdown digital clock looping from 9 to 0)

I want to add an input (Either Sound or Temperature) that changes the LED output. A +/- in variables will then speed up or slow down the LED sequence.

I then want to add another change that when the input reaches a certain threshold +/- (ie. loud sound or high temperature), the LED sequence changes from a set pattern to a random sequence. Where all HIGH and LOW combinations and patterns on each pin is randomised. It will stay random until the input threshold resets to the baseline.

I hope that makes sense. Appreciate your thoughts on how I can get to my goal.

Here's the current code:

int redLED1=13;
int redLED2=12;
int redLED3=11;
int redLED4=10;
int redLED5=8;
int redLED6=4;
int redLED7=2;

int shortW=1000;

void setup() {
  // put your setup code here, to run once:
pinMode (redLED1,OUTPUT);
pinMode (redLED2,OUTPUT);
pinMode (redLED3,OUTPUT);
pinMode (redLED4,OUTPUT);
pinMode (redLED5,OUTPUT);
pinMode (redLED6,OUTPUT);
pinMode (redLED7,OUTPUT);
}

void loop() {
  // put your main code here, to run repeatedly:
  
  // LED formation 1:
digitalWrite(redLED1,LOW);
digitalWrite(redLED2,LOW);
digitalWrite(redLED3,HIGH);
digitalWrite(redLED4,LOW);
digitalWrite(redLED5,LOW);
digitalWrite(redLED6,HIGH);
digitalWrite(redLED7,LOW);

delay (shortW);

  // LED formation 2:
digitalWrite(redLED1,HIGH);
digitalWrite(redLED2,LOW);
digitalWrite(redLED3,HIGH);
digitalWrite(redLED4,HIGH);
digitalWrite(redLED5,HIGH);
digitalWrite(redLED6,LOW);
digitalWrite(redLED7,HIGH);

delay (shortW);

  // LED formation 3:
digitalWrite(redLED1,HIGH);
digitalWrite(redLED2,LOW);
digitalWrite(redLED3,HIGH);
digitalWrite(redLED4,HIGH);
digitalWrite(redLED5,LOW);
digitalWrite(redLED6,HIGH);
digitalWrite(redLED7,HIGH);

delay (shortW);

  // LED formation 4:
digitalWrite(redLED1,LOW);
digitalWrite(redLED2,HIGH);
digitalWrite(redLED3,HIGH);
digitalWrite(redLED4,HIGH);
digitalWrite(redLED5,LOW);
digitalWrite(redLED6,LOW);
digitalWrite(redLED7,HIGH);

delay (shortW);

  // LED formation 5:
digitalWrite(redLED1,HIGH);
digitalWrite(redLED2,HIGH);
digitalWrite(redLED3,LOW);
digitalWrite(redLED4,HIGH);
digitalWrite(redLED5,LOW);
digitalWrite(redLED6,HIGH);
digitalWrite(redLED7,HIGH);

delay (shortW);

  // LED formation 6:
digitalWrite(redLED1,HIGH);
digitalWrite(redLED2,HIGH);
digitalWrite(redLED3,LOW);
digitalWrite(redLED4,HIGH);
digitalWrite(redLED5,HIGH);
digitalWrite(redLED6,HIGH);
digitalWrite(redLED7,HIGH);

delay (shortW);

 // LED formation 7:
digitalWrite(redLED1,HIGH);
digitalWrite(redLED2,LOW);
digitalWrite(redLED3,HIGH);
digitalWrite(redLED4,LOW);
digitalWrite(redLED5,HIGH);
digitalWrite(redLED6,HIGH);
digitalWrite(redLED7,LOW);

delay (shortW);

  // LED formation 8:
digitalWrite(redLED1,HIGH);
digitalWrite(redLED2,HIGH);
digitalWrite(redLED3,HIGH);
digitalWrite(redLED4,HIGH);
digitalWrite(redLED5,HIGH);
digitalWrite(redLED6,HIGH);
digitalWrite(redLED7,HIGH);

delay (shortW);

  // LED formation 9:
digitalWrite(redLED1,HIGH);
digitalWrite(redLED2,HIGH);
digitalWrite(redLED3,HIGH);
digitalWrite(redLED4,HIGH);
digitalWrite(redLED5,LOW);
digitalWrite(redLED6,HIGH);
digitalWrite(redLED7,LOW);

delay (shortW);

}

Hello
You may take a view into the IDE examples to find a timer- and button function to be modified for your project.

1 Like

I would recommend that you learn arrays and 'for' loops. With them your program will become much simpler and more understandable. For a randomly generated LED sequence, use random () and randomSeed ().

https://www.arduino.cc/reference/en/language/variables/data-types/array/
https://www.arduino.cc/reference/en/language/structure/control-structure/for/
https://www.arduino.cc/reference/en/language/functions/random-numbers/random/
https://www.arduino.cc/reference/en/language/functions/random-numbers/randomseed/

1 Like

not so much.
Define:
if the value is above the threashold:

Which event should start the countdown?
What should happen if the countdown reaches 0?
What should restart the countdown?

ha! thanks for your honesty. I'm currently exploring the concepts to see whats possible.

– The countdown will loop. LED Patterns countdown from 9 to 0 and then repeat.
– Sound / or temperature (still exploring which input) will change the speed of the countdown.
– If the sound/temperature goes above a certain range, the patterns of the LEDs will then change to a random and chaotic pattern.
– when the range returns to baseline, the countdown returns to the original pattern

It's for an artistic application. Probably why it doesn't make sense :slight_smile:
Hope that's clear!

Thanks for the links. Will explore further.

problem one:
you haven't design a pattern for 0.
You only have 1-9 ... think about it...

The LEDs are in a digital 8 shape
so the code will visually display the numbers

I'm thinking visually, so just need to adjust the ideas to code.
I'm new to this.

Hello
In this case it is highly recommented to take a view to using C++ with structs and arrays.
Thus you will save a lot of time within the design of LED pattern.

1 Like

using most of your code and what you should have learned in the "Blink Without Delay" example you might come with something like:

/*
    https://forum.arduino.cc/t/noob-random-led-generator-help/894429
*/

const byte redLED1 = 13;
const byte redLED2 = 12;
const byte redLED3 = 11;
const byte redLED4 = 10;
const byte redLED5 = 8;
const byte redLED6 = 4;
const byte redLED7 = 2;

int shortW = 1000;

const byte analogPin = A0;
const int threashold = 500;


byte state = 1;     // current state we are in 
byte previousState = 0; // remember the old state if we switch to state manual
const byte manual = 42; // we just need a marker to be used for "manual" - override the countdown

void setup() {
  Serial.begin(115200);
  pinMode (redLED1, OUTPUT);
  pinMode (redLED2, OUTPUT);
  pinMode (redLED3, OUTPUT);
  pinMode (redLED4, OUTPUT);
  pinMode (redLED5, OUTPUT);
  pinMode (redLED6, OUTPUT);
  pinMode (redLED7, OUTPUT);
  pinMode (analogPin, INPUT_PULLUP); // must fit to your sensor
}

void showRandom()
{
  Serial.println(F("showRandom"));
  digitalWrite(redLED1, random(0, 2));
  digitalWrite(redLED2, random(0, 2));
  digitalWrite(redLED3, random(0, 2));
  digitalWrite(redLED4, random(0, 2));
  digitalWrite(redLED5, random(0, 2));
  digitalWrite(redLED6, random(0, 2));
  digitalWrite(redLED7, random(0, 2));
}

void showDigit(byte actual)
{
  Serial.print(F("showDigit "));
  Serial.println(actual);
  switch (actual)
  {
    case 1 : // LED formation 1:
      digitalWrite(redLED1, LOW);
      digitalWrite(redLED2, LOW);
      digitalWrite(redLED3, HIGH);
      digitalWrite(redLED4, LOW);
      digitalWrite(redLED5, LOW);
      digitalWrite(redLED6, HIGH);
      digitalWrite(redLED7, LOW);

      break;

    case 2 : // LED formation 2:
      digitalWrite(redLED1, HIGH);
      digitalWrite(redLED2, LOW);
      digitalWrite(redLED3, HIGH);
      digitalWrite(redLED4, HIGH);
      digitalWrite(redLED5, HIGH);
      digitalWrite(redLED6, LOW);
      digitalWrite(redLED7, HIGH);
      break;

    case 3 : // LED formation 3:
      digitalWrite(redLED1, HIGH);
      digitalWrite(redLED2, LOW);
      digitalWrite(redLED3, HIGH);
      digitalWrite(redLED4, HIGH);
      digitalWrite(redLED5, LOW);
      digitalWrite(redLED6, HIGH);
      digitalWrite(redLED7, HIGH);
      break;

    case 4:   // LED formation 4:
      digitalWrite(redLED1, LOW);
      digitalWrite(redLED2, HIGH);
      digitalWrite(redLED3, HIGH);
      digitalWrite(redLED4, HIGH);
      digitalWrite(redLED5, LOW);
      digitalWrite(redLED6, LOW);
      digitalWrite(redLED7, HIGH);
      break;

    case 5:   // LED formation 5:
      digitalWrite(redLED1, HIGH);
      digitalWrite(redLED2, HIGH);
      digitalWrite(redLED3, LOW);
      digitalWrite(redLED4, HIGH);
      digitalWrite(redLED5, LOW);
      digitalWrite(redLED6, HIGH);
      digitalWrite(redLED7, HIGH);
      break;

    case 6:   // LED formation 6:
      digitalWrite(redLED1, HIGH);
      digitalWrite(redLED2, HIGH);
      digitalWrite(redLED3, LOW);
      digitalWrite(redLED4, HIGH);
      digitalWrite(redLED5, HIGH);
      digitalWrite(redLED6, HIGH);
      digitalWrite(redLED7, HIGH);
      break;

    case 7 :  // LED formation 7:
      digitalWrite(redLED1, HIGH);
      digitalWrite(redLED2, LOW);
      digitalWrite(redLED3, HIGH);
      digitalWrite(redLED4, LOW);
      digitalWrite(redLED5, HIGH);
      digitalWrite(redLED6, HIGH);
      digitalWrite(redLED7, LOW);
      break;

    case 8:  // LED formation 8:
      digitalWrite(redLED1, HIGH);
      digitalWrite(redLED2, HIGH);
      digitalWrite(redLED3, HIGH);
      digitalWrite(redLED4, HIGH);
      digitalWrite(redLED5, HIGH);
      digitalWrite(redLED6, HIGH);
      digitalWrite(redLED7, HIGH);

    case 9:  // LED formation 9:
      digitalWrite(redLED1, HIGH);
      digitalWrite(redLED2, HIGH);
      digitalWrite(redLED3, HIGH);
      digitalWrite(redLED4, HIGH);
      digitalWrite(redLED5, LOW);
      digitalWrite(redLED6, HIGH);
      digitalWrite(redLED7, LOW);

  }
}

void runFiniteStateMachine()
{
  static uint32_t previousMillis;
  if (state != manual)
  {
    uint32_t currentMillis = millis();
    if (currentMillis - previousMillis > shortW)  // see "Blink Without Delay" Example
    {
      state = state + 1;
      if (state > 9) state = 1; // you don't have a zero!
      showDigit(state);
      previousMillis =currentMillis;
    }
  }
}

void handleInput()
{
  int actual = analogRead(analogPin);
 
  actual = 200; // this is for testing only ... put in a value to see how the programm will work with different sensor values. Finally - just delete this line.

  //Serial.print(F("actual=")); Serial.println(actual);
  if (actual > threashold && state != manual)
  {
    showRandom();
    previousState = state;   // remember the current state to be able to restore it later on
    state = manual;
  }
  if (actual <= threashold && state == manual)
  {
    state = previousState;   // we restore the state
  }

  // to be done: modify the interval /  shortW based on analog in
}

void loop() {
  runFiniteStateMachine();
  handleInput();
}

showRandom will randomly switch on pins
showDigit accepts a parameter (the number which should be shown) and will switch on the pins accordingly. One day, this can be improved using other technics already mentioned in this thread.
runFiniteStateMachine is the time trigger for your countdown.
handleInput reads the analog Input and will call the random pattern if needed or release the state back to the countdown.

you should see, that the modification of the interval is not implemented yet - but first you need to understand why and how "Blink without Delay" is working and why you should use millis.

Amazing. Thank you for taking the time to put this code together.
I'll need some time to figure this out. But will be in touch when I have questions.

1 Like