Hi everybody! I am new to the arduino world and to the firmware programming, but I have found loads of information in this forum and I think I have some initial approach that is worth trying out.
I am trying to start my first (initially-simple-but-you-know...) project which is to add a motor to a rolling curtain. I know there are some approaches in the forum, but I am trying to understand the logic of having different variables in account at the same time and I do not know if my approach is completely wrong or not.
The operation and set-up are explained in the comments area in the code. Could any of you experts let me know if this code should work for what it is intended and if there is any other more compelling angle?
Thank you in advance!!
Joan.
/* ROLLER CURTAIN AUTOMATIC STOP SYSTEM WITH MANUAL CONTROL
* THIS PROGRAM INTENTS TO OPERATE A MOTOR TO ROLL UP AND DOWN A FABRIC CURTAIN
* THE SET UP IS:
* ARDUINO UNO
* MOTOR SHIELD HiLetgo L298P DC Motor Drive Module
* 12VDC GEARED MOTOR
* 2X HALL EFFECT SENSORS AS END OF STROKE SWITCHES - NORMALLY CLOSED (NORMAL STATE HIGH), ACTIVATED WITH A MAGNET EMBEDDED INTO THE CURTAIN
* 2X MECHANICAL SWITCHES IN PULL-UP RESISTOR CONFIGURATION (NORMAL STATE HIGH)
*
* OPERATION:
* PUSH UP OR DOWN BUTTON TO START ROLLING UP OR DOWN THE CURTAIN, UNLESS THE END OF STROKE OF EACH SIDE IS ACTIVE (MEANING THE CURTAIN IS COMPLETELY OPEN OR CLOSED). IN SUCH CASE NOTHING SHOULD HAPPEN
* THE CURTAIN SHOULD STOP IF EITHER THE USER PUSHES ANY BUTTON (UP OR DOWN) OR THE END OF STROKE IS REACHED.
* AS SAFETY FEATURE, IF THE MOTOR IS ACTIVE FOR MORE THAN 10S. THE MOTOR SHOULD STOP TOO.
*/
//PIN SELECTION - SOME PINS NOT AVAILABLE DUE TO THE SHIELD
int pinUp = 3;
int pinDown = 5;
int eosUp = 6;
int eosDown = 7;
//VARIABLES ASSIGNATION
int buttonUp = 0;
int buttonDown = 0;
int endOfStrokeUp = 0;
int endOfStrokeDown = 0;
//VARIABLES FOR TIME CONTROL
long timeActive = 0; //VARIABLE TO CONTRTOL TIME - MAX TIME RUNNING MOTOR
long maxTime = 10000; //MAXIMUM RUNNING TIME FOR THE MOTOR IS 10 SEC
long timeStart = 0; //VARIABLE TO SET THE INITIAL TIME WHEN THE MOTOR STARTS TO MOVE
//MOTOR PINS SELECTION (SHIELD)
int pinMotor = 10; //DIGITAL
int pinDirection = 11; //USED AS ANALOGIC
void setup() {
pinMode(pinUp, INPUT);
pinMode(pinDown, INPUT);
pinMode(eosUp, INPUT);
pinMode(eosDown, INPUT);
pinMode(pinMotor, OUTPUT);
pinMode(pinDirection, OUTPUT);
Serial.begin(9600); // USED TO MONITOR VALUES ONLY, DEBUGGING PURPOSES
}
void loop() {
buttonUp=digitalRead(pinUp); //READ THE INPUT VARIABLES
buttonDown=digitalRead(pinDown);
endOfStrokeUp=digitalRead(eosUp);
endOfStrokeDown=digitalRead(eosDown);
Serial.print("out->"); //SHOW THE VALUES ON MONITOR (DEBUGGING PURPOSES)
Serial.print(buttonUp);
Serial.print(" ");
Serial.print(buttonDown);
Serial.print(" ");
Serial.print(endOfStrokeUp);
Serial.print(" ");
Serial.print(endOfStrokeDown);
Serial.print(" ");
if (buttonUp == LOW && endOfStrokeUp == HIGH) // IF UP BUTTON IS PRESSED AND UPPER END OF STROKE IS NOT ACTIVATED
{
delay(1000); //DELAY TO LET TIME FOR THE BUTTON BE RELEASED
buttonUp=HIGH; //GIVE BACK THE VALUE "HIGH" TO THE VARIABLE TO ALLOW THE WHILE LOOP TO START
timeStart=millis(); //START COUNTING TIME BY GIVING A MILLIS VALUE TO THE VARIABLE
while (endOfStrokeUp == HIGH && buttonUp == HIGH && buttonDown == HIGH && timeActive <= (timeStart+maxTime)) //WHILE THERE ARE NO BUTTONS PRESSED, THE END OF STROKE IS NOT ACTIVE AND THE MAX TIME HAS NOT BEEN REACHED
{
digitalWrite(pinMotor, HIGH); // MOVE MOTOR UP, MAX SPEED
analogWrite(pinDirection, 255);
buttonUp=digitalRead(pinUp); //READ VARIABLES INSIDE THE LOOP
buttonDown=digitalRead(pinDown);
endOfStrokeUp=digitalRead(eosUp); //NO NEED TO READ THE LOW BOTTOM END OF STROKE BECAUSE THE MOTOR IS MOVING UP
timeActive=timeStart+millis(); //COUNT TIME SINCE MOTOR STARTED
Serial.print("in_UP_mode->");
Serial.print(buttonUp);
Serial.print(" ");
Serial.print(buttonDown);
Serial.print(" ");
Serial.print(endOfStrokeUp);
Serial.print(" ");
Serial.print(endOfStrokeDown);
Serial.print(" ");
}
digitalWrite(pinMotor, HIGH); //MAKE A REVERSE MOVEMENT TO BREAK AND STOP MOTOR
analogWrite(pinDirection, -100);
delay(50);
digitalWrite(pinMotor, LOW);
analogWrite(pinDirection, 0);
}
if (buttonDown == LOW && endOfStrokeDown == HIGH) //IF DOWN BUTTON IS PRESSED (PULLUP RESISTOR) AND UPPER END OF STROKE IS NOT ACTIVATED (HALL EFFECT SENSOR, N.C.)
{
delay(1000); //DELAY TO LET TIME FOR THE BUTTON BE RELEASED
buttonDown=HIGH; //GIVE BACK THE VALUE HIGH TO THE VARIABLE TO ALLOW THE WHILE LOOP TO START
timeStart=millis(); //START COUNTING TIME BY GIVING A MILLIS VALUE TO THE VARIABLE
while (endOfStrokeDown == HIGH && buttonUp == HIGH && buttonDown == HIGH && timeActive <= (timeStart+maxTime)) //WHILE THERE ARE NO BUTTONS PRESSED, THE END OF STROKE IS NOT ACTIVE AND THE MAX TIME HAS NOT BEEN REACHED
{
digitalWrite(pinMotor, HIGH); // MOVE MOTOR DOWN, MAX. SPEED
analogWrite(pinDirection, -255);
buttonUp=digitalRead(pinUp); //READ VARIABLES INSIDE THE LOOP
buttonDown=digitalRead(pinDown);
endOfStrokeDown=digitalRead(eosDown); //NO NEED TO READ THE LOW BOTTOM END OF STROKE BECAUSE THE MOTOR IS MOVING UP
timeActive=timeStart+millis(); //COUNT TIME SINCE MOTOR STARTED
Serial.print("in_DOWN_mode->");
Serial.print(buttonUp);
Serial.print(" ");
Serial.print(buttonDown);
Serial.print(" ");
Serial.print(endOfStrokeUp);
Serial.print(" ");
Serial.print(endOfStrokeDown);
Serial.print(" ");
}
digitalWrite(pinMotor, HIGH); //MAKE A REVERSE MOVEMENT TO BREAK AND STOP MOTOR
analogWrite(pinDirection, 100);
delay(50);
digitalWrite(pinMotor, LOW);
analogWrite(pinDirection, 0);
}
}