Temperature controlled actuator

Hello, i've been trying to complete this project for a little while, i'm new to arduino. I have an actuator which is controlled via temp sensor DHT11. Currently it the actuator extends when temp is above 23C and retracts when temp is below 21C, i'm aware those two temps are too close, its just for testing purposes. The issue is i need the actuator to stop after 5 seconds and stay idle at that point unitl temp is above 23 C and extends again. The actuator is controlled by two relays. I have looked into Millis and other methods, please can someone help. Code is below.

#include "DHT.h" //install this library from Library Manager and
//install the additional library it requests while doing so

#define DHTPIN A0 //the digital pin # on which sensor OUT is connected to
#define DHTTYPE DHT11 //sensor type (there is a DHT22 available as well)
DHT dht(DHTPIN, DHTTYPE); //DHT library function

//pin assignment

int relay_1 = 7; //relay 1 pin to activate coil

int relay_2 = 8; //relay 2 pin to activate coil

int relay_3 = 9; //relay 3 pin to activate coil

int relay_4 = 10; //relay 4 pin to activate coil

//Actuator door open and close temperature values in celsius - can be changed to suit application needs
int open_door_temp = 23;
int close_door_temp = 21;
int turn_mat_on_temp = 25; //power off heated matts
int turn_mat_off_temp = 35;

void setup() {
Serial.begin(115200);
Serial.println(F("DHTxx test!"));

dht.begin();

pinMode(relay_1, OUTPUT); //defining relay 1 pin as output
pinMode(relay_2, OUTPUT); //defining relay 2 pin as output
pinMode(relay_3, OUTPUT); //defining relay 3 pin as output
pinMode(relay_4, OUTPUT); //defining relay 4 pin as output

digitalWrite(relay_1, LOW); //deactivating relay 1
digitalWrite(relay_2, LOW); //deactivating relay 2
digitalWrite(relay_3, LOW); //deactivating relay 3
digitalWrite(relay_4, LOW); //deactivating relay 4
}

void loop() {

float h = dht.readHumidity(); //reads humidity
float t = dht.readTemperature(); //reads temperature
float f = dht.readTemperature(true); //reads temperature

if (isnan(h) || isnan(t) || isnan(f)) {
Serial.println(F("Failed to read from DHT sensor!"));
return;
}

float hif = dht.computeHeatIndex(f, h); //converts the readings to celcius
float hic = dht.computeHeatIndex(t, h); //converts the readings to fahrenheit
//float hic = dht.readTemperature();
// //Serial.print is useful if you are using serial monitor on PC and is not required for this code to work
// Serial.print(F(" Humidity: "));
// Serial.print(h);
// Serial.print(F("% Temperature: "));
// Serial.print(t);
//Serial.print(F("°C "));
// Serial.print(f);
// Serial.print(F("°F Heat index: "));
// Serial.print(hic);
// Serial.print(F("°C "));
// Serial.print(hif);
// Serial.println(F("°F"));

if (hic >= open_door_temp) { //if the temperature value is higher than 27C, extend actuator
digitalWrite(relay_1, HIGH);
digitalWrite(relay_2, LOW);
Serial.println(F("open"));
Serial.println(hic);
}

else if (hic <= close_door_temp) { //if the temperature value is lower than 24C, retract actuator
digitalWrite(relay_1, LOW);
// delay(5000);
digitalWrite(relay_2, HIGH);
// delay(5000);
// digitalWrite(relay_1, HIGH);
// digitalWrite(relay_2, HIGH);
// if(relay_2State == HIGH)
//{
// if(millis()=relayCameOn > 5000)
// {
// digitalWrite(relay_1, LOW);
// digitalWrite(relay_2, LOW) ;
//relay_2State = LOW;
}
Serial.println(F("close"));
Serial.println(hic);

if (hic >= turn_mat_off_temp) { //if the temperature value is higher than 35C, turn off relay

digitalWrite(relay_3, LOW);
digitalWrite(relay_4, LOW);
Serial.println(F("off"));
Serial.println(hic);

}

else if (hic <= turn_mat_on_temp) {     //if the temperature value is lower than 25C, turn on relay
digitalWrite(relay_3, HIGH);
digitalWrite(relay_4, HIGH);
Serial.println(F("on"));
Serial.println(hic);

}
delay(500); //can be changed based on needs

}

You can help us help you by following the forum guidelines and post using code tags.

Hi, @jerycollins45
Welcome to the forum.

Can you please post link to specs/data of your actuator?

Does it have any position feedback.

Can we please have a circuit diagram?
An image of a hand drawn schematic will be fine, include ALL power supplies, component names and pin labels.

Thanks.. Tom.. :grinning: :+1: :coffee: :australia:

Here is what your code should look like, posted here after Auto Formatting with Arduino IDE (Tool > Auto Format Ctrl+T ) and using the cpp tag on top of the <code/> button here in the edit box

```cpp
[your code here]
```

Your code :

#include "DHT.h"  //install this library from Library Manager and
//install the additional library it requests while doing so

#define DHTPIN A0          //the digital pin # on which sensor OUT is connected to
#define DHTTYPE DHT11      //sensor type (there is a DHT22 available as well)
DHT dht(DHTPIN, DHTTYPE);  //DHT library function

//pin assignment

int relay_1 = 7;  //relay 1 pin to activate coil
int relay_2 = 8;  //relay 2 pin to activate coil
int relay_3 = 9;  //relay 3 pin to activate coil
int relay_4 = 10;  //relay 4 pin to activate coil

//Actuator door open and close temperature values in celsius - can be changed to suit application needs
int open_door_temp = 23;
int close_door_temp = 21;
int turn_mat_on_temp = 25;  //power off heated matts
int turn_mat_off_temp = 35;

void setup() {
  Serial.begin(115200);
  Serial.println(F("DHTxx test!"));

  dht.begin();

  pinMode(relay_1, OUTPUT);  //defining relay 1 pin as output
  pinMode(relay_2, OUTPUT);  //defining relay 2 pin as output
  pinMode(relay_3, OUTPUT);  //defining relay 3 pin as output
  pinMode(relay_4, OUTPUT);  //defining relay 4 pin as output

  digitalWrite(relay_1, LOW);  //deactivating relay 1
  digitalWrite(relay_2, LOW);  //deactivating relay 2
  digitalWrite(relay_3, LOW);  //deactivating relay 3
  digitalWrite(relay_4, LOW);  //deactivating relay 4
}

void loop() {

  float h = dht.readHumidity();         //reads humidity
  float t = dht.readTemperature();      //reads temperature
  float f = dht.readTemperature(true);  //reads temperature

  if (isnan(h) || isnan(t) || isnan(f)) {
    Serial.println(F("Failed to read from DHT sensor!"));
    return;
  }

  float hif = dht.computeHeatIndex(f, h);  //converts the readings to celcius
  float hic = dht.computeHeatIndex(t, h);  //converts the readings to fahrenheit
  //float hic = dht.readTemperature();
  // //Serial.print is useful if you are using serial monitor on PC and is not required for this code to work
  // Serial.print(F(" Humidity: "));
  // Serial.print(h);
  // Serial.print(F("% Temperature: "));
  // Serial.print(t);
  //Serial.print(F("°C "));
  // Serial.print(f);
  // Serial.print(F("°F Heat index: "));
  // Serial.print(hic);
  // Serial.print(F("°C "));
  // Serial.print(hif);
  // Serial.println(F("°F"));

  if (hic >= open_door_temp) {  //if the temperature value is higher than 27C, extend actuator
    digitalWrite(relay_1, HIGH);
    digitalWrite(relay_2, LOW);
    Serial.println(F("open"));
    Serial.println(hic);
  }

  else if (hic <= close_door_temp) {  //if the temperature value is lower than 24C, retract actuator
    digitalWrite(relay_1, LOW);
    // delay(5000);
    digitalWrite(relay_2, HIGH);
    // delay(5000);
    // digitalWrite(relay_1, HIGH);
    // digitalWrite(relay_2, HIGH);
    // if(relay_2State == HIGH)
    //{
    // if(millis()=relayCameOn > 5000)
    // {
    // digitalWrite(relay_1, LOW);
    // digitalWrite(relay_2, LOW) ;
    //relay_2State = LOW;
  }
  Serial.println(F("close"));  // <--- SHOULDN'T THESE BE INSIDE THE PREVIOUS BRACKET ?
  Serial.println(hic);         // <----------------------------------------------------

  if (hic >= turn_mat_off_temp) {  //if the temperature value is higher than 35C, turn off relay

    digitalWrite(relay_3, LOW);
    digitalWrite(relay_4, LOW);
    Serial.println(F("off"));
    Serial.println(hic);
  }

  else if (hic <= turn_mat_on_temp) {  //if the temperature value is lower than 25C, turn on relay
    digitalWrite(relay_3, HIGH);
    digitalWrite(relay_4, HIGH);
    Serial.println(F("on"));
    Serial.println(hic);
  }
  delay(500);  //can be changed based on needs
}

As you can see, the proper indentation and colors make it easier and more pleasant to read. It's a 10 second job that makes a huge difference.

Now for you request : you're not very specific about which relay for which action so I'll assume it's a H-bridge.

#include "DHT.h"  //install this library from Library Manager and
//install the additional library it requests while doing so

#define DHTPIN  A0         //the digital pin # on wheatIndexCh sensor OUT is connected to
#define DHTTYPE DHT22      //sensor type (there is a DHT11 available as well)
DHT dht(DHTPIN, DHTTYPE);  //DHT library function

#define DOOR_ACTUATION_TIME 500
#define DISPLAY_RESFRESH    5000
#define OPEN                1
#define CLOSED              0
#define ON                  1
#define OFF                 0
#define FAHRENHEIT          true
#define CELSIUS             false

//pin assignment

int open_door_relay       =  7;
int close_door_relay      =  8;
int heated_matts_relay_1  =  9;
int heated_matts_relay_2  = 10;

//Actuator door open and close temperature values in celsius - can be changed to suit application needs
int open_door_temp    = 23;
int close_door_temp   = 21;
int turn_mat_on_temp  = 25; // power on  heated matts
int turn_mat_off_temp = 35; // power off heated matts

void setup() {
  Serial.begin(115200);
  Serial.println(F("DHTxx test!"));

  dht.begin();

  pinMode(open_door_relay,  OUTPUT);
  pinMode(close_door_relay, OUTPUT);
  pinMode(heated_matts_relay_1, OUTPUT);
  pinMode(heated_matts_relay_2, OUTPUT);

  // deactivating relays
  digitalWrite(open_door_relay, LOW);
  digitalWrite(close_door_relay, LOW);
  digitalWrite(heated_matts_relay_1, LOW);
  digitalWrite(heated_matts_relay_2, LOW);
}

void loop() {
  static uint32_t doorRelayTimer;
  // static uint32_t displayTimer;
  static int8_t   doorIs         = CLOSED;
  static int8_t   doorShouldBe   = CLOSED;
  static int8_t   heatedMatts    = OFF;
  static float    prevHeatIndexC = 0;


  float humidity = dht.readHumidity();
  float temperatureC = dht.readTemperature(CELSIUS);
  float temperatureF = dht.readTemperature(FAHRENHEIT);

  if (isnan(humidity) || isnan(temperatureC) || isnan(temperatureF)) {
    Serial.println(F("Failed to read from DHT sensor!"));
    while(true) {
      delay(1000);
    }
  }

  float heatIndexC = dht.computeHeatIndex(temperatureC, humidity);
  // float heatIndexF = dht.computeHeatIndex(temperatureF, humidity);

  if(prevHeatIndexC != heatIndexC) {
    prevHeatIndexC = heatIndexC;
    Serial.print(F("heat Index "));
    Serial.print(heatIndexC);
    Serial.println("°C");
  }

/*
  if(millis() - displayTimer > DISPLAY_RESFRESH) {
    displayTimer = millis();
    Serial.print(F("heat Index "));
    Serial.print(heatIndexC);
    Serial.println("°C");
  }
*/

  if (doorShouldBe == CLOSED && heatIndexC >= open_door_temp) {  //if the temperature value is higher than 27C, extend actuator
    doorShouldBe = OPEN;
    digitalWrite(open_door_relay, HIGH);
    digitalWrite(close_door_relay, LOW);
    doorRelayTimer = millis();
    Serial.println(F("opening door"));
    Serial.println(heatIndexC);
  }

  else if (doorShouldBe == OPEN && heatIndexC <= close_door_temp) {  //if the temperature value is lower than 24C, retract actuator
    doorShouldBe = CLOSED;
    digitalWrite(open_door_relay, LOW);
    digitalWrite(close_door_relay, HIGH);
    doorRelayTimer = millis();
    Serial.println(F("closing door"));
    Serial.println(heatIndexC);
  }

  if(doorIs != doorShouldBe && millis() - doorRelayTimer > DOOR_ACTUATION_TIME) {
    doorIs = doorShouldBe;
    digitalWrite(open_door_relay, LOW);
    digitalWrite(close_door_relay, LOW);
    Serial.print(F("door is "));
    Serial.println(doorIs? "opened" : "closed");
  }


  if (heatedMatts == ON && heatIndexC >= turn_mat_off_temp) {  //if the temperature value is higher than 35C, turn off relay
    digitalWrite(heated_matts_relay_1, LOW);
    digitalWrite(heated_matts_relay_2, LOW);
    heatedMatts = OFF;
    Serial.println(F("heated matts off"));
    Serial.println(heatIndexC);
  }

  else if (heatedMatts == OFF && heatIndexC <= turn_mat_on_temp) {  //if the temperature value is lower than 25C, turn on relay
    digitalWrite(heated_matts_relay_1, HIGH);
    digitalWrite(heated_matts_relay_2, HIGH);
    heatedMatts = ON;
    Serial.println(F("heated matts on"));
    Serial.println(heatIndexC);
  }
}

I gave "things" meaningful names, used DHT22 instead and removed unnecessary comments. Here is the Wokwi simulation :

Are you aware you do the regulation based on the "heat Index" and not the temperature ?

The main remaining problem is the actuator position : at startup and each time the system is restarted, it is supposed to be CLOSED (or retracted). What if you OPEN it although it is OPENed already ?

@Etienne_74 - would a relay help the @jerycollins45

Thanks, and I learned something : delay(2000); // DHT needs two seconds between readings
That's probably why the regulation was not reactive...

Yes. I learned that the hard way. I thought temperature was always available because long ago I had a device which used resistance/voltage to translate temperature change (calibrated temperature was read once from something like the DHT).

Hence this revised code :

#include "DHT.h"  //install this library from Library Manager and
//install the additional library it requests while doing so

#define DHTPIN  A0         //the digital pin # on wheatIndexCh sensor OUT is connected to
#define DHTTYPE DHT22      //sensor type (there is a DHT11 available as well)
DHT dht(DHTPIN, DHTTYPE);  //DHT library function

#define DOOR_ACTUATION_TIME 500
#define MEASURE_RESFRESH    2500
//#define DISPLAY_RESFRESH    5000
#define OPEN                1
#define CLOSED              0
#define ON                  1
#define OFF                 0
#define FAHRENHEIT          true
#define CELSIUS             false

//pin assignment

int open_door_relay       =  7;
int close_door_relay      =  8;
int heated_matts_relay_1  =  9;
int heated_matts_relay_2  = 10;

//Actuator door open and close temperature values in celsius - can be changed to suit application needs
int open_door_temp    = 23;
int close_door_temp   = 21;
int turn_mat_on_temp  = 25; // power on  heated matts
int turn_mat_off_temp = 35; // power off heated matts

float humidity;
float temperatureC;
float temperatureF;
float heatIndexC;
// float heatIndexF;

void setup() {
  Serial.begin(115200);
  Serial.println(F("DHTxx test!"));

  dht.begin();

  pinMode(open_door_relay,  OUTPUT);
  pinMode(close_door_relay, OUTPUT);
  pinMode(heated_matts_relay_1, OUTPUT);
  pinMode(heated_matts_relay_2, OUTPUT);

  // deactivating relays
  digitalWrite(open_door_relay, LOW);
  digitalWrite(close_door_relay, LOW);
  digitalWrite(heated_matts_relay_1, LOW);
  digitalWrite(heated_matts_relay_2, LOW);
  humidity = dht.readHumidity();
  temperatureC = dht.readTemperature(CELSIUS);
  temperatureF = dht.readTemperature(FAHRENHEIT);
  if (isnan(humidity) || isnan(temperatureC) || isnan(temperatureF)) {
    Serial.println(F("Failed to read from DHT sensor!"));
    while(true) { delay(1000); }
  } else {
    heatIndexC = dht.computeHeatIndex(temperatureC, humidity);
    // heatIndexF = dht.computeHeatIndex(newTemperatureF, newHumidity);
  }
}

void loop() {
  static uint32_t doorRelayTimer;
  static uint32_t measureTimer;
  // static uint32_t displayTimer;
  static int8_t   doorIs         = CLOSED;
  static int8_t   doorShouldBe   = CLOSED;
  static int8_t   heatedMatts    = OFF;
  // static float    prevHeatIndexC = 0;


  if(millis() - measureTimer > MEASURE_RESFRESH) {
    measureTimer = millis();
    digitalWrite(LED_BUILTIN, HIGH);
    float newHumidity = dht.readHumidity();
    float newTemperatureC = dht.readTemperature(CELSIUS);
    float newTemperatureF = dht.readTemperature(FAHRENHEIT);
    if (isnan(newHumidity) || isnan(newTemperatureC) || isnan(newTemperatureF)) {
      Serial.println(F("Failed to read from DHT sensor!"));
    } else {
      heatIndexC = dht.computeHeatIndex(newTemperatureC, newHumidity);
      // heatIndexF = dht.computeHeatIndex(newTemperatureF, newHumidity);
      Serial.print(F("heat Index "));
      Serial.print(heatIndexC);
      Serial.println("°C");
    }
    digitalWrite(LED_BUILTIN, LOW);
  }


/*
  if(prevHeatIndexC != heatIndexC) {
    prevHeatIndexC = heatIndexC;
    Serial.print(F("heat Index "));
    Serial.print(heatIndexC);
    Serial.println("°C");
  }


  if(millis() - displayTimer > DISPLAY_RESFRESH) {
    displayTimer = millis();
    Serial.print(F("heat Index "));
    Serial.print(heatIndexC);
    Serial.println("°C");
  }
*/

  if (doorShouldBe == CLOSED && heatIndexC >= open_door_temp) {  //if the temperature value is higher than 27C, extend actuator
    doorShouldBe = OPEN;
    digitalWrite(open_door_relay, HIGH);
    digitalWrite(close_door_relay, LOW);
    doorRelayTimer = millis();
    Serial.println(F("opening door"));
    Serial.println(heatIndexC);
  }

  else if (doorShouldBe == OPEN && heatIndexC <= close_door_temp) {  //if the temperature value is lower than 24C, retract actuator
    doorShouldBe = CLOSED;
    digitalWrite(open_door_relay, LOW);
    digitalWrite(close_door_relay, HIGH);
    doorRelayTimer = millis();
    Serial.println(F("closing door"));
    Serial.println(heatIndexC);
  }

  if(doorIs != doorShouldBe && millis() - doorRelayTimer > DOOR_ACTUATION_TIME) {
    doorIs = doorShouldBe;
    digitalWrite(open_door_relay, LOW);
    digitalWrite(close_door_relay, LOW);
    Serial.print(F("door is "));
    Serial.println(doorIs? "opened" : "closed");
  }


  if (heatedMatts == ON && heatIndexC >= turn_mat_off_temp) {  //if the temperature value is higher than 35C, turn off relay
    digitalWrite(heated_matts_relay_1, LOW);
    digitalWrite(heated_matts_relay_2, LOW);
    heatedMatts = OFF;
    Serial.println(F("heated matts off"));
    Serial.println(heatIndexC);
  }

  else if (heatedMatts == OFF && heatIndexC <= turn_mat_on_temp) {  //if the temperature value is lower than 25C, turn on relay
    digitalWrite(heated_matts_relay_1, HIGH);
    digitalWrite(heated_matts_relay_2, HIGH);
    heatedMatts = ON;
    Serial.println(F("heated matts on"));
    Serial.println(heatIndexC);
  }
}

Is this for a greenhouse window?
I assume you know that there a fully mechanical devices for that.

Hi, @jerycollins45

Thanks.. Tom.. :grinning: :+1: :coffee: :australia:

Hello, yes appologies i just added th epost and didn't look.

Hello, the p/n for the actuator is 754654561317, there isn't much info on it, 12v, 1500N, 10mm-sec. I'l upload a drawing of the circuit.

What is the brand name of the actuator? Post the information from the actuator's data plate.

Hello, yes thats much better thank you for that i'll do it in the future. Relay 1 is extending the actuator, Relay 2 is retracting the actuator. The heat mat is run by relays 3 and 4 but thats separate thing. That looks great i was sure millis funciton was correct but no idea how to impliment it. Any reasong for using DH22 instead? I was not aware of the regulation on the heat index.

Indeed, essentially the actuator at fully retracted position will damage the door its connected to because the actuator will draw the door pasted its closed position. This is why i'm trying to ge the actuator to stop before damage is caused.

Hello, no its for a tortoise home outside, the principal is the same, i did look for a device to do similar but enjoyed the projector making.

Hello, the p/n for the actuator is 754654561317, there isn't much info on it, 12v, 1500N, 10mm-sec. I don't believe it does.

Where is the time of the actuator movement adjusted or is it an internal timer? thanks.

If the actuator does not have position feedback, you need limit switches.

Its tough to design a product with sketchy info, but the lower cost devices are often lacking details.

The ebay actuator that came up in a search is actuator. If this is what you have or looking for let us know.

This actuator seems to have internal limit switches which are not adjustable. Other than that there isn't much more than the motor leads.

I would:

  1. add a limit switch on your door so the actuator will not jam the door.
  2. have you considered what would happen if a Turtle was on the door when it was set to close?
  3. If you are using the blue "Songle" relays you should know folks have reported relay failures.

Variables and constants have meaningful names : DOOR_ACTUATION_TIME is probably the one you're looking for. It is set to 500 (0.5s) in my sketch to speed things up while developing.

DHT22 because there was no DHT11 in Wokwi.

As others say, you need limit switches (or any other feedback) more than "actuation time" to operate your door properly. At startup, the board has no idea if the door is fully closed, half open fully open. Any power failure will cause damage.

Same thing for security : spring loaded switches will detect abnormal forces and warn the controller that the door encounters "difficulties".