I am currently working on a project that consists of a ventilation vane that is actuated by a stepper motor.
Basically, the ventilation vane movement is controlled by a ON/OFF latched pushbutton switch.
When logic value at Digital Pin 2 is :
5V (HIGH) --> the arduino commands the stepper motor to take 50 steps forward.
0V (LOW) --> the arduino commands the stepper motor to take 50 steps backwards.
Here is the code :
#include <AFMotor.h>
// Connect one stepper motor with 200 steps per revolution (1.8 degree)
AF_Stepper motor(200, 2); // to motor port #2 (M3 and M4)
#define ON HIGH
#define OFF LOW
int digitalPin = 2;
int val = 0;
void setup() {
Serial.begin(9600); // set up Serial library at 9600 bps
motor.setSpeed(60); // 30 rpm
}
void loop() {
pinMode(2, INPUT);
val = digitalRead(2); //Read Logical value
if (val == HIGH) {
Serial.println("MICROSTEP steps");
motor.step(50, FORWARD, MICROSTEP); //CLOSE GRILLE VANE
delay(2000);
pinMode(2, INPUT);
val = digitalRead(2); //Read Logical value
if (val == LOW) {
Serial.println("MICROSTEP steps");
motor.step(50, BACKWARD, MICROSTEP); //OPEN GRILLE VANE
delay(2000);
}
}
}
Thus far, it is working as intended except when @ the ON position beyond the delay(2000). When Digital PIN 2 reads the 5V for the first time, the command is executed as intended but after the delay, the stepper motor is receiving a command for another 50 steps, which I do not want.
Basically, when switch is latched @ON (5V) the stepper should only do 50 steps and maintain its position until a LOW value is detected again. For some reason, the OFF position works as intended, meaning the stepper motor takes 50 backwards only once, regardless of subsequent LOWs being detected.
I removed the pinMode declaration from the loop() section and it is now present in the setup() only.
Regarding the state change detection for the switch, I have browsed the language reference and I am having difficulty in assessing the correct control structure to be used here. I do not comprehend why the symptom is not present for the LOW state but is for the HIGH state; given that the loop structure is almost identical.
Basically, when switch is latched @ON (5V) the stepper should only do 50 steps and maintain its position until a LOW value is detected again.
What you want, and what you wrote in the code, are two different things. What you wrote in the code is "if the switch is still pressed after 50 steps, do another 5 steps, and another and another, until the switch is released.
The state change detection example show you how to make something happen when the switch becomes pressed, and NOT happen again until the switch is released and pressed again.
This all assumes, of course, that you have the switch wired with an external resistor.
If not, then you have a floating pin, and you can't be sure what will happen.
You could, of course use the internal pullup resistor, by setting the pin mode to INPUT_PULLUP. Then, LOW means pressed.
PaulS:
What you want, and what you wrote in the code, are two different things. What you wrote in the code is "if the switch is still pressed after 50 steps, do another 5 steps, and another and another, until the switch is released.
The state change detection example show you how to make something happen when the switch becomes pressed, and NOT happen again until the switch is released and pressed again.
I think I understand now. I will report back when it works !
#include <AFMotor.h>
// Connect one stepper motor with 200 steps per revolution (1.8 degree)
AF_Stepper motor(200, 2); // to motor port #2 (M3 and M4)
const int buttonPin = 2; // the pin that the pushbutton is attached to
int buttonState = 0; // current state of the button
int lastButtonState = 0; // previous state of the button
void setup() {
pinMode(buttonPin, INPUT); // initialize the button pin as a input
Serial.begin(9600); // set up Serial library at 9600 bps
motor.setSpeed(90); // 30 rpm
}
void loop() {
buttonState = digitalRead(buttonPin); // read the pushbutton input pin
if (buttonState != lastButtonState) { // compare the buttonState to its previous state
if (buttonState == HIGH) {
Serial.println("MICROSTEP steps");
motor.step(50, FORWARD, MICROSTEP); //CLOSE GRILLE VANE
delay(500);
}
else {
Serial.println("MICROSTEP steps");
motor.step(50, BACKWARD, MICROSTEP); //OPEN GRILLE VANE
delay(500);
}
lastButtonState = buttonState; // save the current state as the last state for next time through the loop
}
}
I am glad you have it working, but may I be permitted to throw a wet blanket on your nice camp fire?
You don't have any mechanism to enable you to set the zero position for your motor. The usual way to do that is to have some code in setup that runs the motor until it trips a limit switch. Without that there is a risk, if the flap jams or the Arduino crashes when the motor is in an unknown position, that it will try to move the motor beyond the range you want.
If all you need to do is open and close a flap I suspect a servo would be more convenient as it has an in-built position detection system.