IF statement

I have a programme for a system where my arduino uno will read 2 temperature sensors. if the temperature is above a set point a fan will be turned on and when below will turn off ect. I have a manual start button which will override the function and turn the fan on for 1 hour and one that will turn the fan off for 1 hour if it is on using millis().
I need help finding a shorter way to write this as it is very long winded. And could somebody help as to how I should implement the second button (where) and if I will need to copy the main function code again. Thanks.

Also if you spot any more errors, please could you let me know.

temperature_control_4.ino.ino (2.56 KB)

I'd probably structure it like this (pseudocode) :

loop() {
   Test override state for time expiry and set as required ;
   Read override buttons and set time and state if pressed ;
   Read sensors ;

   if ( based on override states(s) and sensors the fan should be on ) switch_on_fan() ;
   else switch_off_fan ;
}
while (millis() < time_now + period);

If you are going to do this then you might just as well use delay() as your current code is just as blocking. I assume that the period of 1 second is only for testing purposes

Personally I would turn the program into a state machine, which sounds scary but isn't. The program will be in one of several states at any time, such as

TEMP_IN_RANGE
FAN_ON_COOLING
FAN_ON_MANUAL_OVERRIDE

In each state only certain code needs to be executed and there will also be code common to some/all of them that is executed unconditionally. You can control whether the code for the current state is executed using a series of if/else but personally I like to use switch/case based on the current state. This nicely separates the code into blocks and by defining constants the states can be given meaningful names

Let me know if you want to know more about the techniques suggested

OP's program so others don't have to download it. See How to use the Forum

#include <DHT.h>
#include <LiquidCrystal.h>
int period = 1000;
unsigned long time_now = 0;
LiquidCrystal lcd(A3, 9, 6, 5, 4, 3, 2);

#define DHT1PIN 8 //transformer temperature    
#define DHT2PIN 7 //ambient temperature
#define DHT1TYPE DHT11
#define DHT2TYPE DHT11
#define contrast 6
#define Button1 A4
#define Button2 A5

int fan = A1;
int fanSpeed=0;
const int Button1Pin = A4;
const int Button2Pin = A5;
int Button1State = 0;
int Button2State = 0;

DHT dht1(DHT1PIN, DHT1TYPE);//transformer temperature
DHT dht2(DHT2PIN, DHT2TYPE);//ambient temperature
 
void setup() {
  Serial.begin(9600);  //start Serial in case we need to print debugging info
 
  pinMode(fan,OUTPUT);
  pinMode(contrast, OUTPUT);
  pinMode(Button1Pin,INPUT);
  pinMode(Button2Pin,INPUT);

  Serial.begin(9600);
  lcd.begin(20,4);
  dht1.begin();
  dht2.begin();
  digitalWrite(contrast, LOW);
  delay(1000);
  

}
 
void loop() {
 
  float t1 = dht1.readTemperature();
  float t2 = dht2.readTemperature();
  Button1State = analogRead(Button1Pin);// manual start
  Button2State = analogRead(Button2Pin); //manual stop
  time_now = millis();
  
if (Button1State == HIGH || Button2State==LOW) {
   fanSpeed=280;//if not change to 3300
   analogWrite(fan,fanSpeed);
   Serial.print("manual start on ");//fan is turned on for 60 minutes then will return to programme
   lcd.setCursor(4,1);
   lcd.print("manual start on");
    while(millis() < time_now + period);}//wait approx. [period] ms
    
  else{
    

    lcd.setCursor(1,0);
    lcd.print("Trans temp: ");
    lcd.print(t1);
    lcd.println(" *C");
    delay(100);
    lcd.setCursor(2,1);
    lcd.print("Amb temp: ");
    lcd.print(t2);
    lcd.println(" *C");
   
    delay(100);
    
    
  if (isnan(t1)) {
    Serial.println("Failed to read transformer temperature");}
  else {
    
    Serial.print("Transformer temperature: ");
    Serial.print(t1);
    Serial.println(" *C");
   

  }
  if (isnan(t2)) {
    Serial.println("Failed to read Ambient temperature");
  } else {

    Serial.print("ambient temperature: ");
    Serial.print(t2);
    Serial.println(" *C");
    delay(100);
  }
  if(t1<38){
    fanSpeed=0;
    analogWrite(fan,fanSpeed);
   }
   if(t1>=42)
   {fanSpeed=280;//if not change to 3300
   analogWrite(fan,fanSpeed);
   

    }
   if (fanSpeed==280);
   {lcd.setCursor(0,1);
   lcd.print("Fan = ON");
   Serial.print("Fan = ON");}
   if (fanSpeed==0);
   {lcd.setCursor(0,1);
   lcd.print("Fan = OFF");
   Serial.print("Fan = OFF");}
   
  }}

...R

To add to Reply #2, it makes the development of a program much easier if {A} the reading of inputs {B} the analysis of the values from those inputs and {C} the actions to take based on the analysis are each in separate functions. Then each part can be tested separately.

It is in the part I refer to as "analysis" that changes to the state variable(s) would take place and the "action" part would take account of the current state without needing to know anything about how it got to that value.

Maybe have a look at Planning and Implementing a Program, although it is not a demo of a State Machine.

...R

Apart from your delay()-like use of millis() and the suggestion to take a state machine route, the following's a bit odd:

fanSpeed = 280; //if not change to 3300
analogWrite(fan, fanSpeed);

.... since analogWrite() only goes to 255, not 280 (let alone, over 3000).

fanSpeed = 280; //if not change to 3300

Changes the fan speed to 3300 RPM perhaps

Question: What do the override buttons do when you are already in override?

Does pushing the same override:

  1. Do nothing?
  2. Extend the override by another hour?
  3. Cancel the override and return to automatic control?

Does pushing the opposite override:

  1. Do nothing?
  2. Subtract one hour from the override (and if negative, switch to the opposite state)?
  3. Start an hour in the opposite override state?
  4. Cancel the override and return to automatic control?

UKHeliBob:

fanSpeed = 280; //if not change to 3300

Changes the fan speed to 3300 RPM perhaps

Ah yes, of course: I read it as "if 280 doesn't work, change 280 to 3300 in the code".