I built a system to open and close a ventilation flap on my greenhouse with temperature. Very simple: a robust linear actuator is powered for a little longer than needed to fully extend or fully retract, (using the built in limit switches in the actuator to actually turn off at the extremes. The power to the actuator is controlled by 2 relays, which reverse the polarity appropriately to advance or retract the actuator. The system has worked flawlessly and continuously for the past 6 months except for a failure several months ago, which was repeated again today. On both occasions, the flap was closing, (running the ActuatorRetract routine in the code below) when it abruptly ceased running, with the actuator roughly half retracted. Pressing the reset button on the Arduino did not trigger a resumption of the motor in the actuator. But... briefly cutting the power to the Arduino and reconnecting it, did. And it happily went on to fully close, following which the limit switch in the actuator itself cut the power to the actuator, followed a short time later by the Arduino cutting the power to the relays. (And just to clarify, the relays are isolated from the Arduino by opto-couplers, and are powered from a separate power supply, (so no back currents etc.) And the actuator itself is equally separately powered. The "fix" here involved stopping and restarting the power specifically to the Arduino; the power to the relays and to the actuator were not affected. And, to add an additional factor, when the system had frozen in mid-retraction, the LED on the Arduino remained lit, indicating that the Arduino itself was still powered. All of which makes me think the problem is not hardware related, but either a subtle error in my code, or (is this crazy?) the timer in the Arduino having a finite limit before it runs out of room. (That is, does an Arduino need to be completely rebooted at intervals of every few months?)
My apologies for the lengthy explanation. Sketch follows:
//connect red wire of AM2302 to 5V (on left side of board)
// connect white or yellow wire,(data out), to DHTPIN
//connect black wire (ground) to GND pin (on left side)
// connect 10K pull-up resistor between VCC and data
// To run display portion, connect Arduino, then choose Port,(3), under Tools
// Then, also under Tools, choose Serial Monitor, (or Ctrl-Shift-M)
#include <DHT.h>
#include <DHT_U.h>
#define DHTPIN 6
#define DHTTYPE DHT22
#define extendPin 2
#define retractPin 3
DHT dht(DHTPIN, DHTTYPE);
// Variables
boolean varExtended = false; // to control repetition of action
boolean varRetracted = false;
float temp_Value = 0; // to store temperature reading
const int extendTemp = 28;
const int retractTemp = 25;
void setup() {
//set control pins to OUTPUT, and initialise to HIGH. (They will default to LOW otherwise)
digitalWrite(extendPin, HIGH);
digitalWrite(retractPin, HIGH);
pinMode(extendPin, OUTPUT);
pinMode(retractPin, OUTPUT);
// Initialize sensor
dht.begin();
// Initialize display of readings
Serial.begin(9600);
}
void loop()
{
getTemp();
if (temp_Value > extendTemp && varExtended == false) // Open flap
{
actuatorExtend();
}
if (temp_Value < retractTemp && varRetracted == false) // Close flap
{
actuatorRetract();
}
} // End of loop
void getTemp()
{
// Wait 5 seconds between measurements to permit sensor to read
delay (5000);
// Get temperature and print its value.
temp_Value = dht.readTemperature();
//Check if read failed and exit, (to try again)
if (isnan(temp_Value))
{
Serial.println("Error reading temperature!");
return;
}
// Serial.print (" %\t");
Serial.print("Temperature: ");
Serial.print(temp_Value);
Serial.println(" °C");
}
void actuatorExtend()
{
digitalWrite(extendPin, LOW);
digitalWrite(retractPin, HIGH); // Closes contacts on forward relay
delay (40000); // Runs actuator out fully
varExtended = true; // Prevents routine running repeatedly
varRetracted = false; // Should be defaulted to false, but just to be sure
digitalWrite(extendPin, HIGH); // Sets both relays off
}
void actuatorRetract()
{
digitalWrite(extendPin, HIGH);
digitalWrite(retractPin, LOW); // Closes contacts on reverse relay
delay (40000); // Retracts actuator fully
varRetracted = true; // Prevents routine running repeatedly
varExtended = false; // Should be defaulted to false, but just to be sure
digitalWrite(retractPin, HIGH); // Sets both relays off
}