Bonjour
J'essaie de faire communiquer un Arduino et jeedom en mqtt (5 sonde ds18b20 en one wire et projet de 12 relais)
Mon Arduino redémarre en boucle je ne comprend pas d'ou cela vient il y a t'il quelqu'un qui peut jeter un coup œil a mon code, l'erreur est peut être toute bête;)
/*
* Ce programme tourne sur arduino Mega avec afficheur OLED SSD1306
* Il permet de lire les données de deux capteurs de températures DS18B20
* ainsi que la tension aux bornes d'une LDR et de publier les valeurs sur le réseau Ethernet en MQTT.
* Il permet également de recevoir l'état dun switch virtuel et d'allumer une LED
*/
#include <OneWire.h> // bibliothèque pour le bus 1-Wire
#include <Ethernet.h>
#include <PubSubClient.h>
#include <avr/wdt.h> // bibliothèque pour le watchdog
#define BROCHE_ONEWIRE 23
#define LDR A0
#define RelaisK3 22
#define RelaisK4 24
#define RelaisK5 26
#define RelaisK6 28
#define RelaisK7 2
#define RelaisK8 3
#define RelaisK9 4
#define RelaisK10 5
#define RelaisK11 6
#define RelaisK12 7
#define RelaisK13 8
#define RelaisK14 9
uint8_t mac[6] = { 0x00, 0x01, 0x02, 0x03, 0x04, 0x06 }; // on fixe l'adresse MAC de la carte Ethernet
int LDRValue = 0;
float temperature[2];
char buf[4]; // Buffer de stockage de la valeur de la LDR
const char* MQTTserver = "192.168.2.85"; // Adresse IP du broket MQTT (Raspberry Pi HA)
EthernetClient ethClient; // Initialisation des objets Ethernet & MQTT
PubSubClient mqttClient(ethClient);
enum DS18B20_RCODES {
READ_OK,
NO_SENSOR_FOUND,
INVALID_ADDRESS,
INVALID_SENSOR
};
OneWire ds(BROCHE_ONEWIRE);
void setup() {
Serial.begin(9600); // Initialisation du port série
Serial.println(F("Arduino Chauffage (Températures + Relais)"));
pinMode(RelaisK3, OUTPUT);
pinMode(RelaisK4, OUTPUT);
pinMode(RelaisK5, OUTPUT);
pinMode(RelaisK6, OUTPUT);
pinMode(RelaisK7, OUTPUT);
pinMode(RelaisK8, OUTPUT);
pinMode(RelaisK9, OUTPUT);
pinMode(RelaisK10, OUTPUT);
pinMode(RelaisK11, OUTPUT);
pinMode(RelaisK12, OUTPUT);
pinMode(RelaisK13, OUTPUT);
pinMode(RelaisK14, OUTPUT);
digitalWrite(RelaisK3, HIGH);
digitalWrite(RelaisK4, HIGH);
digitalWrite(RelaisK5, HIGH);
digitalWrite(RelaisK6, HIGH);
digitalWrite(RelaisK7, HIGH);
digitalWrite(RelaisK8, HIGH);
digitalWrite(RelaisK9, HIGH);
digitalWrite(RelaisK10, HIGH);
digitalWrite(RelaisK11, HIGH);
digitalWrite(RelaisK12, HIGH);
digitalWrite(RelaisK13, HIGH);
digitalWrite(RelaisK14, HIGH);
wdt_enable(WDTO_8S); //watchdog timer with 8 Seconds time out
if (Ethernet.begin(mac) == 0) {
Serial.println(F("Impossible de configurer Ethernet via serveur DHCP !"));
for (;;)
;
}
Serial.println(F("Ethernet configuré via DHCP"));
Serial.print(F("IP address: "));
Serial.println(Ethernet.localIP());
// Serial.println(F("------------"));
mqttClient.setServer(MQTTserver, 1883);
Serial.println(F("Client MQTT configuré !"));
Serial.println(F("Connexion au serveur avec l'ID 'Arduino Chauffage'"));
if (mqttClient.connect("core-mosquitto", "Idt", "Mdp")) {
Serial.println(F("La connection a été établie"));
} else {
Serial.println(F("Le serveur ne répond pas"));
}
//mqttClient.publish("Arduino_Chauffage/Relais/RelaisK3", "1");
mqttClient.setCallback(callback);
delay(2000);
}
void loop() {
// static unsigned long prevMillis100ms = 0; // déclaration d'une variable pour la temporisation publiation mqtt
static unsigned long prevMillis10s = 0; // déclaration d'une variable pour la temporisation publiation mqtt
unsigned long curMillis = millis();
mqttClient.loop();
if (!mqttClient.connected()) { // permet de reconnecter l'arduino au broker en cas de crash de celui-ci.
reconnect();
}
mqttClient.subscribe("Arduino_Chauffage/Relais/RelaisK3");
mqttClient.subscribe("Arduino_Chauffage/Relais/RelaisK4");
mqttClient.subscribe("Arduino_Chauffage/Relais/RelaisK5");
mqttClient.subscribe("Arduino_Chauffage/Relais/RelaisK6");
mqttClient.subscribe("Arduino_Chauffage/Relais/RelaisK7");
mqttClient.subscribe("Arduino_Chauffage/Relais/RelaisK8");
mqttClient.subscribe("Arduino_Chauffage/Relais/RelaisK9");
mqttClient.subscribe("Arduino_Chauffage/Relais/RelaisK10");
mqttClient.subscribe("Arduino_Chauffage/Relais/RelaisK11");
mqttClient.subscribe("Arduino_Chauffage/Relais/RelaisK12");
mqttClient.subscribe("Arduino_Chauffage/Relais/RelaisK13");
mqttClient.subscribe("Arduino_Chauffage/Relais/RelaisK14");
if (curMillis - prevMillis10s > 10000) { // on lit les valeurs des capteurs et on les publie toutes les 10s
prevMillis10s = curMillis;
if (getTemperature(&temperature[0], true) != READ_OK) {
Serial.println(F("Erreur de lecture du capteur 1"));
return;
}
if (getTemperature(&temperature[1], false) != READ_OK) {
Serial.println(F("Erreur de lecture du capteur 2"));
return;
}
if (getTemperature(&temperature[2], false) != READ_OK) {
Serial.println(F("Erreur de lecture du capteur 3"));
return;
}
if (getTemperature(&temperature[3], false) != READ_OK) {
Serial.println(F("Erreur de lecture du capteur 4"));
return;
}
if (getTemperature(&temperature[4], false) != READ_OK) {
Serial.println(F("Erreur de lecture du capteur 5"));
return;
}
affValeurs();
//mqttClient.publish("Arduino1/Temperature", itoa(LDRValue, buf, 10));
mqttClient.publish("Arduino_Chauffage/Temperatures/Capteur1", itoa((temperature[0] * 10), buf, 10));
mqttClient.publish("Arduino_Chauffage/Temperatures/Capteur2", itoa((temperature[1] * 10), buf, 10));
mqttClient.publish("Arduino_Chauffage/Temperatures/Capteur3", itoa((temperature[2] * 10), buf, 10));
mqttClient.publish("Arduino_Chauffage/Temperatures/Capteur4", itoa((temperature[3] * 10), buf, 10));
mqttClient.publish("Arduino_Chauffage/Temperatures/Capteur5", itoa((temperature[4] * 10), buf, 10));
Serial.println(F("Publication MQTT effectuée"));
}
wdt_reset();
}
//----------------------- début de la fonction lecture de la température d'un capteur DS18B20 : ---------------------
byte getTemperature(float* temperature, byte reset_search) {
byte data[9], addr[8]; // data[] : Données lues depuis le scratchpad; addr[] : Adresse du module 1-Wire détecté
/* Reset le bus 1-Wire ci nécessaire (requis pour la lecture du premier capteur) */
if (reset_search) {
ds.reset_search();
}
/* Recherche le prochain capteur 1-Wire disponible */
if (!ds.search(addr)) { // Pas de capteur
return NO_SENSOR_FOUND;
}
/* Vérifie que l'adresse a été correctement reçue */
if (OneWire::crc8(addr, 7) != addr[7]) { // Adresse invalide
return INVALID_ADDRESS;
}
/* Vérifie qu'il s'agit bien d'un DS18B20 */
if (addr[0] != 0x28) { // Mauvais type de capteur
return INVALID_SENSOR;
}
/* Reset le bus 1-Wire et sélectionne le capteur */
ds.reset();
ds.select(addr);
/* Lance une prise de mesure de température et attend la fin de la mesure */
ds.write(0x44, 1);
unsigned long prevDSMillis = millis();
unsigned long curDSMillis = millis();
while (curDSMillis - prevDSMillis < 800) {
mqttClient.loop();
curDSMillis = millis();
}
/* Reset le bus 1-Wire, sélectionne le capteur et envoie une demande de lecture du scratchpad */
ds.reset();
ds.select(addr);
ds.write(0xBE);
/* Lecture du scratchpad */
for (byte i = 0; i < 9; i++) {
data[i] = ds.read();
}
/* Calcul de la température en degré Celsius */
*temperature = (int16_t)((data[1] << 8) | data[0]) * 0.0625;
return READ_OK; // Pas d'erreur
}
//----------------------- fin de la fonction lecture de la température d'un capteur DS18B20 : ---------------------
//-------- début de la fonction qui permet de se reconnecter au broker MQTT : ----------
void reconnect() {
while (!mqttClient.connected()) {
if (mqttClient.connect("core-mosquitto", "Idt", "Mdp*")) {
Serial.println();
Serial.println("Reconnecté au broker !");
mqttClient.subscribe("Arduino_Chauffage/Relais/RelaisK3");
mqttClient.subscribe("Arduino_Chauffage/Relais/RelaisK4");
mqttClient.subscribe("Arduino_Chauffage/Relais/RelaisK5");
mqttClient.subscribe("Arduino_Chauffage/Relais/RelaisK6");
mqttClient.subscribe("Arduino_Chauffage/Relais/RelaisK7");
mqttClient.subscribe("Arduino_Chauffage/Relais/RelaisK8");
mqttClient.subscribe("Arduino_Chauffage/Relais/RelaisK9");
mqttClient.subscribe("Arduino_Chauffage/Relais/RelaisK10");
mqttClient.subscribe("Arduino_Chauffage/Relais/RelaisK11");
mqttClient.subscribe("Arduino_Chauffage/Relais/RelaisK12");
mqttClient.subscribe("Arduino_Chauffage/Relais/RelaisK13");
mqttClient.subscribe("Arduino_Chauffage/Relais/RelaisK14");
} else {
Serial.print(F("Broker MQTT indisponible. Status : rc="));
Serial.print(mqttClient.state());
Serial.println(F(" , tentative de reconnexion dans 3 secondes..."));
delay(3000);
}
}
}
//-------- fin de la fonction qui permet de se reconnecter au broker MQTT : ----------
//-------- début de la fonction qui permet de traiter les messages qui arrivent depuis le broker MQTT : ----------
/* Cette fonction est automatiquement appelée lorsque le broquer MQTT envoie un message à l'arduino
* (ou plutôt lorsque l'arduino lit un message)
*/
void callback(char* topic, byte* payload, unsigned int length) {
String Str;
Serial.print(F("**** Message arrivé depuis MQTT broker **** -> [ "));
Serial.print(topic);
Serial.print(F(" ] -> ' "));
for (int i = 0; i < length; i++) { //ici le lenght c'est la variable de la fonction callback
Serial.print((char)payload[i]);
Str = Str + (char)payload[i];
}
Serial.println(F(" '"));
char* Canal_Switch_Virtuel = "Arduino_Chauffage/Relais/RelaisK3";
int valeur_Canal = strcmp(topic, Canal_Switch_Virtuel);
if (valeur_Canal == 0 && Str == "1") {
Serial.println(F("Retour d'etat K3 à 1"));
mqttClient.publish("Arduino_Chauffage/Relais/RelaisK3/Etat", "1");
digitalWrite(RelaisK3, HIGH);
Serial.println(F("RelaisK3 ON"));
} else if (valeur_Canal == 0 && Str == "0") {
Serial.println(F("Retour d'etat K3 à 0"));
mqttClient.publish("Arduino_Chauffage/Relais/RelaisK3/Etat", "0");
digitalWrite(RelaisK3, LOW);
Serial.println(F("RelaisK3 OFF"));
}
}
//-------- fin de la fonction qui permet de traiter les messages qui arrivent depuis le broker MQTT : ----------
// //----------------------- début de la fonction affichage temp : ---------------------
void affValeurs() {
Serial.print(F("Temperatures : "));
Serial.print(temperature[0], 1);
Serial.print(F("°C / "));
Serial.print(temperature[1], 1);
Serial.print(F("°C / "));
Serial.print(temperature[2], 1);
Serial.print(F("°C / "));
Serial.print(temperature[3], 1);
Serial.print(F("°C / "));
Serial.print(temperature[4], 1);
Serial.println(F("°C"));
LDRValue = analogRead(LDR);
Serial.print(F("LDR : "));
Serial.print(LDRValue);
Serial.println(F("mV"));
}
//----------------------- fin de la fonction affichage temp ---------------------