Greetings! I'm writing a program to control shutters and fans in my greenhouse using a NANO board. It works as expected except for one thing: When the temperature exceeds the set value, the servo opens nice and slow -- but when it falls, the servo instantly slams back to position zero! The speed control is based on the "SWEEP" example. I'm wondering if it's a local/global variable issue? For testing purposes, the analog input (temperature) is set from the wiper of a pot across 3.3V, and the output pins simply light LEDs, except for a small servo controlled by pin 9 from the board. Can anyone spot why the servo closes so abruptly? Thanks in advance?
here's the entire code:
/*By CL 2/20/24
This program reads sensor input (from pot for testing) and can output:
-- signals to H-bridge, runs motor fwd/rev when specified values are reached
-- servo control to open/close shutter when specified values are reached
-- signal to turn fan on/off when specified values are reaced
*/
#include <Servo.h> //include servo library
Servo shutterServo; //create a servo object
int pos; //variable stores servo position
int maxPos = 90; //set maximum angle of servo turn
bool a = LOW, b = HIGH; //'flag variables' for state(?)
bool c = LOW, d = HIGH;
//connect 10K pot terminals to +3.3v & ground, and wiper to A0
int sensorPin = A0; // input pin for the potentiometer
int sensorValue; // variable to store the value coming from the sensor
int enablePin = 13; // the pin to enable motor (= onboard LED)
int ledPinA = 3; // the pin for LED A (H-bridge input 1)
int ledPinB = 4; // the pin for LED B (H-bridge input 2)
int fanPin = 6; // to turn on fan
int motorRunTime = 5000; //time motor will be enabled; or use millis()
int highTemp = 80; // set temp to open shutters
int lowTemp = 75; // set temp to close shutters
int highFan = 85; //set temp to turn on fan
int lowFan = 80; //set temp to turn off fan
long previousMillis = 0; //for time counting
long interval = 2000; //Read sensor each 2 seconds
void setup() {
pos = 0; // set servo position at 0 to start or after reset
shutterServo.attach(9); //set control pin for servo
shutterServo.write(pos); //start at position 0
delay(1000); //give time to reach 0 if not there already (e.g power fail)
// initialize digital pins for output, analog input
pinMode(enablePin, OUTPUT);
pinMode(ledPinA, OUTPUT);
pinMode(ledPinB, OUTPUT);
pinMode(fanPin, OUTPUT);
pinMode(A0, INPUT);
//use serial console for debugging
Serial.begin(9600); //open serial connection
Serial.println("welcome to the thermostat control");
Serial.print("the high temp (SHUTTER OPEN) is set at ");
Serial.println(highTemp);
Serial.print("and the low temp (SHUTTER CLOSE) is set at ");
Serial.println(lowTemp);
Serial.print("the servo will turn ");
Serial.print(maxPos);
Serial.println(" degrees");
Serial.print("the high fan temp (FAN ON) is set at ");
Serial.println(highFan);
Serial.print("and the low fan temp (FAN OFF) is set at ");
Serial.println(lowFan);
}
void loop() {
unsigned long currentMillis = millis(); //time elapsed
if (currentMillis - previousMillis >= interval) //if elapsed time longer than interval
{
previousMillis = currentMillis; //"Last time is now": reset current time, then do:
int sensorRead = analogRead(sensorPin); // read the value from the sensor:
sensorValue = map(sensorRead, 0, 760, 0, 100); //test: max raw sensor reading = 760
Serial.print("sensor value is: ");
Serial.println(sensorValue);
if (sensorValue >= highTemp && a == LOW) //if low temp went above 'high' e.g. 80 degrees
{
Serial.println("activating hitemp subroutine - shutters open");
hitemp();
}
else if (sensorValue <= lowTemp && b == LOW) //if hi temp went below 'low' e.g 75 degrees
{
Serial.println("activating lotemp subroutine - shutters close");
lotemp();
}
else if (sensorValue >= highFan && c == LOW) //if low temp went above 'fan on' e.g.85 deg
{
Serial.println("activating hifan subroutine - fan on");
hifan();
}
else if (sensorValue <= lowFan && d == LOW) //if low temp went below 'fan off' e.g.80 deg
{
Serial.println("activating lofan subroutine - fan off");
lofan();
}
}
}
//subroutines for high & low temps
void hitemp() {
if (sensorValue >= highTemp) //check if it's needed; stops it running on restart
{
digitalWrite(ledPinA, HIGH); //start motor rotation first direction (H-bridge)
digitalWrite(ledPinB, LOW); //or use as high temp indicator
digitalWrite(enablePin, HIGH); //enable power to motor, if used
a = HIGH; //note: initial & "lotemp" states: a= LOW, b= HIGH
b = LOW;
Serial.print("position was:");
Serial.println(pos);
for (pos = 0; pos <= maxPos; pos += 1) { //goes from 0 to max degrees @ 1 deg steps
shutterServo.write(pos); // tell servo to go to position in variable 'pos'
delay(15); // waits 15 ms for the servo to reach each position
}
Serial.print("new position is:");
Serial.println(pos);
delay(motorRunTime); // motor enabled for set time, if used; otherwise delay
digitalWrite(enablePin, LOW); //then turn motor off
}
}
void lotemp() {
if (sensorValue <= lowTemp) //check if it's needed; stops it running on restart
{
digitalWrite(ledPinA, LOW); //start motor rotation opposite direction (H-bridge)
digitalWrite(ledPinB, HIGH); //or use as low temp indicator
digitalWrite(enablePin, HIGH); //enable motor, if used
a = LOW; //note: when in "hitemp" state: a= HIGH, b= LOW
b = HIGH;
Serial.print("position was:");
Serial.println(pos);
for (pos = maxPos; pos >= 1; pos -= 1){ // goes from max to 0 degrees @ 1 degree steps
shutterServo.write(pos); // tell servo to go to position in variable 'pos'
delay(15); // waits 15 ms for the servo to reach each position
}
Serial.print("new position is:");
Serial.println(pos);
delay(motorRunTime); // motor enabled for set time, if used; otherwise delay
digitalWrite(enablePin, LOW); //then turn motor off
}
}
void hifan() {
if (sensorValue >= highFan) //check if it's needed; stops it running on restart
{
digitalWrite(fanPin, HIGH); //turn fan pin on
c = HIGH; //note: initial & "loFan" states: c= LOW, d= HIGH
d = LOW;
}
}
void lofan() {
if (sensorValue <= lowFan) //check if it's needed; stops it running on restart
{
digitalWrite(fanPin, LOW); //turn fan pin off
c = LOW; //note: in 'hifan' state, c= HIGH, d= LOW
d = HIGH;
}
}