//////// // // Sketch Arduino pour le Plugin JEEDOUINO v097+ de JEEDOM // Connection via Ethernet // // Généré le 2023-10-21 12:06:44. // Pour l'équipement Arduino Mega (EqID : 354 ). // Modèle de carte : a2560. //////// #define DEBUGtoSERIAL 0 // 0, ou 1 pour debug dans la console serie - attention sur nano au manque de mémoire. #define UseWatchdog 0 #define NODHCP 1          // 0 pour IP via DHCP, 1 pour IP fixée dans le sketch. #define UseDHT 1 #define UseDS18x20 1 #define UseTeleInfo 0 #define UseLCD16x2 0  // 0 = None(Aucun) / 1 = LCD Standard 6 pins / 2 = LCD via I2C #define UseEthernet 0   // Choix de la lib suivant shield ethernet : 0 = W5100 / 1 = ENC28J60 / 2 = W5500 - Voir note ci-dessous #define UseHCSR04 0 #define UsePwm_input 0 // Code obsolete (sera supprimé) - Entrée Numérique Variable (0-255 sur 10s) en PULL-UP #define UseBMP180 0   // pour BMP085/180 Barometric Pressure & Temp Sensor #define UseBMP280 0   // pour BMP280 temperature, barometric pressure #define UseBME280 0   // pour BME280 temperature, barometric pressure and humidity #define UseBME680 0   // pour BME680 temperature, humidity, barometric pressure and VOC gas #define UseServo 0    // Pour controler la postion d'un servo. #define UseWS2811 0 // Pour gerer les led stips a base de WS2811/2 avec l'excellente lib Adafruit_NeoPixel // Concernant UseBMP280, UseBME280 et UseBME680 // =1 capteur(x1) sur i2c addr 0x76 (au choix) // =2 capteur(x1) sur i2c addr 0x77 (au choix) // =3 capteurs(x2) sur i2c addr 0x76 & 0x77 (identiques) // Vous permet d'inclure du sketch perso - voir Doc / FAQ. // Il faut activer l'option dans la configuration du plugin. // Puis choisir le nombre de variables utilisateur sous l'onglet Pins/GPIO de votre équipement. #define UserSketch 1 // Tags pour rechercher l'emplacement pour votre code : //UserVars //UserSetup //UserLoop #if (UseWatchdog == 1)   #include #endif #include // Pour shield avec W5100 #if (UseEthernet == 0)   #include #endif // Pour shield avec W5500 #if (UseEthernet == 2)   #include #endif // Pour shield avec ENC28J60 - Note : il faut passer NODHCP à 1 ci-dessus. // Attention, problèmes de mémoire possibles sur arduino nano/uno/328 avec cette lib (v1.59)! // Pour la récupérer, et l'installer dans l'IDE, voir : https://github.com/ntruchsess/arduino_uip/tree/Arduino_1.5.x // // Il faudra modifier dans le fichier \arduino-IDE\libraries\arduino_uip-master\utility\uipethernet-conf // les lignes suivantes: //#define UIP_SOCKET_NUMPACKETS   3 //#define UIP_CONF_MAX_CONNECTIONS 2 //#define UIP_CONF_UDP             0 // #if (UseEthernet == 1)   #include  // v1.59 #endif // Traitement spécifique a cette librairie (pb de deconnection): int UIPEFailCount = 0; unsigned long UIPEFailTime = millis(); //////// // DHT // https://github.com/adafruit/DHT-sensor-library #if (UseDHT == 1)   #include #endif //////// // DS18x20 // https://github.com/PaulStoffregen/OneWire #if (UseDS18x20 == 1)   #include #endif byte IP_ARDUINO[] = { 192, 168, 1, 200 }; byte IP_JEEDOM[] = { 169, 254, 94, 202 }; byte mac[] = { 0xDE, 0xAD, 0xBE, 0xEF, 0xF1, 0x62 }; EthernetServer server(8081); #include // CONFIGURATION VARIABLES #if defined(__AVR_ATmega1280__) || defined(__AVR_ATmega2560__)   #define NB_DIGITALPIN 54   #define NB_ANALOGPIN 16 #else   #define NB_DIGITALPIN 14   #define NB_ANALOGPIN 6 #endif #define NB_TOTALPIN ( NB_DIGITALPIN + NB_ANALOGPIN) // Etat des pins de l'arduino ( Mode ) char Status_pins[NB_TOTALPIN]; int pin_id; byte echo_pin; String eqLogic = ""; String eqLogic0 = ""; String inString = ""; String Message = ""; byte BootMode; // Pour la detection des changements sur pins en entree byte PinValue; byte OLDPinValue[NB_TOTALPIN ]; unsigned long AnalogPinValue; unsigned long OLDAnalogPinValue[NB_TOTALPIN ]; unsigned long CounterPinValue[NB_TOTALPIN ]; unsigned long PinNextSend[NB_TOTALPIN ]; byte swtch[NB_TOTALPIN]; // pour envoi ver jeedom String jeedom = "\0"; // reception commande char c[250]; byte n=0; byte RepByJeedom=0; // Temporisation sorties unsigned long TempoPinHIGH[NB_TOTALPIN ]; // pour tempo pins sorties HIGH unsigned long TempoPinLOW[NB_TOTALPIN ]; // pour tempo pins sorties LOW unsigned long pinTempo = 0; unsigned long NextRefresh = 0; unsigned long ProbeNextSend = millis(); unsigned long timeout = 0; unsigned long ProbePauseDelay = 300000; #if (UseDHT == 1)   DHT *myDHT[NB_TOTALPIN]; #endif #if (UseServo == 1)   #include   Servo myServo[NB_TOTALPIN]; #endif #if (UseWS2811 == 1)   // More info at https://github.com/adafruit/Adafruit_NeoPixel   #include   // Parameter 1 = number of pixels in strip   // Parameter 2 = Arduino pin number (most are valid)   // Parameter 3 = pixel type flags, add together as needed:   //   NEO_KHZ800  800 KHz bitstream (most NeoPixel products w/WS2812 LEDs)   //   NEO_KHZ400  400 KHz (classic 'v1' (not v2) FLORA pixels, WS2811 drivers)   //   NEO_GRB     Pixels are wired for GRB bitstream (most NeoPixel products)   //   NEO_RGB     Pixels are wired for RGB bitstream (v1 FLORA pixels, not v2)   //   NEO_RGBW    Pixels are wired for RGBW bitstream (NeoPixel RGBW products)   #define WS2811PIN 6   Adafruit_NeoPixel strip = Adafruit_NeoPixel(50, WS2811PIN, NEO_GRB + NEO_KHZ800); #endif #if (UseTeleInfo == 1)   // TeleInfo / Software serial   #include   byte teleinfoRX = 0;   byte teleinfoTX = 0;   SoftwareSerial teleinfo(6,7); // definir vos pins RX , TX #endif #if (UseLCD16x2 == 1)   // LiquidCrystal Standard (not i2c)   #include   LiquidCrystal lcd(8, 9, 4, 5, 6, 7); #endif #if (UseLCD16x2 == 2)   // LiquidCrystal  i2c   #include   #include   LiquidCrystal_I2C lcd(0x27,16,2); #endif #if (UseBMP180 == 1)   //  BMP085/180 Barometric Pressure & Temp Sensor   //  https://learn.adafruit.com/bmp085/downloads   #include   #include   Adafruit_BMP085 bmp; #endif #if (UseBME280 >= 1)   // BME280-barometric-pressure-temperature-humidity-sensor   // https://learn.adafruit.com/adafruit-bme280-humidity-barometric-pressure-temperature-sensor-breakout/arduino-test   #include   #if (UseBME280 != 2)     Adafruit_BME280 bme280; // I2C x76   #endif   #if (UseBME280 >= 2)     Adafruit_BME280 bme280b; // I2C x77   #endif #endif #if (UseBMP280 >= 1)   // BMP280 barometric-pressure-temperature-sensor   // https://learn.adafruit.com/adafruit-bmp280-barometric-pressure-plus-temperature-sensor-breakout/arduino-test   #include   #if (UseBMP280 != 2)     Adafruit_BMP280 bmp280; // I2C x76   #endif   #if (UseBMP280 >= 2)     Adafruit_BMP280 bmp280b; // I2C x77   #endif #endif #if (UseBME680 >= 1)   //  bme680-humidity-temperature-barometic-pressure-voc-gas   //  https://learn.adafruit.com/adafruit-bme680-humidity-temperature-barometic-pressure-voc-gas/arduino-wiring-test   #include "Adafruit_BME680.h"   #if (UseBME680 != 2)     Adafruit_BME680 bme680; // I2C x76   #endif   #if (UseBME680 >= 2)     Adafruit_BME680 bme680b; // I2C x77   #endif #endif #if (UserSketch == 1)   // UserVars   // Vos declarations de variables / includes etc....   //#include     int sortie1=31;     int capteur1=A8;     int detection1;     int sortie2=32;     int capteur2=A9;     int detection2;     int sortie3=33;     int capteur3=A10;     int detection3; #endif // SETUP void setup() {   jeedom.reserve(256);   Message.reserve(16);   inString.reserve(4);   #if (DEBUGtoSERIAL == 1)     Serial.begin(115200); // Init du Port serie/USB     Serial.setTimeout(5); // Timeout 5ms     Serial.println(F("JEEDOUINO IS HERE."));   #endif   if (EEPROM.read(13) != 'J')   {     Init_EEPROM();   #if (NODHCP == 0)     if (Ethernet.begin(mac) == 0)   // 1er demarrage 1er flash Jeedouino, on essaye via dhcp     {       #if (DEBUGtoSERIAL == 1)         Serial.println(F("Connection via DHCP failed."));       #endif       #if (UseWatchdog == 1)         wdt_enable(WDTO_15MS); // try reboot         while(1){}       #endif     }     IPAddress IP_ARDUINO = Ethernet.localIP();     jeedom = F("&ipwifi=");     jeedom += IP_ARDUINO[0];     jeedom += '.';     jeedom += IP_ARDUINO[1];     jeedom += '.';     jeedom += IP_ARDUINO[2];     jeedom += '.';     jeedom += IP_ARDUINO[3];     SendToJeedom();   #else     Ethernet.begin(mac, IP_ARDUINO);   #endif   }   else Ethernet.begin(mac, IP_ARDUINO);   #if (DEBUGtoSERIAL == 1)     Serial.println(F("Connection to: LAN"));   #endif   server.begin();   Load_EEPROM(1);   #if (DEBUGtoSERIAL == 1)     Serial.print(F("\nEqLogic:"));     Serial.println(eqLogic);   #endif   #if (UseLCD16x2 == 1)     lcd.begin(16, 2);     lcd.setCursor(0,0);     lcd.print(F("JEEDOUINO v097+"));   #endif   #if (UseLCD16x2 == 2)     lcd.begin();     lcd.backlight();     lcd.home();     lcd.print(F("JEEDOUINO v097+"));   #endif   #if (UseBMP180 == 1)     bmp.begin();   #endif   #if (UseBME280 >= 1)     #if (UseBME280 != 2)       bme280.begin(0x76);     #endif     #if (UseBME280 >= 2)       bme280b.begin(0x77);     #endif   #endif   #if (UseBMP280 >= 1)     #if (UseBMP280 != 2)       bmp280.begin(0x76);     #endif     #if (UseBMP280 >= 2)       bmp280b.begin(0x77);     #endif   #endif   #if (UseBME680 >= 1)     #if (UseBME680 != 2)       bme680.begin(0x76);     #endif     #if (UseBME680 >= 2)       bme680b.begin(0x77);     #endif   #endif   #if (UseWS2811 == 1)     strip.begin();     strip.show();   #endif   #if (UserSketch == 1)     UserSetup(); // Appel de votre setup()   #endif } //// User Setup #if (UserSketch == 1)   void UserSetup()   {     // Votre setup()       pinMode(sortie1,OUTPUT); // broche "sortie1" (2) en SORTIE       pinMode(capteur1,INPUT); // broche "capteur1" (A1) en ENTREE       pinMode(sortie2,OUTPUT); // broche "sortie2" (3) en SORTIE       pinMode(capteur2,INPUT); // broche "capteur2" (A2) en ENTREE       pinMode(sortie3,OUTPUT); // broche "sortie2" (3) en SORTIE       pinMode(capteur3,INPUT); // broche "capteur2" (A2) en ENTREE   } #endif // LOOP void loop() {   // TRAITEMENT DES TEMPO SORTIES SI IL Y EN A   jeedom="";   for (int i = 2; i < NB_TOTALPIN; i++)   {     if (TempoPinHIGH[i]!=0 && TempoPinHIGH[i]millis())     {       if (client.available())       {         c[n] = client.read();         if (c[n]=='\r') c[n]='\n';         if (c[n]=='\n')         {           while (client.available()) c[n+1] = client.read();           break;         }         n++;       }     }     #if (DEBUGtoSERIAL == 1)       if (timeout3)                    // Petite securite           {             for (int i = 1; i < n; i++)             {               if (isDigit(c[i])) c[i]=c[i]-'0';             }             if (c[0]=='R') CounterPinValue[pin_id]=0; // On reset la valeur si demandé.             pin_id=10*int(c[1])+int(c[2]);                    // récupération du numéro de la pin             int multiple=1;             for (int i = n-1; i >= 3; i--)                    // récupération de la valeur             {               CounterPinValue[pin_id] += int(c[i])*multiple;               multiple *= 10;             }             PinNextSend[pin_id]=millis()+2000;             NextRefresh=millis()+2000;             ProbeNextSend = millis()+10000; // Décalage pour laisser le temps au differents parametrages d'arriver de Jeedom             client.print(F("SCOK"));                        // On reponds a JEEDOM             jeedom+=F("&REP=SCOK");           }       }       else if (c[0]=='S' && c[n]=='P')      // Reçoi le délai de relève des sondes       {         if (n > 1)                    // Petite securite         {           for (int i = 1; i < n; i++)           {             if (isDigit(c[i])) c[i] = c[i] - '0';           }           int multiple = 1;           pinTempo = 0;           for (int i = n-1; i > 0; i--)                   // récupération de la valeur           {             pinTempo += int(c[i]) * multiple;             multiple *= 10;           }           if (pinTempo < 1 || pinTempo > 1000) pinTempo = 5;           ProbePauseDelay = 60000 * pinTempo;           client.print(F("SOK"));                       // On reponds a JEEDOM           jeedom+=F("&REP=SOK");         }       }       else if (c[0]=='S' && c[n]=='F')  // Modifie la valeur de toutes les pins sortie (suite reboot )       {         // NB_TOTALPIN = NB_DIGITALPIN  + NB_ANALOGPIN         if (n==(NB_TOTALPIN+1))      // Petite securite         {           jeedom+=F("&REP=SFOK");           for (int i = 2; i < NB_TOTALPIN; i++)           {             switch (Status_pins[i])             {               case 'o': // output               case 's': // switch               case 'l': // low_relais               case 'h': // high_relais               case 'u': // output_pulse               case 'v': // low_pulse               case 'w': // high_pulse               case 'y': // double_pulse                 if (c[i+1]=='0')                 {                   PinWriteLOW(i);                 }                 else if (c[i+1]=='1')                 {                   PinWriteHIGH(i);                 }               break;             }           }         RepByJeedom=0; // Demande repondue, pas la peine de redemander a la fin de loop()           client.print(F("SFOK"));              // On reponds a JEEDOM           ProbeNextSend = millis()+20000; // Décalage pour laisser le temps au differents parametrages d'arriver de Jeedom         }       }       else if (c[0]=='S' && (c[n]=='L' || c[n]=='H' || c[n]=='A')) // Modifie la valeur de toutes les pins sortie a LOW / HIGH / SWITCH / PULSE       {         if (n==2 || n==7)     // Petite securite  : S2L / S2H / S2A / SP00007L /SP00007H         {           jeedom+=F("&REP=SOK");           for (int i = 1; i < n; i++)           {             if (isDigit(c[i])) c[i]=c[i]-'0';           }           if (c[1]=='P') pinTempo = 10000*int(c[2])+1000*int(c[3])+100*int(c[4])+10*int(c[5])+int(c[6]);           for (int i = 2; i < NB_TOTALPIN; i++)           {             TempoPinHIGH[i] = 0;             TempoPinLOW[i] = 0;             switch (Status_pins[i])             {               case 'o': // output               case 's': // switch               case 'l': // low_relais               case 'h': // high_relais               case 'u': // output_pulse               case 'v': // low_pulse               case 'w': // high_pulse               case 'y': // double_pulse                 if (c[n]=='L')                 {                   if (c[1] == 'P') TempoPinHIGH[i] = pinTempo;                   PinWriteLOW(i);                 }                 else if (c[n] == 'H')                 {                   if (c[1] == 'P') TempoPinLOW[i] = pinTempo;                   PinWriteHIGH(i);                 }                 else                 {                   if (swtch[i]==1) PinWriteLOW(i);                   else PinWriteHIGH(i);                 }               break;             }           }           client.print(F("SOK"));             // On reponds a JEEDOM           ProbeNextSend = millis()+10000; // Décalage pour laisser le temps au differents parametrages d'arriver de Jeedom         }       }       else if (c[0]=='B' && c[n]=='M')  // Choix du BootMode       {         BootMode=int(c[1]-'0');         EEPROM.update(14, BootMode);         client.print(F("BMOK"));                // On reponds a JEEDOM         jeedom+=F("&REP=BMOK");         ProbeNextSend = millis()+3000; // Décalage pour laisser le temps au differents parametrages d'arriver de Jeedom       }     #if (UseHCSR04 == 1)       else if (c[0]=='T' && c[n]=='E')  // Trigger pin + pin Echo pour le support du HC-SR04 (ex: T0203E)       {         if (n==5)        // Petite securite         {           client.print(F("SOK"));               // On reponds a JEEDOM           jeedom+=F("&REP=SOK");           ProbeNextSend = millis()+10000; // Décalage pour laisser le temps aux differents parametrages d'arriver de Jeedom           for (int i = 1; i < n; i++)           {             if (isDigit(c[i])) c[i]=c[i]-'0';           }           pin_id=10*int(c[1])+int(c[2]);          // recuperation du numero de la pin trigger           echo_pin=10*int(c[3])+int(c[4]);      // recuperation du numero de la pin echo           digitalWrite(pin_id, HIGH);             // impulsion de 10us pour demander la mesure au HC-SR04           delayMicroseconds(10);           digitalWrite(pin_id, LOW);           long distance = pulseIn(echo_pin, HIGH);  // attente du retour de la mesure (en us) - timeout 1s           distance = distance * 0.034 / 2;          // conversion en distance (cm). NOTE : V=340m/s, fluctue en foncion de la temperature           // on envoi le resultat a jeedom           jeedom += '&';           jeedom += echo_pin;           jeedom += '=';           jeedom += distance;         }       }     #endif     #if (UseLCD16x2 == 1 || UseLCD16x2 == 2)       else if (c[0]=='S' && c[n]=='M')  // Send Message to LCD       {           client.print(F("SMOK"));                // On reponds a JEEDOM           jeedom+=F("&REP=SMOK");           ProbeNextSend = millis()+10000; // Décalage pour laisser le temps aux differents parametrages d'arriver de Jeedom           //pin_id=10*int(c[1]-'0')+int(c[2]-'0');           lcd.clear();           Message = "";           int i = 3; // Normal, utilise dans les 2x FOR           for (i; i < n; i++) //S17Title|MessageM >>> S 17 Title | Message M  // Title & Message <16chars chacun           {             if (c[i] == '|') break;             Message += (char)c[i];           }           lcd.setCursor(0,0); // Title           lcd.print(Message);           i++;           Message = "";           for (i; i < n; i++)           {             Message += (char)c[i];           }           lcd.setCursor(0,1); // Message           lcd.print(Message);       }     #endif     #if (UseWS2811 == 1)       else if (c[0]=='C' && c[n]=='R')  // COLOR : C09LFF00FFR ou C09M12R pin 09 color L or effect M       {         for (int i = 1; i < n; i++)         {           if (isDigit(c[i])) c[i]=c[i]-'0';           if ((c[i] >= 'A') && (c[i] <= 'F')) c[i]=c[i] - 'A' + 10; // For hex         }         if (c[3]=='M')         {           client.print(F("SOK")); // On reponds a JEEDOM avant le TIMEOUT           pinTempo = 10 * int(c[4]) + int(c[5]);           #if (DEBUGtoSERIAL == 1)             Serial.print(F("\startShow: "));             Serial.println(pinTempo);           #endif           startShow(pinTempo);         }         else if (c[3]=='L')         {           client.print(F("SOK")); // On reponds a JEEDOM avant le TIMEOUT           if (n == 10)       // Petite securite           {             uint8_t r = 16 * int(c[4]) + int(c[5]);             uint8_t g = 16 * int(c[6]) + int(c[7]);             uint8_t b = 16 * int(c[8]) + int(c[9]);             #if (DEBUGtoSERIAL == 1)               Serial.print(F("\R: "));               Serial.println(r);               Serial.print(F("\G: "));               Serial.println(g);               Serial.print(F("\B: "));               Serial.println(b);             #endif             for(uint16_t z = 0; z < strip.numPixels(); z++)             {               strip.setPixelColor(z, r, b, g);             }             strip.show();           }         }         else client.print(F("NOK"));  // On reponds a JEEDOM       }     #endif     #if (UserSketch == 1)       else if (c[0]=='U' && c[n]=='R')  // UseR Action       {         client.print(F("SOK")); // On reponds a JEEDOM         UserAction();       }     #endif       else       {         client.print(F("NOK"));                  // On reponds a JEEDOM         jeedom+=F("&REP=NOK");       }     }   }   client.stop();   // On ecoute les pins en entree   //jeedom="";   for (int i = 2; i < NB_TOTALPIN; i++)   {     byte BPvalue = 0;     switch (Status_pins[i])     {     case 'i': // input     case 'p': // input_pullup       PinValue = digitalRead(i);       if (PinValue != OLDPinValue[i] && (PinNextSend[i] < millis() || NextRefresh < millis()))       {         OLDPinValue[i] = PinValue;         jeedom += '&';         jeedom += i;         jeedom += '=';         jeedom += PinValue;         PinNextSend[i] = millis() + 1000; // Delai pour eviter trop d'envois       }       break;     case 'n':   // BP_input_pulldown       BPvalue = 1;     case 'q':   // BP_input_pullup       PinValue = digitalRead(i);       if (PinValue != OLDPinValue[i])       {         PinNextSend[i] = millis() + 50;  // Delai antirebond         OLDPinValue[i] = PinValue;         ProbeNextSend = millis() + 5000; // decale la lecture des sondes pour eviter un conflit       }       if (PinNextSend[i] < millis() && PinValue != swtch[i])       {         if (PinValue == BPvalue) CounterPinValue[i] += 1;         OLDAnalogPinValue[i] = millis() + 1200;  // Delai Appui long         swtch[i] = PinValue;       }       if ((OLDAnalogPinValue[i] < millis() && CounterPinValue[i] != 0) || (PinNextSend[i] < millis() && PinValue != OLDPinValue[i]))       {         if (PinValue == BPvalue) CounterPinValue[i] = 99; // Appui long         jeedom += '&';         jeedom += i;         jeedom += '=';         jeedom += CounterPinValue[i];         CounterPinValue[i] = 0;         OLDAnalogPinValue[i] = millis() + 1000;       }       break;     #if (UsePwm_input == 1)     case 'g': // input_variable suivant tempo       PinValue = digitalRead(i);       // Calcul       if (PinNextSend[i]>millis()) // bouton laché avant les 10s       {         pinTempo=255-((PinNextSend[i]-millis())*255/10000); // pas de 25.5 par seconde       }       else pinTempo=255;  // si bouton laché après les 10s, on bloque la valeur a 255       if (PinValue!=OLDPinValue[i]) // changement état entrée = bouton appuyé ou bouton relaché       {         OLDPinValue[i]=PinValue;         if (swtch[i]==1)  // on vient de lacher le bouton.         {           swtch[i]=0; // on enregistre le laché.           jeedom += '&';           jeedom += i;           jeedom += '=';           jeedom += pinTempo;           PinNextSend[i]=millis();         }         else         {           swtch[i]=1; // on vient d'appuyer sur le bouton, on enregistre.           PinNextSend[i]=millis()+10000; // Delai pour la tempo de maintient du bouton.           CounterPinValue[i]==millis(); // reutilisation pour economie de ram           ProbeNextSend = millis()+15000; // decale la lecture des sondes pour eviter un conflit         }       }       else       {         if (swtch[i]==1 && CounterPinValue[i] 20) // delta correctif pour eviter les changements negligeables           {             int j=i;             if (i<54) j=i+40;  // petit correctif car dans Jeedom toutes les pins Analog commencent a l'id 54+             OLDAnalogPinValue[i]=AnalogPinValue;             //jeedom += '&' + j + '=' + AnalogPinValue;             jeedom += '&';             jeedom += j;             jeedom += '=';             jeedom += AnalogPinValue;             PinNextSend[i]=millis()+5000; // Delai pour eviter trop d'envois           }         }         break;     case 'c': // compteur_pullup CounterPinValue       PinValue = digitalRead(i);       if (PinValue!=OLDPinValue[i])       {         OLDPinValue[i]=PinValue;         CounterPinValue[i]+=PinValue;       }       if (NextRefreshreadTemperature() * 100);         jeedom += '&';         jeedom += i+1000;         jeedom += '=';         jeedom += int (myDHT[i]->readHumidity() * 100);         PinNextSend[i] = millis() + ProbePauseDelay;  // Delai 60s entre chaque mesures pour eviter trop d'envois         ProbeNextSend = millis() + 5000; // Permet de decaler la lecture entre chaque sonde DHT sinon ne marche pas cf librairie (3000 mini)       }       break;     #endif     #if (UseDS18x20 == 1)     case 'b': // DS18x20       if (PinNextSend[i] < millis() and ProbeNextSend < millis())       {         float reponse = read_DSx(i); // DS18x20         jeedom += '&';         jeedom += i;         jeedom += '=';         jeedom += reponse;         PinNextSend[i] = millis() + ProbePauseDelay;  // Delai 60s entre chaque mesures pour eviter trop d'envois         ProbeNextSend = millis() + 12000; // Permet de laisser du temps pour les commandes 'action', probabilite de blocage moins grande idem^^       }       break;     #endif     #if (UseTeleInfo == 1)     case 'j': // teleinfoRX       if (PinNextSend[i]millis())         {           if (teleinfo.available()) recu = teleinfo.read() & 0x7F; /*          #if (DEBUGtoSERIAL == 1)             Serial.print(recu);           #endif   */         }         jeedom += F("&ADCO=");         timeout = millis()+2000;  // 2s         while (timeout>millis())         {           if (teleinfo.available())           {             recu = teleinfo.read() & 0x7F; /*            #if (DEBUGtoSERIAL == 1)               Serial.print(recu);             #endif */             cntChar++;             if (cntChar > 280) break;             if (recu == 0) break;             if (recu == 0x04) break; // EOT             if (recu == 0x03) break; // permet d'eviter ce caractere dans la chaine envoyée (economise du code pour le traiter)             if (recu == 0x0A) continue;       // Debut de groupe             if (recu == 0x0D)             {               jeedom += ';';  // Fin de groupe               continue;             }             if (recu<33)             {               jeedom += '_';             }             else jeedom += recu;           }         }         teleinfo.end();         #if (DEBUGtoSERIAL == 1)           Serial.println(F("/finRX"));         #endif         PinNextSend[i]=millis()+30000;  // Delai 30s entre chaque mesures pour eviter trop d'envois       }       break;     #endif     #if (UseBMP180 == 1)     case 'r': // BMP085/180       if (PinNextSend[i] < millis())       {         jeedom += '&';         jeedom += i;         jeedom += '=';         jeedom += bmp.readTemperature();         jeedom += '&';         jeedom += i + 1000;         jeedom += '=';         jeedom += bmp.readPressure();         PinNextSend[i] = millis() + ProbePauseDelay;  // Delai 60s entre chaque mesures pour eviter trop d'envois       }       break;     #endif     #if (UseBME280 >= 1)       #if (UseBME280 != 2)       case 'A': // BME280         if (PinNextSend[i] < millis())         {           jeedom += '&';           jeedom += i;           jeedom += '=';           jeedom += bme280.readTemperature();           jeedom += '&';           jeedom += i + 1000;           jeedom += '=';           jeedom += bme280.readPressure();           jeedom += '&';           jeedom += i + 2000;           jeedom += '=';           jeedom += bme280.readHumidity();           PinNextSend[i] = millis() + ProbePauseDelay;  // Delai 60s entre chaque mesures pour eviter trop d'envois         }         break;       #endif       #if (UseBME280 >= 2)       case 'D': // BME280         if (PinNextSend[i] < millis())         {           jeedom += '&';           jeedom += i;           jeedom += '=';           jeedom += bme280b.readTemperature();           jeedom += '&';           jeedom += i + 1000;           jeedom += '=';           jeedom += bme280b.readPressure();           jeedom += '&';           jeedom += i + 2000;           jeedom += '=';           jeedom += bme280b.readHumidity();           PinNextSend[i] = millis() + ProbePauseDelay;  // Delai 60s entre chaque mesures pour eviter trop d'envois         }         break;       #endif     #endif     #if (UseBME680 >= 1)       #if (UseBME680 != 2)       case 'B': // BME680         if (PinNextSend[i] < millis() and bme680.performReading())         {           jeedom += '&';           jeedom += i;           jeedom += '=';           jeedom += bme680.temperature;           jeedom += '&';           jeedom += i + 1000;           jeedom += '=';           jeedom += bme680.pressure;           jeedom += '&';           jeedom += i + 2000;           jeedom += '=';           jeedom += bme680.humidity;           jeedom += '&';           jeedom += i + 3000;           jeedom += '=';           jeedom += bme680.gas_resistance;           PinNextSend[i] = millis() + ProbePauseDelay;  // Delai 60s entre chaque mesures pour eviter trop d'envois         }         break;       #endif       #if (UseBME680 >= 2)       case 'E': // BME680         if (PinNextSend[i] < millis() and bme680b.performReading())         {           jeedom += '&';           jeedom += i;           jeedom += '=';           jeedom += bme680b.temperature;           jeedom += '&';           jeedom += i + 1000;           jeedom += '=';           jeedom += bme680b.pressure;           jeedom += '&';           jeedom += i + 2000;           jeedom += '=';           jeedom += bme680b.humidity;           jeedom += '&';           jeedom += i + 3000;           jeedom += '=';           jeedom += bme680b.gas_resistance;           PinNextSend[i] = millis() + ProbePauseDelay;  // Delai 60s entre chaque mesures pour eviter trop d'envois         }         break;       #endif     #endif     #if (UseBMP280 >= 1)       #if (UseBMP280 != 2)       case 'C': // BMP280         if (PinNextSend[i] < millis())         {           jeedom += '&';           jeedom += i;           jeedom += '=';           jeedom += bmp280.readTemperature();           jeedom += '&';           jeedom += i + 1000;           jeedom += '=';           jeedom += bmp280.readPressure();           PinNextSend[i] = millis() + ProbePauseDelay;  // Delai 60s entre chaque mesures pour eviter trop d'envois         }         break;       #endif       #if (UseBMP280 >= 2)       case 'F': // BMP280         if (PinNextSend[i] < millis())         {           jeedom += '&';           jeedom += i;           jeedom += '=';           jeedom += bmp280b.readTemperature();           jeedom += '&';           jeedom += i + 1000;           jeedom += '=';           jeedom += bmp280b.readPressure();           PinNextSend[i] = millis() + ProbePauseDelay;  // Delai 60s entre chaque mesures pour eviter trop d'envois         }         break;       #endif     #endif     }   }   #if (UserSketch == 1)     //UserLoop(); // Appel de votre loop() permanent     if (NextRefresh < millis()) UserLoop(); // Appel de votre loop() toutes les 60s   #endif   if (NextRefresh < millis())   {     NextRefresh = millis() + 60000; // Refresh auto toutes les 60s     if (RepByJeedom) // sert a verifier que jeedom a bien repondu a la demande dans Load_eeprom     {       jeedom += F("&ASK=1"); // Sinon on redemande     }   } /*  #if (UseLCD16x2 == 1 || UseLCD16x2 == 2)     lcd.setCursor(0,1);     lcd.print(jeedom);   #endif */   if (jeedom != "") SendToJeedom(); } //// User Loop + Action #if (UserSketch == 1)   void UserLoop()   {     // Votre loop()       Capteur1();       Capteur2();       Capteur3();     }     void Capteur1() {       detection1=digitalRead(capteur1); // on lit la broche capteur1       // la sortie OUT du capteur est active sur niveau bas       while (detection1==0) { // objet détecté = niveau 0 sur OUT capteur1         detection1=digitalRead(capteur1);         digitalWrite(sortie1,1); // on commande la sortie 2 (diode L sur la carte)       }       digitalWrite(sortie1,0); // on éteint L dès qu'il n'y a plus detection           }             void Capteur2() {       detection2=digitalRead(capteur2); // on lit la broche capteur2       // la sortie OUT du capteur est active sur niveau bas       while (detection2==0) { // objet détecté = niveau 0 sur OUT capteur2         detection2=digitalRead(capteur2);         digitalWrite(sortie2,1); // on commande la sortie 3 (diode L sur la carte)       }       digitalWrite(sortie2,0); // on éteint L dès qu'il n'y a plus detection     }             void Capteur3() {       detection3=digitalRead(capteur3); // on lit la broche capteur3       // la sortie OUT du capteur est active sur niveau bas       while (detection3==0) { // objet détecté = niveau 0 sur OUT capteur3         detection3=digitalRead(capteur3);         digitalWrite(sortie3,1); // on commande la sortie 4 (diode L sur la carte)       }       digitalWrite(sortie3,0); // on éteint L dès qu'il n'y a plus detection     // pour envoyer une valeur a jeedom, il suffit de remplir la variable jeedom comme cela :     // jeedom += '&';     // jeedom += u; // avec u = numero de la pin "info" dans l'equipement jeedom - info pin number     // jeedom += '=';     // jeedom += info; // la valeur a envoyer - info value to send     //     // Ex:     jeedom += '&';     jeedom += 2049; // Etat pin 500     jeedom += '=';     jeedom += '1';  // '0' ou '1'     //     jeedom += '&';     jeedom += 2055; // Etat pin 500     jeedom += '=';     jeedom += '1';  // '0' ou '1'     // jeedom += '&';     // jeedom += 504; // pin 504     // jeedom += '=';     // jeedom += millis();  // valeur numerique     //     // jeedom += '&';     // jeedom += 506; // pin 506     // jeedom += '=';     // jeedom += "Jeedouino%20speaking%20to%20Jeedom...";  // valeur string     // /!\ attention de ne pas mettre de code bloquant (avec trop de "delays") - max time 2s   }   void UserAction()   {     // En cas d'une reception d'une commande user action depuis jeedom     // c[0]='U' & c[n]='R')     //     // c[1] = c[1] - '0'; ==5 (user pin start at 500)     // c[2] = c[2] - '0';     // c[3] = c[3] - '0';     // ou : for (int i = 1; i < n; i++) if (isDigit(c[i])) c[i] = c[i] - '0'; // conversion simple char(ascii) vers int     // int pin_id = 100 * int(c[1]) + 10 * int(c[2]) + int(c[3]);   // pin action number     //     // c[4] to c[n-1]   // pin action value     //     // Ex1:     // JEEDOM  : Sortie Numérique (Sous-type Jeedom: défaut)     // ARDUINO : c[] = U5000R -> U 500 0 R = binary 0 pin 500 -> c[4] = '0'     // ARDUINO : c[] = U5001R -> U 500 1 R = binary 1 pin 500 -> c[4] = '1'     // Ex2:     // JEEDOM  : Sortie Numérique (Sous-type Jeedom: curseur)     // ARDUINO : c[] = U502128R -> U 502 128 R = Slider, Value 128, pin 502 -> c[4] = '1', c[5] = '2', c[5] = '8'     // Ex3:     // JEEDOM  : Sortie Numérique (Sous-type Jeedom: message)     // ARDUINO : c[] = U507[Jeedom] Message|Ceci est un testR -> U 507 [Jeedom] Message | Ceci est un test R = Message, pin 507     // /!\ attention de ne pas mettre de code bloquant (avec trop de "delays") - max time 2s   } #endif // FONCTIONS void SendToJeedom() {   EthernetClient JEEDOMclient = server.available();   #if (DEBUGtoSERIAL == 1)     Serial.print(F("\nSending: "));     Serial.println(jeedom);     Serial.print(F("To eqLogic: "));     Serial.println(eqLogic);   #endif   int J=JEEDOMclient.connect(IP_JEEDOM, 80);   if (J)   {     JEEDOMclient.print(F("GET /plugins/jeedouino/core/php/Callback.php?BoardEQ="));     JEEDOMclient.print(eqLogic);     JEEDOMclient.print(jeedom);     JEEDOMclient.println(F(" HTTP/1.1"));     JEEDOMclient.print(F("Host: "));     JEEDOMclient.print(IP_JEEDOM[0]);     JEEDOMclient.print('.');     JEEDOMclient.print(IP_JEEDOM[1]);     JEEDOMclient.print('.');     JEEDOMclient.print(IP_JEEDOM[2]);     JEEDOMclient.print('.');     JEEDOMclient.println(IP_JEEDOM[3]);     delay(111);     JEEDOMclient.println(F("Connection: close"));     JEEDOMclient.println();     delay(111);     JEEDOMclient.stop();   #if (DEBUGtoSERIAL == 1)     Serial.print(F("At IP: "));     Serial.print(IP_JEEDOM[0]);     Serial.print('.');     Serial.print(IP_JEEDOM[1]);     Serial.print('.');     Serial.print(IP_JEEDOM[2]);     Serial.print('.');     Serial.println(IP_JEEDOM[3]);   #endif     UIPEFailTime = millis();     UIPEFailCount = 0;   }   else   {     JEEDOMclient.stop();     UIPEFailCount++;   #if (DEBUGtoSERIAL == 1)     Serial.print(F("connection failed : "));     Serial.println(J);     Serial.print(F("UIPEFailCount : "));     Serial.println(UIPEFailCount);   #endif     if (UIPEFailCount>10 and millis()>UIPEFailTime+60000)     {       #if (DEBUGtoSERIAL == 1)         Serial.println(F("Waiting 10s & reboot if UseWatchdog is set"));       #endif       delay(10000); // tentative soft pour laisser le temps a la lib de se resaisir       #if (UseWatchdog == 1)         wdt_enable(WDTO_15MS); // try reboot         while(1){}       #endif       JEEDOMclient.stop();       delay(1000);       Ethernet.begin(mac, IP_ARDUINO);       delay(1000);       server.begin();       UIPEFailTime = millis() + 60000;       delay(999);     }   }   jeedom="";   delay(444);   //JEEDOMclient.stop(); } void Set_OutputPin(int i) {   TempoPinHIGH[i]=0;   TempoPinLOW[i]=0;   switch (Status_pins[i])   {     #if (UseServo == 1)     case 'x':       pinTempo = 100 * int(c[3]) + 10 * int(c[4]) + int(c[5]);       myServo[i].write(pinTempo);       delay(15);       break;     #endif     case 'o': // output      // S131S pin 13 set to 1 (ou S130S pin 13 set to 0)     case 'l': // low_relais // S13S pin 13 set to 0     case 'h': // high_relais  // S13S pin 13 set to 1       if (c[3]==0)       {         PinWriteLOW(i);       }       else       {         PinWriteHIGH(i);       }       break;     case 's': // switch     // S13 pin 13 set to 1 si 0 sinon set to 0 si 1       if (swtch[i]==1)       {         PinWriteLOW(i);       }       else       {         PinWriteHIGH(i);       }       break;     //     // ON VERIFIE SI UNE TEMPORISATION EST DEMANDEE SUR UNE DES SORTIES     // On essai d'etre sur une precision de 0.1s mais ca peut fluctuer en fonction de la charge cpu     // Testé seulement sur mega2560     //     case 'u': // output_pulse // Tempo ON : S1309999S : pin 13 set to 0 during 999.9 seconds then set to 1 (S1319999 : set to 1 then to 0)       pinTempo=10000*int(c[4])+1000*int(c[5])+100*int(c[6])+10*int(c[7])+int(c[8]);       // pinTempo est donc en dixieme de seconde       pinTempo = pinTempo*100+millis(); // temps apres lequel la pin doit retourner dans l'autre etat.       // Peut buguer quand millis() arrive vers 50jours si une tempo est en cours pendant la remise a zero de millis().       // Risque faible si les tempo sont de l'ordre de la seconde (impulsions sur relais par ex.).       if (c[3]==0)       {         TempoPinHIGH[i]=pinTempo;         PinWriteLOW(i);       }       else if (c[3]==1)       {         TempoPinLOW[i]=pinTempo;         PinWriteHIGH(i);       }       break;     case 'v': // low_pulse    // Tempo ON : S139999S : pin 13 set to 0 during 999.9 seconds then set to 1       if (c[3]==0)       {         pinTempo=10000*int(c[4])+1000*int(c[5])+100*int(c[6])+10*int(c[7])+int(c[8]);         // pinTempo est donc en dixieme de seconde         pinTempo = pinTempo*100+millis();  // temps apres lequel la pin doit retourner dans l'autre etat.         TempoPinHIGH[i]=pinTempo;         PinWriteLOW(i);       }       else       {         PinWriteHIGH(i);       }       break;     case 'w': // high_pulse  // Tempo ON : S139999S : pin 13 set to 1 during 999.9 seconds then set to 0       if (c[3]==0)       {         PinWriteLOW(i);       }       else       {         pinTempo=10000*int(c[4])+1000*int(c[5])+100*int(c[6])+10*int(c[7])+int(c[8]);         // pinTempo est donc en dixieme de seconde         pinTempo = pinTempo*100+millis();  // temps apres lequel la pin doit retourner dans l'autre etat.         TempoPinLOW[i]=pinTempo;         PinWriteHIGH(i);       }       break;     case 'm': // pwm_output       pinTempo = 100 * int(c[3]) + 10 * int(c[4]) + int(c[5]);  // the duty cycle: between 0 (always off) and 255 (always on).       analogWrite(i, pinTempo);       jeedom += '&';       jeedom += i;       jeedom += '=';       jeedom += pinTempo;       break;   } } void Load_EEPROM(int k) {   // on recupere le BootMode   BootMode = EEPROM.read(14);   // Recuperation de l'eqLogic   eqLogic = F("354");   eqLogic0 = "";   n = EEPROM.read(15);        // Recuperation de la longueur du eqLogic   if (n > 0)    // bug probable si eqLogic_id<10 dans jeedom   {     for (int i = 1; i < n; i++)     {       eqLogic0 += EEPROM.read(15 + i);     }   }   if (eqLogic != eqLogic0)   {     #if (DEBUGtoSERIAL == 1)       Serial.println(F("Reinit eqID etc"));       Serial.println();     #endif     Init_EEPROM();   }   // Recuperation de l'IP   IP_JEEDOM[0]=EEPROM.read(26);   IP_JEEDOM[1]=EEPROM.read(27);   IP_JEEDOM[2]=EEPROM.read(28);   IP_JEEDOM[3]=EEPROM.read(29);   // on met en place le mode des pins   jeedom = "";   byte y = 1;   #if (UseTeleInfo == 1)     teleinfoRX = 0;     teleinfoTX = 0;   #endif   #if (DEBUGtoSERIAL == 1)     Serial.println(F("Conf. Pins:"));     for (int i = 0; i < NB_TOTALPIN; i++) Serial.print((char)EEPROM.read(30 + i));     Serial.println();   #endif   // au cas ou l'arduino n'ai pas encore recu la conf. des pins.   // for (int i = 2; i < NB_TOTALPIN; i++)   // {   //  byte e = EEPROM.read(30 + i);   //  if (e < ' ' || e > 'z')   //  {   //    jeedom += F("&PINMODE=1");   //    #if (DEBUGtoSERIAL == 1)   //      Serial.println(F("Demande la Conf. Pins."));   //      Serial.println();   //    #endif   //    break;   //  }   // }   for (int i = 2; i < NB_TOTALPIN; i++)   {     Status_pins[i] = EEPROM.read(30 + i); // Etats des pins     // INITIALISATION DES TABLEAUX DE TEMPO SORTIES     TempoPinHIGH[i] = 0;     TempoPinLOW[i] = 0;     //     switch (Status_pins[i])     {       case 'i': // input         OLDPinValue[i] = 2;       //@cpaillet         PinNextSend[i] = millis();         break;       case 'a': // analog_input       case 'n':   // BP_input_pulldown         pinMode(i, INPUT);         break;       #if (UseTeleInfo == 1)       case 'j':   // teleinfoRX pin         teleinfoRX = i;         pinMode(i, INPUT);         break;       case 'k':   // teleinfoTX pin         teleinfoTX = i;         pinMode(i, OUTPUT);         break;       #endif       #if (UseDHT == 1)       case 'd': // DHT11         myDHT[i] = new DHT(i, 11);  // DHT11         PinNextSend[i] = millis() + ProbePauseDelay;         break;       case 'e': // DHT21         myDHT[i] = new DHT(i, 21);  // DHT21         PinNextSend[i] = millis() + ProbePauseDelay;         break;       case 'f': // DHT 22         myDHT[i] = new DHT(i, 22);  // DHT22         PinNextSend[i] = millis() + ProbePauseDelay;         break;       #endif       #if (UseDS18x20 == 1)       case 'b': // DS18x20         PinNextSend[i] = millis() + ProbePauseDelay;         break;       #endif       #if (UseServo == 1)       case 'x':         myServo[i].attach(i);         break;       #endif       case 't':   // trigger pin         pinMode(i, OUTPUT);         digitalWrite(i, LOW);         break;       case 'z':   // echo pin         pinMode(i, INPUT);         break;       case 'p':    // input_pullup         pinMode(i, INPUT_PULLUP);         OLDPinValue[i] = 2;       //@cpaillet         PinNextSend[i] = millis();         break;       case 'g':    // pwm_input       case 'q':   // BP_input_pullup           pinMode(i, INPUT_PULLUP); // pour eviter les parasites en lecture, mais inverse l'etat de l'entree : HIGH = input open, LOW = input closed           // Arduino Doc : An internal 20K-ohm resistor is pulled to 5V.         swtch[i] = 0;   // init pour pwm_input         OLDPinValue[i] = 1;         PinNextSend[i] = millis();           break;       case 'c':    // compteur_pullup           pinMode(i, INPUT_PULLUP); // pour eviter les parasites en lecture, mais inverse l'etat de l'entree : HIGH = input open, LOW = input closed           // Arduino Doc : An internal 20K-ohm resistor is pulled to 5V.           if (k)           {             jeedom += F("&CPT_"); // On demande à Jeedom de renvoyer la dernière valeur connue pour la pin i             jeedom += i;             jeedom += '=';             jeedom += i;           }           break;       case 'o': // output       case 's': // switch       case 'l': // low_relais       case 'h': // high_relais       case 'u': // output_pulse       case 'v': // low_pulse       case 'w': // high_pulse       case 'y': // double_pulse         pinMode(i, OUTPUT);         // restauration de l'etat des pins DIGITAL OUT au demarrage        if (k)        {         switch (BootMode)         {           case 0:             // On laisse tel quel             break;           case 1:             PinWriteLOW(i);             break;           case 2:             PinWriteHIGH(i);             break;           case 3:             PinWriteHIGH(i);             // On demande a Jeedom d'envoyer la valeur des pins             if (y)             {               jeedom += F("&ASK=1");               y=0;               RepByJeedom=1; // sert a verifier que jeedom a bien repondu a la demande             }             break;           case 4:             if (EEPROM.read(110+i) == 0) PinWriteLOW(i);             else PinWriteHIGH(i);             break;           case 5:             PinWriteLOW(i);             // On demande a Jeedom d'envoyer la valeur des pins             if (y)             {               jeedom += F("&ASK=1");               y=0;               RepByJeedom=1; // sert a verifier que jeedom a bien repondu a la demande             }             break;           }        }         // fin restauration         break;       case 'm': // pwm_output         pinMode(i, OUTPUT);         break;     }   }   #if (UseTeleInfo == 1)     if (teleinfoRX != 0)     {         #if (DEBUGtoSERIAL == 1)       Serial.print(F("\nteleinfoRX:"));       Serial.println(teleinfoRX);       Serial.print(F("\nteleinfoTX:"));       Serial.println(teleinfoTX);       #endif       //SoftwareSerial teleinfo(teleinfoRX, teleinfoTX);     }   #endif   if (jeedom != "") SendToJeedom(); } void PinWriteHIGH(long p) {   digitalWrite(p, HIGH);   swtch[p]=1;   jeedom += '&';   jeedom += p;   jeedom += F("=1");   // Si bootmode=4 sauvegarde de l'etat de la pin (en sortie) - !!! Dangereux pour l'eeprom à long terme !!!   if (BootMode==4) EEPROM.update(110+p, 1);   #if (DEBUGtoSERIAL == 1)     Serial.print(F("SetPin "));     Serial.print(p);     Serial.println(F(" to 1"));   #endif } void PinWriteLOW(long p) {   digitalWrite(p, LOW);   swtch[p]=0;   jeedom += '&';   jeedom += p;   jeedom += F("=0");   // Si bootmode=4 sauvegarde de l'etat de la pin (en sortie) - !!! Dangereux pour l'eeprom à long terme !!!   if (BootMode==4) EEPROM.update(110+p, 0);   #if (DEBUGtoSERIAL == 1)     Serial.print(F("SetPin "));     Serial.print(p);     Serial.println(F(" to 0"));   #endif } void Init_EEPROM() {   // Un marqueur   EEPROM.update(13, 'J');  // JEEDOUINO   // BootMode choisi au demarrage de l'arduino   // 0 = Pas de sauvegarde - Toutes les pins sorties non modifi?es au d?marrage.   // 1 = Pas de sauvegarde - Toutes les pins sorties mises ? LOW au d?marrage.   // 2 = Pas de sauvegarde - Toutes les pins sorties mises ? HIGH au d?marrage.   // 3 = Sauvegarde sur JEEDOM - Toutes les pins sorties mises suivant leur sauvegarde dans Jeedom. Jeedom requis, sinon pins mises ? OFF.   // 4 = Sauvegarde sur EEPROM- Toutes les pins sorties mises suivant leur sauvegarde dans l\'EEPROM. Autonome, mais dur?e de vie de l\'eeprom fortement r?duite.   EEPROM.update(14, 2);   BootMode=2;   // Initialisation par default   for (int i = 30; i < 200; i++)   {     EEPROM.update(i, 1);  // Valeur des pins OUT au 1er demarrage ( mes relais sont actis a 0, donc je met 1 pour eviter de les actionner au 1er boot)   }   EEPROM.update(26, IP_JEEDOM[0]);        // Sauvegarde de l' IP   EEPROM.update(27, IP_JEEDOM[1]);   EEPROM.update(28, IP_JEEDOM[2]);   EEPROM.update(29, IP_JEEDOM[3]);   eqLogic = F("354");           // Sauvegarde de eqLogic pour 1er boot apres 1er flashage   EEPROM.update(15, 4);       // Sauvegarde de la longueur du eqLogic   for (int i = 1; i < 4; i++)   {     EEPROM.update(15+i, eqLogic[i-1]-'0');    // Sauvegarde de l' eqLogic   }   // fin initialisation } #if (UseDS18x20 == 1) int read_DSx(int pinD) {   byte data[12];   byte addr[8];   long first, temp;   char buffer[3];   OneWire ds(pinD);   byte nb_ds18 = 0;   ds.reset_search();   while (ds.search(addr))   {     if (OneWire::crc8(addr, 7) != addr[7]) //Check if there is no errors on transmission     {       #if (DEBUGtoSERIAL == 1)         Serial.println(F("CRC invalide..."));       #endif       return 9999;     }     if (addr[0] != 0x28)     {       #if (DEBUGtoSERIAL == 1)         Serial.println(F("Device is not a DS18B20."));       #endif       return 9999;     }     ds.reset();     ds.select(addr);     ds.write(0x44, 1);     nb_ds18++;     delay(250);   }   if (nb_ds18 == 0)   {     ds.reset_search();     #if (DEBUGtoSERIAL == 1)       Serial.println(F("ds not found..."));     #endif     return 9999;   }   nb_ds18 = 0;   delay(800);   jeedom = F("&DS18list_");   jeedom += pinD;   jeedom += F("={");   ds.reset_search();   while (ds.search(addr))   {     jeedom += '"';     jeedom += F("28-");     for (int ii = 6; ii > 0; ii--)     {       if (addr[ii] < 16) jeedom += '0';       itoa (addr[ii], buffer, 16);       jeedom += buffer;     }     jeedom += '"';     jeedom += ':';     jeedom += '"';     ds.reset();     ds.select(addr);     ds.write(0xBE);     for (int ii = 0; ii < 9; ii++)     {       data[ii] = ds.read();     }     temp = (int16_t) ((data[1] << 8) | data[0]) * 6.25;     if (nb_ds18 == 0) first = temp;     nb_ds18++;     #if (DEBUGtoSERIAL == 1)       Serial.println(temp / 100);     #endif     jeedom += temp;     jeedom += '"';     jeedom += ',';   }   jeedom += '}';   return first; } #endif #if (UseWS2811 == 1) // Code below is from https://github.com/adafruit/Adafruit_NeoPixel/blob/master/examples/buttoncycler/buttoncycler.ino // More info at https://github.com/adafruit/Adafruit_NeoPixel void startShow(int i) {   switch(i){     case 0: colorWipe(strip.Color(0, 0, 0), 50);    // Black/off             break;     case 1: colorWipe(strip.Color(255, 0, 0), 50);  // Red             break;     case 2: colorWipe(strip.Color(0, 255, 0), 50);  // Green             break;     case 3: colorWipe(strip.Color(0, 0, 255), 50);  // Blue             break;     case 4: colorWipe(strip.Color(255, 255, 255), 50);  // White             break;     case 5: colorWipe(strip.Color(255, 255, 0), 50);  // Magenta             break;     case 6: colorWipe(strip.Color(255, 0, 255), 50);  // Yellow             break;     case 7: colorWipe(strip.Color(0, 255, 255), 50);  // Cyan             break;     case 8: theaterChase(strip.Color(127, 0, 0), 50); // Red             break;     case 9: theaterChase(strip.Color(0, 127, 0), 50); // Green             break;     case 10: theaterChase(strip.Color(0, 0, 127), 50); // Blue             break;     case 11: theaterChase(strip.Color(127, 127, 127), 50); // White             break;     case 12: theaterChase(strip.Color(127, 127, 0), 50); // Magenta             break;     case 13: theaterChase(strip.Color(127, 0, 127), 50); // Yellow             break;     case 14: theaterChase(strip.Color(0, 127, 127), 50); // Cyan             break;     case 15: rainbow(20);             break;     case 16: rainbowCycle(20);             break;     case 17: theaterChaseRainbow(50);             break;   } } // Fill the dots one after the other with a color void colorWipe(uint32_t c, uint8_t wait) {   for(uint16_t i=0; i