0

Problem 1: LED1 needs to be on only when button1 is held down. Right now it takes several presses to turn on and off and stays on. Problem 1: LEDs 2,3,4 do not turn off with buttons 2,3,4. They are all turned off by button1, which is what I want, but I also need them to turn of with their respective button presses.

I need buttons 2,3,4 to light up LEDs 2,3,4 and stay lit until I press the respective buttons again OR button1 which turns off all lights, and the LED for button1 must only stay on when button1 is held down.

I am half way there with just a few minor problems. The first is LED1 stays on rather than when I hold the button1 down only. And the other problem is, it takes many presses to turn the LEDs on or off. I fixed this on 2,3,4 by removing the following code for each pin:

if (digitalRead(buttonPin2) == HIGH) { // check if buttonPin2 was pressed (be sure to use a resistor?)
  { digitalWrite(ledPin2, LOW);       // turn ledPin2 on
    ledPin2_status = 1;                // 1 = on, set ledPin2_status to 1
  }

After I remove that code the LEDs light straight away and stay on until I press button 1 which is what I want. But I would also like LEDs 2,3,4 to turn off with their respective button press. With that code removed LEDs 2,3,4 no longer work independently of button1.

Full Code:

// set pins
const int buttonPin1 = 2;                 // Pin1's pushbutton
const int buttonPin2 = 4;                 // Pin2's pushbutton
const int buttonPin3 = 6;                 // Pin3's pushbutton
const int buttonPin4 = 8;                 // Pin4's pushbutton
const int ledPin1 = 3;                    // Pin1's LED
const int ledPin2 = 5;                    // Pin2's LED
const int ledPin3 = 7;                    // Pin3's LED
const int ledPin4 = 9;                    // Pin4's LED

// set variables
int ledPin1_status = 0;
int ledPin2_status = 0;
int ledPin3_status = 0;
int ledPin4_status = 0;

void setup() {  //initialize pins
  pinMode(buttonPin1, INPUT); // set PINn as INPUT
  pinMode(buttonPin2, INPUT);
  pinMode(buttonPin3, INPUT);
  pinMode(buttonPin4, INPUT);
  pinMode(ledPin1, OUTPUT);   // set LEDn as OUTPUT
  pinMode(ledPin2, OUTPUT);
  pinMode(ledPin3, OUTPUT);
  pinMode(ledPin4, OUTPUT);
}

// the following variables are unsigned longs because the time, measured in
// milliseconds, will quickly become a bigger number than can be stored in an int.
unsigned long lastDebounceTime = 0;  // the last time the output pin was toggled
unsigned long debounceDelay = 50;    // the debounce time; increase if the output flickers

void loop() {
  if (digitalRead(buttonPin1) == HIGH) { // check if buttonPin1 was pressed (be sure to use a resistor?)
    if (ledPin1_status == 0) {           // check if ledPin1 was not already pressed
      digitalWrite(ledPin1, HIGH);       // turn ledPin1 on
      ledPin1_status = 1;                // 1 = on, set ledPin1_status to 1
    }
    else {
      digitalWrite(ledPin1, LOW);        // turn ledPin1 off
      ledPin1_status = 0;                // 0 = off, set Pin1_status to 0
      digitalWrite(ledPin2, LOW);        // turn ledPin2 off
      ledPin2_status = 0;                // 0 = off, set Pin2_status to 0
      digitalWrite(ledPin3, LOW);        // turn ledPin3 off
      ledPin3_status = 0;                // 0 = off, set Pin2_status to 0
      digitalWrite(ledPin4, LOW);        // turn ledPin4 off
      ledPin3_status = 0;                // 0 = off, set Pin2_status to 0
    }
  }

  if (digitalRead(buttonPin2) == HIGH) { // check if buttonPin2 was pressed (be sure to use a resistor?)
    { digitalWrite(ledPin2, HIGH);       // turn ledPin2 on
      ledPin2_status = 1;                // 1 = on, set ledPin2_status to 1
    }
  }

  if (digitalRead(buttonPin2) == HIGH) { // check if buttonPin2 was pressed (be sure to use a resistor?)
    { digitalWrite(ledPin2, LOW);       // turn ledPin2 on
      ledPin2_status = 1;                // 1 = on, set ledPin2_status to 1
    }
  }

  if (digitalRead(buttonPin3) == HIGH) { // check if buttonPin3 was pressed (be sure to use a resistor?)
    { digitalWrite(ledPin3, HIGH);       // turn ledPin3 on
      ledPin3_status = 1;                // 1 = on, set ledPin3_status to 1
    }
  }

  if (digitalRead(buttonPin3) == HIGH) { // check if buttonPin2 was pressed (be sure to use a resistor?)
    { digitalWrite(ledPin3, LOW);       // turn ledPin3 on
      ledPin2_status = 1;                // 1 = on, set ledPin2_status to 1
    }
  }

  if (digitalRead(buttonPin4) == HIGH) { // check if buttonPin2 was pressed (be sure to use a resistor?)
    { digitalWrite(ledPin4, HIGH);       // turn ledPin4 on
      ledPin2_status = 1;                // 1 = on, set ledPin2_status to 1
    }
  }

  if (digitalRead(buttonPin4) == HIGH) { // check if buttonPin2 was pressed (be sure to use a resistor?)
    { digitalWrite(ledPin4, LOW);       // turn ledPin4 on
      ledPin2_status = 1;                // 1 = on, set ledPin2_status to 1
    }
  }
  • names like buttonPin1, ledPin1 and ledPin1_status clutter up the code listing .... just use names like button1, led1 and led1_status – jsotola Jul 18 '18 at 22:18
1

First thing, you need to debounce your buttons. The fact that you declared the (unused) variable debounceDelay suggests you have though about debouncing, but you did not implement it.

Next thing, you should look for button press and release events. That's when the button pin changes state from LOW to HIGH or vice versa. It is not enough to check whether the pin is HIGH or LOW, you have to check for the changes in state. This is usually called edge detection.

With enough effort, you could probably do that yourself. However, to make your life easier, you can use a debouncing library that does edge detection, such as the quite popular Bounce2. This library provides, for each button it debounces, a rose() method that tells you when the input signal rose (i.e. transitioned from LOW to HIGH) and a fell() method that tells you when it fell (transitioned HIGH → LOW). Using these methods, your problem can be coded in a fair natural way. For example (not tested):

#include <Bounce2.h>

const int     BUTTON_COUNT = 4;
const int16_t DEBOUNCE_DELAY = 50;
const uint8_t buttonPins[BUTTON_COUNT] = {2, 4, 6, 8};
const uint8_t ledPins[BUTTON_COUNT] = {3, 5, 7, 9};

Bounce buttons[BUTTON_COUNT];
uint8_t ledStates[BUTTON_COUNT];

void setup() {
    for (int i = 0; i < BUTTON_COUNT; i++) {
        buttons[i].attach(buttonPins[i], INPUT);
        buttons[i].interval(DEBOUNCE_DELAY);
        pinMode(ledPins[i], OUTPUT);
        ledStates[i] = LOW;
        digitalWrite(ledPins[i], ledStates[i]);
    }
}

void loop() {

    // Update the debouncers.
    for (int i = 0; i < BUTTON_COUNT; i++)
        buttons[i].update();

    // When the first button is pressed:
    if (buttons[0].rose()) {

        // Light up the first LED.
        digitalWrite(ledPins[0], HIGH);

        // and turn off all the others.
        for (int i = 1; i < BUTTON_COUNT; i++) {
            ledStates[i] = LOW;
            digitalWrite(ledPins[i], ledStates[i]);
        }
    }

    // When the first button is released:
    if (buttons[0].fell()) {

        // turn off the first LED.
        digitalWrite(ledPins[0], LOW);
    }

    // When any other button is pressed:
    for (int i = 1; i < BUTTON_COUNT; i++) if (buttons[i].rose()) {

        // Toggle its state.
        ledStates[i] = !ledStates[i];
        digitalWrite(ledPins[i], ledStates[i]);
    }
}

Edit: In order for the first button to only turn off LEDs 1 and 2, the lines

// and turn off all the others.
for (int i = 1; i < BUTTON_COUNT; i++) {
    ledStates[i] = LOW;
    digitalWrite(ledPins[i], ledStates[i]);
}

should be replaced by:

// and turn off LEDs 1 and 2.
for (int i = 1; i <= 2; i++) {
    ledStates[i] = LOW;
    digitalWrite(ledPins[i], ledStates[i]);
}
  • Wow Edgar, what a great sketch, so neat, hopefully I can learn a lot from it, thanks. What methods are there to make windows recognise it as a controller? Is it code or windows I have to play with, or both. – TRUEBRIT Jul 19 '18 at 16:10
  • How would I go about selecting only certain buttons to turn off with button1? Say I wanted to have button 4 independent. – TRUEBRIT Jul 19 '18 at 17:48
  • @TRUEBRIT: 1. Sorry, I know nothing about Windows programming, which is out of topic here anyway. 2. In the section right after the comment “and turn off all the others”, instead of looping through buttons 1 through 3 (they are numbered from zero), you only turn off button 1 and 2. – Edgar Bonet Jul 19 '18 at 18:40
  • I can't see how to do that? – TRUEBRIT Jul 19 '18 at 18:54
  • @TRUEBRIT: See amended answer. – Edgar Bonet Jul 19 '18 at 19:53

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

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