Correia_VSM
Published © GPL3+

Thermostat with Relative Humidity Control

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

BeginnerProtip5,914
Thermostat with Relative Humidity Control

Things used in this project

Hardware components

LED (generic)
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
DHT11 Temperature & Humidity Sensor (4 pins)
DHT11 Temperature & Humidity Sensor (4 pins)
×1
DS3231MPMB1 Peripheral Module
Maxim Integrated DS3231MPMB1 Peripheral Module
×1
Resistor 221 ohm
Resistor 221 ohm
×6
Solderless Breadboard Full Size
Solderless Breadboard Full Size
×1
Arduino Mega 2560
Arduino Mega 2560
×1
LCD 20x4 Display - IIC/I2C 2004
×1

Software apps and online services

Arduino IDE
Arduino IDE

Story

Read more

Schematics

Schematics

Connections sensors, led, display and clock on arduino ATMEGA 2560.

schematics_fritzing_QEEiMQPjuv.pdf

Code

termostato_fsm_19.04.2018

Arduino
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;

  }
}

Credits

Correia_VSM

Correia_VSM

1 project • 2 followers

Comments