Go Down

Topic: Delay Problems please help (Read 852 times) previous topic - next topic

kylem

I have this code for a police flasher with different flashing methods. i have got multiple flashing methods in one code and have a button to switch between the different methods. i have got the button to work but because i am using the delay() function, it limits me to when i can press the button. please help and what other method could i use for a delay that wont interfere with the button use.


Code: [Select]
int ledPins[] = {2,3,4,5,6,7,8,9}; //An array to hold the pin each LED is connected to
  int delays = 50;
 int off = LOW;
 int on = HIGH;

 int amber = 2;
 int amber2 = 3;
 int amber3 = 4;
 int amber4 = 5;

 int white = 6;
 int white2 = 7;
 int white3 = 8;
 int white4 = 9;                                //i.e. LED #0 is connected to pin 2, LED #1, 3 and so on
                                  //to address an array use ledPins[0] this would equal 2
                                  //and ledPins[7] would equal 9
                                 
int buttonPin = 12;  // button pin variable, we will be using pin 11

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

int sequence = 1; // variable to hold current sequence

/*
* setup() - this function runs once when you turn your Arduino on
* We the three control pins to outputs
*/
void setup()
{
 
 //Set each pin connected to an LED to output mode (pulling high (on) or low (off)
 for(int i = 0; i < 8; i++){         //this is a loop and will repeat eight times
     pinMode(ledPins[i],OUTPUT);
     pinMode(amber, OUTPUT);
     pinMode(amber2, OUTPUT);
     pinMode(amber3, OUTPUT);
     pinMode(amber4, OUTPUT);
     pinMode(white, OUTPUT);
     pinMode(white2, OUTPUT);
     pinMode(white3, OUTPUT);
     pinMode(white4, OUTPUT); //we use this to set each LED pin to output
 }                                   //the code this replaces is below
 
 pinMode(buttonPin, INPUT); // set button pin to be an input

 /* (commented code will not run)
  * these are the lines replaced by the for loop above they do exactly the
  * same thing the one above just uses less typing
 pinMode(ledPins[0],OUTPUT);
 pinMode(ledPins[1],OUTPUT);
 pinMode(ledPins[2],OUTPUT);
 pinMode(ledPins[3],OUTPUT);
 pinMode(ledPins[4],OUTPUT);
 pinMode(ledPins[5],OUTPUT);
 pinMode(ledPins[6],OUTPUT);
 pinMode(ledPins[7],OUTPUT);
 (end of commented code)*/
}


/*
* loop() - this function will start after setup finishes and then repeat
* we call a function called oneAfterAnother(). if you would like a different behaviour
* uncomment (delete the two slashes) one of the other lines
*/
void loop()                     // run over and over again
{
 // oneAfterAnotherNoLoop();   //this will turn on each LED one by one then turn each off
 //oneAfterAnotherLoop();   //does the same as oneAfterAnotherNoLoop but with
                            //much less typing
 //oneOnAtATime();          //this will turn one LED on then turn the next one
                            //on turning the
                            //former off (one LED will look like it is scrolling
                            //along the line
 //inAndOut();              //lights the two middle LEDs then moves them out then back
                            //in again
                           
      // check if button pressed

       val = digitalRead(buttonPin);
       if(val == LOW)
       {
           if(sequence == 3) // if sequence is at 3 already, make it 1 again
           {
              sequence = 1;
           } else
               {
                 sequence++; // otherwise go to the next sequence
               }
       }
                           
        switch(sequence)
                {
                    case 1:
                    oneAfterAnotherNoLoop();
                    break;
                    case 2:
                    oneOnAtATime();  
                    break;
                    case 3:
                    inAndOut();
                    break;
                }
                           
                           
}

/*
* oneAfterAnotherNoLoop() - Will light one LED then delay for delayTime then light
* the next LED until all LEDs are on it will then turn them off one after another
*
* this does it without using a loop which makes for a lot of typing.
* oneOnAtATimeLoop() does exactly the same thing with less typing
*/
void oneAfterAnotherNoLoop(){
 digitalWrite(amber, on);    
 digitalWrite(amber2, on);  
 digitalWrite(amber3, on);  
 digitalWrite(amber4, on);

 delay(delays);

 digitalWrite(amber, off);    
 digitalWrite(amber2, off);  
 digitalWrite(amber3, off);  
 digitalWrite(amber4, off);

 delay(delays);
 
 digitalWrite(amber, on);    
 digitalWrite(amber2, on);  
 digitalWrite(amber3, on);  
 digitalWrite(amber4, on);

 delay(delays);

 digitalWrite(amber, off);    
 digitalWrite(amber2, off);  
 digitalWrite(amber3, off);  
 digitalWrite(amber4, off);

 delay(delays);
 
 digitalWrite(amber, on);    
 digitalWrite(amber2, on);  
 digitalWrite(amber3, on);  
 digitalWrite(amber4, on);

 delay(delays);

 digitalWrite(amber, off);    
 digitalWrite(amber2, off);  
 digitalWrite(amber3, off);  
 digitalWrite(amber4, off);

 delay(delays);

 digitalWrite(white, on);
 digitalWrite(white2, on);
 digitalWrite(white3, on);
 digitalWrite(white4, on);
 
 delay(delays);
 
 digitalWrite(white, off);
 digitalWrite(white2, off);
 digitalWrite(white3, off);
 digitalWrite(white4, off);
 
 delay(delays);
 
 digitalWrite(white, on);
 digitalWrite(white2, on);
 digitalWrite(white3, on);
 digitalWrite(white4, on);
 
 delay(delays);
 
 digitalWrite(white, off);
 digitalWrite(white2, off);
 digitalWrite(white3, off);
 digitalWrite(white4, off);
 
 delay(delays);
 
 digitalWrite(white, on);
 digitalWrite(white2, on);
 digitalWrite(white3, on);
 digitalWrite(white4, on);
 
 delay(delays);
 
 digitalWrite(white, off);
 digitalWrite(white2, off);
 digitalWrite(white3, off);
 digitalWrite(white4, off);
 
 delay(delays);
}

/*
* oneAfterAnotherLoop() - Will light one LED then delay for delayTime then light
* the next LED until all LEDs are on it will then turn them off one after another
*
* this does it using a loop which makes for a lot less typing.
* than oneOnAtATimeNoLoop() does exactly the same thing with less typing
*/
void oneAfterAnotherLoop(){
 int delayTime = 100; //the time (in milliseconds) to pause between LEDs
                      //make smaller for quicker switching and larger for slower

//Turn Each LED on one after another
 for(int i = 0; i <= 7; i++){
   digitalWrite(ledPins[i], HIGH);  //Turns on LED #i each time this runs i
   delay(delayTime);                //gets one added to it so this will repeat
 }                                  //8 times the first time i will = 0 the final
                                    //time i will equal 7;

//Turn Each LED off one after another
 for(int i = 7; i >= 0; i--){  //same as above but rather than starting at 0 and counting up
                               //we start at seven and count down
   digitalWrite(ledPins[i], LOW);  //Turns off LED #i each time this runs i
   delay(delayTime);               //gets one subtracted from it so this will repeat
 }                                  //8 times the first time i will = 7 the final
                                    //time it will equal 0
                                   
                                   
}

/*
* oneOnAtATime() - Will light one LED then the next turning off all the others
*/
void oneOnAtATime(){
 digitalWrite(amber, on);    
 digitalWrite(amber2, on);  
 digitalWrite(amber3, on);  
 digitalWrite(amber4, on);

 delay(delays);

 digitalWrite(amber, off);    
 digitalWrite(amber2, off);  
 digitalWrite(amber3, off);  
 digitalWrite(amber4, off);

 delay(delays);
 
 digitalWrite(amber, on);    
 digitalWrite(amber2, on);  
 digitalWrite(amber3, on);  
 digitalWrite(amber4, on);

 delay(delays);

 digitalWrite(amber, off);    
 digitalWrite(amber2, off);  
 digitalWrite(amber3, off);  
 digitalWrite(amber4, off);

 delay(delays);
 
 digitalWrite(amber, on);    
 digitalWrite(amber2, on);  
 digitalWrite(amber3, on);  
 digitalWrite(amber4, on);

 delay(delays);

 digitalWrite(amber, off);    
 digitalWrite(amber2, off);  
 digitalWrite(amber3, off);  
 digitalWrite(amber4, off);

 delay(delays);

 digitalWrite(white, on);
 digitalWrite(white2, on);
 digitalWrite(white3, on);
 digitalWrite(white4, on);
 
 delay(delays);
 
 digitalWrite(white, off);
 digitalWrite(white2, off);
 digitalWrite(white3, off);
 digitalWrite(white4, off);
 
 delay(delays);
}



Nick Gammon

Code: [Select]

 //Set each pin connected to an LED to output mode (pulling high (on) or low (off)
 for(int i = 0; i < 8; i++){         //this is a loop and will repeat eight times
     pinMode(ledPins[i],OUTPUT);
     pinMode(amber, OUTPUT);
     pinMode(amber2, OUTPUT);
     pinMode(amber3, OUTPUT);
     pinMode(amber4, OUTPUT);
     pinMode(white, OUTPUT);
     pinMode(white2, OUTPUT);
     pinMode(white3, OUTPUT);
     pinMode(white4, OUTPUT); //we use this to set each LED pin to output
 }                                   //the code this replaces is below


You don't need to set amber to OUTPUT 8 times. Once is enough.

Nick Gammon

Code: [Select]
int ledPins[] = {2,3,4,5,6,7,8,9}; //An array to hold the pin each LED is connected to
...
  int amber = 2;


You are doing it twice. You can omit all those other lines.

rogue_wraith

Kylem,

You and I are working on very similar problems, I'll be watching this topic closely.

You might want to watch mine, too:
http://arduino.cc/forum/index.php/topic,129639.0.html

Hopefully we'll both get what we need...now I'm off to look at the link Nick Gammon just posted to both of us.

xykobas3rd

#5
Oct 29, 2012, 07:42 am Last Edit: Oct 29, 2012, 07:50 am by xykobas3rd Reason: 1
The link Gammon posted is great.

This video can also help 

EDIT: You'll still need to remove delays from function

http://www.youtube.com/watch?v=CRJUdf5TTQQ

It shows how to use a button as an interrupt by continuosly polling the pin with the button attached.

PaulS

Quote
It shows how to use a button as an interrupt by continuosly polling the pin with the button attached.

If you are continuously polling, then the switch is not interrupting anything.

rogue_wraith

This code is what I wrote to do the police light functionality without delay.

It works, but I'm moving it to Processing, so I did not add the actual ability to change the flash pattern, but it should be easy to add.

Code: [Select]

//Setup the timing variables
long onInterval = 250;
long offInterval = 250;
long interval = onInterval;

//Track the last time the time was updated
long lastMillis = millis();

//Variable to track where in the pattern we are
int flashPatternStepper = 0;
//Variable to track which pattern is being used
int flashPatternSelect = 0;

//Array of possible flash patterns
int flashPatterns [2][4] = {{1, 0, 2, 0},
  {1, 2, 1, 2}};
int arrayLength = 4;

//Variables to track color selection
char color1 = 'r';
char color2 = 'b';

//Pins for the RGB LED
int redPin = 9;
int greenPin = 10;
int bluePin = 11;

//Normal setup just setting pin modes
void setup()
{
pinMode(redPin, OUTPUT);
pinMode(greenPin, OUTPUT);
pinMode(bluePin, OUTPUT);
}

//loop() only calls the handleLEDs function for now
void loop()
{
handleLEDs();

//Code to change values of flashPatternSelect, onInterval, offInterval, color1, and color2 would go here
}


void handleLEDs()
{
//Check to see if lights should be on or off
if(flashPatterns[flashPatternSelect][flashPatternStepper] == 0)
{
interval = offInterval;
}
else
{
interval = onInterval;
}

//Check if we need to advance flashPatternStepper to the next place in the sequence
if(millis() - lastMillis > interval)
{
lastMillis = millis();
flashPatternStepper++;

if(flashPatternStepper > arrayLength-1)
{
flashPatternStepper = 0;
}
}

//colorSelect decides which LED Pins should be active, if any
colorSelect();
}

//Control the colors
void colorSelect()
{
char colorChoice;

///Set colorChoice based on where we are in the sequence
switch (flashPatterns[flashPatternSelect][flashPatternStepper])
{
case 1:
colorChoice = color1;
break;

case 2:
colorChoice = color2;
break;

case 0:
colorChoice = 'o';
break;
}

//Actually turn on/off the LED pin(s)
switch(colorChoice)
{
    case 'y':     
      digitalWrite(redPin, LOW);
      digitalWrite(greenPin, LOW);
      digitalWrite(bluePin, HIGH);
      break;

    case 'w':     
      digitalWrite(redPin, LOW);
      digitalWrite(greenPin, LOW);
      digitalWrite(bluePin, LOW);
      break;

    case 'r':     
      digitalWrite(redPin, LOW);
      digitalWrite(greenPin, HIGH);
      digitalWrite(bluePin, HIGH);
      break;

    case 'g':     
      digitalWrite(redPin, HIGH);
      digitalWrite(greenPin, LOW);
      digitalWrite(bluePin, HIGH);
      break;

    case 'b':     
      digitalWrite(redPin, HIGH);
      digitalWrite(greenPin, HIGH);
      digitalWrite(bluePin, LOW);
      break;

    case 'p':     
      digitalWrite(redPin, LOW);
      digitalWrite(greenPin, HIGH);
      digitalWrite(bluePin, LOW);
      break;

    case 'c':     
      digitalWrite(redPin, HIGH);
      digitalWrite(greenPin, LOW);
      digitalWrite(bluePin, LOW);
      break;

    case 'o':
      digitalWrite(redPin, HIGH);
      digitalWrite(greenPin, HIGH);
      digitalWrite(bluePin, HIGH);
      break;
  }
}

xykobas3rd


Quote
It shows how to use a button as an interrupt by continuosly polling the pin with the button attached.

If you are continuously polling, then the switch is not interrupting anything.


Sorry, I'm new too.
He says something along those lines in the video at around 1:30.
He means that even if you're in a for() or while() loop, pressing the button would still  interrupt it......right?



P.S. continuously* (I knew something looked weird)

PaulS

Quote
He means that even if you're in a for() or while() loop, pressing the button would still  interrupt it......right?

If you check, in the for or while loop, yes.

Often, of course, doing so makes the code a lot more complex, with break statements all over the place, or flag testing to determine whether to continue.

Re-writing the code, so that loop() does the looping is often a much better choice.

holmes4

You need to scrap the code with all the delays in. Nothing happens while delays are in progress. Interrupts will be dealt with but you can not use an interrupt to get out of a delay or loop() or a loop (for /while/do).


You need to start over using the blink with out delay example.

Mark

kylem

thank you to everyone that replied and thank you @nick gammon.
enjoy

Go Up