Go Down

Topic: blink a led with push button (Read 11022 times) previous topic - next topic

jameskirk

I am still not up to figuring out how to enter the code like that.
Do you want me to replace the code in the top box with the code in the bottom box?
Thanks

Paul__B

Sigh!

Here you go:
Code: [Select]
// Blink without "delay()" - multi!

const int led1Pin =  13;    // LED pin number
const int led2Pin =  12;
const int led3Pin =  11;
const int button1 =  A1;

int led1State = LOW;        // initialise the LED
int led2State = LOW;
int led3State = LOW;
char bstate1 = 0;
char togl1 = LOW;

unsigned long count1 = 0;   // will store last time LED was updated
unsigned long count2 = 0;
unsigned long count3 = 0;
unsigned long bcount1 = 0; // button debounce timer.  Replicate as necessary.

// Have we completed the specified interval since last confirmed event?
// "marker" chooses which counter to check
boolean timeout(unsigned long *marker, unsigned long interval) {
  if (millis() - *marker >= interval) {
    *marker += interval;    // move on ready for next interval
    return true;      
  }
  else return false;
}

// Deal with a button read; true if button pressed and debounced is a new event
// Uses reading of button input, debounce store, state store and debounce interval.
// Routines by Paul__B of Arduino Forum
boolean butndown(char button, unsigned long *marker, char *butnstate, unsigned long interval) {
  switch (*butnstate) {               // Odd states if was pressed, >= 2 if debounce in progress
  case 0: // Button up so far,
    if (button == HIGH) return false; // Nothing happening!
    else {
      *butnstate = 2;                 // record that is now pressed
      *marker = millis();             // note when was pressed
      return false;                   // and move on
    }

  case 1: // Button down so far,
    if (button == LOW) return false; // Nothing happening!
    else {
      *butnstate = 3;                 // record that is now released
      *marker = millis();             // note when was released
      return false;                   // and move on
    }

  case 2: // Button was up, now down.
    if (button == HIGH) {
      *butnstate = 0;                 // no, not debounced; revert the state
      return false;                   // False alarm!
    }
    else {
      if (millis() - *marker >= interval) {
        *butnstate = 1;               // jackpot!  update the state
        return true;                  // because we have the desired event!
      }
      else
        return false;                 // not done yet; just move on
    }

  case 3: // Button was down, now up.
    if (button == LOW) {
      *butnstate = 1;                 // no, not debounced; revert the state
      return false;                   // False alarm!
    }
    else {
      if (millis() - *marker >= interval) {
        *butnstate = 0;               // Debounced; update the state
        return false;                 // but it is not the event we want
      }
      else
        return false;                 // not done yet; just move on
    }
  default:                            // Error; recover anyway
    {  
      *butnstate = 0;
      return false;                   // Definitely false!
    }
  }
}

void setup() {
  pinMode(led1Pin, OUTPUT);      
  pinMode(led2Pin, OUTPUT);      
  pinMode(led3Pin, OUTPUT);      
  pinMode(button1, INPUT);      
  digitalWrite(button1,HIGH);        // internal pullup all versions
}

void loop() {
  // Toggle switch if button debounced
  if (butndown(digitalRead(button1), &bcount1, &bstate1, 10UL )) {
    if (togl1 == LOW) {
      togl1 = HIGH;
    }
    else {
      togl1 = LOW;
    }
  }

  // flash if toggle is on
  if (togl1 == HIGH) {

    // Act if the latter time (ms) has now passed on this particular counter,
    if (timeout(&count1, 150UL )) {
      if (led1State == LOW) {
        led1State = HIGH;
      }
      else {
        led1State = LOW;
      }
      digitalWrite(led1Pin, led1State);
    }

    if (timeout(&count2, 500UL )) {
      if (led2State == LOW) {
        led2State = HIGH;
      }
      else {
        led2State = LOW;
      }
      digitalWrite(led2Pin, led2State);
    }

    if (timeout(&count3, 77UL )) {
      if (led3State == LOW) {
        led3State = HIGH;
      }
      else
        led3State = LOW;
      digitalWrite(led3Pin, led3State);
    }      
  }
  else {
    led1State = LOW;
    led2State = LOW;
    led3State = LOW;
    digitalWrite(led1Pin, led1State);
    digitalWrite(led2Pin, led2State);
    digitalWrite(led3Pin, led3State);
  }
}

Note:  Button always goes to ground, using internal pull-up.

jameskirk

That works perfectly...
Thanks so much

jameskirk

There is one more thing that I need to add
to this sketch; it is a non blinking LED...
I tried adding just another line for the LED but it doesn't work...
Can someone give me some info as how to add one to this sketch?
Thanks
Mike

UKHeliBob

Please explain  exactly what you want and post your attempt at doing it.
Please do not send me PMs asking for help.  Post in the forum then everyone will benefit from seeing the questions and answers.

jameskirk

Here is what I did...
I added the 4th LED which I don't want to blink but come on when the rest come on...

Code: [Select]
// Blink without "delay()" - multi!

const int led1Pin =  13;    // LED pin number
const int led2Pin =  12;
const int led3Pin =  11;
const int led4Pin =  10;
const int button1 =  A1;

int led1State = LOW;        // initialise the LED
int led2State = LOW;
int led3State = LOW;
int led4State = LOW;
char bstate1 = 0;
char togl1 = LOW;

unsigned long count1 = 0;   // will store last time LED was updated
unsigned long count2 = 0;
unsigned long count3 = 0;
unsigned long bcount1 = 0; // button debounce timer.  Replicate as necessary.

// Have we completed the specified interval since last confirmed event?
// "marker" chooses which counter to check
boolean timeout(unsigned long *marker, unsigned long interval) {
  if (millis() - *marker >= interval) {
    *marker += interval;    // move on ready for next interval
    return true;       
  }
  else return false;
}

// Deal with a button read; true if button pressed and debounced is a new event
// Uses reading of button input, debounce store, state store and debounce interval.
// Routines by Paul__B of Arduino Forum
boolean butndown(char button, unsigned long *marker, char *butnstate, unsigned long interval) {
  switch (*butnstate) {               // Odd states if was pressed, >= 2 if debounce in progress
  case 0: // Button up so far,
    if (button == HIGH) return false; // Nothing happening!
    else {
      *butnstate = 2;                 // record that is now pressed
      *marker = millis();             // note when was pressed
      return false;                   // and move on
    }

  case 1: // Button down so far,
    if (button == LOW) return false; // Nothing happening!
    else {
      *butnstate = 3;                 // record that is now released
      *marker = millis();             // note when was released
      return false;                   // and move on
    }

  case 2: // Button was up, now down.
    if (button == HIGH) {
      *butnstate = 0;                 // no, not debounced; revert the state
      return false;                   // False alarm!
    }
    else {
      if (millis() - *marker >= interval) {
        *butnstate = 1;               // jackpot!  update the state
        return true;                  // because we have the desired event!
      }
      else
        return false;                 // not done yet; just move on
    }

  case 3: // Button was down, now up.
    if (button == LOW) {
      *butnstate = 1;                 // no, not debounced; revert the state
      return false;                   // False alarm!
    }
    else {
      if (millis() - *marker >= interval) {
        *butnstate = 0;               // Debounced; update the state
        return false;                 // but it is not the event we want
      }
      else
        return false;                 // not done yet; just move on
    }
  default:                            // Error; recover anyway
    { 
      *butnstate = 0;
      return false;                   // Definitely false!
    }
  }
}

void setup() {
  pinMode(led1Pin, OUTPUT);     
  pinMode(led2Pin, OUTPUT);     
  pinMode(led3Pin, OUTPUT);
  pinMode(led4Pin, OUTPUT); 
  pinMode(button1, INPUT);     
  digitalWrite(button1,HIGH);        // internal pullup all versions
}

void loop() {
  // Toggle switch if button debounced
  if (butndown(digitalRead(button1), &bcount1, &bstate1, 10UL )) {
    if (togl1 == LOW) {
      togl1 = HIGH;
    }
    else {
      togl1 = LOW;
    }
  }

  // flash if toggle is on
  if (togl1 == HIGH) {

    // Act if the latter time (ms) has now passed on this particular counter,
    if (timeout(&count1, 150UL )) {
      if (led1State == LOW) {
        led1State = HIGH;
      }
      else {
        led1State = LOW;
      }
      digitalWrite(led1Pin, led1State);
    }

    if (timeout(&count2, 500UL )) {
      if (led2State == LOW) {
        led2State = HIGH;
      }
      else {
        led2State = LOW;
      }
      digitalWrite(led2Pin, led2State);
    }

    if (timeout(&count3, 77UL )) {
      if (led3State == LOW) {
        led3State = HIGH;
      }
      else
        led3State = LOW;
      digitalWrite(led3Pin, led3State);
    }     
  }
  else {
    led1State = LOW;
    led2State = LOW;
    led3State = LOW;
    led4State = LOW;
    digitalWrite(led1Pin, led1State);
    digitalWrite(led2Pin, led2State);
    digitalWrite(led3Pin, led3State);
    digitalWrite(led4Pin, led4State);
  }
}

Paul__B

#21
Jun 22, 2015, 03:53 am Last Edit: Jun 22, 2015, 04:20 am by Paul__B
Code: [Select]
// Blink without "delay()" - multi!

const int led1Pin =  13;    // LED pin number
const int led2Pin =  12;
const int led3Pin =  11;
const int led4Pin =  10;
const int button1 =  A1;

int led1State = LOW;        // initialise the LED
int led2State = LOW;
int led3State = LOW;
int led4State = LOW;
char bstate1 = 0;
char togl1 = LOW;

unsigned long count1 = 0;   // will store last time LED was updated
unsigned long count2 = 0;
unsigned long count3 = 0;
unsigned long bcount1 = 0; // button debounce timer.  Replicate as necessary.

// Have we completed the specified interval since last confirmed event?
// "marker" chooses which counter to check
boolean timeout(unsigned long *marker, unsigned long interval) {
  if (millis() - *marker >= interval) {
    *marker += interval;    // move on ready for next interval
    return true;       
  }
  else return false;
}

// Deal with a button read; true if button pressed and debounced is a new event
// Uses reading of button input, debounce store, state store and debounce interval.
// Routines by Paul__B of Arduino Forum
boolean butndown(char button, unsigned long *marker, char *butnstate, unsigned long interval) {
  switch (*butnstate) {               // Odd states if was pressed, >= 2 if debounce in progress
  case 0: // Button up so far,
    if (button == HIGH) return false; // Nothing happening!
    else {
      *butnstate = 2;                 // record that is now pressed
      *marker = millis();             // note when was pressed
      return false;                   // and move on
    }

  case 1: // Button down so far,
    if (button == LOW) return false; // Nothing happening!
    else {
      *butnstate = 3;                 // record that is now released
      *marker = millis();             // note when was released
      return false;                   // and move on
    }

  case 2: // Button was up, now down.
    if (button == HIGH) {
      *butnstate = 0;                 // no, not debounced; revert the state
      return false;                   // False alarm!
    }
    else {
      if (millis() - *marker >= interval) {
        *butnstate = 1;               // jackpot!  update the state
        return true;                  // because we have the desired event!
      }
      else
        return false;                 // not done yet; just move on
    }

  case 3: // Button was down, now up.
    if (button == LOW) {
      *butnstate = 1;                 // no, not debounced; revert the state
      return false;                   // False alarm!
    }
    else {
      if (millis() - *marker >= interval) {
        *butnstate = 0;               // Debounced; update the state
        return false;                 // but it is not the event we want
      }
      else
        return false;                 // not done yet; just move on
    }
  default:                            // Error; recover anyway
    { 
      *butnstate = 0;
      return false;                   // Definitely false!
    }
  }
}

void setup() {
  pinMode(led1Pin, OUTPUT);     
  pinMode(led2Pin, OUTPUT);     
  pinMode(led3Pin, OUTPUT);
  pinMode(led4Pin, OUTPUT); 
  pinMode(button1, INPUT);     
  digitalWrite(button1,HIGH);        // internal pullup all versions
}

void loop() {
  // Toggle switch if button debounced
  if (butndown(digitalRead(button1), &bcount1, &bstate1, 10UL )) {
    if (togl1 == LOW) {
      togl1 = HIGH;
      digitalWrite(led4Pin, HIGH);
    }
    else {
      togl1 = LOW;
      digitalWrite(led4Pin, LOW);
    }
  }

  // flash if toggle is on
  if (togl1 == HIGH) {

    // Act if the latter time (ms) has now passed on this particular counter,
    if (timeout(&count1, 150UL )) {
      if (led1State == LOW) {
        led1State = HIGH;
      }
      else {
        led1State = LOW;
      }
      digitalWrite(led1Pin, led1State);
    }

    if (timeout(&count2, 500UL )) {
      if (led2State == LOW) {
        led2State = HIGH;
      }
      else {
        led2State = LOW;
      }
      digitalWrite(led2Pin, led2State);
    }

    if (timeout(&count3, 77UL )) {
      if (led3State == LOW) {
        led3State = HIGH;
      }
      else
        led3State = LOW;
      digitalWrite(led3Pin, led3State);
    }     
  }
  else {
    led1State = LOW;
    led2State = LOW;
    led3State = LOW;
    digitalWrite(led1Pin, led1State);
    digitalWrite(led2Pin, led2State);
    digitalWrite(led3Pin, led3State);
  }
}

jameskirk

Thanks so much worked like a charm...
Mike

Paul__B

Actually, don't bet on it!

Apparently there is a problem in the sketch which I discovered a few days ago but have only just investigated.  If the LEDs are turned off - by the button - for a certain length of time (at least, hours), when the button is next pressed, all LEDs turn on but do not flash - immediately.  They start up after a time however.

I suspect a bug in the casting of variables involving the millis() count - a 16 bit counter rolls over in 65.536 seconds, so that must be the maximum time it takes to re-start.

Working on it ...

But I can't locate the bug!  All relevant variables are correctly specified as unsigned long in all cases, aren't they?  Is the compiler dodgy?

Paul__B

#24
Jun 22, 2015, 12:53 pm Last Edit: Jun 22, 2015, 12:55 pm by Paul__B
OK, re-factored code for flashing only LEDs.  (I haven't figured out the problem I mentioned yet however.)
Code: [Select]
// Blink without "delay()" - multi!

const int led1Pin =  13;    // LED pin number
const int led2Pin =  12;
const int led3Pin =  11;
const int button1 =  A1;

char led1State = LOW;        // initialise the LED
char led2State = LOW;
char led3State = LOW;
char bstate1 = 0;
char doflash = LOW;

unsigned long count1 = 0;   // will store last time LED was updated
unsigned long count2 = 0;
unsigned long count3 = 0;
unsigned long bcount1 = 0;  // button debounce timer.  Replicate as necessary.

// ----------------------------- toggle ------------------------------------------
char toggle(char *flip) {   // Yes, it toggles the variable pointed to
  if (*flip == LOW) {
    *flip = HIGH;
  }
  else {
    *flip = LOW;
  }
  return *flip;
}

// ----------------------------- timeout -----------------------------------------
// Have we completed the specified interval since last confirmed event?
// "marker" chooses which counter to check
boolean timeout(unsigned long *marker, unsigned long interval) {
  if (millis() - *marker >= interval) {
    *marker += interval;    // move on ready for next interval
    return true;       
  }
  else return false;
}

// --------------------------- button read ---------------------------------------
// Deal with a button read; true if button pressed and debounced is a new event
// Uses reading of button input, debounce store, state store and debounce interval.
// Routines by Paul__B of Arduino Forum
boolean butndown(char button, unsigned long *marker, char *butnstate, unsigned long interval) {
  switch (*butnstate) {               // Odd states if was pressed, 2 or > if debounce in progress
  case 0: // Button up so far,
    if (button == HIGH) return false; // Nothing happening!
    else {
      *butnstate = 2;                 // record that is now pressed
      *marker = millis();             // note when was pressed
      return false;                   // and move on
    }

  case 1: // Button down so far,
    if (button == LOW) return false; // Nothing happening!
    else {
      *butnstate = 3;                 // record that is now released
      *marker = millis();             // note when was released
      return false;                   // and move on
    }

  case 2: // Button was up, now down.
    if (button == HIGH) {
      *butnstate = 0;                 // no, not debounced; revert the state
      return false;                   // False alarm!
    }
    else {
      if (millis() - *marker >= interval) {
        *butnstate = 1;               // jackpot!  update the state
        return true;                  // because we have the desired event!
      }
      else
        return false;                 // not done yet; just move on
    }

  case 3: // Button was down, now up.
    if (button == LOW) {
      *butnstate = 1;                 // no, not debounced; revert the state
      return false;                   // False alarm!
    }
    else {
      if (millis() - *marker >= interval) {
        *butnstate = 0;               // Debounced; update the state
        return false;                 // but it is not the event we want
      }
      else
        return false;                 // not done yet; just move on
    }
  default:                            // Error; recover anyway
    { 
      *butnstate = 0;
      return false;                   // Definitely false!
    }
  }
}

// -------------------------------------------------------------------------------
void setup() {
  pinMode(led1Pin, OUTPUT);
  pinMode(led2Pin, OUTPUT);
  pinMode(led3Pin, OUTPUT);
  pinMode(button1, INPUT);
  digitalWrite(button1,HIGH);        // internal pullup all versions
}

void loop() {
  // Toggle switch if button debounced
  if (butndown(digitalRead(button1), &bcount1, &bstate1, 10UL )) if (toggle(&doflash) == LOW) {   
    // Turn off LEDs only as and when doflash is switched off
    led1State = LOW;
    led2State = LOW;
    led3State = LOW;
    digitalWrite(led1Pin, led1State);
    digitalWrite(led2Pin, led2State);
    digitalWrite(led3Pin, led3State);
  };

  // flash if toggle is on
  if (doflash == HIGH) {

    // Act if the latter time (ms) has now passed on this particular counter,
    if (timeout(&count1, 150UL )) {
      toggle(&led1State);
      digitalWrite(led1Pin, led1State);
    }

    if (timeout(&count2, 500UL )) {
      toggle(&led2State);
      digitalWrite(led2Pin, led2State);
    }

    if (timeout(&count3, 77UL )) {
      toggle(&led3State);
      digitalWrite(led3Pin, led3State);
    }
  }
}

Paul__B

And for the additional static LED:
Code: [Select]
// Blink without "delay()" - multi!

const int led1Pin =  13;    // LED pin number
const int led2Pin =  12;
const int led3Pin =  11;
const int led4Pin =  10;
const int button1 =  A1;

char led1State = LOW;        // initialise the LED
char led2State = LOW;
char led3State = LOW;
char bstate1 = 0;
char doflash = LOW;

unsigned long count1 = 0;   // will store last time LED was updated
unsigned long count2 = 0;
unsigned long count3 = 0;
unsigned long bcount1 = 0;  // button debounce timer.  Replicate as necessary.

// ----------------------------- toggle ------------------------------------------
char toggle(char *flip) {   // Yes, it toggles the variable pointed to
  if (*flip == LOW) {
    *flip = HIGH;
  }
  else {
    *flip = LOW;
  }
  return *flip;
}

// ----------------------------- timeout -----------------------------------------
// Have we completed the specified interval since last confirmed event?
// "marker" chooses which counter to check
boolean timeout(unsigned long *marker, unsigned long interval) {
  if (millis() - *marker >= interval) {
    *marker += interval;    // move on ready for next interval
    return true;      
  }
  else return false;
}

// --------------------------- button read ---------------------------------------
// Deal with a button read; true if button pressed and debounced is a new event
// Uses reading of button input, debounce store, state store and debounce interval.
// Routines by Paul__B of Arduino Forum
boolean butndown(char button, unsigned long *marker, char *butnstate, unsigned long interval) {
  switch (*butnstate) {               // Odd states if was pressed, 2 or > if debounce in progress
  case 0: // Button up so far,
    if (button == HIGH) return false; // Nothing happening!
    else {
      *butnstate = 2;                 // record that is now pressed
      *marker = millis();             // note when was pressed
      return false;                   // and move on
    }

  case 1: // Button down so far,
    if (button == LOW) return false; // Nothing happening!
    else {
      *butnstate = 3;                 // record that is now released
      *marker = millis();             // note when was released
      return false;                   // and move on
    }

  case 2: // Button was up, now down.
    if (button == HIGH) {
      *butnstate = 0;                 // no, not debounced; revert the state
      return false;                   // False alarm!
    }
    else {
      if (millis() - *marker >= interval) {
        *butnstate = 1;               // jackpot!  update the state
        return true;                  // because we have the desired event!
      }
      else
        return false;                 // not done yet; just move on
    }

  case 3: // Button was down, now up.
    if (button == LOW) {
      *butnstate = 1;                 // no, not debounced; revert the state
      return false;                   // False alarm!
    }
    else {
      if (millis() - *marker >= interval) {
        *butnstate = 0;               // Debounced; update the state
        return false;                 // but it is not the event we want
      }
      else
        return false;                 // not done yet; just move on
    }
  default:                            // Error; recover anyway
    {  
      *butnstate = 0;
      return false;                   // Definitely false!
    }
  }
}

// -------------------------------------------------------------------------------
void setup() {
  pinMode(led1Pin, OUTPUT);
  pinMode(led2Pin, OUTPUT);
  pinMode(led3Pin, OUTPUT);
  pinMode(button1, INPUT);
  digitalWrite(button1,HIGH);        // internal pullup all versions
}

void loop() {
  // Toggle switch if button debounced
  if (butndown(digitalRead(button1), &bcount1, &bstate1, 10UL )) if (toggle(&doflash) == HIGH) {
    digitalWrite(led4Pin, HIGH);
  }
  else {    
    // Turn off LEDs only as and when doflash is switched off
    led1State = LOW;
    led2State = LOW;
    led3State = LOW;
    digitalWrite(led1Pin, led1State);
    digitalWrite(led2Pin, led2State);
    digitalWrite(led3Pin, led3State);
    digitalWrite(led4Pin, LOW);
  };

  // flash if toggle is on
  if (doflash == HIGH) {

    // Act if the latter time (ms) has now passed on this particular counter,
    if (timeout(&count1, 150UL )) {
      toggle(&led1State);
      digitalWrite(led1Pin, led1State);
    }

    if (timeout(&count2, 500UL )) {
      toggle(&led2State);
      digitalWrite(led2Pin, led2State);
    }

    if (timeout(&count3, 77UL )) {
      toggle(&led3State);
      digitalWrite(led3Pin, led3State);
    }
  }
}

jameskirk


jameskirk

Ok now that I got this one...
I've been looking but I can't find it how to have multiple buttons and LED's in the same sketch...
Like 4 buttons and 4 LED's each turning each LED on and then off...
Thanks

UKHeliBob

If you know how to turn one LED on and off with successive button presses then you could
(a) repeat the code 4 times
or
(b) use arrays of variables and pin numbers and a for loop to read the buttons and act on them.

Actually, your requirements are unclear.  Should each button affect only 1 LED or all LEDs ?
Please do not send me PMs asking for help.  Post in the forum then everyone will benefit from seeing the questions and answers.

jameskirk

I have this project that has 4 buttons and 4 LED's on the same
Arduino... Each LED has it's own button to switch separately...
Also there is a sound module that goes with each press of the button...
Example push button 1 blink the LED and the sound module makes a sound
button 2, 3 and 4 also...
I was using the blink sketch for the sound module...

Go Up