Après avoir galéré plusieurs semaines, je tenais à vous partager mon expérience sur la commande et la récupération d'information d'un contrôleur Arduino avec l'eedomus et son API.
Cela à travers l'utilisation d'un module ESP8266-01 pour ajouter une connexion Wifi à votre Arduino et des commandes AT (fonctionnement de base des ESP8266).
Je me suis penché sur ce problème car je souhaite piloter à distance mon SPA Intex: j'ai acquis une carte développée par Jean-Paul Marechal (que je remercie chaleureusement, voir forum Jeedom pour information); celle-ci décode le multiplexage entre le panneau de commande et la carte contrôleur afin d'interagir avec votre SPA (toutes les fonctions du panneau de commande) via l'application REmoteXY (payante).
L'idée est de remplacer RemoteXY par l'eedomus afin de tout centraliser.
Pourquoi les commandes AT:
1) Parce que je n'ai pas le choix avec la carte de contrôle du SPA, crée avec un Arduino Nano et un ESP8266-01,
2) Parce qu'il existe déjà un tas de projet DIY à base d'Arduino, il est alors possible de les rendre communicant uniquement par l'ajout d'un ESP01 à 2€.
3) Parce que j'ai passé des heures sur les forums, je n'ai pas trouvé de tutos traitant le pilotage et la récupération d'information en même temps via des commandes AT.
Remarques:
1) Les modules ESP peuvent être directement programmées en Arduino (les commandes AT sont alors remplacées par des librairies plus faciles à programmer) et remplacer le module Arduino.
2) Ce sujet n'est pas un tutoriel complet, je souhaite juste partager mon programme (lui même adapté de plusieurs sources web) qui permettra à chacun de se lancer dans l'interface de modules Arduino et l'eedomus.
3) Je ne me prétends pas expert programmation Arduino ni électonicien, juste amateur passionné, merci pour votre indulgence.
Le code suivant permet de
- initialiser la connexion Wifi de votre ESP8266
- remonter la température d'une sonde DS18B20 toutes les 5 minutes sur un capteur http de l'eedomus
- commander l'allumage d'une led via des requêtes http de type GET depuis un actionneur HTTP de l'eedomus: http://ADRESSE_IP/?etat=0 ou http://ADRESSE_IP/?etat=1
A adapter dans celui-ci (désolé ce n'est pas variabilisé):
- SSID : à remplacer par le SSID de votre connexion wifi
- PASSWORD_SSID: à remplacer par votre clé wifi
- ID_DU_CAPTEUR_HTTP: à remplacer par l'iD du capteur HTTP crée dans eedomus
- XXXXX : à remplacer par votre user ID eedomus
- YYYYY: à remplacer par votre clé API eedomus
- \"192.168.0.180\",\"192.168.0.1\",\"255.255.255.0\" à remplacer par une adresse IP, la passerrelle et le masque cohérente à votre réseau WLAN
- 0x28, 0xEE, 0x4D, 0x6, 0x1, 0x16, 0x2, 0x79 : à remplacer par l'adresse de votre sonde DS18B20 (il y a des tutos sur le net pour la trouver).
- Code : Tout sélectionner
#include <SoftwareSerial.h>
// Librairies pour la sonde DS18B20
#include <OneWire.h>
#include <DallasTemperature.h>
// GPIO 10 et 11 pour le TX et RX de l'ESP
SoftwareSerial espSerial(10,11);
// Création de la commande à envoyer à l'eedomus
const char* TEMP_EEDOMUS_D= "GET /api/set?action=periph.value&periph_id=ID_DU_CAPTEUR_HTTP&value=";
const char* TEMP_EEDOMUS_F= "&api_user=XXXXX&api_secret=YYYYY\r\n\r\n";
// Initialisation de la variable pour envoi toutes les 5 minutes
#define EedomusInterval 300000
// Initialisation du debuggage pour des commandes sendData
#define DEBUG true
// GPIO 12 pour la led
#define led 12
// GPIO 6 pour la sonde DS18B20
#define ONE_WIRE_BUS 6
#define TEMPERATURE_PRECISION 10
//déclaration des autres variables
unsigned long Timer;
int etat;
String req;
int taille_req;
//Initialisation de l'instance Dallas
OneWire oneWire(ONE_WIRE_BUS);
DallasTemperature sensors(&oneWire);
//Adresse sonde
DeviceAddress sonde = { 0x28, 0xEE, 0x4D, 0x6, 0x1, 0x16, 0x2, 0x79 };
void setup()
{
Serial.begin(9600);
// Démarrage de la communication avec la sonde
sensors.begin();
// Vérifie si la sonde est connectée
if (!sensors.getAddress(sonde, 0)) Serial.println("Impossible de trouver la sonde");
// Résolution à 9 bit
sensors.setResolution(sonde, TEMPERATURE_PRECISION);
// Affiche la température sur la console
Serial.println("");
Serial.print("Température: ");
sensors.requestTemperatures();
Serial.println(sensors.getTempC(sonde));
Serial.println("");
// Démmarrage de l'ESP8266
Serial.println("Start ESP\r\n\r\n");
espSerial.begin(115200);
// reset the ESP8266
Serial.println("reset the module");
sendData("AT+RST\r\n",2000,DEBUG);
Serial.println("Change to station mode");
sendData("AT+CWMODE=1\r\n",1500,DEBUG);
Serial.println("Connect to a network ");
sendData("AT+CWJAP=\"SSID\",\"PASSWORD_SSID\"\r\n",6000,DEBUG);
Serial.println("Set Static IP to 192.168.0.180");
sendData("AT+CIPSTA=\"192.168.0.180\",\"192.168.0.1\",\"255.255.255.0\"\r\n",2000,DEBUG);
Serial.println("Get the ip address assigned ny the router");
sendData("AT+CIFSR\r\n",1000,DEBUG);
Serial.println("Set for multiple connections");
sendData("AT+CIPMUX=1\r\n",1500,DEBUG);
Serial.println("Start the Web server");
sendData("AT+CIPSERVER=1,80\r\n",1500,DEBUG);
Serial.println("");
// Initialisation du timer
Timer=millis();
}
void loop()
{
// **** Gestion des requetes entrantes ****
if(espSerial.available()) // teste si l'ESP envoi un message
{
if(espSerial.find("+IPD,")) // avance jusqu'a trouver +IPD
{
delay(1000);
int connectionId = espSerial.read()-48;
// soustrait 48 parceque la fonction read() retournela valeur ASCII decimale , zero (0) par exemple vaut 48 en ASCII decimal
// Permet de controler plusieurs led si besoin en indiquant le pin dans la requête http
//espSerial.find("pin="); // avance le curseur to "pin="
//int pinNumber = (espSerial.read()-48)*10; // get first number i.e. if the pin 13 then the 1st number is 1, then multiply to get 10
//pinNumber += (espSerial.read()-48); // get second number, i.e. if the pin number is 13 then the 2nd number is 3, then add to the first number
espSerial.find("etat="); //avance le curseur to etat
etat = (espSerial.read()-48);
if (etat==0) digitalWrite(led, LOW);
if (etat==1) digitalWrite(led, HIGH);
Serial.println((String)"La led est " + etat);
String webpage = "<h1>Etat de la led</h1><h2>La Led est ";
webpage += etat;
String cipSend = "AT+CIPSEND=";
cipSend += connectionId;
cipSend += ",";
cipSend +=webpage.length();
cipSend +="\r\n";
sendData(cipSend,1000,DEBUG);
sendData(webpage,1000,DEBUG);
// Fermeture de mla connexion connectionId
String closeCommand = "AT+CIPCLOSE=";
closeCommand+=connectionId;
closeCommand+="\r\n";
sendData(closeCommand,3000,DEBUG);
}
}
// **** Gestion des requetes sortante ****
//Envoi de la température toutes les 5 minutes
if ((millis() - Timer) > EedomusInterval) {
Timer=millis();
sensors.requestTemperatures();
float tempC = sensors.getTempC(sonde);
req=TEMP_EEDOMUS_D + String(tempC) + TEMP_EEDOMUS_F; //req contient la requête http à envoyer
sendData("AT+CIPSTART=1,\"TCP\",\"192.168.0.206\",80\r\n",1500,DEBUG); // 1 étant le numéro d'ID pour cette connexion, ID obligatoire car AT+CIPMUX=1
taille_req=req.length();
String cipSend2 = "AT+CIPSEND=1,";
cipSend2 += taille_req;
cipSend2 +="\r\n";
sendData(cipSend2,1500,DEBUG);
sendData(req,2000,DEBUG);
sendData("AT+CIPCLOSE=1\r\n",1500,DEBUG);
}
}
// fonction sendData utilisee pour initialiser l'ESP
String sendData(String command, const int timeout,boolean debug)
{
String response = "";
espSerial.print(command); // envoi le caractere a l' esp8266
long int time = millis();
while( (time+timeout) > millis())
{
while(espSerial.available())
{
char c = espSerial.read(); // lit le caractere suivant
response+=c;
}
}
if(debug) {Serial.println(response);}
return response;
}
Voila, a adapter suivant vos besoins.
Maintenant que j'arrive a communiquer dans les deux sens, il me reste à adapter le code que m'a fourni le concepteur de la carte de pilotage de Spa Intex, c'est à dire remplacer la communication RemoteXY par des requêtes http.