Mon dernier truc en date est la réparation de mon radiateur soufflant de salle de bains de marque Delonghi.
Il ne s'allumait plus du tout juste après avoir fait un sapin de noël.
La carte de contrôle était noire, bref la merde.....
Cout d'une nouvelle carte : 65€
J'ai donc démonté et j'ai vu que le deux composants (radiant et soufflant) était piloté via 2 relais sur la carte de contrôle. La sécurité du soufflant est géré par les composants interne au soufflant et pas sur la carte de contrôle, et le radiant est piloté par une sonde de température à l'arrière.
Il y a 2 boutons en façade pour lancer soit le soufflant soit le radiant.
Quand on appui dessus ça le lance, et quand on ré-appui dessus ça l'éteint.
Le soufflant à un timer de 15mn et le radiant un timer de 1h.
Une fois le constat fait, il m'est venue l'idée de faire la carte de contrôle moi même avec un ESP8266.
J'ai donc opté pour une liste de courses assez facile :
Un ESP8266-07 -> 4€12
Une carte 2 relais opto-isolé -> 0€93
Une sonde DHT22 -> 2€44
Une alimentation 220V -> 5V -> 3€26
Un regulateur 5v -> 3.3V -> 2€33 les 5
Du fil, quelques resistances.
TOTAL : 13€08
La carte qui contient les 2 switchs est vissé et indépendante de la carte de contrôle, je la garde donc et j'isole les 2 inters sur lesquels je soude 2 fils.
Voici le schéma final :
La sonde DHT22 me permet de contrôler la température et l'humidité dans la salle de bains.
Les deux inters isolés sont branchés sur du 3.3V et sur 2 entrées de l'ESP (avec des resistances pulldown).
Il y a une alim 220V -> 5V et un régulateur 5V -> 3.3V.
La carte relais est alimentés directement par le 5V et les sorties de l'ESP ne débite que pour l'opto de la carte relais (donc pas besoin de résistance ou autre, les sorties directement sur les entrées de la carte relais).
Et donc la carte relais pilote les 2 éléments du chauffage indépendamment.
Les ESP sont programmés via l'IDE Arduino comme pour le DomoPotame.
Voici le sketch correspondant :
#include "DHT.h"Pareil que pour le potame, des appels http qui renvoi du JSON en réponse.
#include <ESP8266WiFi.h>
const char* ssid = "***********"; //SSID WIFI
const char* password = "***********"; //MDP WIFI
// Créé une instance WEB
// Sur le Port 80
WiFiServer server(80);
// Défini le Port GPIO du DHT
#define DHTPIN 12
// Défini le type de DHT (DHT11-DHT21-DHT22)
#define DHTTYPE DHT22
// Crée le DHT
DHT dht(DHTPIN, DHTTYPE, 15);
int valu = '0';
int buttonState1 = 0;
int buttonState2 = 0;
int buttonVal1 = 0;
int buttonVal2 = 0;
int A = 0;
void setup() {
//Prépare la serial
Serial.begin(115200);
delay(10);
//Initialise le DHT
dht.begin();
// Défini les GPIO 4 et 5 en sortie
pinMode(5, OUTPUT);
pinMode(4, OUTPUT);
pinMode(13, INPUT);
pinMode(14, INPUT);
// Met à 0 les GPIO
digitalWrite(5, 1);
digitalWrite(4, 1);
// Connection au WiFi
Serial.println();
Serial.println();
Serial.print("Connecting to ");
Serial.println(ssid);
// Met l'ESP uniquement en station et pas Access Point
WiFi.mode(WIFI_STA);
// Connection au WiFi
WiFi.begin(ssid, password);
for (int i=0; i<60; i++) {
if (WiFi.status() == WL_CONNECTED) {
i = 60;
}
delay(500);
Serial.print(".");
}
if (WiFi.status() == WL_CONNECTED) {
Serial.println("");
Serial.println("WiFi connected");
}
// Démarre le server WEB
server.begin();
Serial.println("Server started");
// Affiche l'adresse IP obtenue
Serial.println(WiFi.localIP());
}
void loop() {
//Déclare les variables Temp et humidity
float temp;
float humidity;
delay(500);
buttonState1 = digitalRead(13);
if (buttonState1 == HIGH && buttonVal1 == 0 ) {
Serial.println("Pin 13 pushed Val 0");
digitalWrite(4, 0);
buttonVal1 = 1;
do {
buttonState1 = digitalRead(13);
Serial.println("Pin 13 released");
delay(500);
} while (buttonState1 == HIGH);
} else if (buttonState1 == HIGH && buttonVal1 >= 1 ) {
Serial.println("Pin 13 pushed Val 1");
digitalWrite(4, 1);
buttonVal1 = 0;
do {
buttonState1 = digitalRead(13);
Serial.println("Pin 13 released");
delay(500);
} while (buttonState1 == HIGH);
}
buttonState2 = digitalRead(14);
if (buttonState2 == HIGH && buttonVal2 == 0 ) {
Serial.println("Pin 14 pushed Val 0");
digitalWrite(5, 0);
buttonVal2 = 1;
do {
buttonState2 = digitalRead(14);
Serial.println("Pin 14 released");
delay(500);
} while (buttonState2 == HIGH);
} else if (buttonState2 == HIGH && buttonVal2 >= 1 ) {
Serial.println("Pin 14 pushed Val 1");
digitalWrite(5, 1);
buttonVal2 = 0;
do {
buttonState2 = digitalRead(14);
Serial.println("Pin 14 released");
delay(500);
} while (buttonState2 == HIGH);
}
if (buttonVal1 >= 1 ) {
Serial.println("ButtonVal1 + 1");
buttonVal1 = buttonVal1 + 1;
Serial.println(buttonVal1);
}
if (buttonVal2 >= 1 ) {
Serial.println("ButtonVal2 + 1");
buttonVal2 = buttonVal2 + 1;
Serial.println(buttonVal2);
}
//Si ça fait 2400 tics de 0.5s (soit 20mn)
if (buttonVal1 >= 2400 ) {
digitalWrite(4, 1);
Serial.println("ButtonVal1 OFF");
buttonVal1 = 0;
}
//Si ça fait 1200 tics de 0.5s (soit 10mn)
if (buttonVal2 >= 1200 ) {
digitalWrite(5, 1);
Serial.println("ButtonVal2 OFF");
buttonVal2 = 0;
}
// Vérifie si quelqu'un se connecte sur le Web server
WiFiClient client = server.available();
if (!client) {
return;
}
// Attendre que le client envoi des infos
Serial.println("new client");
while(!client.available() && A < 3000){
delay(1);
A++;
}
A = 0;
// Lit la première ligne de la requête
String req = client.readStringUntil('\r');
Serial.println(req);
client.flush();
//Prépare la sortie JSON en success
int val;
String httpHeader = "HTTP/1.1 200 OK\r\nContent-Type:application/json\r\nAccess-Control-Allow-Origin:*\r\nCache-Control:no-cache\r\n";
httpHeader += "Content-Length: ";
String resultat = "{ \"success\": \"1\",";
// Analyse de la requête client
// si l'URI est /gpio4/0
if (req.indexOf("/gpio4/0") != -1) {
val = 1;
// Met GPIO à 0 comme demandé
digitalWrite(4, val);
// Continue la réponse JSON
resultat += "\"GPIO4\":\"";
resultat += (val);
buttonVal1 = 0;
// si l'URI est /gpio4/1
} else if (req.indexOf("/gpio4/1") != -1) {
val = 0;
// Met GPIO à 1 comme demandé
digitalWrite(4, val);
buttonVal1 = 1;
// Continue la réponse JSON
resultat += "\"GPIO4\":\"";
resultat += (val);
// si l'URI est /gpio5/0
} else if (req.indexOf("/gpio5/0") != -1) {
val = 1;
// Met GPIO à 0 comme demandé
digitalWrite(5, val);
buttonVal2 = 0;
// Continue la réponse JSON
resultat += "\"GPIO5\":\"";
resultat += (val);
// si l'URI est /gpio5/1
} else if (req.indexOf("/gpio5/1") != -1) {
val = 0;
// Met GPIO à 1 comme demandé
digitalWrite(5, val);
buttonVal2 = 1;
// Continue la réponse JSON
resultat += "\"GPIO5\":\"";
resultat += (val);
// si l'URI est /gpio/temp
} else if (req.indexOf("/gpio/temp") != -1) {
// Prépare une boucle en cas de non réponse du DHT
int A=0;
do {
A++;
delay(2000);
humidity = dht.readHumidity();
temp = dht.readTemperature();
Serial.println(temp);
Serial.println(humidity);
// Si aucune réponse n'est valide au bout de 10 essai, Echec
if (A == 10) {
//Renvoi le JSON en success 0 et erreur
String resultat = "{ \"success\": \"0\",";
resultat += "\"TEMP\":\"Error\"";
resultat += "\" }\n";
httpHeader += resultat.length();
httpHeader += "\r\n";
httpHeader +="Connection: close\r\n\r\n";
String MESSAGE = httpHeader + resultat;
client.flush();
// Send the response to the client
client.print(MESSAGE);
client.stop();
Serial.println("Client disconnected");
return;
}
} while (isnan(temp) || isnan(humidity));
// Continue la réponse JSON
resultat += "\"TEMP\":\"";
resultat += temp;
resultat += "\",\"HUM\":\"";
resultat += humidity;
} else {
Serial.println("invalid request");
client.stop();
return;
}
// Fini la réponse JSON
resultat += "\" }\n";
httpHeader += resultat.length();
httpHeader += "\r\n";
httpHeader +="Connection: close\r\n\r\n";
String MESSAGE = httpHeader + resultat;
client.flush();
// Envoi la réponse JSON complète au client
client.print(MESSAGE);
delay(1);
Serial.println("Client disconnected");
// Déconnecte le client
}
http://IP-DE-RADIATEUR/gpio/temprenvoi la mesure de température de la sonde DHT22
{ "success": "1","TEMP":"23.20","HUM":"75.50" }
http://IP-DE-RADIATEUR/gpio4/0 ou http://IP-DE-RADIATEUR/gpio4/1Allume ou éteint le Radiant (qui s'éteint tout seul au bout de 20mn)
{ "success": "1","GPIO4":"0" }
http://IP-DE-RADIATEUR/gpio5/0 ou http://IP-DE-RADIATEUR/gpio5/1Allume ou éteint le Soufflant (qui s'éteint tout seul au bout de 10mn)
Enfin une petite vidéo de l'ensemble via Eedomus :{ "success": "1","GPIO5":"0" }
Et les graphs de température :