/*Dados do projeto original: https://marlonnardi.com/?p=1529
~~~~~~~> Este projeto foi adaptado para uso com tela TFT antiga
https://docs.arduino.cc/retired/getting-started-guides/TFT/
TFT screen assembly https://wokwi.com/projects/411005460788041729
~~> To-do List
(X) Clear the original code
( ) Humidity control
( ) 3d print/assembly Iris Exhaust
( ) Servo Control Iris Exhaust hardware e software
( ) Second Iris Intake nofan
(X) Sound alerts
( ) Auxiliary DHT external
( ) EEPROM storage*/
#define DEBUG 1
#if DEBUG == 1
#define debug(x) Serial.print(x)
#define debugln(x) Serial.println(x)
#define debugbg(x) Serial.begin(x)
#else
#define debug(x)
#define debugln(x)
#define debugbg(x)
#endif
#include <TFT.h>
#include <SPI.h>
#include "DHT.h"
#include "pitches.h"
#define buzzerPin 2
#define dhtPin 3
#define dhtType DHT22
#define fanPin 5
#define relePin 6
#define servoPin 7
#define rst 8
#define dc 9
#define cs 10
#define umidadeAlvo 13
#define maxDifUmi 2
#define temperaturaAlvo 45.00 // ºC
#define maxDifTemp 1.00 // ºC
#define umiAbsMax 50 // g/cm³
#define umiAbsMin 30 // g/cm³
#define black 0x0000
#define blue 0xF800
#define red 0x001F
#define yellow 0x07ff
#define green 0x5fe0
#define violet 0xe01f
#define e 2.718281828459045235360287471352 // Constante Matemática de Euler
int tempAlert = 0, humAlert = 0;
float temp = 0;
float hum = 0;
float humAbs = 0;
float pretemp = 0;
float prehum = 0;
float prehumAbs = 0;
float currtemp = 0;
float currhum = 0;
float currhumAbs = 0;
float i = 0;
float j = 0;
TFT TFTscreen = TFT(cs, dc, rst);
DHT dht(dhtPin, dhtType);
void setup(void) {
debugbg(9600);
debugln("Booting up...");
pinMode(relePin, OUTPUT);
pinMode(fanPin, OUTPUT);
pinMode(buzzerPin, OUTPUT);
alarm();
digitalWrite(relePin, LOW); //Valor inicial desligado
digitalWrite(fanPin, LOW);
TFTscreen.begin();
TFTscreen.fillScreen(black);
dht.begin();
debugln("Drybox LAB MAKER IFFARSan is up and running!");
delay(500);
TFTscreen.setRotation(1);
TFTscreen.fillScreen(black);
TFTscreen.drawRect(0, 0, 160, 128, black);
TFTscreen.setTextSize(3);
TFTscreen.setTextColor(red, black);
TFTscreen.setCursor(45, 10);
TFTscreen.print("LAB");
TFTscreen.setTextColor(green, black);
TFTscreen.setCursor(35, 50);
TFTscreen.print("MAKER");
TFTscreen.setTextColor(blue, black);
TFTscreen.setCursor(10, 90);
TFTscreen.print("IFFarSAN");
alarm();
delay(500);
TFTscreen.fillScreen(black);
TFTscreen.setTextSize(1);
TFTscreen.setTextColor(yellow, black);
TFTscreen.setCursor(2, 5);
TFTscreen.print("LABORATORIO MAKER IFFarSAN");
TFTscreen.setTextSize(1);
TFTscreen.setTextColor(green, black);
TFTscreen.setCursor(12, 85);
TFTscreen.print("0");
TFTscreen.setCursor(31, 85);
TFTscreen.print("70");
TFTscreen.setTextSize(1);
TFTscreen.setCursor(2, 15);
TFTscreen.print("TEMPERATURA");
TFTscreen.setCursor(15, 54);
TFTscreen.setTextSize(2);
TFTscreen.print("*C");
TFTscreen.setTextSize(1); //Umidade Relativa
TFTscreen.setTextColor(red, black);
TFTscreen.setCursor(60, 85);
TFTscreen.print("0");
TFTscreen.setCursor(77, 85);
TFTscreen.print("100");
TFTscreen.setTextSize(1);
TFTscreen.setCursor(70, 15);
TFTscreen.print("UMIDADE");
TFTscreen.setCursor(60, 25);
TFTscreen.print("RELATIVA");
TFTscreen.setCursor(70, 54);
TFTscreen.setTextSize(2);
TFTscreen.print("R%");
TFTscreen.setTextSize(1); //Umidade Absoluta
TFTscreen.setTextColor(violet, black);
TFTscreen.setCursor(117, 85);
TFTscreen.print("0");
TFTscreen.setCursor(134, 85);
TFTscreen.print("80");
TFTscreen.setTextSize(1);
TFTscreen.setCursor(115, 15);
TFTscreen.print("UMIDADE");
TFTscreen.setCursor(110, 25);
TFTscreen.print("ABSOLUTA");
TFTscreen.setTextSize(2);
TFTscreen.setCursor(124, 40);
TFTscreen.print("g/");
TFTscreen.setCursor(124, 60);
TFTscreen.print("m3");
}
void loop(void) {
temp = dht.readTemperature();
hum = dht.readHumidity();
humAbs = calculaUmidadeAbsoluta();
TFTscreen.setTextColor(green, black);
TFTscreen.setTextSize(2);
TFTscreen.setCursor(5, 100);
TFTscreen.print(temp, 1);
TFTscreen.setTextColor(red, black);
TFTscreen.setTextSize(2);
TFTscreen.setCursor(55, 100);
TFTscreen.print(hum, 1);
TFTscreen.setTextColor(violet, black);
TFTscreen.setTextSize(2);
TFTscreen.setCursor(105, 100);
TFTscreen.print(humAbs, 1);
TFTscreen.setTextSize(1.5);
TFTscreen.setTextColor(green, black);
TFTscreen.setCursor(3, 120);
TFTscreen.setTextColor(yellow, black);
TFTscreen.print("Alvo:");
TFTscreen.setCursor(34, 120);
TFTscreen.print(temperaturaAlvo, 0);
TFTscreen.setCursor(46, 120);
TFTscreen.print("*C");
TFTscreen.setCursor(63, 120);
TFTscreen.print("FAN:");
TFTscreen.setCursor(87, 120);
bool fanState = digitalRead(fanPin);
fanState == 1 ? TFTscreen.print(" ON") : TFTscreen.print("OFF");
TFTscreen.setCursor(110, 120);
TFTscreen.print("RELE:");
TFTscreen.setCursor(140, 120);
bool releState = digitalRead(relePin);
releState == 1 ? TFTscreen.print(" ON") : TFTscreen.print("OFF");
currtemp = temp;
currhum = hum;
currhumAbs = humAbs;
i = map(pretemp, 0, 70, 0, 300);
j = map(currtemp, 0, 70, 0, 300);
for (i; i <= j; i = i + 0.1) {
float j = i - 150;
float angle = (j / 57.2958) - 1.57;
float x1 = 53 + cos(angle) * 40;
float y1 = 120 + sin(angle) * 40;
float x2 = 53 + cos(angle) * 50;
float y2 = 120 + sin(angle) * 50;
TFTscreen.drawLine(x1 / 2, y1 / 2, x2 / 2, y2 / 2, green);
}
for (i - 2; i >= j; i = i - 0.05) {
float j = i - 150;
float angle = (j / 57.2958) - 1.57;
float x1 = 53 + cos(angle) * 40;
float y1 = 120 + sin(angle) * 40;
float x2 = 53 + cos(angle) * 50;
float y2 = 120 + sin(angle) * 50;
TFTscreen.drawLine(x1 / 2, y1 / 2, x2 / 2, y2 / 2, black);
}
i = map(prehum, 0, 100, 0, 300);
j = map(currhum, 0, 100, 0, 300);
for (i; i <= j; i = i + 0.1) {
float j = i - 150;
float angle = (j / 57.2958) - 1.57;
float x1 = 160 + cos(angle) * 40;
float y1 = 120 + sin(angle) * 40;
float x2 = 160 + cos(angle) * 50;
float y2 = 120 + sin(angle) * 50;
TFTscreen.drawLine(x1 / 2, y1 / 2, x2 / 2, y2 / 2, red);
}
for (i - 2; i >= j; i = i - 0.05) {
float j = i - 150;
float angle = (j / 57.2958) - 1.57;
float x1 = 160 + cos(angle) * 40;
float y1 = 120 + sin(angle) * 40;
float x2 = 160 + cos(angle) * 50;
float y2 = 120 + sin(angle) * 50;
TFTscreen.drawLine(x1 / 2, y1 / 2, x2 / 2, y2 / 2, black);
}
i = map(prehumAbs, 0, 100, 0, 300);
j = map(currhumAbs, 0, 100, 0, 300);
for (i; i <= j; i = i + 0.1) {
float j = i - 150;
float angle = (j / 57.2958) - 1.57;
float x1 = 265 + cos(angle) * 40;
float y1 = 120 + sin(angle) * 40;
float x2 = 265 + cos(angle) * 50;
float y2 = 120 + sin(angle) * 50;
TFTscreen.drawLine(x1 / 2, y1 / 2, x2 / 2, y2 / 2, violet);
}
for (i - 2; i >= j; i = i - 0.05) {
float j = i - 150;
float angle = (j / 57.2958) - 1.57;
float x1 = 265 + cos(angle) * 40;
float y1 = 120 + sin(angle) * 40;
float x2 = 265 + cos(angle) * 50;
float y2 = 120 + sin(angle) * 50;
TFTscreen.drawLine(x1 / 2, y1 / 2, x2 / 2, y2 / 2, black);
}
debugln("");
debugln("");
debugln("Drybox LAB MAKER IFFarSAN");
debug("Temperatura Alvo: ");
debug(temperaturaAlvo);
debugln("*C");
debug(currtemp);
debugln("*C Temperatura Atual");
debug(currhum);
debugln("% Umidade Relativa");
debug(currhumAbs);
debugln("g/m3 Umidade Absoluta");
debug("Fan: ");
if (fanState == 1) {
debugln("ON");
} else {
debugln("OFF");
}
debug("Rele: ");
if (releState == 1) {
debugln("ON");
} else {
debugln("OFF");
}
delay(5000);
controleTemperatura();
controleUmidade();
}
float calculaUmidadeAbsoluta(void) {
float UA = ((6.112 * (pow(e, ((17.67 * temp) / (temp + 243.5)))) * hum * 2.1674) / (273.15 + temp));
return UA;
}
void controleTemperatura(void) {
if (temp >= temperaturaAlvo) {
if (tempAlert == 1) {
tempAlert = 0;
digitalWrite(relePin, LOW);
nokia();
}
}
if (temp <= (temperaturaAlvo - maxDifTemp)) {
if (tempAlert == 0) {
tempAlert = 1;
digitalWrite(relePin, HIGH);
tantan();
}
}
}
void controleUmidade(void) {
if (temp > 40) {
if (hum >= umidadeAlvo) {
// OPEN IRIS WITH SERVO
if (humAlert == 0) {
humAlert = 1;
digitalWrite(fanPin, HIGH);
pacman();
}
}
}
if (hum <= (umidadeAlvo - maxDifUmi)) {
// CLOSE IRIS WITH SERVO
if (humAlert == 1) {
humAlert = 0;
digitalWrite(fanPin, LOW);
tantan();
}
}
}
void alarm() {
tone(buzzerPin, 523, 300);
delay(1000);
noTone(buzzerPin);
}
void nokia() {
int melody[] = {
NOTE_E5, NOTE_D5, NOTE_FS4, NOTE_GS4,
NOTE_CS5, NOTE_B4, NOTE_D4, NOTE_E4,
NOTE_B4, NOTE_A4, NOTE_CS4, NOTE_E4,
NOTE_A4
};
int durations[] = {
8, 8, 4, 4,
8, 8, 4, 4,
8, 8, 4, 4,
2
};
int size = sizeof(durations) / sizeof(int);
for (int note = 0; note < size; note++) {
int duration = 1000 / durations[note];
tone(buzzerPin, melody[note], duration);
int pauseBetweenNotes = duration * 1.30;
delay(pauseBetweenNotes);
noTone(buzzerPin);
}
}
void pacman() {
int melody[] = {
NOTE_B4, NOTE_B5, NOTE_FS5, NOTE_DS5,
NOTE_B5, NOTE_FS5, NOTE_DS5, NOTE_C5,
NOTE_C6, NOTE_G6, NOTE_E6, NOTE_C6, NOTE_G6, NOTE_E6,
NOTE_B4, NOTE_B5, NOTE_FS5, NOTE_DS5, NOTE_B5,
NOTE_FS5, NOTE_DS5, NOTE_DS5, NOTE_E5, NOTE_F5,
NOTE_F5, NOTE_FS5, NOTE_G5, NOTE_G5, NOTE_GS5, NOTE_A5, NOTE_B5
};
int durations[] = {
16, 16, 16, 16,
32, 16, 8, 16,
16, 16, 16, 32, 16, 8,
16, 16, 16, 16, 32,
16, 8, 32, 32, 32,
32, 32, 32, 32, 32, 16, 8
};
int size = sizeof(durations) / sizeof(int);
for (int note = 0; note < size; note++) {
int duration = 1000 / durations[note];
tone(buzzerPin, melody[note], duration);
int pauseBetweenNotes = duration * 1.30;
delay(pauseBetweenNotes);
noTone(buzzerPin);
}
}
void tantan() {
int melody[] = {
NOTE_C4, NOTE_G3, NOTE_G3, NOTE_A3, NOTE_G3, 0, NOTE_B3, NOTE_C4
};
int durations[] = {
4, 8, 8, 4, 4, 4, 4, 4
};
int size = sizeof(durations) / sizeof(int);
for (int note = 0; note < size; note++) {
int duration = 1000 / durations[note];
tone(buzzerPin, melody[note], duration);
int pauseBetweenNotes = duration * 1.30;
delay(pauseBetweenNotes);
noTone(buzzerPin);
}
}