2

The overview of my code is that I want a toggle button to be pushed and each button push will move the code to the next case statement. In each case statement, there will be different LED functions. I need help with a few things

  1. I need help with blinking 4 of the LEDs continuously with 100ms pause in case 1. Because it is not in the main loop, I am having trouble getting the 4 LEDs to switch on and off. Normally, I could just have a simple code that turns it on, then compares previous to last and if different, turns it off, and this continues.
  2. I need the code to go back to case 0 once the button has been held for 2 seconds.
  3. I cannot get my button debounce code to work from case 0 to case 1. If I add the debounce code in case 0 how I have it in the rest of the cases, it wont run through the rest of the cases. Below is the code:

//LED variables for left turn signal OUT
int LED_1 = 2; 
int LED_2 = 3;
int LED_3 = 4;
int LED_4 = 5; 

//LED variables for right turn signal OUT
int LED_5 = 6;
int LED_6 = 7;
int LED_7 = 8;
int LED_8 = 9;

//break signal OUT
int BS_OUT = A5;

//reverse signal OUT
int RS_OUT = 10;

//toggle switch button between different modes
int toggle_IN = A4;

//switch case statement variable for togglemodes
int toggleState = 0;

//variables to see if the toggle button has been pressed or not
boolean oldSwitchStateToggle = LOW;
boolean newSwitchStateToggle = LOW;

//true or false to save whether button has been pressed for switching case statements 
bool enabledToggle;

//debounce time to take care of button bouncing
const int debounce = 100; //ms

//time for holding a current time of millis()
unsigned long t = 0;



void setup() 
{
  Serial.begin(9600);
  //toggle button input
  pinMode(toggle_IN, INPUT);

  //led outputs
  pinMode(LED_4, OUTPUT);
  pinMode(LED_3, OUTPUT);
  pinMode(LED_2, OUTPUT);
  pinMode(LED_1, OUTPUT);
  pinMode(LED_5, OUTPUT);
  pinMode(LED_6, OUTPUT);
  pinMode(LED_7, OUTPUT);
  pinMode(LED_8, OUTPUT);


}

void loop() 
{
   //checking to see if toggle button has been pushed 
   newSwitchStateToggle = digitalRead(toggle_IN);
   if(newSwitchStateToggle != oldSwitchStateToggle)
  {
    if(newSwitchStateToggle == HIGH)
    {
      //enabling toggle for if statements
      enabledToggle = true;
      //case switch for flow through 4 different LED output options 
      toggleButtonState();
      
    }
    else
    enabledToggle = false;
    oldSwitchStateToggle = newSwitchStateToggle;
  }
}

void toggleButtonState()
{
  unsigned long nowToggle = millis(); 
  switch (toggleState)
  {

    case 0:
    Serial.println("0000");
          if(enabledToggle)
          {
            digitalWrite(LED_1, HIGH);
            t = nowToggle;
            toggleState = 1;
          }

          break; 
          
    case 1:
    Serial.println("1111"); 
          if(enabledToggle)
          {
            digitalWrite(LED_1, LOW);
            digitalWrite(LED_2, HIGH);
            //alows going to next state after 100ms for button debounce
            if(nowToggle - t > debounce)
            {
              toggleState = 2;
              t = nowToggle;
            }
          }
       
          break;

     case 2:
     Serial.println("2222"); 
          if(enabledToggle)
          {
            digitalWrite(LED_2, LOW);
            digitalWrite(LED_3, HIGH);
            if(nowToggle - t > debounce)
            {
              toggleState = 3;
              t = nowToggle;
            }
          }
          
          break;
          
     case 3:
     Serial.println("3333"); 
         if(enabledToggle)
          {
            digitalWrite(LED_3, LOW);
            digitalWrite(LED_4, HIGH);
            if(nowToggle - t > debounce)
            {
              toggleState = 4;
              t = nowToggle;
            }
          }
          break;
          
     case 4:
     Serial.println("44444"); 
          if(enabledToggle)
          {
            turnOffLeds();
            if(nowToggle - t > debounce)
            {
              toggleState = 0;
              t = nowToggle;
            }
          }
          break;
         
  }
}

void turnOffLeds()
{
  digitalWrite(LED_1, LOW);
  digitalWrite(LED_2, LOW);
  digitalWrite(LED_3, LOW);
  digitalWrite(LED_4, LOW);
}

updated code: trying to add in debounce but it will not work


int LED_1 = 2; 
int LED_2 = 3;
int LED_3 = 4;
int LED_4 = 5; 


int LED_5 = 6;
int LED_6 = 7;
int LED_7 = 8;
int LED_8 = 9;


//toggle switch button between different modes
int toggle_IN = A4;

//switch case statement variable for togglemodes
int toggleState = 0;

//variables to see if the toggle button has been pressed or not
boolean oldSwitchStateToggle = LOW;
boolean newSwitchStateToggle = LOW;

//true or false to save whether button has been pressed for switching case statements 
bool enabledToggle;

//debounce time to take care of button bouncing
const int debounce = 100; //ms

//time for holding a current time of millis()
unsigned long t = 0;

int ledBlinkState = LOW;

unsigned long prevBlinkMillis = 0;

const int blinkInterval = 150;

bool state1 = false;
bool state2 = false;
bool state3 = false;
bool state4 = false;
bool state0 = false;

void setup() 
{
  Serial.begin(9600);
  //toggle button input
  pinMode(toggle_IN, INPUT);

  //led outputs
  pinMode(LED_4, OUTPUT);
  pinMode(LED_3, OUTPUT);
  pinMode(LED_2, OUTPUT);
  pinMode(LED_1, OUTPUT);
  pinMode(LED_5, OUTPUT);
  pinMode(LED_6, OUTPUT);
  pinMode(LED_7, OUTPUT);
  pinMode(LED_8, OUTPUT);


}

void loop() 
{
  unsigned long nowToggle = millis(); 
  Serial.print("NOWWWWWW");
  Serial.println(nowToggle);
   //checking to see if toggle button has been pushed 
   newSwitchStateToggle = digitalRead(toggle_IN);
   if(newSwitchStateToggle != oldSwitchStateToggle)
   {
    t = nowToggle;
    Serial.print("TIMEEEEE");
    Serial.println(t);
    if(newSwitchStateToggle == HIGH)
    {
      if(nowToggle - t > debounce)
      {
        //enabling toggle for if statements
        enabledToggle = true;
        //case switch for flow through 4 different LED output options 
        toggleButtonState();
      }
      
    }
    else
    enabledToggle = false;
    oldSwitchStateToggle = newSwitchStateToggle;
  }

  unsigned long currentBlinkMillis = millis();
  
  if(state0 == true)
  {
    digitalWrite(LED_5, HIGH);
    digitalWrite(LED_6, HIGH);
    digitalWrite(LED_7, HIGH);
    digitalWrite(LED_8, HIGH);
    
    if(currentBlinkMillis - prevBlinkMillis >= blinkInterval)
    {
      prevBlinkMillis = currentBlinkMillis;
      if(ledBlinkState == LOW)
      {
        ledBlinkState = HIGH;
      }
      else
      {
        ledBlinkState = LOW;
      }
      digitalWrite(LED_1, ledBlinkState);
      digitalWrite(LED_2, ledBlinkState);
      digitalWrite(LED_3, ledBlinkState);
      digitalWrite(LED_4, ledBlinkState);
    }
  }
  
  if(state1 == true)
  {
    digitalWrite(LED_1, HIGH);
    digitalWrite(LED_2, HIGH);
    digitalWrite(LED_3, HIGH);
    digitalWrite(LED_4, HIGH);
    
    if(currentBlinkMillis - prevBlinkMillis >= blinkInterval)
    {
      prevBlinkMillis = currentBlinkMillis;
      if(ledBlinkState == LOW)
      {
        ledBlinkState = HIGH;
      }
      else
      {
        ledBlinkState = LOW;
      }
      digitalWrite(LED_5, ledBlinkState);
      digitalWrite(LED_6, ledBlinkState);
      digitalWrite(LED_7, ledBlinkState);
      digitalWrite(LED_8, ledBlinkState);
    }
  }

  if(state2 == true)
  {
    if(currentBlinkMillis - prevBlinkMillis >= blinkInterval)
    {
      prevBlinkMillis = currentBlinkMillis;
      if(ledBlinkState == LOW)
      {
        ledBlinkState = HIGH;
      }
      else
      {
        ledBlinkState = LOW;
      }
      digitalWrite(LED_1, ledBlinkState);
      digitalWrite(LED_2, ledBlinkState);
      digitalWrite(LED_3, ledBlinkState);
      digitalWrite(LED_4, ledBlinkState);
      digitalWrite(LED_5, ledBlinkState);
      digitalWrite(LED_6, ledBlinkState);
      digitalWrite(LED_7, ledBlinkState);
      digitalWrite(LED_8, ledBlinkState);
    }
  }
  
  if(state3 == true)
  {
    digitalWrite(LED_1, HIGH);
    digitalWrite(LED_2, HIGH);
    digitalWrite(LED_3, HIGH);
    digitalWrite(LED_4, HIGH);
    digitalWrite(LED_5, HIGH);
    digitalWrite(LED_6, HIGH);
    digitalWrite(LED_7, HIGH);
    digitalWrite(LED_8, HIGH);
  }
  
  if(state4 == true)
  {
    turnOffLeds();
  }
  
}

void toggleButtonState()
{
  switch (toggleState)
  {

    case 0:
    Serial.println("0000");
          if(enabledToggle)
          {
            turnOffLeds();
            state4 = false;
            state0 = true;
            toggleState = 1;
          }

          break; 
          
    case 1:
    Serial.println("1111"); 
          if(enabledToggle)
          {
            turnOffLeds();
            state0 = false;
            state1 = true;
            toggleState = 2;
          }
       
          break;

     case 2:
     Serial.println("2222"); 
          if(enabledToggle)
          {
            turnOffLeds();
            state1 = false;
            state2 = true;
            toggleState = 3;
          }
          
          break;
          
     case 3:
     Serial.println("3333"); 
         if(enabledToggle)
          {
            turnOffLeds();
            state2 = false;
            state3 = true;
            toggleState = 4;
          }
          break;
          
     case 4:
     Serial.println("44444"); 
          if(enabledToggle)
          {
            turnOffLeds();
            state3 = false;
            state4 = true;
            toggleState = 0;
          }
          break;
         
  }
}

void turnOffLeds()
{
  digitalWrite(LED_1, LOW);
  digitalWrite(LED_2, LOW);
  digitalWrite(LED_3, LOW);
  digitalWrite(LED_4, LOW);
  digitalWrite(LED_5, LOW);
  digitalWrite(LED_6, LOW);
  digitalWrite(LED_7, LOW);
  digitalWrite(LED_8, LOW);
}

6
  • 1
    1. the toggleButtonState() should not contain any LED code ... it should only set a flag ... the blink code should be inside loop() and be activated by the flag
    – jsotola
    Mar 15, 2022 at 20:42
  • 2. do button detection at begining of loop() ... the button code should only set a flag, nothing more
    – jsotola
    Mar 15, 2022 at 20:44
  • 3. ... read 2.
    – jsotola
    Mar 15, 2022 at 20:45
  • 1. So for example, I would be in case 1, and it would set a variable to true. Then in the loop, have an if statement to where if that variable is true, then it will loop through that blinking LED code?
    – Myles
    Mar 15, 2022 at 22:14
  • yes ... the loop() repeats many times a second ... use millis() to blink ... see blinkWithoutDelay example sketch
    – jsotola
    Mar 16, 2022 at 0:20

2 Answers 2

1

I would recommend you start with an existing library to do the "button debouncing" and "long button press" detection.

The EasyButton library on github and via the Arduino IDE library manager has potential.

Here is a test sketch which shows the "button detection" part of your requirement.

If you were to add a variable to represent "state", this code could be adapted to control a case statement bases on state.

// Sketch uses 3286 bytes (10%) of program storage space.
// Global variables use 357 bytes (17%) of dynamic memory.
#include <EasyButton.h>

// EasyButton(uint8_t pin, 
//            uint32_t debounce_time = 35, 
//            bool pullup_enable = true, 
//            bool active_low = true)
EasyButton button(2);

void onPressed(){
  // Your code here to INCREMENT a "state counter".
  Serial.println("Button pressed");
}

void onPressedForDuration(){
  // Your code here to SET the "state counter" to 0.
  Serial.println("Button pressed for duration");
}

void setup(){

  // Test output to serial monitor.
  Serial.begin(9600);

  // Initialize the button.
  button.begin();

  // Add the callback function to be called when the button is pressed.
  button.onPressed(onPressed);

  // Add the callback function to be called when the button is pressed
  // for at least the given time.
  button.onPressedFor(2000, onPressedForDuration);

}

void loop(){

  // Continuously read the status of the button.
  button.read();

}

2
  • I would have done it this way, but I am going to transfer this into the eclipse compiler. I am staying away from arduino made libraries. I am trying to find a way to look at what is going on in the background of the easybutton.h. Do you know where I could find this?
    – Myles
    Mar 18, 2022 at 13:55
  • 1
    @Myles - You can look at the EasyButton source code to see how it works: github.com/evert-arias/EasyButton/tree/main/src
    – VE7JRO
    Mar 18, 2022 at 16:15
0

I answered how to do a mode switch with just one button many many years ago. Make use of it what you will... it's just a sample skeleton. Here is the code I used:

/*
 Using a single switch to select between 3 modes
*/
// Schematic: http://www.pwillard.com/files/mode4.jpg
//===============================================================
// Global Variables & Constants
//===============================================================
 
const int ledPinOne = 2; // LED1 ANODE
const int ledPinTwo = 4; // LED2 ANODE
const int ledPinThree = 7; // LED3 ANODE
const int modePin = 13; // Active HIGH, held low by 4.7K
 
int mode = 0; // Selector State (Initial state = ALL OFF)
int val = 0; // Pin 13 HIGH/LOW Status
int butState = 0; // Last Button State
int modeState = 0; // Last Mode State
boolean debug = 1; // 1 = Print Serial Enabled / 0 = disabled
 
//===============================================================
// SETUP
//===============================================================
void setup () {
 pinMode(ledPinOne, OUTPUT);
 pinMode(ledPinTwo, OUTPUT);
 pinMode(ledPinThree, OUTPUT);
 pinMode(modePin, INPUT);
 if (debug){
 Serial.begin(9600);
 Serial.print("Initial Mode: ");
 Serial.println(mode);
 Serial.print("Setup Complete\n");
 }
}
 
//===============================================================
// Main Loop
//===============================================================
void loop() {
 
 val = digitalRead(modePin);
 
 // If we see a change in button state, increment mode value
 if (val != butState && val == HIGH){
 mode++;
 }
 
 butState = val; // Keep track of most recent button state
 
 // No need to keep setting pins *every* loop
 if (modeState != mode){
 
 // If no keys have been pressed yet don't execute
 // the switch code below
 // if (mode != 0) {
 
 switch ( mode ) {
 //case 1 is actually handled below as default
 
case 2:
 digitalWrite(ledPinOne, LOW);
 digitalWrite(ledPinTwo, HIGH);
 showState();
 break;
 case 3:
 digitalWrite(ledPinTwo, LOW);
 digitalWrite(ledPinThree, HIGH);
 showState();
 break;
 default:
 mode = 1;
 // loop back to 1 by default, seems redundant but
 // it also handles the "mode is > 3" problem
 digitalWrite(ledPinThree, LOW);
 digitalWrite(ledPinOne, HIGH);
 showState();
 break;
 } // end switch
// } // end of "if mode = 0" check
 } // end of ModeState check
 modeState = mode; // Keep track of mode recent mode value
 delay(10); // slow the loop just a bit for debounce
}
 
//===============================================================
// Subroutine
//===============================================================
void showState() {
 if (debug){
 Serial.print("Mode: ");
 Serial.println(mode);
 }
}

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Not the answer you're looking for? Browse other questions tagged or ask your own question.