Hello! I am total beginner in Arduino or at programming! Hope you can help me to guide in right direction why i cant get my sketch work.
So my idea is to use one pushbutton witch works as toggle switch to turn LED`s in three conditions, you push once it turn on one LED, push second time, both LEDs turn on and when you push third time both go off, and i want to use millis() for pushbutton debounce and switch case for led state change, but i cant figure out why i can get them turned on, I have multiple times readed and whatched youtube videos of examples of toggle switch, debounce, millis, switch state, but cant figure what I do wrong.
my sketch code:
int ButtonPin = 2;
int LedPin1 = 7;
int LedPin2 = 8;
int LedState = LOW;
int ButtonRead;
int ButtonState = 0;
int ButtonStateOld = 0;
unsigned long lastDebounceTime = 0;
unsigned long debounceDelay = 50;
void setup() {
pinMode(ButtonPin, INPUT_PULLUP);
pinMode(LedPin1, OUTPUT);
pinMode(LedPin2, OUTPUT);
}
void loop() {
ButtonRead = digitalRead(ButtonPin); //Read value form ButtonPin
if (ButtonRead != ButtonStateOld) { //check if ButtonRead differs from ButtonStateOld, check if button is pressed, whent from 111111... to 00000...
lastDebounceTime = millis(); //if differs start millis function
ButtonStateOld = ButtonRead; //assign 0 to ButtonStateOld
}
if ((millis() - lastDebounceTime) > debounceDelay) { //if statement fulfilled, that button is still pressed goes to next step
if (ButtonRead == HIGH && ButtonStateOld == LOW) { // check if button whent from 1 to 0 back to 1
if (LedState == LOW) {
LedState = LedState + 1;
}
}
switch (LedState) {
case 1:
digitalWrite(LedPin1, HIGH);
break;
case 2:
digitalWrite(LedPin1, HIGH);
digitalWrite(LedPin2, HIGH);
break;
case 3:
digitalWrite(LedPin1, LOW);
digitalWrite(LedPin2, LOW);
break;
}
}
ButtonStateOld = ButtonRead; //assign
}
yes, pushbutton gives me 1 or HIGH when not pressed and when I pres it, it gives me 0 or LOW, also LEDs work, if i open button example and change pins to my pins i can turn them on
Please do not mix HIGH and LOW with integer numbers.
The digitalRead() and digitalWrite() functions use HIGH and LOW.
If you need a number in your sketch, then make a new variable.
The variable names for a pin number can have "Pin" in the name to avoid confusion.
int ButtonPin = 2; // push button pin
int Led1Pin = 7; // led pin
int Led2Pin = 8;
A value or a state should not have "Pin" in the name. Your "ButtonPinRead" is a value or a state of the button, it does not identify the pin number.
This is good:
if (millis() - lastDebounceTime > debounceDelay)
This is also good:
if ( (millis() - lastDebounceTime) > debounceDelay)
this i taked from example in ArduinoIDE => example => 02Digital =>Debounce.
i did find similar code from internt where use delay but what I read delay is not good so i try to use millis(), so here is internet code:
// constants won't change. They're used here to set pin numbers:
const int buttonPin = 4; // the number of the pushbutton pin
const int ledPin = 13; // the number of the LED pin
const int ledPin1 = 12;
const int ledPin2 = 11;
// variables will change:
int initial = 0; //hold current initial
int oldstate = 0; //hold last initial
int buttonstate = 0; // variable for reading the pushbutton status
void setup() {
pinMode(ledPin, OUTPUT); // initialize the LED pin as an output:
pinMode(ledPin1, OUTPUT);
pinMode(ledPin2, OUTPUT);
pinMode(buttonPin, INPUT); // initialize the pushbutton pin as an input:
}
void loop(){
//debouncing routline to read button
buttonstate = digitalRead(buttonPin); //state the initial of button
if(buttonstate == HIGH){ //check if it has been pressed
delay(50);
buttonstate = digitalRead(buttonPin);//state button again
if(buttonstate == LOW){ //if it is 0 considered one press
initial = oldstate + 1; //increase initial by 1
}
}else{ //check if it has been NOT pressed
delay(100);
}
switch (initial){ //react to button press a initial
case 1: //if initial is 1
digitalWrite(ledPin, HIGH);//on
digitalWrite(ledPin1, LOW);//off
digitalWrite(ledPin2, LOW);//off
oldstate = initial; //set oldstate initial as current initial
break;
case 2:
digitalWrite(ledPin, LOW);
digitalWrite(ledPin1, HIGH);
digitalWrite(ledPin2, LOW);
oldstate = initial;
break;
case 3:
digitalWrite(ledPin, LOW);
digitalWrite(ledPin1, LOW);
digitalWrite(ledPin2, HIGH);
oldstate = initial;
break;
default: //if initial is not 1 2 3
digitalWrite(ledPin, LOW); //off
digitalWrite(ledPin1, LOW);
digitalWrite(ledPin2, LOW);
oldstate = 0; //reset to all off/initial 0
break;
}
}
When low is pressed and humans intuitively read high as pressed you can get confused. This is correct in that you use input pull-up and so this logic is blessed but sometimes if you are getting confused it is best to use the #define to change low to Pressed. It is not best practice but avoids confusion sometimes until you get the logic
Can you write two test-sketches ?
One that debounces and one that has three states with the leds.
The sketch for debouncing can show the result in the Serial Monitor. That was already mentioned in the first reply by pmagowan in post #2.
You can try the three states with the leds with a "artificial" button that does not bounce. Go to the project in Wokwi "ThreeConditions.ino", click on the button (while the simulation is not running) and then you see the options for the button. You can turn off the Bounce. Wokwi enables the Bounce by default, it is a pretty bad bounce (or it bounces really good) so if you can debounce the button in Wokwi, then the debounce will work in real life.
You have to be logged in in Wokwi to save a copy of my Wokwi project to your own projects and make changes. It is free.
When you combine the sketches, don't combine variables that have different meanings. You have now the same variable to remember the old button state before and after the debouncing.