3 buttons for 3 LEDS - SOLVED

Hi All,
I am writing a simple program that is supposed to have 3 buttons control 3 LEDS when the button is double clicked.

The code itself works fine for a single button + LED and for 2 buttons + 2 LEDS. When I put the 3rd one in it won't work.
I believe it has something to do with the UNO HW restricting me but I could not find anything online to suggest so.

If I switch the button pins (use 2,3,4 or 4,5,6 etc) I can only get 2 LEDS to work. I can swap the cable from the pin to the button (swap between 2 and 4 for example assuming 2 works and 4 doesn't) - now the circuit that was connected to 4 (and didn't work) is connected to 2 and works (and vise versa) suggesting it is not my wiring or circuit.

I am using pins (2,3,4) for button and (7,8,9) for LED but used all sorts of comps.
When I use this setup Pin 4 doesn't work.
Code below
Thanks!

//button declerations  
const int buttonGRN = 2;
const int buttonRED = 3;
const int buttonGRN1 =4;

// led decleratons
int lightOutputGRN = 7;
int lightOutputRED = 8;
int lightOutputGRN1 = 9;

int bounceTime = 50;
int doubleTime = 500; 

int lastReadingGRN = LOW;
int lastReadingRED = LOW;
int lastReadingGRN1 = LOW;

long onTimeGRN = 0;
long onTimeRED= 0;
long onTimeGRN1= 0;

long lastSwitchTime = 0;
long lastSwitchTimeRED = 0;
long lastSwitchTimeGRN1 = 0;


void setup() 
{
  pinMode(buttonGRN, INPUT);
  pinMode(lightOutputGRN, OUTPUT);
  
  pinMode(buttonRED, INPUT);
  pinMode(lightOutputRED, OUTPUT);
  
  pinMode(buttonGRN1, INPUT);
  pinMode(lightOutputGRN1, OUTPUT);
  
  Serial.begin(9600); // to communicate with serial
}

void loop() 
{
          int readingGRN1 = digitalRead(buttonGRN1);

  //first pressed
  if (readingGRN1 == HIGH && lastReadingGRN1 == LOW) 
  {
    onTimeGRN1 = millis();
 }
 
//released
  if (readingGRN1 == LOW && lastReadingGRN1 == HIGH) 
  {
    if (((millis() - onTimeGRN1) > bounceTime)) 
    {
     onReleaseGRN1();
    }
 
  }
  lastReadingGRN1 = readingGRN1;
  
  int readingGRN = digitalRead(buttonGRN);

//first pressed
  if (readingGRN == HIGH && lastReadingGRN == LOW) 
  {
    onTimeGRN = millis();
  }

//released
  if (readingGRN == LOW && lastReadingGRN == HIGH) 
  {
    if (((millis() - onTimeGRN) > bounceTime)) 
    {
      onReleaseGRN();
    }
  }
  lastReadingGRN = readingGRN;

  int readingRED = digitalRead(buttonRED);

//first pressed
  if (readingRED == HIGH && lastReadingRED == LOW) 
  {
    onTimeRED = millis();
  }

//released
  if (readingRED == LOW && lastReadingRED == HIGH) 
  {
    if (((millis() - onTimeRED) > bounceTime)) 
    {
     onReleaseRED();
    }
 
  }
  lastReadingRED = readingRED;
} //end loop

void onReleaseGRN() 
{

  if ((millis() - lastSwitchTime) >= doubleTime) 
  {
    lastSwitchTime = millis();
    return;
  }  

  if ((millis() - lastSwitchTime) < doubleTime) 
  {
    lastSwitchTime = millis();
  
          //light up led for 3 sec then turn off
         digitalWrite(lightOutputGRN, HIGH);
         delay(3000);
         digitalWrite(lightOutputGRN, LOW);
  }  

}

void onReleaseRED() 
{

  if ((millis() - lastSwitchTimeRED) >= doubleTime) 
  {
    lastSwitchTimeRED = millis();
    return;
  }  

  if ((millis() - lastSwitchTimeRED) < doubleTime) 
  {
    lastSwitchTimeRED = millis();
 
         //light up led for 3 sec then turn off
         digitalWrite(lightOutputRED, HIGH);
         delay(3000);
         digitalWrite(lightOutputRED, LOW);
  }  

}


void onReleaseGRN1() 
{

  if ((millis() - lastSwitchTimeGRN1) >= doubleTime) 
  {
    lastSwitchTimeGRN1 = millis();
    return;
  }  

  if ((millis() - lastSwitchTimeGRN1) < doubleTime) 
  {
         //light up led for 3 sec then turn off
         digitalWrite(lightOutputGRN1, HIGH);
         delay(3000);
         digitalWrite(lightOutputGRN1, LOW);
    
  }  
}

[EDIT]
I forgot to mention I also did the following test:

I added one line of code (see below for exact location in code)
Serial.println(lastReadingGRN);
and did he same for GRN1 (the problematic LED)

When I do that for GRN - the serial monitor shows a lot of 0-s, then I click (once) and it changes to 1-s and then 0-s again after I release.
when I do this for GRN1 - serial shows 0-s, then I click once and is shows 1-s, but does not show 0-s again when I release.
Any ideas as to why it doesn't set the value back to LOW?

//released
  if (readingGRN == LOW && lastReadingGRN == HIGH) 
  {
    if (((millis() - onTimeGRN) > bounceTime)) 
    {
      onReleaseGRN();
    }
  }
  lastReadingGRN = readingGRN;
        Serial.println(lastReadingGRN);

Thanks!
[/EDIT]

Hi yoavac,

Can I just check: you do have pulldown resistors on your switch inputs? What you describe sounds like they may be "floating".

Paul

Hi Paul,
yes, i do have a pulldown resistor on each one of my inputs
Thanks

There is nothing in you code that is "Limited by the UNO hardware".

From bitter experience I know that cut-n-pasted code-snippets and then changing variable names (your identical code sections that use ...RED, GRN and ...GRN1) is prone to forgetting or mixing up a name. I've looked and didnt find one, but these are hard to see.

PaulRB has asked about the pulldown resistor - this assumes the switch pulls the line high.

There is the possibililty that pin4 is "bad". If you played a lot with your UNO you may have "stressed" the pin. Try using pin 5 instead of 4.

Hi,
I actually tried changing the pins several time, but i figured heck, i'll give it another try.
5 didn't work either :frowning:
but i moved things around and managed find enough that do work.
sometimes you just have to try one more time haha.
Thanks a lot of the help!!! :grin:

Well, if it works then everybody is happy. :slight_smile:

If it works and you do not know why it suddenly worked, then you may suddenly have a surprise. (It stops working)

Some possible faults have been mentioned. In addition I can suggest you may not have the wiring you think you have - which is why the troubles started with the 3rd LED/button. You may have an errenous wiring one that is wrong but happens to work for the wrong reasons.