Thermostat with Relative Humidity Control © GPL3+

Temperature and humidity control to achieve the ideal confort conditions. The system work in a automatic way without a manual control.

  • 1,133 views
  • 0 comments
  • 5 respects

Components and supplies

09590 01
LED (generic)
3mm Led green - Ventilation ON; 3mm Led red - Heating ON; 3mm Led blue - Cooling ON; 3 mm Led yellow blinking - When cooling or heating are ON; 5mm Led blue - Dehumidification ON; 5mm bright led - Humidification ON; 5 mm Led orange blinking - When humidification or dehumidification are ON;
×7
386 00
DHT11 Temperature & Humidity Sensor
×1
Ds3231mpmb1 en4txppxku
Maxim Integrated DS3231MPMB1 Peripheral Module
×1
Mfr 25fbf52 221r sml
Resistor 221 ohm
×6
Adafruit industries ada239 image 75px
Solderless Breadboard Full Size
×1
Ardgen mega
Arduino Mega 2560 & Genuino Mega 2560
×1
LCD 20x4 Display - IIC/I2C 2004
×1

Apps and online services

About this project

The program was designed to ensure that the temperature in a room is between 20 °C and 24 °C and the relative humidity between 40% and 60%.

The implemented programming use the concept of Finite State Machines (FSM).

Next the resume of the schematic of the Entity, the Architecture and the four state machine icluded in the code.

Code

termostato_fsm_19.04.2018Arduino
Finite state machine
//  Autoria do projeto: Vasco Correia
//  Data de execuo: Abril de 2018 - verso 00
//  Controlo de humidade e temperatura de um espao a climatizar
//  Garantir os nveis ideais de humidade e temperatura no ar
//  Sistemas autnomos de controlo das cargas sensveis e latentes do ar
//  Projeto baseado em mquinas de estado finitas

// Bibliotecas
#include <DS3231.h> // biblioteca para o relgio em tempo real
#include <LiquidCrystal_I2C.h>  // biblioteca para comunicao I2C com o display de 20x4
#include<dht.h> // biblioteca relativa ao sensor DHT11 - sensor de T e HR do ar
dht DHT;

#define DHT11_PIN 7    // Definido o pino n 7 para o sensor de HR e Temperatura ambiente do espao a climatizar
#define HoldTime 10000   // Aguardar 10 segundos antes de ir para o estado inicial
#define HoldTime2 5000   // Aguardar 5 segundos antes de ir para o estado inicial
#define FSM1_L_pin 6        // Luz intermitente aquando o aquecimento ou o arrefecimento do espao a climatizar - FSM1
#define Vent_pin 5          // Ventilao ON - led verde
#define Aquec_pin 2         // Aquecimento ON - led vermelho
#define Arref_pin 3         // Arrefecimento ON - led azul
#define FSM3_L_pin 4        // Luz Amarelo torrado intermitente aquando a desumidificao ou humidificao do espao a climatizar - FSM3
#define Desum_pin 8         // Desumidificao ON - led azul
#define Humid_pin 9         // Desumidificao ON - led brilhante incolor

//  Comunicao IC2 utilizando o display LCD 4x20
LiquidCrystal_I2C lcd(0x3F, 2, 1, 0, 4, 5, 6, 7, 3, POSITIVE);
//  Clock externo
DS3231  rtc(SDA, SCL);

//Declarao dos OUTPUTS como variveis globais das mquinas de estados
static int FSM0_state = 1;   // estado incial - controlo da climatizao do espao - afeta a carga sensvel
static int FSM1_state = 1;   // estado incial - led amarelo a piscar aquando o aquecimento ou arrefecimento do espao a climatizar
static int FSM2_state = 1;   // estado inicial - controlo da carga latente no espao a climatizar
static int FSM3_state = 1;   // estado incial - led brilhante a piscar aquando a desumidificao e humidificao do espao a climatizar
static int FSM0_L = 0;  // estmulo da mquina de estados do led amarelo a piscar FSM1
static int FSM2_L = 0;  // estmulo da mquina de estados do led laranja a piscar FSM3

static  int Taquec;   // estmulo para acionar o aquecimento
static  int Tarref;   // estmulo para acionar o arrefecimento
static int T;   // estmulo para as temperaturas intermdias para o estado 2 e 3 da FSM0

static int Hhum;   // estmulo para acionar a humidificao
static int Hdesum;   // estmulo para acionar a desumidificao
static int H;   // estmulo para a HR  nos estados 2 e 3 da FSM2

static unsigned long FSM0_ts; // guarda o tempo atual para a FSM0
static unsigned long FSM1_ts; // guarda o tempo atual para a FSM1
static unsigned long FSM2_ts; // guarda o tempo atual para a FSM2
static unsigned long FSM3_ts; // guarda o tempo atual para a FSM3

void setup()
{
  pinMode(Vent_pin, OUTPUT);
  pinMode(Aquec_pin, OUTPUT);
  pinMode(Arref_pin, OUTPUT);
  pinMode(DHT11_PIN, INPUT);
  pinMode(FSM1_L_pin, OUTPUT);
  pinMode(Desum_pin, OUTPUT);
  pinMode(Humid_pin, OUTPUT);
  pinMode(FSM3_L_pin, OUTPUT);

  Serial.begin(9600);
  lcd.begin(20, 4);
  lcd.setCursor(0, 0);
  rtc.begin();

  //Descomente as linhas para configurar o horrio atual (upload), aps o processo comente e faa o upload novamente para o Arduino
  //rtc.setDOW(TUESDAY);     // Set Day-of-Week to SUNDAY
  //rtc.setTime(21,18, 0);     // Set the time to 12:00:00 (24hr format)
  //rtc.setDate(10,04,2018);

}

void loop()
{
  int chk = DHT.read11(DHT11_PIN);
  int FSM0_E_time;
  int FSM1_E_time;
  int FSM2_E_time;
  int FSM3_E_time;
  int Vent;
  int Aquec;
  int Arref;
  int Desum;
  int Humid;
  int FMS1_L;
  int FSM3_L;


  Vent = digitalRead(Vent_pin);
  Aquec = digitalRead(Aquec_pin);
  Arref = digitalRead(Arref_pin);
  Desum = digitalRead(Desum_pin);
  Humid = digitalRead(Humid_pin);

  if (millis() - FSM0_ts > HoldTime)
  {
    FSM0_E_time = 1;
  } else {
    FSM0_E_time = 0;
  }


  if (DHT.temperature <= 20) {
    Taquec = 1;
  }
  else
  {
    Taquec = 0;
  }


  if (DHT.temperature >= 24) {
    Tarref = 1;
  }
  else
  {
    Tarref = 0;
  }

  if (DHT.temperature > 22) {
    T = 1;
  }
  else
  {
    T = 0;
  }
  FSM0(FSM0_E_time, Taquec, Tarref, T);


  int LedOnOffTime = 750;
  if (millis() - FSM1_ts > LedOnOffTime) {
    FSM1_E_time = 1;
  } else {
    FSM1_E_time = 0;
  }
  FSM1(FSM1_E_time, FSM0_L);

  if (millis() - FSM2_ts > HoldTime2)
  {
    FSM2_E_time = 1;
  } else {
    FSM2_E_time = 0;
  }

  if (DHT.humidity <= 40) {
    Hhum = 1;
  }
  else
  {
    Hhum = 0;
  }


  if (DHT.humidity >= 60) {
    Hdesum = 1;
  }
  else
  {
    Hdesum = 0;
  }

  if (DHT.humidity > 50) {
    H = 1;
  }
  else
  {
    H = 0;
  }
  FSM2(FSM2_E_time, Hhum, Hdesum, H);


  int LedOnOffTime3 = 500;
  if (millis() - FSM3_ts > LedOnOffTime3) {
    FSM3_E_time = 1;
  } else {
    FSM3_E_time = 0;
  }
  FSM3(FSM3_E_time, FSM2_L);




}

// FSM0 sub arquitetura
void FSM0(int FSM0_E_time, int Taquec, int Tarref, int T)
{
  FSM0_next_state(FSM0_E_time, Taquec, Tarref, T);
  FSM0_output();
}

// FSM1 sub arquitetura
void FSM1(int FSM1_E_time, int FSM0_L)
{
  FSM1_next_state(FSM1_E_time, FSM0_L);
  FSM1_output();
}

// FSM2 sub arquitetura
void FSM2(int FSM2_E_time, int Hhum, int Hdesum, int H)
{
  FSM2_next_state(FSM2_E_time, Hhum, Hdesum, H);
  FSM2_output();
}

// FSM3 sub arquitetura
void FSM3(int FSM3_E_time, int FSM2_L)
{
  FSM3_next_state(FSM3_E_time, FSM2_L);
  FSM3_output();
}


void FSM0_next_state(int FSM0_E_time, int Taquec, int Tarref, int T)
{
  switch (FSM0_state)
  {
    case 1:
      if (Taquec == 1) {
        FSM0_state = 3;
      }
      else if (Tarref == 1) {
        FSM0_state = 2;
      }
      else
        FSM0_state = 1;
      break;

    case 2:
      if (T == 0)
      {
        FSM0_state = 4;
      }
      else
        FSM0_state = 2;
      break;

    case 3:
      if (T == 1)
      {
        FSM0_state = 5;
      }
      else
        FSM0_state = 3;
      break;

    case 4:
      if (FSM0_E_time == 1) {
        FSM0_state = 1;
      }
      break;

    case 5:
      if (FSM0_E_time == 1) {
        FSM0_state = 1;
      }
      break;

    default:
      break;

  }
  Serial.print("Temperatura = ");
  Serial.print(DHT.temperature);
  Serial.print(" C");
  Serial.println(" ");
  Serial.print("FSM0_state: ");
  Serial.println(FSM0_state);
  Serial.print("FSM1_state: ");
  Serial.println(FSM1_state);
  Serial.print("FSM2_state: ");
  Serial.println(FSM2_state);
  Serial.print("FSM3_state: ");
  Serial.println(FSM3_state);
  Serial.print("HR = ");
  Serial.print(DHT.humidity);
  Serial.println(" %");
  Serial.println(" ");

  lcd.setCursor(0, 1);
  lcd.print(rtc.getTimeStr());
  lcd.setCursor(10, 1);
  lcd.print(rtc.getDOWStr());
  lcd.setCursor(10, 0);
  lcd.print(rtc.getDateStr());
  lcd.setCursor(0, 4);
  lcd.print("T=");
  lcd.setCursor(2, 4);
  lcd.print(DHT.temperature);
  lcd.setCursor(6, 4);
  lcd.print(" C");
  lcd.setCursor(13, 4);
  lcd.print("HR=");
  lcd.setCursor(16, 4);
  lcd.print(DHT.humidity);
  lcd.setCursor(18, 4);
  lcd.print(" %");
  lcd.setCursor(0, 0);
  lcd.print("UALG-EEE");
  //lcd.setCursor(0,0);
  //lcd.print("  ");

  delay(500);
}

void FSM0_output()
{
  switch (FSM0_state)
  {
    case 1:
      digitalWrite(Vent_pin, HIGH);
      digitalWrite(Aquec_pin, LOW);
      digitalWrite(Arref_pin, LOW);
      break;

    case 2:
      digitalWrite(Vent_pin, HIGH);
      digitalWrite(Aquec_pin, LOW);
      digitalWrite(Arref_pin, HIGH);
      FSM0_L = 1;
      FSM0_ts = millis();
      break;

    case 3:
      digitalWrite(Vent_pin, HIGH);
      digitalWrite(Aquec_pin, HIGH);
      digitalWrite(Arref_pin, LOW);
      FSM0_L = 1;
      FSM0_ts = millis();
      break;

    case 4:
      digitalWrite(Vent_pin, HIGH);
      digitalWrite(Aquec_pin, LOW);
      digitalWrite(Arref_pin, LOW);
      FSM0_L = 0;
      break;

    case 5:
      digitalWrite(Vent_pin, HIGH);
      digitalWrite(Aquec_pin, LOW);
      digitalWrite(Arref_pin, LOW);
      FSM0_L = 0;
      break;

    default:
      break;
  }
}

void FSM1_next_state(int FSM1_E_time, int FSM0_L)
{
  switch (FSM1_state)
  {
    case 1:
      if (FSM0_L == 1) {
        FSM1_state = 2;
      }
      break;

    case 2:
      FSM1_state = 3;
      if (FSM0_L == 0) {
        FSM1_state = 6;
      }

    case 3:
      if (FSM1_E_time == 1) {
        FSM1_state = 4;
      }
      if (FSM0_L == 0) {
        FSM1_state = 6;
      }
      break;

    case 4:
      FSM1_state = 5;
      if (FSM0_L == 0) {
        FSM1_state = 6;
      }
      break;

    case 5:
      if (FSM1_E_time == 1) {
        FSM1_state = 2;
      }
      if (FSM0_L == 0) {
        FSM1_state = 6;
      }
      break;

    case 6:
      FSM1_state = 1;
      break;

    default:
      FSM1_state = 1;
      break;
  }
}

void FSM1_output()
{

  switch (FSM1_state)
  {
    case 1:
      break;

    case 2:
      digitalWrite(FSM1_L_pin, HIGH);
      FSM1_ts = millis();
      break;

    case 3:
      break;

    case 4:
      digitalWrite(FSM1_L_pin, LOW);
      FSM1_ts = millis();
      break;

    case 5:
      break;

    case 6:
      digitalWrite(FSM1_L_pin, LOW);
      break;

    default:
      break;

  }
}

void FSM2_next_state(int FSM2_E_time, int Hhum, int Hdesum, int H)
{
  switch (FSM2_state)
  {
    case 1:
      if (Hhum == 1) {
        FSM2_state = 3;
      }
      else if (Hdesum == 1) {
        FSM2_state = 2;
      }
      else
        FSM2_state = 1;
      break;

    case 2:
      if (H==0)
      {
        FSM2_state = 4;
      }
      break;

    case 3:
      if (H==1) {
        FSM2_state = 5;
      }
      break;

    case 4:
      if (FSM2_E_time == 1) {
        FSM2_state = 1;
      }
      break;

    case 5:
      if (FSM2_E_time == 1) {
        FSM2_state = 1;
      }
      break;

    default:
      break;
  }
}
void FSM2_output()
{
  switch (FSM2_state)
  {
    case 1:
      digitalWrite(Desum_pin, LOW);
      digitalWrite(Humid_pin, LOW);
      break;

    case 2:
      digitalWrite(Desum_pin, HIGH);
      digitalWrite(Humid_pin, LOW);
      FSM2_L = 1;
      FSM2_ts = millis();
      break;

    case 3:
      digitalWrite(Desum_pin, LOW);
      digitalWrite(Humid_pin, HIGH);
      FSM2_L = 1;
      FSM2_ts = millis();
      break;

    case 4:
      digitalWrite(Desum_pin, LOW);
      digitalWrite(Humid_pin, LOW);
      FSM2_L = 0;
      break;

    case 5:
      digitalWrite(Desum_pin, LOW);
      digitalWrite(Humid_pin, LOW);
      FSM2_L = 0;
      break;

    default:
      break;
  }
}

void FSM3_next_state(int FSM3_E_time, int FSM2_L)
{
  switch (FSM3_state)
  {
    case 1:
      if (FSM2_L == 1) {
        FSM3_state = 2;
      }
      break;

    case 2:
      FSM3_state = 3;
      if (FSM2_L == 0) {
        FSM3_state = 6;
      }

    case 3:
      if (FSM3_E_time == 1) {
        FSM3_state = 4;
      }
      if (FSM2_L == 0) {
        FSM3_state = 6;
      }
      break;

    case 4:
      FSM3_state = 5;
      if (FSM2_L == 0) {
        FSM3_state = 6;
      }
      break;

    case 5:
      if (FSM3_E_time == 1) {
        FSM3_state = 2;
      }
      if (FSM2_L == 0) {
        FSM3_state = 6;
      }
      break;

    case 6:
      FSM3_state = 1;
      break;

    default:
      FSM3_state = 1;
      break;
  }
}

void FSM3_output()
{

  switch (FSM3_state)
  {
    case 1:
      break;

    case 2:
      digitalWrite(FSM3_L_pin, HIGH);
      FSM3_ts = millis();
      break;

    case 3:
      break;

    case 4:
      digitalWrite(FSM3_L_pin, LOW);
      FSM3_ts = millis();
      break;

    case 5:
      break;

    case 6:
      digitalWrite(FSM3_L_pin, LOW);
      break;

    default:
      break;

  }
}

Schematics

Schematics
Connections sensors, led, display and clock on arduino ATMEGA 2560.
Schematics gdzacdlm9l
schematics_fritzing_QEEiMQPjuv.pdf

Comments

Similar projects you might like

Vivarium Temperature and Humidity Control with Arduino

Project showcase by Christopher G Stanton

  • 2,777 views
  • 2 comments
  • 1 respect

Control an LED with the Remote Control

Project showcase by Nicholas_N

  • 2,158 views
  • 1 comment
  • 6 respects

Tweeting Thermostat with Arduino!

Project tutorial by Arduino “having11” Guy

  • 3,453 views
  • 0 comments
  • 9 respects

ESP-201 (ESP8266) Temperature & Humidity Web Server

Project tutorial by Gustavo Reynaga

  • 4,816 views
  • 0 comments
  • 9 respects

Servo Control with TV Remote Control

Project showcase by eldo85

  • 4,734 views
  • 5 comments
  • 15 respects
Add projectSign up / Login