Controlling LED light using a limit switch

Hello everyone,

I having a few problem with coding. My goal is to control an LED light using a limit switch. When first press the switch, the light turn on and when release the switch the light stay on until the switch is pressed again then the light will turn off. Does that make sense to you guys? (I am sorry. English is not my first language). This is what I got in my code so far but it does not seem to work. Please let me know if you have any suggestion. Thank you in advance.

int sw1;
int LM1 = 6;
int LED1 = 4;
//Status variable, 0 is off and 1 is on
int Status_variable = 0;

void setup() {
  
  pinMode(LM1, INPUT_PULLUP);

  pinMode(LED1, OUTPUT);
  digitalWrite(LED1, LOW);
  
}

void loop(){

  sw1 = digitalRead(LM1);

  if (sw1 == LOW && Status_variable == 0)
  {

      digitalWrite(LED1, LOW);
      Status_variable = 0;
      delay(500);
 
    
  }
  if (sw1 == HIGH && Status_variable == 0)
  {

      digitalWrite(LED1, HIGH);
      Status_variable = 1;
      delay(500);
    
  }
   if (sw1 == LOW && Status_variable == 1)
  {

      digitalWrite(LED1, HIGH);
      Status_variable = 1;
      delay(500);
   
  }
    if (sw1 == HIGH && Status_variable == 1)
  {

      digitalWrite(LED1, LOW);
      Status_variable = 0;
      delay(500);
    
  }
  
  
  }

We know it does not seem to work because you would not be here if it did work. Your sketch does something. What does it actually do?

How are the LED and switch wired? Active-low or active-high?

At first glance those delays seem to be excessive.

@MorganS

Yes, my coded toggles the light off and on endlessly. Only when I hold the switch, the light will stay on.

The LED is wired anode to 5V cathode to pin 4. The switch is wired to pin 6 and ground.

I am not certain but it should be active-low (please don't roast me if I am wrong).

Thank you.

No, that is correct. By setting LOW on the output pin, the LED will be powered on.

So I just read through the code in order. It starts by recording the state of the switch. Then...

  1. If the switch is pressed and the status is 0 (off) then turn the LED on and set status to 0.

  2. If the switch is not pressed and the status is 0 then turn it off and set status to 1.

  3. If the switch is pressed and the status is 1 (on) then turn it off and set status to 1.

  4. If the switch is not pressed and the status is 1 then turn it on and set status to 0.

So if the switch isn't pressed, 2 and 4 will blink it on and off. If it is pressed then 1 turns it on repeatedly. Unless you pressed it while it was on, then 3 turns it off repeatedly.

I hope the logical changes are obvious?

@MorganS

I have made some modification based on your suggestion.

  1. If the switch is not pressed, do nothing.

  2. If the switch is press and the status is 0 then turn the light on and set status to 1.

  3. If the switch is press and the status is 1 then turn the light off and set status to 0.

The result that I got is

  1. When the switch is pressed, the light turn on. When the switch is released, the light turn off.

  2. When holding the switch, it toggles the light on and off every half second.

  3. The Serial.println shows the status variable is always 0 unless the switch is pressed that when it will change to 1 and immediately goes back to 0.

What am I missing here? Thank you!

int sw1;
int LM1 = 6;

int LED1 = 4;
//Status variable, 0 is off and 1 is on
int Status_variable = 0;

void setup() {
  
  pinMode(LM1, INPUT_PULLUP);

  pinMode(LED1, OUTPUT);
  digitalWrite(LED1, HIGH);
  Serial.begin(9600);
  
}

void loop(){

  sw1 = digitalRead(LM1);

  if (sw1 == HIGH)
  {
 
    Serial.println(Status_variable);
  }

  if (sw1 == LOW && Status_variable == 0)
  {

      digitalWrite(LED1, LOW);
      Status_variable = 1;
      delay(500);
     Serial.println(Status_variable);
   
  }
   if (sw1 == LOW && Status_variable == 1)
  {

      digitalWrite(LED1, HIGH);
      Status_variable = 0;
       delay(500);
      Serial.println(Status_variable);
  }
  
  
  }

I found the solution!

// This will store the last known state of the button
const int buttonPin = 6;   // change as per your button attached. 
   // 
const int ledPin = 4;
 int x = 1;
// variables will change:
int buttonState = 0;         
int oldButtonState = HIGH;


void setup() {
  // initialize the LED pin as an output:
   
  // initialize the pushbutton pin as an input:
  pinMode(buttonPin, INPUT_PULLUP);   
  pinMode(ledPin, OUTPUT);  
  digitalWrite(ledPin, HIGH);
}




void loop()
{
  // Get the current state of the button
  int newButtonState = digitalRead(buttonPin);

  // Has the button gone high since we last read it?
  if (newButtonState == HIGH && oldButtonState == LOW) {

    if (x == 0) {
      // Toggle on
      digitalWrite(ledPin, HIGH);
      x = 1;
      delay(500);

    } else {
      // Toggle off
      digitalWrite(ledPin, LOW);
      x = 0;
      delay(500);
    }
  }

  // Store the button's state so we can tell if it's changed next time round
  oldButtonState = newButtonState;
}

My main issue is that I did not store the new statement so it always change.

Good to know you got it working. Now you can reduce that 500-millisecond delay down to a more useful number like 5. Or learn about proper de-bouncing for mechanical switches.