Help needed please for novice user with a 25 light

I AM A NEWBIE AND LOOKING FOR SOME ADVISE PLEASE

Looking to have a circle of 25 LEDs. They need to flash on/off one at a time, on after another starting with a push of a button

When the button is released lights need carry on flashing on/off for a short delay say (2 seconds) and then at the end of this time period one light is randomly selected to stay on until the button is pressed again

I have got the button working and light flashing in sequence

I am really struggling to get right information for the off delay and the random light to selection

My current code

//LED Pin Variables


int ledPins[] = {22,23,24,25,26,27,28,29,30,31,32,33,34,35,36,37,38,39,40,41,42,43,44,45,46}; //An array to hold the pin each LED is connected to
                                   
int buttonPin = 11;  // button pin variable, we will be using pin 11

int val = 0; // variable to read button pin value

 
void setup()
{
  //Set each pin connected to an LED to output mode (pulling high (on) or low (off)
  
  for(int i = 0; i < 25; i++){         //this is a loop and will repeat 25 times
      pinMode(ledPins[i],OUTPUT); //we use this to set each LED pin to output
  }                                   //the code this replaces is below
  
  pinMode(buttonPin, INPUT_PULLUP); // set button pin to be an input
}


void loop( )  // run over and over again
{   
val = digitalRead(buttonPin);
if(val == LOW)     
oneOnAtATime();    

}
 
 //oneOnAtATime() - Will light one LED then the next turning off all the others

void oneOnAtATime(){
  int delayTime = 100; //the time (in milliseconds) to pause between LEDs
                       //make smaller for quicker switching and larger for slower
  
  for(int i = 0; i <= 25; i++){
    int offLED = i - 1;  
    if(i == 0) {         
      offLED = 25 ;        
    }                    
                       
    digitalWrite(ledPins[i], HIGH);     //turn on LED #i
    digitalWrite(ledPins[offLED], LOW); //turn off the LED we turned on last time
    delay(delayTime);
  }
}

(thanks to Mitesh Upda for assistance so far)

Not sure if the above is best approach, but started with an array for the 25 pins thought this would save coding later.

can anyone help with this next stage or tell me if I have the wrong approach

This is an interesting project. Especially since you can use the button press to come up with the random number.

The Arduino can count incredibly fast. If you have it sit there in a very tight counting loop while waiting for the button to be released, you can use the final count to select the winning LED. Just divide the final count by 25, and use the remainder to index the winning LED.

There are two issues with your code. First, you're waiting until the button is pressed, whereas your specifications says you're supposed to wait until the button is released.

Second, you don't have any debouncing. Usually when you press or release a switch, the physical mechanics of the switch are such that it makes and breaks contact several times withing a couple of milliseconds until the contact is solid. You want your button release to not be one of these bounces. The debounceDelay will depend on your switch. You may have to try different values until you get one that works. It is too low if your function is activated by pressing the button and not releasing. It is too high if you can press and release the button fast enough that it doesn't activate the function.

Try something like this:

const int DebounceDelay = 100;  // This will depend on your switch.

void loop () {
  int lowCount = 0;
  int winningLEDIndex;

  while (digitalRead(buttonPin == LOW))
    ++lowCount;
  if (lowCount > DebounceDelay)
  {
    winningLEDIndex = lowCount % 25;
    oneAtATime();   // Cycle through the 25 LEDs.  This should take 2.5 seconds.
    digitalWrite(ledPins[winningLEDIndex], HIGH);
  }
}

Hi Jimus

Thanks for the reply Ill give your code a go and see what happens

My description for the button may be bit of off.

The press the of button to starts the on/off sequence the 25 lights, they need to say on for a futher 2.5 seconds(approx) when the button is released then after the 2.5 seconds the on/off sequencing stops and lands on a random light.

I was thinking the button press would enter a small amount of randomness into the equation as I do not know how long people will press the button for. But i think I am getting this wrong

The idea for what we are trying to do is similar to this http://wheeldecide.com/ but we are using lights around the edge of a static sign to create the animation

Hope this helps explain thinks a bit better

Well the Arduino counts incredibly fast. I wired up a little tactile switch to see what the BounceDelay would be, and I couldn't press and release the switch any faster than 1000 counts. Taking the remainder after dividing that by 25, it pretty much doesn't matter how long they hold down the switch. It will be quite random.

Which also showed me that there was a problem with my code. The lowCount variable should be an unsigned int. Otherwise it quickly passes the 32K max signed int value and goes negative, which breaks the if conditional.

In any case, you'll have to mess with it a little bit to make it work for your application. If you need it to be blinking the lights while the button is pressed, you can't have it sit there in that tight while loop. You'll probably want to use the milis() function to time the blink durations while it's counting.

hi jimmus

Made a few changes and the lights flash on and off and i can use a button to stop start, (Not really what I want)

really lost with how to get the winning led to work.

any advise?

const int buttonPin = 11;
int speed  = 100;
boolean running = true;
long currentMillis =0;
long previousMillis =0;

void setup() {

pinMode (buttonPin, INPUT_PULLUP);

for(int pin = 22; pin <= 46; pin++){
    pinMode(pin,OUTPUT);
  }
}
void loop() {
for(int pin = 22; pin <= 46; pin++){
 digitalWrite (pin, LOW);
 }
 for(int highPin = 22; highPin <= 46; highPin++) {
      digitalWrite(highPin, HIGH);
      readButton (speed);
      digitalWrite(highPin, LOW);
      readButton (speed);
    }
  //  speed =speed +100;
  // if (speed >1000){
 //  speed=1000;
   // }
    
   }

void readButton(int delay) {

  boolean buttonDown = false;
  boolean buttonBackUp = false;

  boolean input;

  currentMillis = millis();
  previousMillis = currentMillis;

  while(currentMillis - previousMillis < delay) {

    input = digitalRead(buttonPin);
    if (input == LOW) {
      buttonDown = true;
    }
    else if (buttonDown == true & input == HIGH) {
      buttonBackUp = true;
    }
    currentMillis = millis();
  }

  if(buttonDown == true) {
    running = false;
  }

  while(running == false & buttonBackUp == false){
    input = digitalRead(buttonPin);
    if(input == HIGH)
    {
      buttonBackUp = true;
    }
  }
  
  int lastInput = HIGH;
  while(running == false){

    input = digitalRead(buttonPin);
    if(input == LOW){
      lastInput = LOW;
    }
    else if(input == HIGH & lastInput == HIGH) {
      running = true;
    }
  }
}