0

I am trying to make a button work as a switch. The code works to turn the lights "on" but the code doesn't want to turn them off.

My code works like so:

  1. If button is pressed and the lights are off, turn on the lights.
  2. If button is pressed and the lights are on, turn off the lights.

But number 2 doesn't work.

int buttonStatus = 0;
int check = 1;
int Status = 0;

void setup() {
  pinMode(5,OUTPUT);
  pinMode(7,OUTPUT);
  pinMode(9,OUTPUT);
  pinMode(11,OUTPUT);
  pinMode(13,OUTPUT);
  pinMode(2,INPUT);
}

void loop() {
  if (check = 1) {
    buttonStatus = digitalRead(2);
    if (buttonStatus == HIGH && Status == 0) {
      Status = 1;
      buttonStatus = 0;
    } else if (buttonStatus == HIGH && Status == 1) {
      Status = 0;
      buttonStatus = 0;
    }
  }

  if (Status == 1) {
    digitalWrite(5,HIGH);
    delay(50);
    digitalWrite(5,LOW);
    digitalWrite(7,HIGH);
    delay(50);
    digitalWrite(7,LOW);
    digitalWrite(9,HIGH);
    delay(50);
    digitalWrite(9,LOW);
    digitalWrite(11,HIGH);
    delay(100);
    digitalWrite(11,LOW);
    digitalWrite(13,HIGH);
    delay(100);
    digitalWrite(13,LOW);
  } else {
    digitalWrite(5,LOW);
    digitalWrite(7,LOW);
    digitalWrite(9,LOW);
    digitalWrite(11,LOW);
    digitalWrite(13,LOW);
  }
}
dda
  • 6,030
  • 2
  • 25
  • 34
  • You're turning off the lights in both cases... `digitalWrite(5,HIGH); delay(50); digitalWrite(5,LOW);` will turn off the LED after turning it on quickly. – dda Jan 02 '17 at 07:11
  • @dda Yeah thats my code it turns on then turns of then another turns on and turns off. – JulesTheGodOfMC Jan 02 '17 at 09:00

3 Answers3

0

Try adding debounce delay. This is common issue with switches. https://www.arduino.cc/en/Tutorial/Debounce

bnss
  • 1
  • 1
  • I don't see how that would help at all or block it – JulesTheGodOfMC Jan 02 '17 at 12:58
  • Pressing switch without debounce delay may be read as multiple presses and lead to malfunction in process. There is an example code that shows a good way to handle switches on one state buttons. – bnss Jan 02 '17 at 15:04
0

Maybe it's because of a floating pin. Have you built in a pull up or pull down resistor?

It's a common thing...

Chris8447
  • 306
  • 4
  • 7
0

Ok, your description and your code tell two different things. I'm try to interprete them, but if I'm wrong just tell me and I'll try to correct the answer.

This code lets you use a pushbutton to turn on and off a light on pin 5. One press will turn it on, the other will turn it off. You have to connect the button with one end to pin 2 and the other to ground (since we are using a pull-up resistor).

I also added a small debounce delay to cope with the bounces of the mechanical switch (50ms)

byte buttonStatus;
unsigned long lastEqualButtonTime;
#define debounceTimeMs 50

void setup() {
    pinMode(5,OUTPUT);
    pinMode(2,INPUT_PULLUP);
    buttonStatus = digitalRead(2);
    lastEqualButtonTime = millis();
}

void loop() {
    byte currentButtonStatus = digitalRead(2);
    if (currentButtonStatus == buttonStatus)
        lastEqualButtonTime = millis();
    else if ((millis() - lastEqualButtonTime) > debounceTimeMs)
    {
        lastEqualButtonTime = millis();
        buttonStatus = currentButtonStatus;

        // Change only on change, not on value
        if (buttonStatus == LOW) {
            digitalWrite(5, !digitalRead(5));
        }
    }
}

When you press the button the led on pin 5 will turn on, when you press it again it will turn off.

This is the behavior you asked. Your code, on the other side, lights up a sequence of LEDs when you push the button. In this case, if you want to start the cycle with a press and then stop it with another press, you have to use a sort of simple state machine, like the one in the code. I also added a small debounce to the button, which needs again to be connected between 2 and ground.

byte buttonStatus;
unsigned long lastEqualButtonTime;
#define debounceTimeMs 50

// Statuses
#define STATE_LEDSOFF 0
#define STATE_LED5ON  1
#define STATE_LED7ON  2
#define STATE_LED9ON  3
#define STATE_LED11ON 4
#define STATE_LED13ON 5

// How much time should each led be on?
// Expressed in milliseconds
#define TIME_LED5ON   50
#define TIME_LED7ON   50
#define TIME_LED9ON   50
#define TIME_LED11ON 100
#define TIME_LED13ON 100

byte stateMachineStatus;
unsigned long stateMachineTime;

void setup() {
    pinMode(5,OUTPUT);
    pinMode(7,OUTPUT);
    pinMode(9,OUTPUT);
    pinMode(11,OUTPUT);
    pinMode(13,OUTPUT);
    pinMode(2,INPUT_PULLUP);
    buttonStatus = digitalRead(2);
    lastEqualButtonTime = millis();
    stateMachineStatus = STATE_LEDSOFF;
}

void loop() {
    byte currentButtonStatus = digitalRead(2);
    if (currentButtonStatus == buttonStatus)
        lastEqualButtonTime = millis();
    else if ((millis() - lastEqualButtonTime) > debounceTimeMs)
    {
        lastEqualButtonTime = millis();
        buttonStatus = currentButtonStatus;

        // Change only on change, not on value
        if (buttonStatus == LOW) {
            // Turn on the LEDs sequence if it was off
            if (stateMachineStatus == STATE_LEDSOFF)
            {
                stateMachineStatus = STATE_LED5ON;
                stateMachineTime = millis();
            }
            else // Turn it off if it was on
                stateMachineStatus = STATE_LEDSOFF;
        }
    }

    switch (stateMachineStatus)
    {
    case STATE_LEDSOFF:
        digitalWrite(5,LOW);
        break;
    case STATE_LED5ON:
        digitalWrite(5,HIGH);
        if ((millis() > stateMachineTime) > TIME_LED5ON)
        {
            stateMachineTime += TIME_LED5ON;
            digitalWrite(5,LOW);
            stateMachineStatus = STATE_LED7ON;
        }
        break;
    case STATE_LED7ON:
        digitalWrite(7,HIGH);
        if ((millis() > stateMachineTime) > TIME_LED7ON)
        {
            stateMachineTime += TIME_LED7ON;
            digitalWrite(7,LOW);
            stateMachineStatus = STATE_LED9ON;
        }
        break;
    case STATE_LED9ON:
        digitalWrite(9,HIGH);
        if ((millis() > stateMachineTime) > TIME_LED9ON)
        {
            stateMachineTime += TIME_LED9ON;
            digitalWrite(9,LOW);
            stateMachineStatus = STATE_LED11ON;
        }
        break;
    case STATE_LED11ON:
        digitalWrite(11,HIGH);
        if ((millis() > stateMachineTime) > TIME_LED11ON)
        {
            stateMachineTime += TIME_LED11ON;
            digitalWrite(11,LOW);
            stateMachineStatus = STATE_LED13ON;
        }
        break;
    case STATE_LED13ON:
        digitalWrite(13,HIGH);
        if ((millis() > stateMachineTime) > TIME_LED13ON)
        {
            stateMachineTime += TIME_LED13ON;
            digitalWrite(13,LOW);
            stateMachineStatus = STATE_LED5ON;
        }
        break;
    default:
        stateMachineStatus = STATE_LEDSOFF;
        break;

    }
}

This works in this way: you press the button and the board will start cycling through the LEDS. 5, 7, 9, 11, 13, 5, 7, 9, 11, 13, ... Until you press again the button. When you do this, it stops, then at the next press restarts from 5.

If you want that after the 13 it stops, change the line 105 from stateMachineStatus = STATE_LED5ON; to stateMachineStatus = STATE_LEDSOFF;.

One note: in your code the delay is too low (and it is the same that I put here): 50 ms between one led and the other cannot be noticed. If you want to actually see them in sequence, put values of at least 250 in the TIME_LEDxON defines.

DISCLAIMER: I haven't tested these codes since I don't have arduino ide installed at present. If there are some bugs, simply tell me and I'll fix them.

frarugi87
  • 2,826
  • 1
  • 20
  • 41