Hi,
I’m trying to write logic to control a linear actuator to open and close a greenhouse vent depending on the inside temperature and I’m unsure how to write it. I’m new to Arduinos and coding. I’m using an UNO, a 2 channel 5v relay, a DS18B20 temperature probe and an actuator. I attempted the logic and got part of the way. I’m not sure how to structure it so it only tries to retract the actuator when it is extended. Here is the logic I want written out:
check temp every 3 minutes If temp > x; (open vent) after (open vent), check temperature every 3 minutes and if temp < x; (close vent)
My problem is that it tries to retract the actuator every 3 minutes when it reads that the temp is > x.
My main questions are:
What should the logic look like?
should it go in setup or loop?
Here is the code. I started with the sketch called Simple from Dallastemperature.h
#include <OneWire.h>
#include <DallasTemperature.h>
// Data wire is plugged into pin 2 on the Arduino
#define ONE_WIRE_BUS 2
// Setup a oneWire instance to communicate with any OneWire devices
// (not just Maxim/Dallas temperature ICs)
OneWire oneWire(ONE_WIRE_BUS);
// Pass our oneWire reference to Dallas Temperature.
DallasTemperature sensors(&oneWire);
const int relay1 = 6; //Arduino pin that triggers relay #1
const int relay2 = 7; //Arduino pin that triggers relay #2
void setup(void)
{
// start serial port
Serial.begin(9600);
Serial.println("Dallas Temperature IC Control Library Demo");
// Start up the library
sensors.begin();
//Set pinMode to OUTPUT for the two relay pins
pinMode(relay1, OUTPUT);
pinMode(relay2, OUTPUT);
}
void extendActuator() {
digitalWrite(relay1, HIGH);
digitalWrite(relay2, LOW);
}
void retractActuator() {
digitalWrite(relay1, LOW);
digitalWrite(relay2, HIGH);
}
void stopActuator() {
digitalWrite(relay1, LOW);
digitalWrite(relay2, LOW);
}
void loop(void)
{
// call sensors.requestTemperatures() to issue a global temperature
// request to all devices on the bus
Serial.print(" Requesting temperatures...");
sensors.requestTemperatures(); // Send the command to get temperatures
Serial.println("DONE");
Serial.print("Temperature for Device 1 is: ");
Serial.print(sensors.getTempCByIndex(0)); // Why "byIndex"?
if (sensors.getTempCByIndex(0) > 32)
{extendActuator();
delay(20000);
stopActuator();
delay(60000);sensors.requestTemperatures();};
if (sensors.getTempCByIndex(0) < 32)
{retractActuator(); delay(20000); stopActuator();}
else
{stopActuator();}
delay(60000);
}
// You can have more than one IC on the same bus.
// 0 refers to the first IC on the wire
DKWatson:
When checking the temperature, check also whether the actuator is extended or retracted. If it's already where it should be, do nothing.
I don't have a sensor to tell me whether the actuator is extended or retracted. I was hoping to be able to get around that in the code by having it check temp after extending, and retract if it is lower than x.
Thank you for the help. I added your code but it did not function. Is it because I have stopActuator() before the assignment "actuator = extended"? stopActuator() sets both relays to zero volts. I realized that I don't actually need stopActuator() since the actuator has internal limit switches that stop it at the stroke limits, and I don't plan on stopping it mid-stroke.
I modified my code and added a temp buffer to 29 degrees and it seemed to work
if (sensors.getTempCByIndex(0) > 32)
{extendActuator();
delay(180000);}
else if (sensors.getTempCByIndex(0) > 29)
{extendActuator();}
else
{retractActuator();
delay(20000);}
I have another question. The greenhouse is sealed tight in order to keep heat in, so in order to let fresh air in during extended periods when the vent stays closed I want to be able to add a periodic operation to extend and retract the actuator on a time interval. For example, once an hour it extends open for a minute and then retracts closed. The only way I know how to do this is to add an hour delay in the code, but then that will disrupt the temperature operation, correct? I assume I could do it by adding a real time clock, but is there a simple way of doing it without a clock?
Since the timing is not down-to-the-second crucial, you can just check elapsed time with millis() and skip the RTC. You will not be using delay so that your code can continue functioning.
do something like
currentMillis = millis()
if( currentMillis - previousMillis > hourInTermsOfMillis)
do that thing you want
previousMillis = millis()
INTP:
Since the timing is not down-to-the-second crucial, you can just check elapsed time with millis() and skip the RTC. You will not be using delay so that your code can continue functioning.
do something like
currentMillis = millis()
if( currentMillis - previousMillis > hourInTermsOfMillis)
do that thing you want
previousMillis = millis()
Thank You!! That's great, I will add this to my code.