I am new to Arduino.
I have a motor which drives a sliding door back and forth. The motor is connected to an H bridge which has two control pins (direction, speed). I have a switch which is intended to activate the motor for a set amount of seconds to open the door fully. When the switch is deactivated, the motor reverses for the same duration as opening.
I have written some basic code using the 'if' argument, but my issue is that the code under the 'if' argument loops when my switch is activated/deactivated whereas I want it to run once per switch activation. Looking online I saw that a state machine may be my solution, but my lack of expertise with coding means I cannot create a state machine. This is my code:
const int Switch = 2;
const int hbridge1 = 13;
const int hbridge2 = 12;
const int threshold = 400;
int buttonState = 0;
void setup() {
pinMode(hbridge1, OUTPUT);
pinMode(hbridge2, OUTPUT);
pinMode(Switch, INPUT_PULLUP);
Serial.begin(9600);
}
void loop() {
int buttonState = digitalRead(Switch);
Serial.println(buttonState);
if (buttonState == HIGH) {
digitalWrite(hbridge1, HIGH);
digitalWrite(hbridge2, LOW);
delay(4000);
digitalWrite(hbridge1, LOW);
digitalWrite(hbridge2, LOW); //I only need the motor to activate for four seconds, but 'if' loops it infinitely
} else {
digitalWrite(hbridge1, LOW);
digitalWrite(hbridge2, HIGH);
delay(4000);
digitalWrite(hbridge1, LOW);
digitalWrite(hbridge2, LOW); //Same issue here
}
;
delay(1);
}
2 Answers 2
Creating a few boolian variables could help with this.
bool opening = 0
bool closing = 0
const int Switch = 2;
const int hbridge1 = 13;
const int hbridge2 = 12;
const int threshold = 400;
int buttonState = 0;
void setup() {
pinMode(hbridge1, OUTPUT);
pinMode(hbridge2, OUTPUT);
pinMode(Switch, INPUT_PULLUP);
Serial.begin(9600);
}
void loop() {
int buttonState = digitalRead(Switch);
Serial.println(buttonState);
if (buttonState == HIGH && opening == 0) { //variable "opening" is tested
opening == 1 //variable "opening" is set to on
closing == 0 //variable "closing" is set to off
digitalWrite(hbridge1, HIGH);
digitalWrite(hbridge2, LOW);
delay(4000);
digitalWrite(hbridge1, LOW);
digitalWrite(hbridge2, LOW);
}
else if (buttonState == Low && closing == 0){ //variable "closing" is tested
opening == 0 //variable "opening" is set to off
closing == 1 //variable "closing" is set to on
digitalWrite(hbridge1, LOW);
digitalWrite(hbridge2, HIGH);
delay(4000);
digitalWrite(hbridge1, LOW);
digitalWrite(hbridge2, LOW); //Same issue here
}
delay(1000) // delay is in milliseconds. So 1000 = 1 second
}
These new variables are set when the code is ran the first time. Therefore, no looping.
A schematic will help to create a solution. Are you using a resistor, like 10K, to pull the switch pin low? If the button is not pressed and the code keeps looping through like it is pressed, I recommend adding the resistor. You may need to add another component though. Like a micro-switch on the frame of the door that gets tripped while it is closed. Or a button to close the door. Without that every loop through the code will think the switch is held low and activate the motor. Which might burn out the motor or trip a fuse.
if(buttonstate == high){
//open door
}
else{
if(microswitch == high){
//H-bridge pins low, low
{
else{
//close door
{
schematic
simulate this circuit – Schematic created using CircuitLab
-
Thank you for your response. I am using the inbuilt pull up resistor to pull the switch pin low. As for the microswitch, it is a good idea however for my purposes I would like to control the motor using a fixed duration (I have timed how long it takes for the motor to open/close the door using a stopwatch). When the switch is low, activate the HBRIDGE1 pin for closing duration then halt till the switch is activated. When the switch is high, activate HBRIDGE2 pin for opening duration.Marcus– Marcus2018年09月08日 22:52:58 +00:00Commented Sep 8, 2018 at 22:52
-
every time void loop() loops it will look at the switch and see it is low and activate the else{} loop of the if. So the door will be closed and it will do else{} you might need something more. like if(buttonstate == high){ //open //delay //close } else{ //h bridge low, low }lineman2208– lineman22082018年09月08日 23:02:01 +00:00Commented Sep 8, 2018 at 23:02
-
I'll do that until I can work out how to make a state machine. Thanks.Marcus– Marcus2018年09月08日 23:38:57 +00:00Commented Sep 8, 2018 at 23:38
-
K.I.S.S. Keep It Simple Stupid. I think that is the simplest solution. It will open, delay, close, then if it is low it will sit with the motor in break modelineman2208– lineman22082018年09月09日 00:36:24 +00:00Commented Sep 9, 2018 at 0:36
to open it when it is switched on
.... to open what? ... the switch?code under the 'if' argument loops infinitely
..... that is not correct .... code in theloop()
function loops infinitelyBlinkWithoutDelay
example sketch .... it shows how to time an event .... you also need to store the value ofbuttonState
and run the code only when it changes (store the new value ofbuttonState
at the end of the code)