0
votes

functionality:

User presses the red dome button (is not a 2 state button), hence it has to toggle upon the first press "0"->"1" & when pressed again "1"->"0".

Therefore, when pressed, the serial monitor will print "1"s from "0"s at every 100ms. The behaviour signals that the buttonState is toggled from LOW to HIGH

Furthermore, an LED stripe is also connected to arduino. Therefore, when the buttonstate displays a HIGH in the serial monitor, the LED state will toggle to HIGH after a delay of 10s and will remain in HIGH state for 10s before toggling to a LOW state.

Lastly, the buttonState should toggle from HIGH to LOW after a delay(25s), without user physically pressing the button.

Issue:

At this point, user has to press the red dome button to toggle between LOW & HIGH state. Hence, when the button initial state is LOW, it shows "0"s in the serial monitor and when pressed, button will toggle to HIGH, shows "1"s in the serial monitor and when button is pressed again, it will toggle from HIGH to LOW, showing "0"s in the serial monitor.

Hence, I would like to ask for assistance on how to allow the buttonstate to toggle from HIGH to LOW without user pressing the button.

therefore, correctBehaviour:

initial state: "0"s are shown in serial monitor and when user presses button buttonstate shows "1"s in serial monitor and after a count of 25s, the buttonstate will toggle to LOW without user pressing the button again.

Code:

const int buttonPin = 2; //the number of the pushbutton pin
const int Relay     = 4; //the number of the LED relay pin

uint8_t    stateLED = LOW;
uint8_t      btnCnt = 1;

int buttonState = 0; //variable for reading the pushbutton status
int buttonLastState = 0;
int outputState = 0;

void setup() {
  Serial.begin(9600);
  pinMode(buttonPin, INPUT); 
  pinMode(Relay, OUTPUT);
  digitalWrite(Relay, LOW);
}

void loop() {

  // read the state of the pushbutton value:
  buttonState = digitalRead(buttonPin);
   // Check if there is a change from LOW to HIGH
  if (buttonLastState == LOW && buttonState == HIGH)
  {
     outputState = !outputState; // Change outputState
  }
  buttonLastState = buttonState; //Set the button's last state

   // Print the output
  if (outputState)
 {
      switch (btnCnt++) {
        case 100:
        stateLED = LOW;
         digitalWrite(Relay, HIGH); // after 10s turn on
         break;

       case 200:
         digitalWrite(Relay, LOW); // after 20s turn off
         break;

       case 202: // small loop at the end, to do not repeat the LED cycle
         btnCnt--;
         break;    
       }

       Serial.println("1");
  }else{
    Serial.println("0");
    if (btnCnt > 0) {  
       // disable all:
       stateLED = LOW;
       digitalWrite(Relay, LOW);
    }
    btnCnt = 0;
  }

  delay(100);
}
1

1 Answers

0
votes

I guess your code is nearly correct.

In case 200: I'd toggle outputstate as well, to return to the default state.

BTW: btncnt is a misleading name as you count your 100 ms intervals, not button presses or similar.

IMO, delay(100); is an acceptable compromise: still reacting on button presses, but without doing it properly using if (millis() - lastpressed > 20000) { ...