/*
Este proyecto es una *prueba de concepto* de un termostato de calefacción que
tenga en cuenta la inercia térmica de los radiadores, es decir, que una vez
que los radiadores estén calientes, se apague la calefacción para dejar que
los mismos emitan el calor a las habitaciones (hasta cierta cierta tempera-
tura). Una vez que los radiadores hayan emitido calor, se volverá a encender
la calefacción en caso necesario.
Con esto se pretende que la calefacción no esté continuamente encendida hasta
que la temperatura de las habitaciones supere el valor del termostato, sino
que esta se enciendia y apague a intervalos para permitir que los radiadores
hagan su trabajo sin estar continuamente endendida.
Notas técnicas: actualmente utiliza dos termostatos, uno para medir la
temperatura de las habitaciones y otro para medir la temperatura de los
radiadores. La idea es que haya comunicación entre este termostato y otro
dispositivo que mida la temperatura de los radiadores de forma inalámbrica
(con ESP Now, por ejemplo), para así poder colocar el termostato del los
radiadores en cualquier lugar y no depender de cables largos (no está aquí
contemplado porque Wokwi no soporta simular más de un ESP32 simultáneamente).
Autor : @diegolgz
Fecha : 20231112
Estado: En desarrollo.
*/
#include <LiquidCrystal_I2C.h>
#include <Button.h>
uint8_t degree_symbol[8] = {
0b00100,
0b01010,
0b00100,
0b00000,
0b00000,
0b00000,
0b00000,
0b00000,
};
byte left_fire_symbol[8] = {
0b01000,
0b01110,
0b00111,
0b00111,
0b01111,
0b11011,
0b11011,
0b01110
};
uint8_t center_fire_symbol[8] = {
0b00100,
0b00100,
0b01110,
0b01110,
0b11111,
0b11011,
0b11011,
0b01110
};
byte right_fire_symbol[8] = {
0b00010,
0b01110,
0b11100,
0b11100,
0b11110,
0b11011,
0b11011,
0b01110
};
enum HeaterState {
HeaterState_OFF,
HeaterState_ON
};
const int TEMPERATURE_PIN_ROOM = 12;
const int TEMPERATURE_PIN_RADIATOR = 14;
const int RELAY_PIN = 18;
HeaterState heaterState = HeaterState_OFF;
LiquidCrystal_I2C lcd = LiquidCrystal_I2C(0x27, 20, 4);
float selectedTemperature = 20.0;
Button upTempButton(17);
Button downTempButton(16);
void
init_lcd() {
lcd.init();
lcd.backlight();
lcd.noCursor();
lcd.noAutoscroll();
lcd.setCursor(0, 0);
lcd.createChar(1, degree_symbol);
lcd.createChar(2, left_fire_symbol);
lcd.createChar(3, center_fire_symbol);
lcd.createChar(4, right_fire_symbol);
lcd.createChar(5, center_fire_symbol);
}
float
read_temperature_celsius_from(int from) {
int temperature = analogRead(from);
return 1 / (log(1 / (1023. / temperature - 1)) / 3950 + 1.0 / 298.15) - 273.15;
}
void
print_temperature(float t, String title = "", int x = 0, int y = 0) {
lcd.setCursor(x, y);
if (title != "") {
lcd.print(title);
}
lcd.print(t);
lcd.write('\x01'); lcd.write('C');
}
void
print_fire() {
static int fire_char_counter = 0;
static int fire_chars_offset = 2;
if (heaterState == HeaterState_ON) {
int char_to_print = fire_char_counter % 4 + fire_chars_offset;
lcd.setCursor(0, 3);
lcd.write(byte(char_to_print));
lcd.write(byte(char_to_print));
lcd.write(byte(char_to_print));
fire_char_counter++;
} else {
lcd.setCursor(0, 3);
lcd.print(" ");
}
}
void
print_temperatures(float thermostate, float room, float radiator) {
lcd.setCursor(0, 0);
lcd.print("Term. Sala Rad.");
lcd.setCursor(0, 1);
lcd.print(thermostate, 1);
lcd.write('\x01'); lcd.write('C');
lcd.setCursor(8, 1);
lcd.print(room, 1);
lcd.write('\x01'); lcd.write('C');
lcd.setCursor(16, 1);
lcd.print(radiator, 0);
lcd.write('\x01'); lcd.write('C');
}
void
heater_on() {
if (heaterState == HeaterState_OFF) {
digitalWrite(RELAY_PIN, HIGH);
heaterState = HeaterState_ON;
Serial.println("Heater ON");
}
}
void
heater_off() {
if (heaterState == HeaterState_ON) {
digitalWrite(RELAY_PIN, LOW);
heaterState = HeaterState_OFF;
Serial.println("Heater OFF");
}
}
void setup() {
Serial.begin(115200);
analogReadResolution(10);
pinMode(TEMPERATURE_PIN_ROOM, INPUT);
pinMode(TEMPERATURE_PIN_RADIATOR, INPUT);
pinMode(RELAY_PIN, OUTPUT);
upTempButton.begin();
downTempButton.begin();
init_lcd();
}
void loop() {
float temperature_room = read_temperature_celsius_from(TEMPERATURE_PIN_ROOM);
float temperature_radiator = read_temperature_celsius_from(TEMPERATURE_PIN_RADIATOR);
print_temperatures(selectedTemperature, temperature_room, temperature_radiator);
print_fire();
if (upTempButton.released()) {
selectedTemperature += .5;
Serial.println("Up button pressed: selected temperature: " + String(selectedTemperature));
}
if (downTempButton.released()) {
selectedTemperature -= .5;
Serial.println("Down button pressed: selected temperature: " + String(selectedTemperature));
}
if (selectedTemperature > temperature_room) {
heater_on();
} else {
heater_off();
}
delay(100);
}