Temp Control + "PWM" + Relays simultaneously

Hi all!
This is my first time EVER on Arduino or C. I already feel sorry for those reading the code below. Anyways... A friend of mine is having his b-day in about two weeks, so wanted to make him a gift for his dawgie to keep him warm the rest of the winter when he's in his cabin.
I need this to control the temperature, adjust the speed of a 12VDC PWM fan, a heater and run the lights at the hours the dog is awake. Problem is that my Arduino and components are still being shipped to me. Just want to advance as much guess-work as I can. I just need some advice
I bought an ""Arduino Pro Mini"", Atmega328P 8M -which I think it is a clone-. I already tried compiling this code to test but I'm getting errors one after the other and I'm pretty sure I did so many things wrong I shouldn't be allowed to use the IDE for the rest of my life.
If someone could give me some advice on how to set a timer for the lights -while not loosing all other functions in the process- would be so much appreciated. Just found out, after paying for the thing, that it doesn't support RTC? Meaning... I can't use it in any way to trigger a relay every some hours?

Here's the code I came up with so far, along with annotations on every line to what should do/what I think it does.

/*Libraries*/
#include <Wire.h> 
#include <DHT.h>
#include <EEPROM.h>
#include <Adafruit_Sensor.h>

/*Definitions*/
const int DHT = A4;           // DHT22 SENSOR
const int LightPin = 2;       // RELAY1
const int FanPin = 4;         // RELAY2
const int HeaterPin = 6;      // RELAY3
const int AlarmPin = 8;       // RELAY4
const int PWRLED = 9;         // POWER LED
const int StatusLed = 12;     // STATUS LED
const int FanPWM = 5;         // FAN PWM
int LightStatus = HIGH;       // DEFAULT VALUES AT STARTUP
int HeaterStatus = HIGH;      //..
int FanStatus = HIGH;         //..
int AlarmStatus = HIGH;       //..

void setup() {
  serial.begin(9600);          //TO START I2C COMMUNICATION?
  float t=0 h=0;               //BLANK VALUES FOR TEMP/RH
  dht.begin();                 //START SENSOR
  pinMode(LightPin,OUTPUT);    //PIN SETUP
  pinMode(FanPin,OUTPUT);      //..
  pinMode(HeaterPin,OUTPUT);   //..
  pinMode(AlarmPin,OUTPUT);    //..
  pinMode(PWRLED,OUTPUT);      //..
  pinMode(StatusLED,OUTPUT);   //..
  pinMode(FanPWM,OUTPUT);      //..
  digitalWrite(PwrLed,HIGH);   //LED ON
  DigitalWrite(LightPin,LOW);  //POWER ON RELAY SELFTEST
  DigitalWrite(LightPin,HIGH); //..
  delay(300);                  //..
  DigitalWrite(FanPin,LOW);    //..
  DigitalWrite(FanPin,HIGH);   //..
  delay(300);                  //..
  DigitalWrite(HeaterPin,LOW);  //..
  DigitalWrite(HeaterPin,HIGH); //..
  delay(300);                   //..
  DigitalWrite(AlarmPin,LOW);   //..
  DigitalWrite(AlarmPin,HIGH);  //..
}

void loop() {

currentMillis = millis();       //TIMING
temprh();                       //CYCLE THROUGH SUBROUTINES
pwmsignal();                    //..
lightvoid();                    //..

}

void temprh() {                     //TEMP CONTROL
int readData = DHT.read22(DHT);     //DHT READ
float t = DHT.temperature;          //READ TEMP
float h = DHT.humidity;             //READ RH
  if (t<21 && (HeaterPin,HIGH) {    //LOW TEMP TRIGGER
    DigitalWrite(HeaterPin,LOW)     //ACTIVATE HEATER RELAY
    int HeaterStatus = LOW;          //STORE NEW STATE
  }
  if (t>24) {                       //HIGH TEMP TRIGGER
    DigitalWrite(HeaterPin,HIGH);   //DEACTIVATE HEATER RELAY
    FanStatus = LOW;                //STORE NEW DESIRED FAN STATE
  }
}

void pwmsignal() {
  if FanStatus == HIGH {                //CHECK DESIRED STATUS
    DigitalWrite(FanPin,LOW);       //TURN ON FAN RELAY***
    AnalogWrite(FanPWM, 255);       //MAX. PWM SPEED
    float t = DHT.temperature;      //READ TEMP AGAIN
    while (t>24);                   //KEEP AT MAX. SPEED IF NOT BELOW 24C (will it keep reading the temp?)
    delay(1500);                    //MAINTAIN SPEED FOR 1.5 SEC
    AnalogWrite(FanPWM, 170);       //DROP TO 65-70%
    delay(2000);                    //MAINTAIN FOR 2 SECONDS
    DigitalWrite(FanPin,HIGH);       //TURN OFF FAN RELAY
    AnalogWrite(FanPWM, 0);          //DONT KNOW IF REALLY NEEDED.
    int FanStatus = HIGH;             //SAVE DESIRED STATUS
  }
}
    
void lightvoid() {
  if LightStatus == HIGH {             //SAME STRUCTURE BUT NOW I THINK ARDUINO PRO MINI DOESNT
    DigitalWrite(LightPin,LOW);     //SUPPORT RTC SO I DON'T KNOW HOW TO SET A TIMER.
    delay(1000);
    int LightStatus = LOW;
  }
  
  if LightStatus == LOW {
    DigitalWrite(LightPin,HIGH);
    delay(1000);
    int LightStatus = HIGH;
  }
}

This is the way I'd join everything together:

imgur.com/PBPR3Q5

Except for the PWM signal, that turns out I can't run directly off it either due to the frequency, but will jerry-rig some intermediary circuit on pin5.
Due to the memory size on the board, I guess I should compress the code as much as possible, amirite?

Thank you very much in advance

I did so many things wrong I shouldn't be allowed to use the IDE for the rest of my life.

Or the forum, either, since you couldn't follow the rules in the stickies at the top of the forum.

Go read those threads now, and fix your post, to use code tags, not quote tags.

  if (t<21 && (HeaterPin,HIGH) {    //LOW TEMP TRIGGER

What do you think this is supposed to do?

You Can'T jUst uSe CapiTal LeTTers whereVer you likE.

    int FanStatus = HIGH             //SAVE DESIRED STATUS
  }

That variable, which masks the global variable of the same name, goes out of scope immediately, so it was a waste of effort typing the statement. Especially without the ; at the end. If you meant to assign a value to the global variable, why did you type int in front of the name?

Fixed.

PaulS:

  if (t<21 && (HeaterPin,HIGH) {    //LOW TEMP TRIGGER

What do you think this is supposed to do?

Activate the heater if below 21C if the heater is currently turned off.
Then turn off the heater if temp exceeds 24C on the next if statement.
The heater is not powerful at all - 240V 160W which means it'll take quite some time to jump between 21 and 24. Also the heater won't blast the termocouple directly.

PaulS:
You Can'T jUst uSe CapiTal LeTTers whereVer you likE.

I realized it wouldn't matter on variable names or values, and for convenience I did it this way. Should I use lower-case only?

PaulS:
That variable, which masks the global variable of the same name, goes out of scope immediately, so it was a waste of effort typing the statement. Especially without the ; at the end. If you meant to assign a value to the global variable, why did you type int in front of the name?

In hopes to store a new value in the variable, so it changes the predefined one and the code can recognize whether or not the fan is currently running. Same repeats across every subroutine. Since I can't use the PWM control directly (due to very different operating frequencies) I guess I can't let the code to fine-tune the speeds in realtime, so it'll have to be set manually on the code and try different values by trial and error.
And true, I totally forgot about ";".

I can't seem to understand the part of the scope yet, I'll google.

Based on your code, I'd suggest you start with some of the example sketches and figure out how they work. There is also an example sketch for the DHT sensor you should try...

The below code at least compiles (Case Matters - DigitalRead() is not a function, digitalRead() is)
but you still have some logic errors..

/*Libraries*/
#include <Wire.h>
#include <DHT.h>
//#include <EEPROM.h>
#include <Adafruit_Sensor.h>

// define the type of DHT sensor you have
#define DHTTYPE DHT22   // DHT 22  (AM2302), AM2321
/*Definitions*/
const int DHTPin = A4;           // DHT22 SENSOR
const int LightPin = 2;       // RELAY1
const int FanPin = 4;         // RELAY2
const int HeaterPin = 6;      // RELAY3
const int AlarmPin = 8;       // RELAY4
const int PWRLED = 9;         // POWER LED
const int StatusLED = 12;     // STATUS LED
const int FanPWM = 5;         // FAN PWM
int LightStatus = HIGH;       // DEFAULT VALUES AT STARTUP
int HeaterStatus = HIGH;      //..
int FanStatus = HIGH;         //..
int AlarmStatus = HIGH;       //..
float t = 0, h = 0;           //BLANK VALUES FOR TEMP/RH

DHT dht(DHTPin, DHTTYPE);

void setup() {
  Serial.begin(9600);          //TO START Serial COMMUNICATION
  while ( !Serial ) {
    // wait for Serial to be ready
  }
  dht.begin();                 //START SENSOR
  pinMode(LightPin, OUTPUT);   //PIN SETUP
  pinMode(FanPin, OUTPUT);     //..
  pinMode(HeaterPin, OUTPUT);  //..
  pinMode(AlarmPin, OUTPUT);   //..
  pinMode(PWRLED, OUTPUT);     //..
  pinMode(StatusLED, OUTPUT);  //..
  pinMode(FanPWM, OUTPUT);     //..
  digitalWrite(PWRLED, HIGH);  //LED ON
  digitalWrite(LightPin, LOW); //POWER ON RELAY SELFTEST
  digitalWrite(LightPin, HIGH); //..
  delay(300);                  //..
  digitalWrite(FanPin, LOW);   //..
  digitalWrite(FanPin, HIGH);  //..
  delay(300);                  //..
  digitalWrite(HeaterPin, LOW); //..
  digitalWrite(HeaterPin, HIGH); //..
  delay(300);                   //..
  digitalWrite(AlarmPin, LOW);  //..
  digitalWrite(AlarmPin, HIGH); //..
}

unsigned long currentMillis;

void loop() {

  currentMillis = millis();       //TIMING
  temprh();                       //CYCLE THROUGH SUBROUTINES
  pwmsignal();                    //..
  lightvoid();                    //..

}

void temprh() {                     //TEMP CONTROL
  float t = dht.readTemperature();          //READ TEMP
  float h = dht.readHumidity();             //READ RH
  if (t < 21.0 && HeaterStatus == HIGH) { //LOW TEMP TRIGGER
    digitalWrite(HeaterPin, LOW);    //ACTIVATE HEATER RELAY
    HeaterStatus = LOW;          //STORE NEW STATE
    FanStatus = HIGH;
  }
  if (t > 24.0) {                     //HIGH TEMP TRIGGER
    digitalWrite(HeaterPin, HIGH);  //DEACTIVATE HEATER RELAY
    HeaterStatus = HIGH;
    FanStatus = LOW;                //STORE NEW DESIRED FAN STATE
  }
}

void pwmsignal() {
  float t;
  if (FanStatus == HIGH) {                //CHECK DESIRED STATUS
    digitalWrite(FanPin, LOW);      //TURN ON FAN RELAY***
    analogWrite(FanPWM, 255);       //MAX. PWM SPEED
    do {
      t = dht.readTemperature();      //READ TEMP AGAIN
    }  while (t > 24);                 //KEEP AT MAX. SPEED IF NOT BELOW 24C (will it keep reading the temp?)
    delay(1500);                    //MAINTAIN SPEED FOR 1.5 SEC
    analogWrite(FanPWM, 170);       //DROP TO 65-70%
    delay(2000);                    //MAINTAIN FOR 2 SECONDS
    digitalWrite(FanPin, HIGH);      //TURN OFF FAN RELAY
    analogWrite(FanPWM, 0);          //DONT KNOW IF REALLY NEEDED.
    FanStatus = HIGH;             //SAVE DESIRED STATUS
  }
}

void lightvoid() {
  if (LightStatus == HIGH) {             //SAME STRUCTURE BUT NOW I THINK ARDUINO PRO MINI DOESNT
    digitalWrite(LightPin, LOW);    //SUPPORT RTC SO I DON'T KNOW HOW TO SET A TIMER.
    delay(1000);
    LightStatus = LOW;
  }

  if (LightStatus == LOW) {
    digitalWrite(LightPin, HIGH);
    delay(1000);
    LightStatus = HIGH;
  }
}

Activate the heater if below 21C if the heater is currently turned off.

No, that is not what the code does.

if (t<21 && (HeaterPin,HIGH) {

If the temperature is less than 21, the second part of the statement is evaluated. The comma operator returns the last item in the list, so this becomes:

if (t<21 && (HIGH) {

Since HIGH is not false, this is equivalent to:

if (t<21) {

which doesn't give a rat's ass if the heater is on or off.

If you meant to read the state of a pin, you forgot to call the function to do that. And, that function does not take two arguments.

Sounds like a fun little project.

Do you have a state diagram or flow-chart of how all the elements of the system come together? Or is the pseudocode above sort of a "stream of consciousness" type thing from which all the interdependencies can be determined?

At first glance I would handle each logical block as its own state machine; you're already hinting at this with your comment in loop() "CYCLE THROUGH SUBROUTINES". But each function call should only last a very brief period of time; no delays(), for example -- use millis() timing to ensure nothing blocks other stuff being done.

PaulS:
No, that is not what the code does.

Sorry. You're right, I didn't pay enough attention, the comma should be '==' instead as I did everywhere else.

blh64:
Based on your code, I'd suggest you start with some of the example sketches and figure out how they work. There is also an example sketch for the DHT sensor you should try...

The below code at least compiles (Case Matters - DigitalRead() is not a function, digitalRead() is)
but you still have some logic errors..

/*Libraries*/

#include <Wire.h>
#include <DHT.h>
//#include <EEPROM.h>
#include <Adafruit_Sensor.h>

// define the type of DHT sensor you have
#define DHTTYPE DHT22  // DHT 22  (AM2302), AM2321
/Definitions/
const int DHTPin = A4;          // DHT22 SENSOR
const int LightPin = 2;      // RELAY1
const int FanPin = 4;        // RELAY2
const int HeaterPin = 6;      // RELAY3
const int AlarmPin = 8;      // RELAY4
const int PWRLED = 9;        // POWER LED
const int StatusLED = 12;    // STATUS LED
const int FanPWM = 5;        // FAN PWM
int LightStatus = HIGH;      // DEFAULT VALUES AT STARTUP
int HeaterStatus = HIGH;      //..
int FanStatus = HIGH;        //..
int AlarmStatus = HIGH;      //..
float t = 0, h = 0;          //BLANK VALUES FOR TEMP/RH

DHT dht(DHTPin, DHTTYPE);

void setup() {
  Serial.begin(9600);          //TO START Serial COMMUNICATION
  while ( !Serial ) {
    // wait for Serial to be ready
  }
  dht.begin();                //START SENSOR
  pinMode(LightPin, OUTPUT);  //PIN SETUP
  pinMode(FanPin, OUTPUT);    //..
  pinMode(HeaterPin, OUTPUT);  //..
  pinMode(AlarmPin, OUTPUT);  //..
  pinMode(PWRLED, OUTPUT);    //..
  pinMode(StatusLED, OUTPUT);  //..
  pinMode(FanPWM, OUTPUT);    //..
  digitalWrite(PWRLED, HIGH);  //LED ON
  digitalWrite(LightPin, LOW); //POWER ON RELAY SELFTEST
  digitalWrite(LightPin, HIGH); //..
  delay(300);                  //..
  digitalWrite(FanPin, LOW);  //..
  digitalWrite(FanPin, HIGH);  //..
  delay(300);                  //..
  digitalWrite(HeaterPin, LOW); //..
  digitalWrite(HeaterPin, HIGH); //..
  delay(300);                  //..
  digitalWrite(AlarmPin, LOW);  //..
  digitalWrite(AlarmPin, HIGH); //..
}

unsigned long currentMillis;

void loop() {

currentMillis = millis();      //TIMING
  temprh();                      //CYCLE THROUGH SUBROUTINES
  pwmsignal();                    //..
  lightvoid();                    //..

}

void temprh() {                    //TEMP CONTROL
  float t = dht.readTemperature();          //READ TEMP
  float h = dht.readHumidity();            //READ RH
  if (t < 21.0 && HeaterStatus == HIGH) { //LOW TEMP TRIGGER
    digitalWrite(HeaterPin, LOW);    //ACTIVATE HEATER RELAY
    HeaterStatus = LOW;          //STORE NEW STATE
    FanStatus = HIGH;
  }
  if (t > 24.0) {                    //HIGH TEMP TRIGGER
    digitalWrite(HeaterPin, HIGH);  //DEACTIVATE HEATER RELAY
    HeaterStatus = HIGH;
    FanStatus = LOW;                //STORE NEW DESIRED FAN STATE
  }
}

void pwmsignal() {
  float t;
  if (FanStatus == HIGH) {                //CHECK DESIRED STATUS
    digitalWrite(FanPin, LOW);      //TURN ON FAN RELAY***
    analogWrite(FanPWM, 255);      //MAX. PWM SPEED
    do {
      t = dht.readTemperature();      //READ TEMP AGAIN
    }  while (t > 24);                //KEEP AT MAX. SPEED IF NOT BELOW 24C (will it keep reading the temp?)
    delay(1500);                    //MAINTAIN SPEED FOR 1.5 SEC
    analogWrite(FanPWM, 170);      //DROP TO 65-70%
    delay(2000);                    //MAINTAIN FOR 2 SECONDS
    digitalWrite(FanPin, HIGH);      //TURN OFF FAN RELAY
    analogWrite(FanPWM, 0);          //DONT KNOW IF REALLY NEEDED.
    FanStatus = HIGH;            //SAVE DESIRED STATUS
  }
}

void lightvoid() {
  if (LightStatus == HIGH) {            //SAME STRUCTURE BUT NOW I THINK ARDUINO PRO MINI DOESNT
    digitalWrite(LightPin, LOW);    //SUPPORT RTC SO I DON'T KNOW HOW TO SET A TIMER.
    delay(1000);
    LightStatus = LOW;
  }

if (LightStatus == LOW) {
    digitalWrite(LightPin, HIGH);
    delay(1000);
    LightStatus = HIGH;
  }
}

Thank you very much! Yes, I know I should refine the code and check every example. Just need to learn most of the stuff the best I can before getting my hands on the Arduino where I'll be able to see exacly how it works and debug small mistakes. As I said, never used one or coded in C...

Blackfin:
Sounds like a fun little project.

Do you have a state diagram or flow-chart of how all the elements of the system come together? Or is the pseudocode above sort of a "stream of consciousness" type thing from which all the interdependencies can be determined?

At first glance I would handle each logical block as its own state machine; you're already hinting at this with your comment in loop() "CYCLE THROUGH SUBROUTINES". But each function call should only last a very brief period of time; no delays(), for example -- use millis() timing to ensure nothing blocks other stuff being done.

There is a link to the picture of the wiring diagram on the first post, but no flow-chart. Exact timings are not really crucial except for lights and PWM, also I guess using millis to control even the temperature check would make the code excessively large, but tell me if I'm wrong. For now I used delay() in PWM until I know how to do it with millis. Every subroutine is supposed to tell other subroutines what to do/not to do next.

Flow would be something like...

check temp > activate fan or heater if needed
if fan active, start PWM signal
subroutine using millis to activate lights from 9 to 15PM, 21 to 3AM (not yet in the code since I still need to learn how to use it)
subroutine for alarm, active for 3 seconds every 20 minutes. (not yet in the code either)

Delays before setting a new variable value were in place in order to avoid any weird state in which an IF statement could read an outdated value. It did make sense when I did the code but probably not needed at all.

Now it's study time with millis and examples, will post the new code tomorrow :grin:

I think I somewhat understand how millis work now, so changed the whole structure and now everything is included in void loop, instead acting like a spaghetti code.

Should I add some small delays here and there to make the arduino run slower?
I don't know if it can be harmful that it's checking non-stop so many things.
This is supposed to be working 24/7.
Also I don't care if it gets stuck on the while loop, since the fan is really underpowered for what it has to do, and is still a long way until summer kicks in so I can learn more and change the design

/*Libraries*/
#include <Wire.h>
#include <DHT.h>
//#include <EEPROM.h>
#include <Adafruit_Sensor.h>

/*Definitions*/
unsigned long startMillis;
unsigned long currentMillis;
unsigned long previousMillis=0;
unsigned long previousAlarm=0;
unsigned long currentFan=0;
const unsigned long light = 21600000;
const unsigned long alarmtime = 3000;
const unsigned long pwm2 = 2500;
const unsigned long alarm = 20000;
#define DHTTYPE DHT22         // SENSOR MODEL
const int DHTPin = A4;        // DHT22 SENSOR
const int LightPin = 2;       // RELAY1
const int FanPin = 4;         // RELAY2
const int HeaterPin = 6;      // RELAY3
const int AlarmPin = 8;       // RELAY4
const int PWRLED = 9;         // POWER LED
const int StatusLED = 12;     // STATUS LED
const int FanPWM = 5;         // FAN PWM
int LightStatus = HIGH;       // DEFAULT VALUES AT STARTUP
int HeaterStatus = HIGH;      // (ALL RELAYS OFF)
int FanStatus = HIGH;         //..
int AlarmStatus = HIGH;       //..
float t = 0, h = 0;           //BLANK VALUES FOR TEMP/RH
DHT dht(DHTPin, DHTTYPE);

void setup() {
  Serial.begin(9600);          //TO START Serial COMMUNICATION
  while ( !Serial ) {
    // wait for Serial to be ready
  }
  dht.begin();                    //START SENSOR
  pinMode(LightPin, OUTPUT);      //PIN SETUP
  pinMode(FanPin, OUTPUT);        //..
  pinMode(HeaterPin, OUTPUT);     //..
  pinMode(AlarmPin, OUTPUT);      //..
  pinMode(PWRLED, OUTPUT);        //..
  pinMode(StatusLED, OUTPUT);     //..
  pinMode(FanPWM, OUTPUT);        //..
  digitalWrite(PWRLED, HIGH);     //LED ON
  digitalWrite(LightPin, LOW);    //POWER ON RELAY SELFTEST
  digitalWrite(LightPin, HIGH);   //..
  delay(300);                     //..
  digitalWrite(FanPin, LOW);      //..
  digitalWrite(FanPin, HIGH);     //..
  delay(300);                     //..
  digitalWrite(HeaterPin, LOW);   //..
  digitalWrite(HeaterPin, HIGH);  //..
  delay(300);                     //..
  digitalWrite(AlarmPin, LOW);    //..
  digitalWrite(AlarmPin, HIGH);   //..
}

void loop() {
  currentMillis = millis();                     //TIMING
  if (currentMillis - previousMillis >= light); //6 HRS ROLLOVER
    {
    previousMillis = currentMillis;
    if (LightStatus == HIGH) {                  
      digitalWrite(LightPin, LOW);              
      LightStatus = LOW;
      }
    if (LightStatus == LOW) {
      digitalWrite(LightPin, HIGH);
      LightStatus = HIGH;
      }
    }
  if (currentMillis - previousAlarm >= alarm); //ALARM
    {
    previousAlarm = currentMillis;
    digitalWrite(AlarmPin, LOW);
    if (previousAlarm - currentMillis >= alarmtime);
      digitalWrite(AlarmPin, HIGH);
    }

    float t = dht.readTemperature();          //READ TEMP
    float h = dht.readHumidity();             //READ RH
     
     if (t < 21.0) {                          //LOW TEMP TRIGGER
      digitalWrite(HeaterPin, LOW);           //ACTIVATE HEATER RELAY
      FanStatus = HIGH;
     }
    
    if (t > 24.0) {                         //HIGH TEMP TRIGGER
    digitalWrite(HeaterPin, HIGH);          //DEACTIVATE HEATER RELAY
    FanStatus = LOW;                        //STORE NEW DESIRED FAN STATE
    }
    if (FanStatus == LOW) {                //CHECK DESIRED STATUS
      currentFan = millis();
      digitalWrite(HeaterPin, HIGH);
      digitalWrite(FanPin, LOW);            //TURN ON FAN RELAY***
      analogWrite(FanPWM, 255);             //MAX. PWM SPEED
      do {
      t = dht.readTemperature();            //READ TEMP LOOP
      }  while (t > 24);                    //KEEP AT MAX. SPEED IF NOT BELOW 24C
      analogWrite(FanPWM, 170);             //DROP TO 65-70%
      if (currentFan - millis() >= pwm2) {
      analogWrite(FanPWM, 1);               //DONT KNOW IF REALLY NEEDED.
      digitalWrite(FanPin, HIGH);           //TURN OFF FAN RELAY
      FanStatus = HIGH;                     //SAVE DESIRED STATUS
    }
  }
}

Checked and at least it compiles using 5366 bytes (17%) so I believe I have plenty of room for code improvement

Any advice and what you'd change?

Thanks!

if (currentMillis - previousMillis >= light); //6 HRS ROLLOVER

Remove semicolon.

        if (LightStatus == HIGH) 
        {                  
            digitalWrite(LightPin, LOW);              
            LightStatus = LOW;
        }
        
        if (LightStatus == LOW) 
        {
            digitalWrite(LightPin, HIGH);
            LightStatus = HIGH;
        }

Change "if( LightStatus == LOW )" to "else if(...", otherwise when light is turned off in code above, it will immediately be turned back on.

if (currentMillis - previousAlarm >= alarm); //ALARM

See above re semicolon.

        previousAlarm = currentMillis;
        digitalWrite(AlarmPin, LOW);
        if (previousAlarm - currentMillis >= alarmtime);
            digitalWrite(AlarmPin, LOW);

You just updated previousAlarm to currentMillis and then check to see if previousAlarm - current...

Well, that's just not going to work.

You fan logic needs work. Do you really want to lock the processor into a while loop reading the temperature and do nothing else?

Blackfin:

        if (LightStatus == HIGH) 

{                  
           digitalWrite(LightPin, LOW);              
           LightStatus = LOW;
       }
       
       if (LightStatus == LOW)
       {
           digitalWrite(LightPin, HIGH);
           LightStatus = HIGH;
       }




Change "if( LightStatus == LOW )" to "else if(...", otherwise when light is turned off in code above, it will immediately be turned back on.

You're right, wanted to do a A=B B=A but did not look at the overall picture.

Blackfin:

        previousAlarm = currentMillis;

digitalWrite(AlarmPin, LOW);
       if (previousAlarm - currentMillis >= alarmtime);
           digitalWrite(AlarmPin, LOW);




You just updated previousAlarm to currentMillis and then check to see if previousAlarm - current...

Well, that's just not going to work.

Yeah... Embarassing.

Blackfin:
You fan logic needs work. Do you really want to lock the processor into a while loop reading the temperature and do nothing else?

For now it would work for me, because at most it can get hot only two hours in the morning and one at the afternoon, the sun is hitting directly on the cabin but the dawg wants to be in there ¯_(ツ)_/¯. It doesn't conflict with the light times either, only the alarm signal would get totally interrupted (not critical at those hours). And tbh I can't seem to find a nice way to keep the fan on based on the temperature reading without interrupting the code.

I'll try to set the fan to be on in the void loop unless temperature drops, tomorrow when I wakes up

Thank you very much for the tons of patience :sad:

Here's a reimagining of your code done with state machines controlling the various things. I took a liberty or two here or there when I wasn't sure what you wanted. It compiles and runs on my 2560 (the heartbeat LED blinks at least...) I can't make any guarantees it's bug-free or even does what you want. Hopefully this will help you some:

/*Libraries*/
#include <Wire.h>
#include <DHT.h>
//#include <EEPROM.h>
#include <Adafruit_Sensor.h>

/*Definitions*/
const unsigned long light = 21600000;
const unsigned long alarmtime = 3000;
const unsigned long pwm2 = 2500;
const unsigned long alarm = 20000;

#define DHTTYPE DHT22         // SENSOR MODEL
const byte DHTPin = A4;        // DHT22 SENSOR
const byte LightPin = 2;       // RELAY1
const byte FanPin = 4;         // RELAY2
const byte HeaterPin = 6;      // RELAY3
const byte AlarmPin = 8;       // RELAY4
const byte PWRLED = 9;         // POWER LED
const byte StatusLED = 12;     // STATUS LED
const byte FanPWM = 5;         // FAN PWM
const byte pinBILED = LED_BUILTIN;

DHT dht(DHTPin, DHTTYPE);

void setup() 
{
    Serial.begin(9600);          //TO START Serial COMMUNICATION
    while ( !Serial ) {
        // wait for Serial to be ready
    }
    
    dht.begin();                    //START SENSOR
    pinMode(LightPin, OUTPUT);      //PIN SETUP
    pinMode(FanPin, OUTPUT);        //..
    pinMode(HeaterPin, OUTPUT);     //..
    pinMode(AlarmPin, OUTPUT);      //..
    pinMode(PWRLED, OUTPUT);        //..
    pinMode(StatusLED, OUTPUT);     //..
    pinMode(FanPWM, OUTPUT);        //..
    pinMode(pinBILED, OUTPUT );
    
    //
    digitalWrite(PWRLED, HIGH);     //LED ON
    
    digitalWrite(LightPin, LOW);    //POWER ON RELAY SELFTEST
    delay(1000);                     //..
    digitalWrite(LightPin, HIGH);   //..
 
    digitalWrite(FanPin, LOW);      //..
    analogWrite(FanPWM, 255);
    delay(1300);                     //.. 
    analogWrite(FanPWM, 0);
    digitalWrite(FanPin, HIGH);     //..
  
    digitalWrite(HeaterPin, LOW);   //..
    delay(1000);                     //..
    digitalWrite(HeaterPin, HIGH);  //..
  
    digitalWrite(AlarmPin, LOW);    //..
    delay(300);                     //..
    digitalWrite(AlarmPin, HIGH);   //..
  
}//setup

void loop() 
{
    LightSM();
    AlarmSM();
    HeaterSM();
    FanSM();

    //let you know the processor is alive by blinking the built-in LED
    BlinkBuiltIn();
    
}//loop

//since all the statemachine timing uses a similar structure for time checks,
//I put the checks in one function. This will return true if the
//elapsed time between *timeNow and *timeEvent is >= value
bool CheckTime( unsigned long *timeNow, unsigned long *timeEvent, unsigned long value )
{
    *timeNow = millis();
    if( *timeNow - *timeEvent >= value )
        return true;
    else
        return false;
    
}//CheckTime

void BlinkBuiltIn( void )
{
    static bool
        stateBILED = false;
    static unsigned long
        timeBILED = millis();
    unsigned long
        timeNow;

    if( !CheckTime( &timeNow, &timeBILED, 300ul ) )
        return;
        
    timeBILED = timeNow;

    stateBILED ^= true;     //toggle stateBILED from true to false or false to true
    //write internal state stateBILED to built-in LED
    digitalWrite( pinBILED, (stateBILED)?HIGH:LOW );
    
}//BlinkBuiltIn

void LightSM( void )
{
    static byte
        stateLight = LOW;
    static unsigned long
        timeLight = millis();
    unsigned long
        timeNow;

    if( !CheckTime( &timeNow, &timeLight, light ) )
        return;
    timeLight = timeNow;
    
    //toggle state of light every light mS
    //don't really need switch to do that but if you add a RTC later
    //this can come in handy.
    switch( stateLight )
    {
        case    HIGH:
            digitalWrite(LightPin, LOW);              
            stateLight = LOW;
        break;

        case    LOW:
            digitalWrite(LightPin, HIGH);              
            stateLight = HIGH;
        break;
        
    }//switch
    
}//LightSM

#define ALARM_OFF   0
#define ALARM_ON    1
void AlarmSM( void )
{
    static byte
        stateAlarm = ALARM_OFF;
    static unsigned long
        timeAlarm = millis();
    unsigned long
        timeNow;

    switch( stateAlarm )
    {
        case    ALARM_OFF:
            if( !CheckTime( &timeNow, &timeAlarm, alarm ) )
                return;

            timeAlarm = timeNow;
            digitalWrite( AlarmPin, LOW );
            stateAlarm = ALARM_ON;
            
        break;    

        case    ALARM_ON:
            if( !CheckTime( &timeNow, &timeAlarm, alarmtime ) )
                return;

            timeAlarm = timeNow;
            digitalWrite( AlarmPin, HIGH );
            stateAlarm = ALARM_OFF;
            
        break;
        
    }//switch
    
}//AlarmSM

#define HEATER_OFF      0
#define HEATER_ON       1
void HeaterSM( void )
{
    static byte
        stateHeater = HEATER_OFF;
    static unsigned long
        timeHeater = millis();
    float
        temperature;
    unsigned long
        timeNow;
            
    if( !CheckTime( &timeNow, &timeHeater, 100ul ) )
        return;
    timeHeater = timeNow;

    temperature = dht.readTemperature();          //READ TEMP
    switch( stateHeater )
    {
        case    HEATER_OFF:
            //if temperature falls below 21oC, turn on the heater
            if( temperature < 21.0 )
            {
                digitalWrite(HeaterPin, LOW);           //ACTIVATE HEATER RELAY
                stateHeater = HEATER_ON;
                    
            }//if
        
        break;

        case    HEATER_ON:
            //when temp reaches 24oC or above, turn the heater off
            if( temperature >= 24.0 )
            {
                digitalWrite(HeaterPin, HIGH);           //DEACTIVATE HEATER RELAY
                stateHeater = HEATER_OFF;
                    
            }//if
        
        break;
        
    }//switch
    
}//HeaterSM

#define FAN_OFF     0
#define FAN_ON      1
void FanSM( void )
{
    static byte
        stateFan = FAN_OFF;
    static unsigned long
        timeFan;
    unsigned long
        timeNow;
    float
        temperature;
        
    if( !CheckTime( &timeNow, &timeFan, 250ul ) )
        return;
    timeFan = timeNow;
    
    temperature = dht.readTemperature();          //READ TEMP    
    switch( stateFan )
    {
        case    FAN_OFF:            
            //turn on fan at max PWM duty when temperature is 24 or higher
            if( temperature >= 24.0 )
            {
                digitalWrite(FanPin, LOW);            //TURN ON FAN RELAY***
                analogWrite(FanPWM, 255);             //MAX. PWM SPEED
                stateFan = FAN_ON;
                
            }//if
            
        break;

        case    FAN_ON:
            //fan is on; if temperature falls below 22.5, turn it off
            if( temperature <= 22.5 )
            {
                digitalWrite(FanPin, HIGH);            //TURN OFF FAN RELAY***
                analogWrite(FanPWM, 0);                 //MAX. PWM SPEED
                stateFan = FAN_OFF;
                return;
                
            }//if

            //temperature >22.5; is it 24 or above?
            if( temperature >= 24.0 )
                //yes; command max speed
                analogWrite(FanPWM, 255);             //MAX. PWM SPEED
            else
                //below 24oC we can slow the fan down
                analogWrite(FanPWM, 170);             //DROP TO 60-75%

        break;
        
    }//switch
    
}//FanSM

Sorry. You're right, I didn't pay enough attention, the comma should be '==' instead as I did everywhere else.

That's STILL not right. If you change the statement to use == instead of the comma, it looks like:

if (t<21 && (HeaterPin == HIGH) {

Ignoring the unbalanced parentheses (the compiler will not), HeaterPin has the value 6, which is NOT equal to HIGH.

You MUST read the state of the pin, and compare the state to HIGH or LOW, not the pin number.

Blackfin:
Here's a reimagining of your code done with state machines controlling the various things. I took a liberty or two here or there when I wasn't sure what you wanted. It compiles and runs on my 2560 (the heartbeat LED blinks at least...) I can't make any guarantees it's bug-free or even does what you want. Hopefully this will help you some:

Just a personal preference, but I'd make timeNow a global variable and set it at the beginning of loop(). That way, for a given run throup loop() all the comparisons in the state machines behave as if they test at the exact same moment in time.

For this application, it really doesn't matter, but sometimes it does

unsigned long timeNow;
void loop() 
{
    timeNow = millis();
    LightSM();
    AlarmSM();
    HeaterSM();
    FanSM();

    //let you know the processor is alive by blinking the built-in LED
    BlinkBuiltIn();
    
}//loop

bool CheckTime( unsigned long *timeEvent, unsigned long value )
{
    if( timeNow - *timeEvent >= value )
        return true;
    else
        return false;
    
}//CheckTime

Blackfin:
Here's a reimagining of your code done with state machines controlling the various things. I took a liberty or two here or there when I wasn't sure what you wanted. It compiles and runs on my 2560 (the heartbeat LED blinks at least...) I can't make any guarantees it's bug-free or even does what you want. Hopefully this will help you some:

/*Libraries*/

#include <Wire.h>
#include <DHT.h>
//#include <EEPROM.h>
#include <Adafruit_Sensor.h>

/Definitions/
const unsigned long light = 21600000;
const unsigned long alarmtime = 3000;
const unsigned long pwm2 = 2500;
const unsigned long alarm = 20000;

#define DHTTYPE DHT22        // SENSOR MODEL
const byte DHTPin = A4;        // DHT22 SENSOR
const byte LightPin = 2;      // RELAY1
const byte FanPin = 4;        // RELAY2
const byte HeaterPin = 6;      // RELAY3
const byte AlarmPin = 8;      // RELAY4
const byte PWRLED = 9;        // POWER LED
const byte StatusLED = 12;    // STATUS LED
const byte FanPWM = 5;        // FAN PWM
const byte pinBILED = LED_BUILTIN;

DHT dht(DHTPin, DHTTYPE);

void setup()
{
    Serial.begin(9600);          //TO START Serial COMMUNICATION
    while ( !Serial ) {
        // wait for Serial to be ready
    }
   
    dht.begin();                    //START SENSOR
    pinMode(LightPin, OUTPUT);      //PIN SETUP
    pinMode(FanPin, OUTPUT);        //..
    pinMode(HeaterPin, OUTPUT);    //..
    pinMode(AlarmPin, OUTPUT);      //..
    pinMode(PWRLED, OUTPUT);        //..
    pinMode(StatusLED, OUTPUT);    //..
    pinMode(FanPWM, OUTPUT);        //..
    pinMode(pinBILED, OUTPUT );
   
    //
    digitalWrite(PWRLED, HIGH);    //LED ON
   
    digitalWrite(LightPin, LOW);    //POWER ON RELAY SELFTEST
    delay(1000);                    //..
    digitalWrite(LightPin, HIGH);  //..

digitalWrite(FanPin, LOW);      //..
    analogWrite(FanPWM, 255);
    delay(1300);                    //..
    analogWrite(FanPWM, 0);
    digitalWrite(FanPin, HIGH);    //..
 
    digitalWrite(HeaterPin, LOW);  //..
    delay(1000);                    //..
    digitalWrite(HeaterPin, HIGH);  //..
 
    digitalWrite(AlarmPin, LOW);    //..
    delay(300);                    //..
    digitalWrite(AlarmPin, HIGH);  //..
 
}//setup

void loop()
{
    LightSM();
    AlarmSM();
    HeaterSM();
    FanSM();

//let you know the processor is alive by blinking the built-in LED
    BlinkBuiltIn();
   
}//loop

//since all the statemachine timing uses a similar structure for time checks,
//I put the checks in one function. This will return true if the
//elapsed time between *timeNow and *timeEvent is >= value
bool CheckTime( unsigned long *timeNow, unsigned long *timeEvent, unsigned long value )
{
    *timeNow = millis();
    if( *timeNow - *timeEvent >= value )
        return true;
    else
        return false;
   
}//CheckTime

void BlinkBuiltIn( void )
{
    static bool
        stateBILED = false;
    static unsigned long
        timeBILED = millis();
    unsigned long
        timeNow;

if( !CheckTime( &timeNow, &timeBILED, 300ul ) )
        return;
       
    timeBILED = timeNow;

stateBILED ^= true;    //toggle stateBILED from true to false or false to true
    //write internal state stateBILED to built-in LED
    digitalWrite( pinBILED, (stateBILED)?HIGH:LOW );
   
}//BlinkBuiltIn

void LightSM( void )
{
    static byte
        stateLight = LOW;
    static unsigned long
        timeLight = millis();
    unsigned long
        timeNow;

if( !CheckTime( &timeNow, &timeLight, light ) )
        return;
    timeLight = timeNow;
   
    //toggle state of light every light mS
    //don't really need switch to do that but if you add a RTC later
    //this can come in handy.
    switch( stateLight )
    {
        case    HIGH:
            digitalWrite(LightPin, LOW);             
            stateLight = LOW;
        break;

case    LOW:
            digitalWrite(LightPin, HIGH);             
            stateLight = HIGH;
        break;
       
    }//switch
   
}//LightSM

#define ALARM_OFF  0
#define ALARM_ON    1
void AlarmSM( void )
{
    static byte
        stateAlarm = ALARM_OFF;
    static unsigned long
        timeAlarm = millis();
    unsigned long
        timeNow;

switch( stateAlarm )
    {
        case    ALARM_OFF:
            if( !CheckTime( &timeNow, &timeAlarm, alarm ) )
                return;

timeAlarm = timeNow;
            digitalWrite( AlarmPin, LOW );
            stateAlarm = ALARM_ON;
           
        break;

case    ALARM_ON:
            if( !CheckTime( &timeNow, &timeAlarm, alarmtime ) )
                return;

timeAlarm = timeNow;
            digitalWrite( AlarmPin, HIGH );
            stateAlarm = ALARM_OFF;
           
        break;
       
    }//switch
   
}//AlarmSM

#define HEATER_OFF      0
#define HEATER_ON      1
void HeaterSM( void )
{
    static byte
        stateHeater = HEATER_OFF;
    static unsigned long
        timeHeater = millis();
    float
        temperature;
    unsigned long
        timeNow;
           
    if( !CheckTime( &timeNow, &timeHeater, 100ul ) )
        return;
    timeHeater = timeNow;

temperature = dht.readTemperature();          //READ TEMP
    switch( stateHeater )
    {
        case    HEATER_OFF:
            //if temperature falls below 21oC, turn on the heater
            if( temperature < 21.0 )
            {
                digitalWrite(HeaterPin, LOW);          //ACTIVATE HEATER RELAY
                stateHeater = HEATER_ON;
                   
            }//if
       
        break;

case    HEATER_ON:
            //when temp reaches 24oC or above, turn the heater off
            if( temperature >= 24.0 )
            {
                digitalWrite(HeaterPin, HIGH);          //DEACTIVATE HEATER RELAY
                stateHeater = HEATER_OFF;
                   
            }//if
       
        break;
       
    }//switch
   
}//HeaterSM

#define FAN_OFF    0
#define FAN_ON      1
void FanSM( void )
{
    static byte
        stateFan = FAN_OFF;
    static unsigned long
        timeFan;
    unsigned long
        timeNow;
    float
        temperature;
       
    if( !CheckTime( &timeNow, &timeFan, 250ul ) )
        return;
    timeFan = timeNow;
   
    temperature = dht.readTemperature();          //READ TEMP   
    switch( stateFan )
    {
        case    FAN_OFF:           
            //turn on fan at max PWM duty when temperature is 24 or higher
            if( temperature >= 24.0 )
            {
                digitalWrite(FanPin, LOW);            //TURN ON FAN RELAY***
                analogWrite(FanPWM, 255);            //MAX. PWM SPEED
                stateFan = FAN_ON;
               
            }//if
           
        break;

case    FAN_ON:
            //fan is on; if temperature falls below 22.5, turn it off
            if( temperature <= 22.5 )
            {
                digitalWrite(FanPin, HIGH);            //TURN OFF FAN RELAY***
                analogWrite(FanPWM, 0);                //MAX. PWM SPEED
                stateFan = FAN_OFF;
                return;
               
            }//if

//temperature >22.5; is it 24 or above?
            if( temperature >= 24.0 )
                //yes; command max speed
                analogWrite(FanPWM, 255);            //MAX. PWM SPEED
            else
                //below 24oC we can slow the fan down
                analogWrite(FanPWM, 170);            //DROP TO 60-75%

break;
       
    }//switch
   
}//FanSM

Omg :open_mouth: looks very different. Another example proving my approach was wrong. Will be reading and trying to understand as best I can every process in this code, I didn't even know the existence or use of some commands used here..
I'll also be testing the code as soon as I receive the Arduino, test everything is alright and posting the final code if any changes have to be made in case it could help a full newbie like me

blh64:
Just a personal preference, but I'd make timeNow a global variable and set it at the beginning of loop(). That way, for a given run throup loop() all the comparisons in the state machines behave as if they test at the exact same moment in time.

For this application, it really doesn't matter, but sometimes it does

unsigned long timeNow;

void loop()
{
   timeNow = millis();
   LightSM();
   AlarmSM();
   HeaterSM();
   FanSM();

//let you know the processor is alive by blinking the built-in LED
   BlinkBuiltIn();
   
}//loop

bool CheckTime( unsigned long *timeEvent, unsigned long value )
{
   if( timeNow - *timeEvent >= value )
       return true;
   else
       return false;
   
}//CheckTime

Thanks for the tip if I experience something weird or want to expand the functionality in the future