Please help!

I have been staring, troubleshooting, researching, and testing this program for the past 7 hours and I can’t figure out how to get it to work. I posted a question yesterday, but I think my problem was misinterpreted. So, I am simplifying it here, and hopefully I can apply any advice to my main program.

I am brand new at programming. The answer to this problem seems so simple it’s frustrating. Someone please kindly point me in the right direction or offer me an example that I can apply.

TASK:

Push Button1.

Led1 blinks 4 times then stops.

Push Button2.

Led2 blinks 4 times then stops.

Button1 has priority over Button2 at ALL times. So, If Button2 is pressed, Led2 will begin to blink. However, if Button1 is pressed while Led2 is blinking, Led2 will PAUSE, and Led1 will blink 4 times. Then, Led2 will finish blinking.

I can get both LED’s to blink with the button presses. I just do not know how to PAUSE Led2, and give Led1 priority. I’ve tried the if-else statements to no avail. Someone please kindly help me.

Here’s what I have:

int ledPin1 = 3;
int ledPin2 = 4;

int buttonPin  = 2;
int buttonPin2 = 11;

int a =0;
int b =0;


void setup()
 {
    pinMode(ledPin1,OUTPUT);
    pinMode(ledPin2,OUTPUT);
    pinMode(buttonPin,INPUT);
    pinMode(buttonPin2,INPUT);
  }
   

void loop() 

{
       a = digitalRead(buttonPin);
       b = digitalRead(buttonPin2);
     
      if (a == HIGH)
       
       {
             digitalWrite(ledPin1, HIGH); 
             delay(1000);
             digitalWrite(ledPin1,LOW);
             delay(1000);
             digitalWrite(ledPin1, HIGH); 
             delay(1000);
             digitalWrite(ledPin1,LOW);
             delay(1000);
        }
        
       if (b == HIGH)
       
        {
             digitalWrite(ledPin2, HIGH); 
             delay(1000);
             digitalWrite(ledPin2,LOW);
             delay(1000);
             digitalWrite(ledPin2, HIGH); 
             delay(1000);
             digitalWrite(ledPin2,LOW);
             delay(1000);
        }
        
        
     
}

**EDIT: I have now been working on this problem for 10 hours. Desperately need help!

Some clarification please.

Push Button1.

Does the button have to remain pressed for the LED to blink or can it be released ?

if Button1 is pressed while Led2 is blinking,

You will need to do is to get rid if the delay()s because while they happen the button pins cannot be read. Look at the BlinkWithoutDelay example in the IDE and this thread to see how to do timing without using delay() Several things at the same time

Thank-you for your reply.

I have ran the blink without delay program given. My understanding of it is tenuous at best. I see where it works for the Single if statement to "turn on Led." However I do not understand it's application to multiple parts of a program.

The Two buttons are just momentary push buttons. Press either one once, and they begin to blink LEDs for a set number of times.

BUT, if the first button is pressed while the second LED is blinking, it will pause, and then finish blinking once the first LED finishes it's number of blinks.

I've added to my code what the blink without delay demonstrates. However, this is all I can come up with as far as translating it to my application.

int ledPin1 = 3;
int ledPin2 = 4;

int buttonPin  = 2;
int buttonPin2 = 11;

int a =0;
int b =0;

int currentstate = LOW;

long previousMillis = 0;        
long interval = 1000;  


void setup()
 {
    pinMode(ledPin1,OUTPUT);
    pinMode(ledPin2,OUTPUT);
    pinMode(buttonPin,INPUT);
    pinMode(buttonPin2,INPUT);
  }
   

void loop() 

{
       unsigned long currentMillis = millis();
       a = digitalRead(buttonPin);
       b = digitalRead(buttonPin2);
     
     if(currentMillis - previousMillis > interval) 
     
     {
     
              previousMillis = currentMillis;   

     
      if (a == HIGH)  ///If button 1 is pressed
       
        {      
             digitalWrite(ledPin1, HIGH); 
            
        }                                  
                                        
        
   
   
       if (b == HIGH) ////If button 2 is pressed
       
        {
             digitalWrite(ledPin2, HIGH); 
        }
        
     }
     
}

Duplicate thread deleted.

DO NOT CROSS-POST, CROSS-POSTING WASTES TIME.

To get you started here is a program that will blink LED1 4 times when button1 is pressed. I have also included variables to control LED2 but no code.

const byte button1 = 7;
const byte button2 = 8;
const byte led1 = 10;
const byte led2 = 11;
unsigned long blinkStartTime;
unsigned long currentTime;
unsigned long blinkInterval = 1000;
byte blinkCount = 0;
byte ledState = LOW;
byte button1State = HIGH;
byte button2State = HIGH;
boolean blinking1 = false;
boolean blinking2 = false;

void setup()
{
  Serial.begin(115200);
  pinMode(button1, INPUT_PULLUP);
  pinMode(button2, INPUT_PULLUP);
  pinMode(led1, OUTPUT);
  pinMode(led2, OUTPUT);
}

void loop()
{
  button1State = digitalRead(button1);
  if (button1State == LOW && blinking1 == false)  //new blink start
  {
    blinking1 = true;
    blinkCount = 0;
    blinkStartTime = millis();
    ledState = LOW;
  }

  if (blinking1 && millis() - blinkStartTime > blinkInterval)
  {
    ledState = !ledState;
    blinkStartTime = millis();
    digitalWrite(led1, ledState);
    blinkCount++;
    if (blinkCount == 8)
    {
       blinking1 = false; 
    }
  }
}

Boolean variables are used to denote that the LED is blinking. Changing them to false will stop that LED blinking as will 4 blinks having taken place.

There is still much to do. Read the other button and act on it. As no delay()s are used you can do this in loop() If LED1 is not currently flashing allow LED2 to flash If LED1 is flashing do not allow LED2 to flash. The boolean variables will be handy for this.

ethom:
I have been staring, troubleshooting, researching, and testing this program for the past 7 hours and I can’t figure out how to get it to work. I posted a question yesterday, but I think my problem was misinterpreted. So, I am simplifying it here, and hopefully I can apply any advice to my main program.

I am brand new at programming.

What I’m always propagating is the IPO programming model:

  • Input
  • Processing
  • Output

This is what you would have to do: You write three functions input(), processing() and output() for these three tasks and call them from within your loop() function in a round robin scheduling like that:

void loop() 
{
  input();
  processing();
  output();
}

That’s easy and the best of all: You can write any Arduino program using such a programming logic. All you would have to do: Write these three functions accordingly to what you want.

ethom:
Desperately need help!

To give you a start I have prepared a demo program which already has an “input()” function that reads buttons, and an “output()” function that print each action of pressed and released buttons to serial.

This is the demo:

#define INPUTMODE INPUT_PULLUP    // INPUT or INPUT_PULLUP
#define BOUNCETIME 5              // bouncing time in milliseconds
byte buttonPins[]={2, 3, 4, 5, 6};// pin numbers of all buttons
#define NUMBUTTONS sizeof(buttonPins) // number of buttons (automatically calculated)
byte buttonState[NUMBUTTONS];  // array holds the actual HIGH/LOW states
byte buttonChange[NUMBUTTONS]; // array holds the state changes when button is pressed or released
enum{UNCHANGED,BUTTONUP,BUTTONDOWN};

void input(){
// read the input state and state changes of all buttons
  static unsigned long lastButtonTime; // time stamp for remembering the time when the button states were last read
  memset(buttonChange,0,sizeof(buttonChange)); // reset all old state changes
  if (millis()-lastButtonTime<BOUNCETIME) return;  // within bounce time: leave the function
  lastButtonTime=millis(); // remember the current time
  for (int i=0;i<NUMBUTTONS;i++) 
  {
    byte curState=digitalRead(buttonPins[i]);        // current button state
    if (INPUTMODE==INPUT_PULLUP) curState=!curState; // logic is inverted with INPUT_PULLUP
    if (curState!=buttonState[i])                    // state change detected
    {
      if (curState==HIGH) buttonChange[i]=BUTTONDOWN;
      else buttonChange[i]=BUTTONUP;
    }
    buttonState[i]=curState;  // save the current button state
  }
}


void output(){
// send a message to Serial if a button state (pressed/released) has changed
// button pressed: Send button pin number with minus sign
// button released: Send button pin number
  byte action;
  for (int i=0;i<NUMBUTTONS;i++)
  {
    switch (buttonChange[i])  
    {
      case BUTTONUP: Serial.println(buttonPins[i]);break;
      case BUTTONDOWN: Serial.println(-buttonPins[i]);break;
    }
  }
}


void setup() {
  Serial.begin(9600); // initialize Serial at 9600 baud
  // then initialize all buttons
  for (int i=0;i<NUMBUTTONS;i++) pinMode(buttonPins[i],INPUTMODE);
}

void loop() {
  input();
  // processing(); // if you need any processing, write a function for it!  
  output();
}

This demo is to handle 5 different buttons, they are declared in the “buttonPins” array. If you want a program that handles less or more buttons, just change the declaration of the “buttonPins” array.

The “input()” function is fully working. You probably need make no changes.

What you would have to do:

  1. Write your own “processing()” function.
  2. Change the “output()” function so that you get blinking output on LEDs as you want

Some suggestions for writing the “processing()” function:
For example you could write a processing function that sets a variable to remeber the numer of blinks on each LED you want to see.

  • if button one is pressed down ==> buttonOneBlinknum=4;
  • if button two is pressed down ==> buttonTwoBlinknum=4;
    And then you need a handling for the blink cycles: “ON time” and “Cycle duration”. If both LEDs are set to a number of blinks above zero, only the cycle of the high priority LED will be running. Or if only the low priority LED will have left some blinks to show, the cycle of the low priority LED will be running.

Just let me know if you need further programming help.

I would like to thank you for the help! I have been struggling trying to understand the basics and your assistance has made a big difference.

UKHeliBob,

I have taken the code that you provided and was able to add what I need to get my program to work for the most part. I had to learn a lot of the concepts in the code through trial and error, but none the less, I am learning slowly but surely.

There is one problem that I have not solved yet. When button1 is pressed while the second LED is blinking, LED 2 will pause, let LED 1 blink, but it will continue to Stay paused.

Lets say LED2 blinks twice and button 1 is pressed in this time frame. After LED 1 finishes blinking, I need LED 2 to finish it's last 2 blinks.

const byte button1 = 7;
const byte button2 = 8;
const byte led1 = 10;
const byte led2 = 11;
unsigned long blinkStartTime;
unsigned long currentTime;
unsigned long blinkInterval = 500;
byte blinkCount = 0;
byte blinkCount2 = 0;
byte ledState = LOW;
byte button1State = LOW;
byte button2State = LOW;
boolean blinking1 = false;
boolean blinking2 = false;

void setup()
{
  pinMode(button1, INPUT_PULLUP);
  pinMode(button2, INPUT_PULLUP);
  pinMode(led1, OUTPUT);
  pinMode(led2, OUTPUT);
}

void loop()
{
  button1State = digitalRead(button1);
  button2State = digitalRead(button2);
  
  {if (button1State == HIGH && blinking1 == false)  //new blink start
  {
    blinking1 = true;
    blinking2 = false;
    blinkCount = 0;
    blinkStartTime = millis();
    ledState = LOW;
  }

  if (blinking1 && millis() - blinkStartTime > blinkInterval)
  {
    ledState = !ledState;
    blinkStartTime = millis();
    digitalWrite(led1, ledState);
    blinkCount++;
    if (blinkCount == 8)
    {
       blinking1 = false; 
    }
  }
  }
  { 
  
   if (button2State == HIGH && blinking2 == false && blinking1 == false )  //new blink start
  {
    blinking2 = true;

    blinkCount2 = 0;
    blinkStartTime = millis();
    ledState = LOW;
  }

  if (blinking2 && millis() - blinkStartTime > blinkInterval)
  {
    ledState = !ledState;
    blinkStartTime = millis();
    digitalWrite(led2, ledState);
    blinkCount2++;
    if (blinkCount2 == 8)
    {
       blinking2 = false; 
    }
  }
  }
  
}

Well done for getting this far. You will no doubt use the techniques in this program in the future.

if (button2State == HIGH && blinking2 == false && blinking1 == false )  //new blink start

As you know, this is the line that causes the LED 2 flashing to start. Can we make it continue where it left off, I wonder ?

Try this. Add a new boolean variable, let's call it carryOn, and set it to false. Now change the line to

if ( (button2State == HIGH && blinking2 == false && blinking1 == false) || carryOn)  //new blink start or continuation

Set the carryOn variable to true when the LED 1 blinking interrupts LED 2 but not if LED 2 is not blinking at that time. You can tell this because blinking2 will be true at that time.

How to make LED 2 not start again from zero when carrying on ? Well, if carryOn is true, do not reset blinkCount2 to zero as you do now.

Warning - I have not tested this so it may need some tweaking.

Thank-you again for your response.

I've been reading over your advice and tweaking my code trying to understand. I would say that I'm at a complete roadblock at this point.

Here's my interpretation of what you suggested:

I am still very unclear how to get the program to GO BACK to Led2 to finish its number of blinks.

const byte button1 = 7;
const byte button2 = 8;
const byte led1 = 10;
const byte led2 = 11;
unsigned long blinkStartTime;
unsigned long currentTime;
unsigned long blinkInterval = 500;
byte blinkCount = 0;
byte blinkCount2 = 0;
byte ledState = LOW;
byte button1State = LOW;
byte button2State = LOW;
boolean blinking1 = false;
boolean blinking2 = false;
boolean carryOn = false; 
byte carryOnBlinkcount = 0; 

void setup()
{
  pinMode(button1, INPUT_PULLUP);
  pinMode(button2, INPUT_PULLUP);
  pinMode(led1, OUTPUT);
  pinMode(led2, OUTPUT);
}

void loop()
{
  button1State = digitalRead(button1);
  button2State = digitalRead(button2);
  
  if (button1State == HIGH && blinking1 == false)  //new blink start
  {
    blinking1 = true;
    blinking2 = false;
    blinkCount = 0;
    blinkStartTime = millis();
    ledState = LOW;
  }

  if (blinking1 && millis() - blinkStartTime > blinkInterval)
  {
    ledState = !ledState;
    blinkStartTime = millis();
    digitalWrite(led1, ledState);
    blinkCount++;
    if (blinkCount == 8)
    {
       blinking1 = false; 
       
    }
  
  }

  
   if ((button2State == HIGH && blinking2 == false && blinking1 == false) || carryOn )  /////// not sure how carryOn works here. 
                                                                                        ////// Arduino website has the format as  "if (x > 0 || y > 0)"
                                                                                        ////// Why is it not || carryOn == false   ?
                                                                                        
    
    
    if (carryOn == false)     ////////adding this if statement caused LED 2 to stop blinking.
    {
        { 
          
          blinking2 = true;
          blinkCount2 = 0;
          blinkStartTime = millis();
          ledState = LOW;
        }

        if (blinking2 && millis() - blinkStartTime > blinkInterval)
        {
          ledState = !ledState;
          blinkStartTime = millis();
          digitalWrite(led2, ledState);
          blinkCount2++;
          carryOnBlinkcount = blinkCount;
          if (blinkCount2 == 8)
          {
             blinking2 = false; 

          }
        }
    }
    
    else if (carryOn == true)
    
    {
      
      { 
          blinking2 = true;
          blinkCount2 = carryOnBlinkcount;
          blinkStartTime = millis();
          ledState = LOW;
        }

        if (blinking2 && millis() - blinkStartTime > blinkInterval)
        {
          ledState = !ledState;
          blinkStartTime = millis();
          digitalWrite(led2, ledState);
          carryOnBlinkcount++;
          if (carryOnBlinkcount == 8)
          {
             blinking2 = false; 
          }
        }
      
      
    }
  
}