Not sure if this is the right place, please move me if I am in the wrong spot.
I'm sure this has been asked a lot before, but even with all my research on the subject I cannot quite get the coin to drop on it's side.
I'm working on my first large project, a pinball machine driven by arduino uno.
I got quite a lot done, but I need to know for how long a button is pushed, in order to protect solenoids from overheating. I seem to be able to detect single button push, but even if I release the button instantly I still see button held in the console. I don't know if this is because it's working correctly and just being super duper quick.
Can someone help me verify if this is working correctly?
Here is my code:
// whenever we start our arduino, because the switches are connected to a schmitt trigger,
// when the button is not pressed the low signal becomes a high signal.
// therefore, initially you can see in the serial monitor, that the buttons were held.
// What happens so far:
/*
When I press my button(s) only for a short tap, the console outputs 1 trigger but also 4 or 5 or more button held returns.
This could become a problem, once I attach solenoids to the trigger. (it may activate for too short) cause there should be some power to initially shoot a ball away.
after the button has been pressed for a while (still looking for how long) lets say 100ms, the solenoid should be ran with less power to prevent solenoid overheating.
I'm looking for 1 trigger to drive the solenoid high
and then looking for how long the button was held to allow for driving the solenoid with lower power.
*/
// define variables
int Led1pin = 7;
int Led2pin = 8;
int Led3pin = 12;
// switch 1
int state_s1 = 0; // In what state is the switch. (0-5)
int state_prev_s1 = 0; // What was the previous state. (0-5)
int pin_s1 = 2; // right flipper button is connected to this pin on the board.
int val_s1 = 0; // is the button on or off.
unsigned long t_s1 = 0; // timing value for debouncing.
unsigned long t_0_s1 = 0; // timing value for debouncing.
unsigned long bounce_delay_s1 = 5; // delay some time for debouncing.
// variable only for debugging purposes. the other switches should behave the same way so that might be overkill. (it's only temp variable removed when not having to debug any more.)
unsigned long s1_times_pressed = 0; // let us know how many times the button was pressed.
// switch 2
int state_s2 = 0;
int state_prev_s2 = 0;
int pin_s2 = 3; // left flipper button
int val_s2 = 0;
unsigned long t_s2 = 0;
unsigned long t_0_s2 = 0;
unsigned long bounce_delay_s2 = 5;
// switch 3
int state_s3 = 0;
int state_prev_s3 = 0;
int pin_s3 = 4; // enter button
int val_s3 = 0;
unsigned long t_s3 = 0;
unsigned long t_0_s3 = 0;
unsigned long bounce_delay_s3 = 5;
void setup() {
// put your setup code here, to run once:
pinMode(pin_s1, INPUT);
Serial.begin(9600);
}
void loop() {
// put your main code here, to run repeatedly:
// sense the switches.
SM_s1();
SM_s2();
SM_s3();
// handle the outcome (let us know what has been done)
if (state_s1 == 4) {
Serial.print("right flipper triggered!!! ");
Serial.print("This many times: ");
Serial.println(s1_times_pressed);
}
if (state_s1 == 1) {
Serial.println("right flipper held!");
}
if (state_s1 != state_prev_s1) {
Serial.print("right flipper state = ");
Serial.println(state_s1);
}
if (state_s2 == 4) {
Serial.println("left flipper triggered");
}
if (state_s2 == 1) {
Serial.println("left flipper held!");
}
if (state_s2 != state_prev_s2) {
Serial.print("left flipper state = ");
Serial.println(state_s2);
}
if (state_s3 == 4) {
Serial.println("enter button triggered");
}
if (state_s3 == 1) {
Serial.println("enter button held!");
}
if (state_s3 != state_prev_s3) {
Serial.print("enter button state = ");
Serial.println(state_s3);
}
}
// for debugging purposes we want some blinking leds.
void blink_s1() {
digitalWrite(Led1pin, !digitalRead(Led1pin)); // no need to check anything, just write to the pin the value opposite to what the value is. (so 0 becomes 1, and 1 becomes 0)
// this gets called quite a few times during the sensing of the switch, causing a blink to happen.
}
void blink_s2() {
digitalWrite(Led2pin, !digitalRead(Led2pin));
}
void blink_s3() {
digitalWrite(Led3pin, !digitalRead(Led3pin));
}
// detecting switch input cases.
void SM_s1() {
state_prev_s1 = state_s1;
switch (state_s1) {
case 0: // start
// code here
state_s1 = 1;
break;
case 1: // read pin
// next case code
val_s1 = digitalRead(pin_s1);
blink_s1();
if (val_s1 == LOW) {state_s1 = 2;}
break;
case 2: // GO
// next case code
t_0_s1 = millis();
state_s1 = 3;
break;
case 3: // wait debounce
// next case code
val_s1 = digitalRead(pin_s1);
t_s1 = millis();
if(val_s1 == HIGH) {state_s1 = 0;}
if(t_s1 - t_0_s1 > bounce_delay_s1) {
state_s1 = 5;
}
break;
case 4: // pressed!
// next case code
state_s1 = 0;
break;
case 5: // armed!
val_s1 = digitalRead(pin_s1);
digitalWrite(Led1pin, 0);
if(val_s1 == HIGH) {
state_s1 = 4;
s1_times_pressed++;
}
}
}
void SM_s2() {
state_prev_s2 = state_s2;
switch (state_s2) {
case 0: // start
// code here
state_s2 = 1;
break;
case 1: // read pin
// next case code
val_s2 = digitalRead(pin_s2);
blink_s2();
if (val_s2 == LOW) {state_s2 = 2;}
break;
case 2: // GO
// next case code
t_0_s2 = millis();
state_s2 = 3;
break;
case 3: // wait debounce
// next case code
val_s2 = digitalRead(pin_s2);
t_s2 = millis();
if(val_s2 == HIGH) {state_s2 = 0;}
if(t_s2 - t_0_s2 > bounce_delay_s2) {
state_s2 = 5;
}
break;
case 4: // pressed!
// next case code
state_s2 = 0;
break;
case 5: // armed!
val_s2 = digitalRead(pin_s2);
digitalWrite(Led2pin, 0);
if(val_s2 == HIGH) {state_s2 = 4;}
}
}
void SM_s3() {
state_prev_s3 = state_s3;
switch (state_s3) {
case 0: // start
// code here
state_s3 = 1;
break;
case 1: // read pin
// next case code
val_s3 = digitalRead(pin_s3);
blink_s3();
if (val_s3 == LOW) {state_s3 = 2;}
break;
case 2: // GO
// next case code
t_0_s3 = millis();
state_s3 = 3;
break;
case 3: // wait debounce
// next case code
val_s3 = digitalRead(pin_s3);
t_s3 = millis();
if(val_s3 == HIGH) {state_s3 = 0;}
if(t_s3 - t_0_s3 > bounce_delay_s3) {
state_s3 = 5;
}
break;
case 4: // pressed!
// next case code
state_s3 = 0;
break;
case 5: // armed!
val_s3 = digitalRead(pin_s3);
digitalWrite(Led3pin, 0);
if(val_s3 == HIGH) {state_s3 = 4;}
}
}
I also have a video on youtube of the code in action. here: https://www.youtube.com/shorts/9fS7Qp7z7gw