Update Serre_menuLCD.ino

Update Serre_menuLCD.ino

Fixed Menu issues

--- Serre_menuLCD.ino
+++ Serre_menuLCD.ino
@@ -10,8 +10,11 @@
 #include <Greenhouse.h>

 //*****************DEFINITIONS***********************
-//#define DS18B20
-#define SHT1X
+//Select your temperature probe
+#define DS18B20
+//define SHT1X
+
+//Select your ouput pins
 #define LCDKEYPAD A0
 #define MENU_PIN 2
 const byte SAFETY_SWITCH[2] = {2,3};
@@ -57,7 +60,6 @@
 boolean rollupSafety[sizeof(rollups)];

 //Sonde de température
-float greenhouseTemperature;     //données de la sonde de température
 boolean failedSensor = false;

 //Poisition des Rollups
@@ -93,6 +95,8 @@
 byte Nbitems = 6;
 char* menuitems[10];
 int yr; byte mt; byte dy; byte hr; byte mn; byte sc;
+byte nr; byte inc; unsigned int rot; unsigned int p; int mod; byte hys; boolean sfty;
+byte typ; byte tt;

 //**************************************************************
@@ -114,6 +118,7 @@
   defineProgram(3, CLOCK, 11, 10, 22);
   defineProgram(4, SS, 0, -60, 28);
   defineProgram(5, SS, 0, -2, 18);
+
   defineRollup(1, 5, 1, 1, 0, 1, false);
   defineFan(1, 2, 1, false);
   defineHeater(1, -3, 1);
@@ -156,12 +161,8 @@
     selectProgram();
     //Définition de la température d'activation des sorties
     startRamping();
-    //Actualise la température
-    getTemperature();
-    //Protocoles spéciaux (pré-jour/pré-nuit)
+    //Protocoles spéciaux (pré-jour/pré-nuit) [VIDE]
     specialPrograms();
-    //Affichage LCD
-    lcdDisplay();
     //Activation des relais
     relayLogic();
     //Affichage LCD
@@ -193,7 +194,7 @@
   for (int x = 0; x < sizeof(rollups);x++){
     rollups[x] = true;
     firstOpening[x] = true;
-    rollupSafety[x] = EEPROM.read(ROLLUPSAFETY+x);
+    rollupSafety[x] = rollupSafetyE(x);
     if (rollupSafety[x] == true) {
         attachInterrupt(digitalPinToInterrupt(SAFETY_SWITCH[0]), endOfTheRun0, FALLING);
         attachInterrupt(digitalPinToInterrupt(SAFETY_SWITCH[1]), endOfTheRun1, FALLING);
@@ -201,7 +202,7 @@
   }
   for (int x = 0; x < sizeof(fans);x++){
     fans[x] = true;
-    fanSafety[x] = EEPROM.read(FANSAFETY+x);
+    fanSafety[x] = fanSafetyE(x);
   }
   for (int x = 0; x < sizeof(heaters);x++){
     heaters[x] = true;
@@ -209,7 +210,7 @@
 }

 void endOfTheRun0(){
-  incrementCounter[0] = EEPROM.read(INCREMENTS);
+  incrementCounter[0] = incrementsE(0);
 }
 void endOfTheRun1(){
   byte x;
@@ -217,7 +218,7 @@
     case 1 : x = 0;
     case 2 : x = 1;
   }
-  incrementCounter[x] = EEPROM.read(INCREMENTS+x);
+  incrementCounter[x] = incrementsE(x);
 }

 void initVariables(){
@@ -228,7 +229,7 @@
   //Définition de la température cible
   setTempCible();
   //Définition de la température d'activation des sorties
-  getTemperature();
+  //getTemperature();
 }

 void getDateAndTime(){
@@ -245,17 +246,9 @@
 void selectProgram(){
   //Définition des variables locales
   int P[nbPrograms][3];
-  byte sunRise[6];
-  byte sunSet[6];
-  int srmod[nbPrograms];
-  int ssmod[nbPrograms];
-  byte programType[nbPrograms];
-
-  for(byte x = 0; x < nbPrograms; x++){
-    programType[x] = EEPROM.read(PROGRAMS+x);
-    srmod[x] =  EEPROM.read(SRMOD+x)-60;
-    ssmod[x] =  EEPROM.read(SSMOD+x)-60;
-  }
+  byte sunRise[3];
+  byte sunSet[3];
+
   //Exécution du programme
   //Définit l'heure du lever et coucher du soleil
   myLord.SunRise(sunTime); ///On détermine l'heure du lever du soleil
@@ -274,21 +267,21 @@
   //Ajuste l'heure des programmes en fonction du lever et du coucher du soleil
   for(byte x = 0; x < nbPrograms; x++){
     //Serial.println(x);Serial.println (programType[x]);
-    if (programType[x] == SR){
+    if (programsE(x) == SR){
       P[x][HEURE] = sunRise[HEURE];
-      P[x][MINUTE] = sunRise[MINUTE] + srmod[x];
+      P[x][MINUTE] = sunRise[MINUTE] + srmodE(x);
       convertDecimalToTime(&P[x][HEURE], &P[x][MINUTE]);
       //Serial.print(" Program ");Serial.print(x);Serial.print(" : ");Serial.print(P[x][HEURE]);Serial.print(" : ");Serial.println(P[x][MINUTE]);
     }
-    else if (programType[x] == CLOCK){
+    else if (programsE(x) == CLOCK){
       P[x][HEURE] = PROGRAM_TIME(x, HEURE);
       P[x][MINUTE] = PROGRAM_TIME(x, MINUTE);
       //Serial.print(" Program ");Serial.print(x);Serial.print(" : ");Serial.print(P[x][HEURE]);Serial.print(" : ");Serial.println(P[x][MINUTE]);
     }

-    else if (programType[x] == SS){
+    else if (programsE(x) == SS){
       P[x][HEURE] = sunSet[HEURE];
-      P[x][MINUTE] = sunSet[MINUTE] + ssmod[x];
+      P[x][MINUTE] = sunSet[MINUTE] + ssmodE(x);
       convertDecimalToTime(&P[x][HEURE], &P[x][MINUTE]);
       //Serial.print(" Program ");Serial.print(x); Serial.print(" : "); Serial.print(P[x][HEURE]);Serial.print(" : ");Serial.println(P[x][MINUTE]);

@@ -313,32 +306,36 @@
 void setTempCible(){
   for (byte x = 0; x < nbPrograms; x++){
     if(program == x+1){
-      tempCible = EEPROM.read(TEMPCIBLE+x);
+      tempCible = targetTempE(x);
       //Serial.println(tempCible);
     }
   }
 }

-void getTemperature(){
+float greenhouseTemperature() {
+  float temp;
   #ifdef DS18B20
     sensors.requestTemperatures();
-    greenhouseTemperature = sensors.getTempCByIndex(0);
-
-    if((greenhouseTemperature < -20.00)||(greenhouseTemperature > 80)){
-      greenhouseTemperature = EEPROM.read(TEMPCIBLE+program-1)+2;
+    temp = sensors.getTempCByIndex(0);
+    if((temp < -20.00)||(temp > 80)){
+      temp = targetTempE(program-1)+2;
+      return temp;
       failedSensor = true;
     }
     else{
+      return temp;
       failedSensor = false;
     }
   #endif
   #ifdef SHT1X
-    greenhouseTemperature = sht1x.readTemperatureC();
-    if((greenhouseTemperature < -20.00)||(greenhouseTemperature > 80)){
-      greenhouseTemperature = EEPROM.read(TEMPCIBLE+program-1)+2;
+    temp = sht1x.readTemperatureC();
+    if((temp < -20.00)||(temp > 80)){
+      temp = targetTempE(program-1)+2;
+      return temp;
       failedSensor = true;
     }
     else{
+      return temp;
       failedSensor = false;
     }
   #endif
@@ -350,6 +347,7 @@
   //Si passe du mode menu au mode controle...
   if (menuPinState == 0) {
     lcdPrintTemp();
+    lcdPrintTempCible();
     lcdPrintTime();
     lcdPrintRollups();
     lcdPrintOutputsStatus();
@@ -357,6 +355,7 @@
   }
   //Séquence normale...
   lcdPrintTemp();
+  lcdPrintTempCible();
   lcdPrintTime();
   lcdPrintRollups();
   lcdPrintOutputsStatus();
@@ -371,17 +370,12 @@
 //Programme de courbe de température
 void startRamping(){
   //Définition des variables locales
-  byte tempCibleE[nbPrograms];
-  unsigned int RAMPING_INTERVAL = EEPROM.read(RAMPING)*60*1000;
-  Serial.println((unsigned long)EEPROM.read(RAMPING)*60*1000);
-  for (byte x = 0; x < nbPrograms; x++){
-    tempCibleE[x] = EEPROM.read(TEMPCIBLE+x);
-  }
+  Serial.println(rampingE());

   //Exécution du programme
   for (byte x = 0; x < nbPrograms; x++){
     if(program == x+1){
-      newTempCible = tempCibleE[x];
+      newTempCible = targetTempE(x);
     }
   }

@@ -389,14 +383,14 @@
     unsigned long rampingCounter = millis();
     Serial.println(rampingCounter);
     Serial.println(rampingCounter - lastCount);
-    if(rampingCounter - lastCount > RAMPING_INTERVAL) {
+    if(rampingCounter - lastCount > rampingE()) {
       lastCount = rampingCounter;
       tempCible += 0.5;
     }
   }
   else if (newTempCible < tempCible){
     unsigned long rampingCounter = millis();
-    if(rampingCounter - lastCount > RAMPING_INTERVAL) {
+    if(rampingCounter - lastCount > rampingE()) {
       lastCount = rampingCounter;
       tempCible -= 0.5;
     }
@@ -411,22 +405,15 @@
   float tempRollup[sizeof(rollups)];         //Température d'activation des rollups (max.2)
   float tempHeater[sizeof(heaters)];         //Température d'activation des fournaises (max.2)
   float tempFan[sizeof(fans)];                //Température d'activation des fans (max.2)
-  //Définition des variables locales
-  byte hystRollups[sizeof(rollups)];
-  byte hystHeater[sizeof(heaters)];
-  byte hystFan[sizeof(fans)];

   for(byte x = 0; x < sizeof(rollups); x++){
-    tempRollup[x] = tempCible + EEPROM.read(RMOD+x) -10;
-    hystRollups[x] = EEPROM.read(RHYST+x);
+    tempRollup[x] = tempCible + rmodE(x);
   }
   for(byte x = 0; x < sizeof(heaters); x++){
-    tempHeater[x] = tempCible + EEPROM.read(HMOD+x)-10;
-    hystHeater[x] = EEPROM.read(HHYST+x);
+    tempHeater[x] = tempCible + hmodE(x);
   }
   for(byte x = 0; x < sizeof(rollups); x++){
-    tempFan[x] = tempCible + EEPROM.read(VMOD+x)-10;
-    hystFan[x] = EEPROM.read(VHYST+x);
+    tempFan[x] = tempCible + vmodE(x);
   }

   //Exécution du programme
@@ -434,9 +421,9 @@
   //Programme d'ouverture/fermeture des rollups
   for(byte x = 0; x < sizeof(rollups); x++){
     if (rollups[x] == true){
-      if (greenhouseTemperature < (tempRollup[x] - hystRollups[x])) {
+      if (greenhouseTemperature() < (tempRollup[x] - rhystE(x))) {
         closeSides(x);
-      } else if (greenhouseTemperature > tempRollup[x]) {
+      } else if (greenhouseTemperature() > tempRollup[x]) {
         openSides(x);
       }
     }
@@ -446,9 +433,9 @@
   for(byte x = 0; x < sizeof(heaters); x++){
     if (heaters[x] == true){

-      if ((greenhouseTemperature < tempHeater[x])&&(incrementCounter[0] == 0)) {
+      if ((greenhouseTemperature() < tempHeater[x])&&(incrementCounter[0] == 0)) {
         digitalWrite(CHAUFFAGE[x], ON);
-      } else if ((greenhouseTemperature > (tempHeater[x] + hystHeater[x]))||(incrementCounter[0] != 0)) {
+      } else if ((greenhouseTemperature() > (tempHeater[x] + hhystE(x)))||(incrementCounter[0] != 0)) {
         digitalWrite(CHAUFFAGE[x], OFF);
       }
     }
@@ -458,18 +445,18 @@
   for(byte x = 0; x < sizeof(fans); x++){
     if (fans[x] == true){
       if (fanSafety[x] == true){
-        if (greenhouseTemperature > tempFan[x]&&(digitalRead(SAFETY_SWITCH[0]) == OFF)){
+        if (greenhouseTemperature() > tempFan[x]&&(digitalRead(SAFETY_SWITCH[0]) == OFF)){
           digitalWrite(FAN[x], ON);
         }
-        else if ((greenhouseTemperature < (tempFan[x] - hystFan[x]))||(digitalRead(SAFETY_SWITCH[0]) == ON)) {
+        else if ((greenhouseTemperature() < (tempFan[x] - vhystE(x)))||(digitalRead(SAFETY_SWITCH[0]) == ON)) {
           digitalWrite(FAN[x], OFF);
         }
       }
       else if (fanSafety[x] == false){
-        if (greenhouseTemperature > tempFan[x]){
+        if (greenhouseTemperature() > tempFan[x]){
           digitalWrite(FAN[x], ON);
         }
-        else if (greenhouseTemperature < (tempFan[x] - hystFan[x])) {
+        else if (greenhouseTemperature() < (tempFan[x] - vhystE(x))) {
           digitalWrite(FAN[x], OFF);
         }
       }
@@ -481,23 +468,20 @@
 //****************    MACROS - AUTRES     **********************
 //**************************************************************

-
-
-
 //Programme d'ouverture des rollup
 void openSides(byte number) {
-  unsigned int pause = EEPROM.read(PAUSE+number) * 1000;
+  unsigned int pause = pauseE(number);

   if (firstOpening[number] == true){
     incrementCounter[number] = 0;
     firstOpening[number] = false;
   }
-  if (incrementCounter[number] < EEPROM.read(INCREMENTS)) {
+  if (incrementCounter[number] < incrementsE(number)) {
   incrementCounter[number] += 1;
     lcd.setCursor(0, 1);
     lcd.print(F("OUVERTURE"));
     digitalWrite(ROLLUP_OPEN[number], ON);
-    delay(EEPROM.read(ROTATION+number) * 1000);
+    delay(rotationE(number));
     digitalWrite(ROLLUP_OPEN[number], OFF);
     lcd.setCursor(0, 1);
     lcd.print(F("R-U:     "));
@@ -510,10 +494,10 @@

 //Programme de fermeture des rollups
 void closeSides(byte number) {
-  unsigned int pause = EEPROM.read(PAUSE+number) * 1000;
+  unsigned int pause = pauseE(number);

   if (firstOpening[number] == true){
-    incrementCounter[number] = EEPROM.read(INCREMENTS+number);
+    incrementCounter[number] = incrementsE(number);
     firstOpening[number] = false;
   }
   if (incrementCounter[number] > 0) {
@@ -521,7 +505,7 @@
     lcd.setCursor(0, 1);
     lcd.print(F("FERMETURE"));
     digitalWrite(ROLLUP_CLOSE[number], ON);
-    delay(EEPROM.read(ROTATION+number) * 1000);
+    delay(rotationE(number));
     digitalWrite(ROLLUP_CLOSE[number], OFF);
     lcd.setCursor(0, 1);
     lcd.print(F("R-U:     "));
@@ -538,14 +522,16 @@
     lcd.setCursor(5, 1); lcd.print(incrementCounter[0]);
  }
 void lcdPrintTemp(){
-    lcd.setCursor(0,0); lcd.print(F("                    "));
+    lcd.setCursor(0,0); lcd.print(F("         "));
     if(failedSensor == false){
-      lcd.setCursor(0,0); lcd.print(F("T:")); lcd.print(greenhouseTemperature); lcd.print(F("C |TC:"));
+      lcd.setCursor(0,0); lcd.print(F("T:")); lcd.print(greenhouseTemperature()); lcd.print(F("C"));
     }
     else{
-      lcd.setCursor(0,0); lcd.print(F("T:")); lcd.print("!!!"); lcd.print(F("("));lcd.print((int)greenhouseTemperature);lcd.print(F(")|TC:"));
-    }
-    lcd.setCursor(13,0); lcd.print(tempCible); lcd.print(F("C"));
+      lcd.setCursor(0,0); lcd.print(F("T:")); lcd.print("!!!"); lcd.print(F("("));lcd.print((int)greenhouseTemperature());lcd.print(F(")"));
+    }
+}
+void lcdPrintTempCible(){
+    lcd.setCursor(9,0);lcd.print("|TC:");lcd.print(tempCible); lcd.print(F("C"));
 }
 void lcdPrintTime(){
     lcd.setCursor(9,1); lcd.print(F("|(P")); lcd.print(program); lcd.print(F(":"));
@@ -559,20 +545,20 @@

   if (fans[0] == true){
       lcd.setCursor(0, 3); lcd.print(F("FAN:"));
-      if (digitalRead(FAN[0]) == OFF) {      lcd.setCursor(5, 3); lcd.print(F("OFF"));    }
-      else if (digitalRead(FAN[0]) == ON) {      lcd.setCursor(5, 3); lcd.print(F("ON "));    }
+      if (digitalRead(FAN[0]) == OFF) {lcd.setCursor(5, 3); lcd.print(F("OFF"));    }
+      else if (digitalRead(FAN[0]) == ON) {lcd.setCursor(5, 3); lcd.print(F("ON "));    }
     }

   if (heaters[0] == true){
     lcd.setCursor(0, 2); lcd.print(F("H1:"));
-    if (digitalRead(CHAUFFAGE[0]) == OFF) {      lcd.setCursor(5, 2); lcd.print(F("OFF |"));    }
-    else if (digitalRead(CHAUFFAGE[0]) == ON) {      lcd.setCursor(5, 2); lcd.print(F("ON  |"));    }
+    if (digitalRead(CHAUFFAGE[0]) == OFF) {lcd.setCursor(5, 2); lcd.print(F("OFF |"));    }
+    else if (digitalRead(CHAUFFAGE[0]) == ON) {lcd.setCursor(5, 2); lcd.print(F("ON  |"));    }
   }

   if (heaters[1] == true){
     lcd.setCursor(11, 2); lcd.print(F("H2:"));
-    if (digitalRead(CHAUFFAGE[1]) == OFF) {      lcd.setCursor(16, 2); lcd.print(F("OFF"));    }
-    else if (digitalRead(CHAUFFAGE[1]) == ON) {      lcd.setCursor(16, 2); lcd.print(F("ON "));    }
+    if (digitalRead(CHAUFFAGE[1]) == OFF) {lcd.setCursor(16, 2); lcd.print(F("OFF"));    }
+    else if (digitalRead(CHAUFFAGE[1]) == ON) {lcd.setCursor(16, 2); lcd.print(F("ON "));    }
   }
 }

@@ -646,7 +632,7 @@
   }
 }

-void Scrollingmenu (int x, const char a[20] PROGMEM, const char b[20] PROGMEM, const char c[20] PROGMEM, const char d[20] PROGMEM, const char e[20] PROGMEM, const char f[20] PROGMEM, const char g[20] PROGMEM, const char h[20] PROGMEM, const char i[20] PROGMEM, const char j[20] PROGMEM, int y) {
+void Scrollingmenu (const char t[6] PROGMEM, int x, const char a[20] PROGMEM, const char b[20] PROGMEM, const char c[20] PROGMEM, const char d[20] PROGMEM, const char e[20] PROGMEM, const char f[20] PROGMEM, const char g[20] PROGMEM, const char h[20] PROGMEM, const char i[20] PROGMEM, const char j[20] PROGMEM, int y) {
   const int numLcdRows = 3;
   byte scrollPos = 0;
   Nbitems = x;
@@ -658,6 +644,7 @@
     scrollPos = 0;
   }
   clearPrintTitle();
+  lcd.setCursor(14,0);lcd.print(t);
   for (byte i = 0; i < numLcdRows; ++i) {
     lcd.setCursor(0, i + 1);
     lcd.print(menuitems[i + scrollPos]);
@@ -666,7 +653,7 @@
   lcd.blink();
 }

-void Scrollingnumbers(int x, int y, int z, int a) {
+void Scrollingnumbers(const char t[6] PROGMEM,int x, int y, int z, int a) {
   const int numLcdRows = 3;
   int scrollPos = 0;
   Nbitems = x;
@@ -677,6 +664,7 @@
     scrollPos = 0;
   }
   clearPrintTitle();
+  lcd.setCursor(14,0);lcd.print(t);
   for (byte i = 0; i < numLcdRows; ++i) {
     lcd.setCursor(0, i + 1);
     if (y < 4) {
@@ -705,45 +693,49 @@

 void displayMenu(int x) {
   switch (x) {
-    case 0: Scrollingmenu(6, "Capteurs", "Date/time", "Rollups", "Ventilation", "Chauffage", "Programmes", "", "", "", "", currentMenuItem); break;
-    case 1: Scrollingmenu(6, "Date", "Time", "SetDOW", "Set date", "Set time", "back", "", "", "", "", currentMenuItem); break;
-
-    case 11: Scrollingmenu(8, "Monday", "Tuesday", "Wednesday", "Thursday", "Friday", "Saturday", "Sunday", "back", "", "", currentMenuItem); break;
-    case 12: Scrollingnumbers(11, currentMenuItem, 2016, 1);  break;
-    case 121: Scrollingnumbers(13, currentMenuItem, 1 , 1);  break;
-    case 1211: Scrollingnumbers(32, currentMenuItem, 1, 1); break;
-    case 13: Scrollingnumbers(25, currentMenuItem, 1, 1); break;
-    case 131: Scrollingnumbers(62, currentMenuItem, 0 , 1); break;
-    case 1311: Scrollingnumbers(62, currentMenuItem, 0, 1); break;
-
-    case 2: Scrollingmenu(4, "Etat", "setProgram", "back", "", "", "", "",  "", "", "", currentMenuItem); break;
-    case 21: Scrollingnumbers((sizeof(rollups)+1), currentMenuItem, 1, 1); break;
-    case 22: Scrollingnumbers((sizeof(rollups)+1), currentMenuItem, 1, 1); break;
-
-    case 23: Scrollingmenu(10, "5", "15", "20", "30", "45", "60", "75", "90", "120", "back", currentMenuItem); break;
-
-    case 3: Scrollingmenu(3, "Etat", "Set hysteresis", "back", "", "", "", "", "", "", "", currentMenuItem); break;
-    case 31: Scrollingnumbers(6, currentMenuItem, 1, 1); break;
-    case 4: Scrollingmenu(5, "(F1)Etat", "(F2)Etat", "(F1)Set hysteresis", "(F2)Set hysteresis", "back", "", "", "", "", "", currentMenuItem); break;
-    case 41: Scrollingnumbers(6, currentMenuItem, 1, 1); break;
-    case 42: Scrollingnumbers(6, currentMenuItem, 1, 1); break;
-    case 5: Scrollingmenu(10, "Programme 1", "Programme 2", "Programme 3", "Modificateurs", "Set Programme 1", "Set Programme 2", "Set Programme 3", "Set Modificateurs", "Set Ramping", "back", currentMenuItem); break;
-    case 51: Scrollingmenu(3, "Set Heure", "Set Temp. cible", "back", "", "", "", "", "", "", "", currentMenuItem); break;
-    case 511: Scrollingnumbers(121, currentMenuItem, -60, 1); break;
-    case 512: Scrollingnumbers(51, currentMenuItem, 0 , 1); break;
-    case 52: Scrollingmenu(3, "Set Heure", "Set Temp. cible", "back", "", "", "", "", "", "", "", currentMenuItem); break;
-    case 521: Scrollingnumbers(25, currentMenuItem, 1, 1); break;
-    case 5211: Scrollingnumbers(62, currentMenuItem, 0, 1); break;
-    case 522: Scrollingnumbers(51, currentMenuItem, 0, 1); break;
-    case 53: Scrollingmenu(3, "Set Heure", "Set Temp. cible", "back", "", "", "", "", "", "", "", currentMenuItem); break;
-    case 531: Scrollingnumbers(121, currentMenuItem, -60, 1); break;
-    case 532: Scrollingnumbers(51, currentMenuItem, 0, 1); break;
-    case 54: Scrollingmenu(5, "Mod. rollups", "Mod. ventilation", "Mod. fournaise1", "Mod. fournaise2", "back", "", "", "", "", "", currentMenuItem); break;
-    case 541: Scrollingnumbers(22, currentMenuItem, -10, 1); break;
-    case 542: Scrollingnumbers(22, currentMenuItem, -10, 1); break;
-    case 543: Scrollingnumbers(22, currentMenuItem, -10, 1); break;
-    case 544: Scrollingnumbers(22, currentMenuItem, -10, 1); break;
-    case 55: Scrollingnumbers(62, currentMenuItem, 0, 1); break;
+    case 0: Scrollingmenu("", 6, "Capteurs", "Date/time", "Rollups", "Ventilation", "Chauffage", "Programmes", "", "", "", "", currentMenuItem); break;
+    case 1: Scrollingmenu("TIME*", 6, "Date", "Time", "SetDOW", "Set date", "Set time", "back", "", "", "", "", currentMenuItem); break;
+
+    case 11: Scrollingmenu("DOW**", 8, "Monday", "Tuesday", "Wednesday", "Thursday", "Friday", "Saturday", "Sunday", "back", "", "", currentMenuItem); break;
+    case 12: Scrollingnumbers("YEAR*",11, currentMenuItem, 2016, 1);  break;
+    case 121: Scrollingnumbers("MONTH", 13, currentMenuItem, 1 , 1);  break;
+    case 1211: Scrollingnumbers("DAY**", 32, currentMenuItem, 1, 1); break;
+    case 13: Scrollingnumbers("HOUR*",25, currentMenuItem, 1, 1); break;
+    case 131: Scrollingnumbers("MIN***",62, currentMenuItem, 0 , 1); break;
+    case 1311: Scrollingnumbers("SEC**",62, currentMenuItem, 0, 1); break;
+
+    case 2: Scrollingmenu("ROLL*", 3, "Parameters", "setParameters", "back", "", "", "", "",  "", "", "", currentMenuItem); break;
+    case 21: Scrollingmenu("ITEM*",(sizeof(rollups)+1),"1", "2", "back", "", "", "", "",  "", "", "", currentMenuItem); break;
+    case 22: Scrollingmenu("ITEM*",(sizeof(rollups)+1),"1", "2", "back", "", "", "", "",  "", "", "", currentMenuItem); break;
+    case 221: Scrollingnumbers("INCR*",11, currentMenuItem, 1, 1); break;
+    case 2211: Scrollingnumbers("ROTA*", 61, currentMenuItem, 2, 2); break;
+    case 22111: Scrollingmenu("PAUSE", 10, "5", "15", "20", "30", "45", "60", "75", "90", "120", "back", currentMenuItem); break;
+    case 221111: Scrollingnumbers("MOD**", 22, currentMenuItem, -10, 1); break;
+    case 2211111: Scrollingnumbers("HYST*", 6, currentMenuItem, 1, 1); break;
+    case 22111111: Scrollingmenu("SAFTY", 3, "Oui", "Non", "back", "", "", "", "",  "", "", "", currentMenuItem); break;
+
+    case 3: Scrollingmenu("FANS*", 3, "Parameters", "setParameters", "back", "", "", "", "",  "", "", "", currentMenuItem); break;
+    case 31: Scrollingmenu("ITEM*",(sizeof(fans)+1),"1", "2", "back", "", "", "", "",  "", "", "", currentMenuItem); break;
+    case 32: Scrollingmenu("ITEM*",(sizeof(fans)+1),"1", "2", "back", "", "", "", "",  "", "", "", currentMenuItem); break;
+    case 321: Scrollingnumbers("MOD**", 22, currentMenuItem, -10, 1); break;
+    case 3211: Scrollingnumbers("HYST*", 6, currentMenuItem, 1, 1); break;
+    case 32111: Scrollingmenu("SAFTY", 3, "Oui", "Non", "back", "", "", "", "",  "", "", "", currentMenuItem); break;
+
+    case 4: Scrollingmenu("HEATR", 3, "Parameters", "setParameters", "back", "", "", "", "",  "", "", "", currentMenuItem); break;
+    case 41: Scrollingmenu("ITEM*",(sizeof(heaters)+1),"1", "2", "back", "", "", "", "",  "", "", "", currentMenuItem);break;
+    case 42: Scrollingmenu("ITEM*",(sizeof(heaters)+1),"1", "2", "back", "", "", "", "",  "", "", "", currentMenuItem);break;
+    case 421: Scrollingnumbers("MOD**", 22, currentMenuItem, -10, 1); break;
+    case 4211: Scrollingnumbers("HYST*", 6, currentMenuItem, 1, 1); break;
+
+    case 5: Scrollingmenu("PROG*", 3, "Timezones", "setTimezones", "back", "", "", "", "",  "", "", "", currentMenuItem); break;
+    case 51: Scrollingnumbers("TIMZ*",(nbPrograms+1),currentMenuItem, 1, 1);break;
+    case 52: Scrollingnumbers("TIMZ*",(nbPrograms+1),currentMenuItem, 1, 1);break;
+    case 521: Scrollingmenu("ITEM*", 3,"SR", "MANUAL", "SS", "", "", "", "",  "", "", "", currentMenuItem);break;
+    case 5211: Scrollingnumbers("HOUR*",25, currentMenuItem, 1, 1); break;
+    case 52111: Scrollingnumbers("MIN***",62, currentMenuItem, 0 , 1); break;
+    case 5212: Scrollingnumbers("MOD***",122, currentMenuItem, -60 , 1); break;
+    case 521111: Scrollingnumbers("TEMP", 42, currentMenuItem, 0, 1);break;
+
   }
 }
 //------------------------SELECT-------------------
@@ -764,23 +756,15 @@
     case 0:
       switch (y) {
         case 1:
-          float temperature;
-          #ifdef DS18B20
-            sensors.requestTemperatures();
-            temperature = sensors.getTempCByIndex(0);
-          #endif
-          #ifdef SHT1X
-              temperature = sht1x.readTemperatureC();
-          #endif
           lcd.noBlink();
           clearPrintTitle();
-          lcd.setCursor(0, 1); lcd.print(F("Sonde temp. : ")); lcd.print(temperature); lcd.print(F("C"));
+          lcd.setCursor(0, 1); lcd.print(F("Sonde temp. : ")); lcd.print(greenhouseTemperature()); lcd.print(F("C"));
           break;
         case 2: switchmenu(1); break;
         case 3: switchmenu(2); break;
         case 4: switchmenu(3); break;
         case 5: switchmenu(4); break;
-        case 6: switchmenu(0); break;
+        case 6: switchmenu(5); break;
       }
       break;
     //-------------------------------SelectMenu1-----------------------------------------
@@ -796,13 +780,7 @@
         case 2:
           lcd.noBlink();
           clearPrintTitle();
-
-          t = rtc.getTime();
-          sunTime[HEURE] = t.hour;
-          sunTime[MINUTE] = t.min;
-          sunTime[0] = t.sec;
-          myLord.DST(sunTime);
-
+          getDateAndTime();
           lcd.setCursor(0, 1); lcd.print(F("Time : ")); lcdPrintDigits(sunTime[HEURE]);lcd.print(":"); lcdPrintDigits(sunTime[MINUTE]);lcd.print(":");lcdPrintDigits(sunTime[MINUTE]);
           break;
         case 3: switchmenu(11); break;
@@ -909,26 +887,25 @@
           switchmenu(21); break;
         case 2:
           switchmenu(22); break;
-        case 3: switchmenu(23); break;
-        case 4: switchmenu(0); break;
+        case 3: switchmenu(0); break;
       }
       break;
     //-------------------------------SelectMenu21-----------------------------------------
-    //ETAT DES ROLLUPS
+    //PROGRAMMES DES ROLLUPS
     case 21 :
       if (y < Nbitems) {
         switch(y){
           case 1 :
           lcd.noBlink();
           clearPrintTitle();
-          lcd.setCursor(0, 1); lcd.print(F("Increment: ")); lcd.print(incrementCounter[0]); lcd.print(F(""));
-          lcd.setCursor(0, 2); lcd.print(F("TP: ")); lcd.print(EEPROM.read(PAUSE)); lcd.print(F("s")); lcd.setCursor(8,2);lcd.print(F("| TR: ")); lcd.print(EEPROM.read(ROTATION)); lcd.print(F("s"));
-          lcd.setCursor(0, 3); lcd.print(F("H: ")); lcd.print(EEPROM.read(RHYST)); lcd.print(F("C")); lcd.setCursor(8,3);lcd.print(F("| TA: ")); lcd.print(tempCible + byteToNegative(EEPROM.read(RMOD), 10));lcd.print("C");
+          lcd.setCursor(0, 1); lcd.print(F("Increments: ")); lcd.print(incrementsE(0)); lcd.print(F(""));
+          lcd.setCursor(0, 2); lcd.print(F("TP: ")); lcd.print(pauseE(0)/1000); lcd.print(F("s")); lcd.setCursor(8,2);lcd.print(F("| TR: ")); lcd.print(rotationE(0)/1000); lcd.print(F("s"));
+          lcd.setCursor(0, 3); lcd.print(F("H: ")); lcd.print(rhystE(0)); lcd.print(F("C")); lcd.setCursor(8,3);lcd.print(F("| TA: ")); lcd.print(tempCible + rmodE(0));lcd.print("C");
           break;
           case 2 :
-          lcd.setCursor(0, 1); lcd.print(F("Increment: ")); lcd.print(incrementCounter[1]); lcd.print(F("%"));
-          lcd.setCursor(0, 2); lcd.print(F("TP: ")); lcd.print(EEPROM.read(PAUSE+1)); lcd.print(F("s")); lcd.setCursor(8,2);lcd.print(F("| TR:")); lcd.print(EEPROM.read(ROTATION+1)); lcd.print(F("s"));
-          lcd.setCursor(0, 3); lcd.print(F("H: ")); lcd.print(EEPROM.read(RHYST+1)); lcd.print(F("C")); lcd.setCursor(8,3);lcd.print(F("| TA: ")); lcd.print(tempCible - byteToNegative(EEPROM.read(RMOD+1), 10));lcd.print("C");
+          lcd.setCursor(0, 1); lcd.print(F("Increment: ")); lcd.print(incrementsE(1)); lcd.print(F("%"));
+          lcd.setCursor(0, 2); lcd.print(F("TP: ")); lcd.print(pauseE(1)/1000); lcd.print(F("s")); lcd.setCursor(8,2);lcd.print(F("| TR:")); lcd.print(rotationE(1)/1000); lcd.print(F("s"));
+          lcd.setCursor(0, 3); lcd.print(F("H: ")); lcd.print(rhystE(1)); lcd.print(F("C")); lcd.setCursor(8,3);lcd.print(F("| TA: ")); lcd.print(tempCible - rmodE(1));lcd.print("C");
           break;
         }
       }
@@ -937,340 +914,398 @@
       }
       break;
     //-------------------------------SelectMenu22-----------------------------------------
+    //SET ROLLUP PROGRAM
+    case 22 :
+      if (y < Nbitems) {
+        nr = y;
+        switchmenu(221);
+      }
+      else {
+        switchmenu(2);
+      }
+      break;
+    //-------------------------------SelectMenu221-----------------------------------------
+    //SET INCREMENTS
+    case 221 :
+      if (y < Nbitems) {
+        inc = y;
+        switchmenu(2211);
+      }
+      else {
+        switchmenu(2);
+      }
+      break;
+    //-------------------------------SelectMenu2211-----------------------------------------
     //SET ROTATION TIME
-    case 22 :
-      if (y < Nbitems) {
-        //rotation = y;
-        EEPROM.update(ROTATION, y);
+    case 2211 :
+      if (y < Nbitems) {
+        rot = y*2;
+        switchmenu(22111);
+      }
+      else {
         switchmenu(2);
       }
-      else {
-        switchmenu(2);
-      }
-      break;
-    //-------------------------------SelectMenu23-----------------------------------------
-    //"5", "15", "20", "30", "45", "60", "75", "90", "120", "back"
-    case 23 :
-      int pause;
-      switch (y) {
-        case 1: pause = 5; switchmenu(2); EEPROM.write(PAUSE, pause);break;
-        case 2: pause = 15; switchmenu(2); EEPROM.write(PAUSE, pause); break;
-        case 3: pause = 20; switchmenu(2); EEPROM.write(PAUSE, pause); break;
-        case 4: pause = 30; switchmenu(2); EEPROM.write(PAUSE, pause); break;
-        case 5: pause = 45; switchmenu(2); EEPROM.write(PAUSE, pause); break;
-        case 6: pause = 60; switchmenu(2); EEPROM.write(PAUSE, pause); break;
-        case 7: pause = 75; switchmenu(2); EEPROM.write(PAUSE, pause); break;
-        case 8: pause = 90; switchmenu(2); EEPROM.write(PAUSE, pause); break;
-        case 9: pause = 120; switchmenu(2); EEPROM.write(PAUSE, pause); break;
-        case 10: switchmenu(2); break;
-      }
-      break;
-
-    //-------------------------------SelectMenu3-----------------------------------------
-    case 3 :
-      switch (y) {
-        case 1:
+      break;
+      //-------------------------------SelectMenu22111-----------------------------------------
+      //SET PAUSE TIME
+      case 22111 :
+        switch (y) {
+          case 1: p = 5; switchmenu(221111);break;
+          case 2: p = 15; switchmenu(221111); break;
+          case 3: p = 20; switchmenu(221111); break;
+          case 4: p = 30; switchmenu(221111); break;
+          case 5: p = 45; switchmenu(221111); break;
+          case 6: p = 60; switchmenu(221111); break;
+          case 7: p = 75; switchmenu(221111); break;
+          case 8: p = 90; switchmenu(221111); break;
+          case 9: p = 120; switchmenu(221111); break;
+          case 10: switchmenu(2); break;
+          }
+        break;
+      //-------------------------------SelectMenu221111-----------------------------------------
+      //SET MODIFICATOR
+      case 221111 :
+        if (y < Nbitems) {
+          mod = y-11;
+          switchmenu(2211111);
+        }
+        else {
+          switchmenu(2);
+        }
+      break;
+      //-------------------------------SelectMenu221111-----------------------------------------
+      //SET HYSTERESIS
+      case 2211111 :
+        if (y < Nbitems) {
+          hys = y;
+          switchmenu(22111111);
+        }
+        else {
+          switchmenu(2);
+        }
+      break;
+      //-------------------------------SelectMenu221111-----------------------------------------
+      //SET SAFETY AND UPDATE EEPROM
+      case 22111111 :
+        switch (y){
+          case 1: sfty = true;defineRollup(nr,inc,rot,p,mod,hys,sfty); switchmenu(2);break;
+          case 2: sfty = false;defineRollup(nr,inc,rot,p,mod,hys,sfty); switchmenu(2);break;
+          case 3: switchmenu(2);break;
+        }
+      break;
+    //-------------------------------SelectMenu31-----------------------------------------
+  /*  case 3: Scrollingmenu("FANS*", 3, "Program", "setProgram", "back", "", "", "", "",  "", "", "", currentMenuItem); break;
+    case 31: Scrollingnumbers("#****",(sizeof(fans)+1), currentMenuItem, 1, 1); break;
+    case 32: Scrollingnumbers("#****", (sizeof(fans)+1), currentMenuItem, 1, 1); break;
+    case 321: Scrollingnumbers("MOD**", 22, currentMenuItem, -10, 1); break;
+    case 3211: Scrollingnumbers("HYST*", 6, currentMenuItem, 1, 1); break;
+    case 32111: Scrollingmenu("SAFTY", 3, "Oui", "Non", "back", "", "", "", "",  "", "", "", currentMenuItem); break;
+*/
+
+//-------------------------------SelectMenu3-----------------------------------------
+//État, setProgram
+case 3 :
+  switch (y) {
+    case 1:
+      switchmenu(31); break;
+    case 2:
+      if (sizeof(rollups) == 2){switchmenu(32);}
+      else{switchmenu(0);}
+      break;
+    case 3: switchmenu(0); break;
+  }
+break;
+
+//-------------------------------SelectMenu31-----------------------------------------
+    //PROGRAMME DES FANS
+    case 31 :
+      if (y < Nbitems) {
+        switch(y){
+          case 1 :
           lcd.noBlink();
           clearPrintTitle();
-          lcd.setCursor(0, 1); lcd.print(F("FAN : "));
-          if (digitalRead(FAN[0]) == OFF) {
-            lcd.print(F("OFF"));
-          }
-          else {
-            lcd.print(F("ON"));
-          }
-          lcd.setCursor(0, 2); lcd.print(F("Temp. cible : ")); lcd.print(tempCible+EEPROM.read(VMOD)-10); lcd.print(F("C"));
-          lcd.setCursor(0, 3); lcd.print(F("Hysteresis : ")); lcd.print(EEPROM.read(VHYST)); lcd.print(F("C"));
+          lcd.setCursor(0, 1); lcd.print(F("TA: ")); lcd.print(tempCible + vmodE(0)); lcd.print("C");
+          lcd.setCursor(0, 2); lcd.print(F("H: ")); lcd.print(rhystE(0)); lcd.print(F("C"));
+          lcd.setCursor(0, 3); lcd.print(F("SAFETY: ")); if(fanSafetyE(0)== true){lcd.print(F("Activated"));}else{lcd.print(F("Deactivated"));}
           break;
-        case 2: switchmenu(31); break;
-        case 3: switchmenu(0); break;
-      }
-      break;
-    //-------------------------------SelectMenu31-----------------------------------------
+          case 2 :
+          lcd.setCursor(0, 1); lcd.print(F("TA: ")); lcd.print(tempCible + vmodE(1)); lcd.print("C");
+          lcd.setCursor(0, 2); lcd.print(F("H: ")); lcd.print(rhystE(1)); lcd.print(F("C"));
+          lcd.setCursor(0, 3); lcd.print(F("SAFETY: ")); if(fanSafetyE(1)== true){lcd.print(F("Activated"));}else{lcd.print(F("Deactivated"));}
+          break;
+        }
+      }
+      else {
+        switchmenu(3);
+      }
+      break;
+    //-------------------------------SelectMenu32-----------------------------------------
+    //SET FAN PROGRAM
+    case 32 :
+      if (y < Nbitems) {
+        nr = y;
+        switchmenu(321);
+      }
+      else {
+        switchmenu(3);
+      }
+      break;
+    //-------------------------------SelectMenu321-----------------------------------------
+    //SET MOD
+    case 321 :
+      if (y < Nbitems) {
+        mod = y-11;
+        switchmenu(3211);
+      }
+      else {
+        switchmenu(2);
+      }
+      break;
+    //-------------------------------SelectMenu3211-----------------------------------------
     //SET HYSTERESIS
-    case 31 :
-      if (y < Nbitems) {
-        switchmenu(3);
-        EEPROM.write(1, y);
-      }
-      else {
-        switchmenu(3);
-      }
-      break;
-    //-------------------------------SelectMenu4-----------------------------------------
-    case 4 :
-      switch (y) {
-        case 1:
+    case 3211 :
+      if (y < Nbitems) {
+        hys = y;
+        switchmenu(32111);
+      }
+      else {
+        switchmenu(2);
+      }
+      break;
+      //-------------------------------SelectMenu321111-----------------------------------------
+      //SET SAFETY AND UPDATE EEPROM
+      case 32111 :
+        switch (y){
+          case 1: sfty = true;defineFan(nr,mod,hys,sfty); switchmenu(3);break;
+          case 2: sfty = false;defineFan(nr,mod,hys,sfty); switchmenu(3);break;
+          case 3: switchmenu(3);break;
+        }
+      break;
+
+/*  case 4: Scrollingmenu("HEATR", 3, "Program", "setProgram", "back", "", "", "", "",  "", "", "", currentMenuItem); break;
+    case 41: Scrollingnumbers("ITEM*",(sizeof(fans)+1), currentMenuItem, 1, 1); break;
+    case 42: Scrollingnumbers("ITEM*", (sizeof(fans)+1), currentMenuItem, 1, 1); break;
+    case 421: Scrollingnumbers("MOD**", 22, currentMenuItem, -10, 1); break;
+    case 4211: Scrollingnumbers("HYST*", 6, currentMenuItem, 1, 1); break;
+*/
+
+//-------------------------------SelectMenu4-----------------------------------------
+//État, setProgram
+case 4 :
+  switch (y) {
+    case 1:
+      switchmenu(41); break;
+    case 2:
+      if (sizeof(fans) == 2){switchmenu(42);}
+      else{switchmenu(0);}
+      break;
+    case 3: switchmenu(0); break;
+  }
+break;
+
+//-------------------------------SelectMenu41-----------------------------------------
+    //PROGRAMME DES CHAUFFERETTES
+    case 41 :
+      if (y < Nbitems) {
+        switch(y){
+          case 1 :
           lcd.noBlink();
           clearPrintTitle();
-          lcd.setCursor(0, 1); lcd.print(F("FOURNAISE(1) : "));
-          if (digitalRead(CHAUFFAGE[0]) == OFF) {
-            lcd.print(F("OFF"));
-          }
-          else {
-            lcd.print(F("ON"));
-          }
-          lcd.setCursor(0, 2); lcd.print(F("Temp. cible : ")); lcd.print(tempCible+EEPROM.read(HMOD)-10); lcd.print(F("C"));
-          lcd.setCursor(0, 3); lcd.print(F("Hysteresis : ")); lcd.print(EEPROM.read(HHYST)); lcd.print(F("C"));
+          lcd.setCursor(0, 1); lcd.print(F("TA: ")); lcd.print(tempCible + hmodE(0)); lcd.print("C");
+          lcd.setCursor(0, 2); lcd.print(F("H: ")); lcd.print(hhystE(0)); lcd.print(F("C"));
           break;
-        case 2:
+          case 2 :
+          lcd.setCursor(0, 1); lcd.print(F("TA: ")); lcd.print(tempCible + hmodE(1)); lcd.print("C");
+          lcd.setCursor(0, 2); lcd.print(F("H: ")); lcd.print(hhystE(1)); lcd.print(F("C"));
+          break;
+        }
+      }
+      else {
+        switchmenu(4);
+      }
+      break;
+    //-------------------------------SelectMenu42-----------------------------------------
+    //SET CHAUFFERETTES PROGRAM
+    case 42 :
+      if (y < Nbitems) {
+        nr = y;
+        switchmenu(421);
+      }
+      else {
+        switchmenu(4);
+      }
+      break;
+    //-------------------------------SelectMenu421-----------------------------------------
+    //SET MOD
+    case 421 :
+      if (y < Nbitems) {
+        mod = y-11;
+        switchmenu(4211);
+      }
+      else {
+        switchmenu(4);
+      }
+      break;
+    //-------------------------------SelectMenu4211-----------------------------------------
+    //SET HYSTERESIS
+    case 4211 :
+      if (y < Nbitems) {
+        hys = y;
+        defineHeater(nr,mod,hys);
+        switchmenu(4);
+      }
+      else {
+        switchmenu(4);
+      }
+      break;
+      /*
+      case 5: Scrollingmenu("PROG*", 3, "Timezones", "setTimezones", "back", "", "", "", "",  "", "", "", currentMenuItem); break;
+      case 51: Scrollingnumbers("TIMZ*",(sizeof(nbPrograms)+1),currentMenuItem, 1, 1);break;
+      case 52: Scrollingnumbers("TIMZ*",(sizeof(nbPrograms)+1),currentMenuItem, 1, 1);break;
+      case 521: Scrollingmenu("ITEM*", 3,"SR", "MANUAL", "SS", "", "", "", "",  "", "", "", currentMenuItem);break;
+      case 5211: Scrollingnumbers("HOUR*",25, currentMenuItem, 1, 1); break;
+      case 52111: Scrollingnumbers("MIN***",62, currentMenuItem, 0 , 1); break;
+      case 5212: Scrollingnumbers("MOD***",122, currentMenuItem, -60 , 1); break;
+      case 521111: Scrollingnumbers("TEMP", 42, currentMenuItem, 0, 1);break;
+*/
+      //-------------------------------SelectMenu5-----------------------------------------
+      //État, setProgram
+      case 5 :
+        switch (y) {
+          case 1:
+            switchmenu(51); break;
+          case 2:
+            if (sizeof(nbPrograms) >= 2){switchmenu(52);}
+            else{switchmenu(0);}
+            break;
+          case 3:
+            if (sizeof(nbPrograms) >= 3){switchmenu(52);}
+            else{switchmenu(0);}
+            break;
+          case 4:
+            if (sizeof(nbPrograms) >= 4){switchmenu(52);}
+            else{switchmenu(0);}
+            break;
+          case 5:
+            if (sizeof(nbPrograms) >= 5){switchmenu(52);}
+            else{switchmenu(0);}
+            break;
+          case 6: switchmenu(0); break;
+        }
+      break;
+
+      //-------------------------------SelectMenu41-----------------------------------------
+    //PROGRAMME DES TIMEZONES
+    case 51 :
+        switch(y){
+          case 1 :
           lcd.noBlink();
           clearPrintTitle();
-          lcd.setCursor(0, 1); lcd.print(F("FOURNAISE(2) : "));
-          if (digitalRead(CHAUFFAGE[1]) == OFF) {
-            lcd.print(F("OFF"));
-          }
-          else {
-            lcd.print(F("ON"));
-          }
-          lcd.setCursor(0, 2); lcd.print(F("Temp. cible : ")); lcd.print(tempCible+EEPROM.read(HMOD+1)-10); lcd.print(F("C"));
-          lcd.setCursor(0, 3); lcd.print(F("Hysteresis : ")); lcd.print(EEPROM.read(HHYST+1)); lcd.print(F("C"));
+          lcd.setCursor(0, 1);
+          lcd.setCursor(0, 2);
           break;
-        case 3: switchmenu(41); break;
-        case 4: switchmenu(42); break;
-        case 5: switchmenu(0); break;
-      }
-      break;
-    //-------------------------------SelectMenu41-----------------------------------------
-    //SET HYSTERESIS
-    case 41 :
-      if (y < Nbitems) {
-        switchmenu(4);
-        EEPROM.update(HHYST, y);
-      }
-      else {
-        switchmenu(4);
-      }
-      break;
-    //-------------------------------SelectMenu42-----------------------------------------
-    //SET HYSTERESIS
-    case 42 :
-      if (y < Nbitems) {
-        switchmenu(4);
-        EEPROM.write(HHYST+1, y);
-      }
-      else {
-        switchmenu(4);
-      }
-      break;
-    //-------------------------------SelectMenu5-----------------------------------------
-    //"Programme 1", "Programme 2", "Programme 3", "Modificateurs" "Set Programme 1", "Set Programme 2", "Set Programme 3", "Set Modificateurs", "back"
-    case 5 :/*
-      switch (y) {
-        case 1:
+          case 2 :
           lcd.noBlink();
           clearPrintTitle();
-          lcd.setCursor(0, 1); lcd.print(F("HD: ")); lcd.print(P[0][HEURE]); lcd.print(F(":")); lcd.print(P[0][MINUTE]); lcd.print(F(" | HF: ")); lcd.print(P[1][HEURE]); lcd.print(F(":")); lcd.print(P[1][MINUTE]);
-          //lcd.setCursor(0, 2); lcd.print(F("TEMP.CIBLE : ")); lcd.print(tempCibleE[0]); lcd.print(F("C"));
-          //lcd.setCursor(0,3); lcd.print(F("RAMPING : "));  lcd.print(ramping); lcd.print(F(" min"));
-          break;
-        case 2:
+          lcd.setCursor(0, 1);
+          lcd.setCursor(0, 2);
+          case 3 :
           lcd.noBlink();
           clearPrintTitle();
-          lcd.setCursor(0, 1); lcd.print(F("HD: ")); lcd.print(P[1][HEURE]); lcd.print(F(":")); lcd.print(P[1][MINUTE]); lcd.print(F(" | HF: ")); lcd.print(P[2][HEURE]); lcd.print(F(":")); lcd.print(P[2][HEURE]);
-          //lcd.setCursor(0, 2); lcd.print(F("TEMP.CIBLE : ")); lcd.print(tempCibleE[1]); lcd.print(F("C"));
-          //lcd.setCursor(0,3); lcd.print(F("RAMPING : "));  lcd.print(RAMPING); lcd.print(F(" min"));
-          break;
-        case 3:
+          lcd.setCursor(0, 1);
+          lcd.setCursor(0, 2);
+          case 4 :
           lcd.noBlink();
           clearPrintTitle();
-          lcd.setCursor(0, 1); lcd.print(F("HD: ")); lcd.print(P[2][HEURE]); lcd.print(F(":")); lcd.print(P[2][HEURE]); lcd.print(F(" | HF: ")); lcd.print(P[0][HEURE]); lcd.print(F(":")); lcd.print(P[0][MINUTE]);
-          //lcd.setCursor(0, 2); lcd.print(F("TEMP.CIBLE : ")); lcd.print(tempCibleE[2]); lcd.print(F("C"));
-          //lcd.setCursor(0,3); lcd.print(F("RAMPING : "));  lcd.print(RAMPING); lcd.print(F(" min"));
-          break;
-        case 4:
+          lcd.setCursor(0, 1);
+          lcd.setCursor(0, 2);
+          case 5 :
           lcd.noBlink();
           clearPrintTitle();
-          lcd.setCursor(0, 1); lcd.print(F("TEMP.CIBLE : ")); lcd.print(tempCible);
-          lcd.setCursor(0, 2); lcd.print(F("RMod:")); lcd.print(EEPROM.read(RMOD)-11);
-          lcd.setCursor(8, 2); lcd.print(F("| HMOD[0]:")); lcd.print(EEPROM.read(HMOD)-11);
-          lcd.setCursor(0, 3); lcd.print(F("VMOD[0]:")); lcd.print(EEPROM.read(VMOD)-11);
-          lcd.setCursor(8, 3); lcd.print(F("| HMOD[1]:")); lcd.print(EEPROM.read(HMOD+1)-11);
+          lcd.setCursor(0, 1);
+          lcd.setCursor(0, 2);
           break;
-        case 5: switchmenu(51); break;
-        case 6: switchmenu(52); break;
-        case 7: switchmenu(53); break;
-        case 8: switchmenu(54); break;
-        case 9: switchmenu(55); break;
-        case 10: switchmenu(0); break;
-      }*/
-      break;
-    //-------------------------------SelectMenu51-----------------------------------------
-    case 51:
-      switch (y) {
-        case 1: switchmenu(511);break;
-        case 2: switchmenu(512); break;
-        case 3: switchmenu(5); break;
-      }
-      break;
-    //-------------------------------SelectMenu511-----------------------------------------
-    //SET MINUTES PAST/BEFORE SUNRISE
-    case 511 :
-      if (y < Nbitems) {
-        EEPROM.write(SSMOD, y);
-        switchmenu(51);
-      }
-      else {
-        switchmenu(51);
-      }
-      break;
-    //-------------------------------SelectMenu512-----------------------------------------
-    //SET tempCible
-    case 512 :
-      if (y < Nbitems) {
-        //tempCibleE[0] = y-1;
-        switchmenu(51);
-        //EEPROM.write(TEMP_CIBLEE, y-1);
-      }
-      else {
-        switchmenu(51);
-      }
+          case 6 :
+          switchmenu(5);
+          break;
+        }
       break;
     //-------------------------------SelectMenu52-----------------------------------------
-    case 52:
-      switch (y) {
-        case 1: switchmenu(521);break;
-        case 2: switchmenu(522); break;
-        case 3: switchmenu(5); break;
+    //SET TIMEZONES PROGRAM
+    case 52 :
+      if (y < Nbitems) {
+        nr = y;
+        switchmenu(521);
+      }
+      else {
+        switchmenu(5);
       }
       break;
     //-------------------------------SelectMenu521-----------------------------------------
+    //SET TYPE
+    case 521 :
+      switch(y){
+        case 1:typ = SR;switchmenu(5212);break;
+        case 2:typ = CLOCK;switchmenu(5211);break;
+        case 3:typ = SS;switchmenu(5212);break;
+        case 4:switchmenu(5);break;
+      }
+      break;
+    //-------------------------------SelectMenu5211-----------------------------------------
     //SET HOUR
-    case 521 :
-      if (y < Nbitems) {
-        //P[1][HEURE] = y;
-        switchmenu(5211);
-        //EEPROM.write(7, P[1][HEURE]);
-      }
-      else {
-        switchmenu(52);
-      }
-      break;
-    //-------------------------------SelectMenu5211-----------------------------------------
+    case 5211 :
+      t = rtc.getTime();
+      sunTime[HEURE] = t.hour;
+      myLord.DST(sunTime);
+        if ((t.hour != sunTime[HEURE]) && (y < Nbitems)) {
+        hr = y-1;
+        switchmenu(52111);
+      }
+      else if ((t.hour == sunTime[HEURE]) && (y < Nbitems)) {
+        hr = y;
+        switchmenu(52111);
+      }
+      else{
+        switchmenu(5);
+      }
+      break;
+    //-------------------------------SelectMenu52111-----------------------------------------
     //SET MINUTES
-    case 5211 :
-      if (y < Nbitems) {
-        //P[1][MINUTE] = (y - 1);
-        switchmenu(52);
-        //EEPROM.write(8, P[1][MINUTE]);
-      }
-      else {
-        switchmenu(52);
-      }
-      break;
-    //-------------------------------SelectMenu522-----------------------------------------
-    //SET tempCible
-    case 522 :
-      if (y < Nbitems) {
-        //tempCibleE[1] = y-1;
-        switchmenu(52);
-        //EEPROM.write(9, tempCibleE[1]);
-      }
-      else {
-        switchmenu(52);
-      }
-      break;
-    //-------------------------------SelectMenu53-----------------------------------------
-    //"Heure", "Tempcible", "back"
-    case 53:
-      switch (y) {
-        case 1: switchmenu(531); break;
-        case 2: switchmenu(532); break;
-        case 3: switchmenu(5); break;
-      }
-      break;
-    //-------------------------------SelectMenu531-----------------------------------------
-    //SET MINUTES PAST/BEFORE SUNSET
-    case 531 :
-      if (y < Nbitems) {
-        //SSMOD[0] = y;
-        //EEPROM.write(10, SSMOD[0]);
-        switchmenu(53);
-      }
-      else {
-        switchmenu(53);
-      }
-      break;
-    //-------------------------------SelectMenu532-----------------------------------------
-    //SET tempCible
-    case 532 :
-      if (y < Nbitems) {
-        //tempCibleE[2] = y-1;
-        switchmenu(53);
-        //EEPROM.write(12, tempCibleE[2]);
-      }
-      else {
-        switchmenu(53);
-      }
-      break;
-    //-------------------------------SelectMenu54-----------------------------------------
-    //
-    case 54:
-      switch (y) {
-        case 1: switchmenu(541); break;
-        case 2: switchmenu(542); break;
-        case 3: switchmenu(543); break;
-        case 4: switchmenu(544); break;
-        case 5: switchmenu(5); break;
-      }
-      break;
-    //-------------------------------SelectMenu541-----------------------------------------
+    case 52111 :
+      if (y < Nbitems) {
+        mn = y - 1;
+        switchmenu(1311);
+      }
+      else {
+        switchmenu(5);
+      }
+      break;
+    //-------------------------------SelectMenu5212-----------------------------------------
     //SET MOD
-    case 541 :
-      if (y < Nbitems) {
-        //tempRollup = tempCible + y -11;
-        switchmenu(54);
-        EEPROM.write(15, y);
-      }
-      else {
-        switchmenu(54);
-      }
-      break;
-    //-------------------------------SelectMenu541-----------------------------------------
-    //SET MOD
-    case 542 :
-      if (y < Nbitems) {
-        switchmenu(54);
-        EEPROM.write(16, y);
-      }
-      else {
-        switchmenu(54);
-      }
-      break;
-    //-------------------------------SelectMenu541-----------------------------------------
-    //SET MOD
-    case 543 :
-      if (y < Nbitems) {
-        switchmenu(54);
-        EEPROM.write(17, y);
-      }
-      else {
-        switchmenu(54);
-      }
-      break;
-    //-------------------------------SelectMenu541-----------------------------------------
-    //SET MOD
-    case 544 :
-      if (y < Nbitems) {
-        switchmenu(54);
-        EEPROM.write(18, y);
-      }
-      else {
-        switchmenu(54);
-      }
-      break;//-------------------------------SelectMenu541-----------------------------------------
-    //SET ramping interval
-    case 55:/*
-    if (y < Nbitems) {
-        RAMPING = y-1;
-        EEPROM.read(RAMPING)*60*1000 = ((unsigned long)y-1)*60*1000;
-        EEPROM.write(19, RAMPING);
+    case 5212 :
+      if (y < Nbitems) {
+        mod = y-60;
+        switchmenu(52111);
+      }
+      else {
         switchmenu(5);
       }
+    break;
+    //-------------------------------SelectMenu521111-----------------------------------------
+    //SET TEMP CIBLE AND UPDATE EEPROM
+    case 521111 :
+      if (y < Nbitems) {
+        tt = y-1;
+        if (typ == CLOCK){
+          defineProgram(nr,typ,hr,mn,tt);
+        }
+        else{
+          defineProgram(nr,typ,0,mod,tt);
+        }
+      }
       else {
         switchmenu(5);
-      }*/
-      break;
-  }
-
-}
+      }
+      break;
+    }
+  }


Clean up wifi template

Clean up wifi template

--- create/files/Wifi.ino
+++ create/files/Wifi.ino
@@ -9,23 +9,23 @@

 void setup() {
   Serial.begin(115200);
+
   WiFi.begin(WIFI_SSID, WIFI_PASSWORD);
-
   while (WiFi.status() != WL_CONNECTED) {
     delay(500);
     Serial.print(".");
   }
-
   Serial.println(WiFi.localIP());

   app.use(staticFiles());
+
   server.begin();
 }

-void loop(){
+void loop() {
   WiFiClient client = server.available();

   if (client.connected()) {
     app.process(&client);
   }
-}
+}


Fixed redeclaration of variables

Fixed redeclaration of variables

--- frontdesk/frontdesk.ino
+++ frontdesk/frontdesk.ino
@@ -10,11 +10,6 @@
 unsigned char readData[bufferSize];

 volatile char characterRead[bufferSize];
-const char COMMAND_GET_TIME = '1';
-const char COMMAND_RESET_TIME = '2';
-const char COMMAND_REGISTER = '3';
-const unsigned char END_CHAR = 0x00;
-
 volatile int id = 0;

 void setup() {


distance: use haversine formula

distance: use haversine formula

--- src/src.ino
+++ src/src.ino
@@ -18,6 +18,12 @@
   {"Home", {45.022884, -93.244983}},
   {"Work", {44.989136, -93.250454}},
 };
+
+// For calculating distance
+// Earth's radius, in mi
+const double EARTH_RADIUS = 3959;
+// Radians per degree
+const double RADS_PER_DEG = 2 * 3.14159 / 360;

 // Updated by on_new_gps
 // Location
@@ -41,9 +47,15 @@
 // Change current_dest to change the distance and eta
 Location current_dest = dests[0].loc;

-// Assumes flat world - error: ~1km @ 1000km
+// Uses Haversine formula
+// http://www.movable-type.co.uk/scripts/gis-faq-5.1.html
+// http://andrew.hedges.name/experiments/haversine/
 double distance(Location from, Location to) {
-  return sqrt(pow(from.lat - to.lat, 2) + pow(from.lng - to.lng, 2));
+  double dlat = (to.lat - from.lat) * RADS_PER_DEG;
+  double dlng = (to.lng - from.lng) * RADS_PER_DEG;
+  double a = pow(sin(dlat/2), 2) + cos(from.lat) * cos(to.lat) * pow(sin(dlng/2), 2);
+  double c = 2 * atan2(sqrt(a), sqrt(1-a));
+  return EARTH_RADIUS * c;
 }

 // Stores a value for the sliding window average


Avoid compiler warning in status code declaration.

This reduces the number of `warning: deprecated conversion from string
constant to 'char*'` warnings by 1. It does, unfortunately, increase the
sketch size from 30,080 to 30,108 when compiled using Arduino 1.0.1.

--- printer.ino
+++ printer.ino
@@ -187,7 +187,7 @@
       while(client.available()) {
         if (parsingHeader) {
           client.find("HTTP/1.1 ");
-          char *statusCode = "xxx";
+          char statusCode[] = "xxx";
           client.readBytes(statusCode, 3);
           statusOk = (strcmp(statusCode, "200") == 0);
           client.find("Content-Length: ");


Explain the purpose of the infinite loop.

--- printer.ino
+++ printer.ino
@@ -266,6 +266,7 @@
 inline void terminalError(unsigned int times) {
   flashErrorLEDs(times, 500);
   digitalWrite(errorLED, HIGH);
+  // no point in carrying on, so do nothing forevermore:
   while(true);
 }


Bump the sketch version.

Bump the sketch version.

--- printer.ino
+++ printer.ino
@@ -39,7 +39,7 @@

 // -- Everything below here can be left alone

-const char* sketchVersion = "1.0.2";
+const char* sketchVersion = "1.0.3";

 // -- Debugging


Fix problem with crazy large durations..

If the connection to printer.gofreerange.com times out (after about 33
seconds) then we try to report the duration of the request.
Unfortunately, this relies on `start` being assigned a sensible value,
which was only happening after a successful connection.  Prior to this fix,
when the connection timed out, the duration would be reported as a very
large number like 4289767837.

This commit also removes the (in hindsight, obvious) compiler warning,
`printer.cpp:176: warning: 'start' may be used uninitialized in this
function`.

--- printer.ino
+++ printer.ino
@@ -158,7 +158,7 @@
   statusOk = false;

 #ifdef DEBUG
-    unsigned long start;
+  unsigned long start = millis();
 #endif

   if (SD.exists(cacheFilename)) {
@@ -183,10 +183,6 @@
     client.print("X-Printer-Version: "); client.println(sketchVersion);
     client.println();
     boolean parsingHeader = true;
-
-#ifdef DEBUG
-    start = millis();
-#endif

     while(client.connected()) {
       debug("Still connected");


Remove unnecessary DU_SEQ_Values struct.

--- examples/seq/seq.ino
+++ examples/seq/seq.ino
@@ -53,19 +53,6 @@

 static const unsigned char semitone_lt[] PROGMEM = {'C', 'C', 'D', 'E', 'E', 'F', 'F', 'G', 'G', 'A', 'B', 'B'};
 static const Intonation semitone_in[] PROGMEM = {IN, IS, IN, IF, IN, IN, IS, IN, IS, IN, IF, IN};
-
-struct DU_SEQ_Values {
-  float stage_cv[8];
-  uint8_t stage_steps[8];
-  GateMode stage_gate[8];
-  bool stage_slew[8];
-  uint8_t stage_count;
-  bool diradd_mode;
-  float slew_hz;
-  uint16_t gate_ms;
-};
-
-volatile DU_SEQ_Values seq_values;

 volatile uint8_t stage, step;
 volatile bool gate, reverse;
@@ -169,7 +156,6 @@
       {
         widget_save_->params.vals.stage_pitch[i] = 119;
       }
-      seq_values.stage_cv[i] = note_to_cv(widget_save_->params.vals.stage_pitch[i]);
     }

     for(uint8_t i = 0; i < 8; ++i)
@@ -178,7 +164,6 @@
       {
         widget_save_->params.vals.stage_steps[i] = 8;
       }
-      seq_values.stage_steps[i] = widget_save_->params.vals.stage_steps[i];
     }

     for(uint8_t i = 0; i < 8; ++i)
@@ -187,28 +172,18 @@
       {
         widget_save_->params.vals.stage_gate[i] = 2;
       }
-      seq_values.stage_gate[i] = (GateMode)(widget_save_->params.vals.stage_gate[i]);
-    }
-
-    for(uint8_t i = 0; i < 8; ++i)
-    {
-      seq_values.stage_slew[i] = (bool)((widget_save_->params.vals.stage_slew >> i) & 1);
     }

     if(widget_save_->params.vals.stage_count < 1 || widget_save_->params.vals.stage_count > 8)
     {
       widget_save_->params.vals.stage_count = 8;
     }
-    seq_values.stage_count = widget_save_->params.vals.stage_count;
-
-    seq_values.diradd_mode = (bool)(widget_save_->params.vals.diradd_mode);

     if(widget_save_->params.vals.slew_rate < 0 || widget_save_->params.vals.slew_rate > 16)
     {
       widget_save_->params.vals.slew_rate = 8;
     }
-    seq_values.slew_hz = slew_hz(widget_save_->params.vals.slew_rate);
-    slew_filter->set_frequency(seq_values.slew_hz);
+    slew_filter->set_frequency(slew_hz(widget_save_->params.vals.slew_rate));

     if(widget_save_->params.vals.clock_bpm < 0 || widget_save_->params.vals.clock_bpm > 300)
     {
@@ -227,7 +202,7 @@
     {
       widget_save_->params.vals.gate_time = 8;
     }
-    seq_values.gate_ms = widget_save_->params.vals.gate_time * (uint16_t)(Clock.get_period() / 8000);
+    gate_ms = widget_save_->params.vals.gate_time * (uint16_t)(Clock.get_period() / 8000);

     // draw global elements
     for(uint8_t i = 0; i < 6; ++i)
@@ -303,7 +278,7 @@
     }

     // set gate state
-    switch(seq_values.stage_gate[cached_stage])
+    switch((GateMode)(widget_save_->params.vals.stage_gate[cached_stage]))
     {
       case GATE_NONE:
         gate = false;
@@ -318,7 +293,7 @@
         gate = partial_gate();
         break;
       case GATE_LONG:
-        if(cached_step == seq_values.stage_steps[cached_stage] - 1)
+        if(cached_step == widget_save_->params.vals.stage_steps[cached_stage] - 1)
         {
           gate = partial_gate();
         }
@@ -336,15 +311,16 @@
     }

     // set pitch CV state
-    float slew_cv = slew_filter->filter(seq_values.stage_cv[cached_stage]);
-    cv_out(CO1, seq_values.stage_slew[cached_stage] ? slew_cv : seq_values.stage_cv[cached_stage]);
+    const float pitch_cv = note_to_cv(widget_save_->params.vals.stage_pitch[cached_stage]);
+    const bool slew_on = (bool)((widget_save_->params.vals.stage_slew >> cached_stage) & 1);
+    cv_out(CO1, slew_on ? slew_filter->filter(pitch_cv) : pitch_cv);

     // set gate and clock states
     gt_out(GT1, gate);
     gt_out(GT2, cached_clock_gate);

     // update reverse setting
-    if(!seq_values.diradd_mode)
+    if(!widget_save_->params.vals.diradd_mode)
     {
       reverse = gt_read(CI1);
     }
@@ -352,12 +328,12 @@
     widget_loop();

     // display reverse/address
-    if(seq_values.diradd_mode != last_diradd_mode
-        || (!seq_values.diradd_mode && reverse != last_reverse)
-        || (seq_values.diradd_mode && stage != last_stage))
+    if(widget_save_->params.vals.diradd_mode != last_diradd_mode
+        || (!widget_save_->params.vals.diradd_mode && reverse != last_reverse)
+        || (widget_save_->params.vals.diradd_mode && stage != last_stage))
     {
       display_reverse_address(30, 12);
-      last_diradd_mode = seq_values.diradd_mode;
+      last_diradd_mode = widget_save_->params.vals.diradd_mode;
       last_reverse = reverse;
       Display.display(30, 34, 1, 2);
     }
@@ -392,12 +368,12 @@
     if(Clock.state())
     {
       step++;
-      step %= seq_values.stage_steps[stage];
+      step %= widget_save_->params.vals.stage_steps[stage];
       if(!step)
       {
-        stage = seq_values.diradd_mode ? address_to_stage() : (reverse ?
-            (stage ? stage - 1 : seq_values.stage_count - 1) : stage + 1);
-        stage %= seq_values.stage_count;
+        stage = widget_save_->params.vals.diradd_mode ? address_to_stage() : (reverse ?
+            (stage ? stage - 1 : widget_save_->params.vals.stage_count - 1) : stage + 1);
+        stage %= widget_save_->params.vals.stage_count;
       }
     }
   }
@@ -422,7 +398,6 @@
     {
       widget_save_->params.vals.stage_count = 8;
     }
-    seq_values.stage_count = widget_save_->params.vals.stage_count;
     widget_save_->mark_changed();
     widget_save_->display();
     Display.fill_rect(widget_count_->x() + 1, widget_count_->y() + 1, 5, 7, DUINO_SH1106::White);
@@ -441,7 +416,6 @@
     {
       widget_save_->params.vals.diradd_mode = 1;
     }
-    seq_values.diradd_mode = (bool)(widget_save_->params.vals.diradd_mode);
     widget_save_->mark_changed();
     widget_save_->display();
     Display.fill_rect(widget_diradd_->x() + 1, widget_diradd_->y() + 1, 5, 7, DUINO_SH1106::White);
@@ -461,8 +435,7 @@
     {
       widget_save_->params.vals.slew_rate = 16;
     }
-    seq_values.slew_hz = slew_hz(widget_save_->params.vals.slew_rate);
-    slew_filter->set_frequency(seq_values.slew_hz);
+    slew_filter->set_frequency(slew_hz(widget_save_->params.vals.slew_rate));
     widget_save_->mark_changed();
     widget_save_->display();
     Display.fill_rect(widget_slew_->x() + 2, widget_slew_->y() + 2, 16, 5, DUINO_SH1106::White);
@@ -482,7 +455,7 @@
     {
       widget_save_->params.vals.gate_time = 16;
     }
-    seq_values.gate_ms = widget_save_->params.vals.gate_time * (uint16_t)(Clock.get_period() / 8000);
+    gate_ms = widget_save_->params.vals.gate_time * (uint16_t)(Clock.get_period() / 8000);
     widget_save_->mark_changed();
     widget_save_->display();
     Display.fill_rect(widget_gate_->x() + 2, widget_gate_->y() + 2, 16, 5, DUINO_SH1106::White);
@@ -510,7 +483,7 @@
     {
       Clock.set_external();
     }
-    seq_values.gate_ms = widget_save_->params.vals.gate_time * (uint16_t)(Clock.get_period() / 8000);
+    gate_ms = widget_save_->params.vals.gate_time * (uint16_t)(Clock.get_period() / 8000);
     widget_save_->mark_changed();
     widget_save_->display();
     Display.fill_rect(widget_clock_->x() + 1, widget_clock_->y() + 1, 17, 7, DUINO_SH1106::White);
@@ -530,7 +503,6 @@
     {
       widget_save_->params.vals.stage_pitch[stage_selected] = 119;
     }
-    seq_values.stage_cv[stage_selected] = note_to_cv(widget_save_->params.vals.stage_pitch[stage_selected]);
     widget_save_->mark_changed();
     widget_save_->display();
     Display.fill_rect(widgets_pitch_->x(stage_selected), widgets_pitch_->y(stage_selected), 16, 15,
@@ -551,7 +523,6 @@
     {
       widget_save_->params.vals.stage_steps[stage_selected] = 8;
     }
-    seq_values.stage_steps[stage_selected] = widget_save_->params.vals.stage_steps[stage_selected];
     widget_save_->mark_changed();
     widget_save_->display();
     Display.fill_rect(widgets_steps_->x(stage_selected) + 1, widgets_steps_->y(stage_selected) + 1, 5, 7,
@@ -572,7 +543,6 @@
     {
       widget_save_->params.vals.stage_gate[stage_selected] = 5;
     }
-    seq_values.stage_gate[stage_selected] = (GateMode)(widget_save_->params.vals.stage_gate[stage_selected]);
     widget_save_->mark_changed();
     widget_save_->display();
     Display.fill_rect(widgets_gate_->x(stage_selected) + 1, widgets_gate_->y(stage_selected) + 1, 7, 7,
@@ -592,7 +562,6 @@
     {
       widget_save_->params.vals.stage_slew |= (1 << stage_selected);
     }
-    seq_values.stage_slew[stage_selected] = (bool)((widget_save_->params.vals.stage_slew >> stage_selected) & 1);
     widget_save_->mark_changed();
     widget_save_->display();
     Display.fill_rect(widgets_slew_->x(stage_selected) + 1, widgets_slew_->y(stage_selected) + 1, 14, 4,
@@ -638,9 +607,9 @@
     {
       addr_stage = 0;
     }
-    else if(stage > seq_values.stage_count - 1)
-    {
-      addr_stage = seq_values.stage_count - 1;
+    else if(stage > widget_save_->params.vals.stage_count - 1)
+    {
+      addr_stage = widget_save_->params.vals.stage_count - 1;
     }
     return (uint8_t)addr_stage;
   }
@@ -650,7 +619,7 @@
   {
     return (Clock.get_external() && cached_clock_gate)
            || cached_retrigger
-           || ((millis() - clock_time) < seq_values.gate_ms);
+           || ((millis() - clock_time) < gate_ms);
   }

   float note_to_cv(int8_t note)
@@ -732,7 +701,7 @@
   {
     Display.fill_rect(x, y, 5, 7, DUINO_SH1106::Black);

-    if(seq_values.diradd_mode)
+    if(widget_save_->params.vals.diradd_mode)
     {
       Display.draw_char(30, 12, '1' + stage, DUINO_SH1106::White);
     }
@@ -780,6 +749,7 @@
   uint8_t last_stage;
   bool last_diradd_mode;
   bool last_reverse;
+  uint16_t gate_ms;
 };

 DU_SEQ_Function * function;


Added floor

Added floor

--- ray-gfx.ino
+++ ray-gfx.ino
@@ -91,8 +91,8 @@
 void drawWallLine(uint8_t x, uint8_t h, uint8_t side);
 void rotatePlayer(Player *player, uint8_t right);
 void movePlayer(Player *player);
-void drawDottedLine(int16_t x, int16_t y0, int16_t y1);
 void drawLine(int16_t x, int16_t y0, int16_t y1);
+void drawShadedLine(int16_t x, int16_t y0, int16_t y1);
 void timer_IRQ();

 volatile uint8_t timer_flag = 0;
@@ -180,9 +180,9 @@
   }
 }

-void drawDottedLine(int16_t x, int16_t y0, int16_t y1) {
+void drawShadedLine(int16_t x, int16_t y0, int16_t y1) {
   uint16_t color = BLACK;
-  static uint8_t i = 0;
+  uint8_t i = x%2;
   for (; y0>=y1; y0--) {
     i ? i=0:i=1;
     i ? color=WHITE:color=BLACK;
@@ -200,10 +200,15 @@
     drawEnd = DISP_HEIGHT;
   }
   if (side){
-    display.drawLine(x, drawStart , x, drawEnd, WHITE);
+    drawLine(x, drawStart , drawEnd);
   } else {
-    drawDottedLine(x, drawStart , drawEnd); //add shade to y-axis wall to give better contrast
-  }
+    drawShadedLine(x, drawStart , drawEnd); //add shade to y-axis wall to give better contrast
+  }
+  drawFloorLine(x, drawStart);
+}
+
+void drawFloorLine(uint8_t x, uint8_t drawEnd) {
+  drawLine(x, DISP_HEIGHT ,drawEnd + 2);
 }

 void doRayCasting(Player *player) {


[MB202] indentation OCD

[MB202] indentation OCD

--- Electronics101/PowerMB102/PowerMB102.ino
+++ Electronics101/PowerMB102/PowerMB102.ino
@@ -34,8 +34,8 @@
 void setup() {
   Serial.begin(9600);                   // initialize serial communications at 9600 bps

-  pinMode(read_v1_pin, INPUT);        // enable Vout read
-  pinMode(read_v2_pin, INPUT);        // enable Vout read
+  pinMode(read_v1_pin, INPUT);          // enable Vout read
+  pinMode(read_v2_pin, INPUT);          // enable Vout read

   FlexiTimer2::set(50, sample);         // sample every 50ms
   FlexiTimer2::start();


Tweaking a bit of stuff

Tweaking a bit of stuff

--- app.ino
+++ app.ino
@@ -7,7 +7,7 @@
 #include "RainbowCycle.h"
 #include "TheaterChase.h"

-using Controller = PatternController<3, 75, 0>;
+using Controller = PatternController<4, 75, 0>;

 class CyclePatterns : public IOnComplete
 {
@@ -18,13 +18,16 @@
 };

 PatternPtr patterns[] = {
-	new NightwingRegular(5, CRGB::Blue, CRGB::White),
+	new NightwingRegular(1, CRGB::Blue, CRGB::Yellow),
+	new NightwingRegular(2, CRGB::Red, CRGB::Cyan),
 	new TheaterChase(CRGB::Blue, CRGB::Gold),
 	new RainbowCycle()
 };

-FastLEDProvider<8> leds = {&(FastLED.addLeds<NEOPIXEL, (int)6>)};
-Controller controller = Controller { &leds, patterns, new CyclePatterns() };
+FastLEDProvider<16> leds = {&(FastLED.addLeds<NEOPIXEL, (int)6>)};
+Controller controller = Controller { &leds, patterns
+	, new CyclePatterns()
+};

 void setup()
 {


Reduced DEBUG output in HMTL Modules

Reduced DEBUG output in HMTL Modules

--- HMTL_Modules/HMTL_Module/HMTL_Module.ino
+++ HMTL_Modules/HMTL_Module/HMTL_Module.ino
@@ -9,7 +9,7 @@
 #include "Adafruit_WS2801.h"
 #include "Wire.h"

-#define DEBUG_LEVEL DEBUG_HIGH
+#define DEBUG_LEVEL DEBUG_MID
 #include "Debug.h"

 #include "GeneralUtils.h"
@@ -243,7 +243,7 @@
 void free_tracker(program_tracker_t *trackers[], int index) {
   program_tracker_t *tracker = trackers[index];
   if (tracker != NULL) {
-      DEBUG_VALUELN(DEBUG_HIGH, "free_tracker: clearing program for ",
+      DEBUG_VALUELN(DEBUG_MID, "free_tracker: clearing program for ",
 		    index);
       if (tracker->state) free(tracker->state);
       free(tracker);
@@ -277,7 +277,7 @@
  * Program function to turn an output on and off
  */
 boolean program_blink_init(msg_program_t *msg, program_tracker_t *tracker) {
-  DEBUG_PRINT(DEBUG_HIGH, "Initializing blink program state");
+  DEBUG_PRINT(DEBUG_MID, "Initializing blink program state");

   state_blink_t *state = (state_blink_t *)malloc(sizeof (state_blink_t));
   memcpy(&state->msg, msg->values, sizeof (state->msg)); // ??? Correct size?
@@ -286,8 +286,8 @@

   tracker->state = state;

-  DEBUG_VALUE(DEBUG_HIGH, " on_period:", state->msg.on_period);
-  DEBUG_VALUELN(DEBUG_HIGH, " off_period:", state->msg.off_period);
+  DEBUG_VALUE(DEBUG_MID, " on_period:", state->msg.on_period);
+  DEBUG_VALUELN(DEBUG_MID, " off_period:", state->msg.off_period);

   return true;
 }
@@ -331,18 +331,18 @@
  */
 boolean program_timed_change_init(msg_program_t *msg,
 				  program_tracker_t *tracker) {
-  DEBUG_PRINT(DEBUG_HIGH, "Initializing timed change program");
+  DEBUG_PRINT(DEBUG_MID, "Initializing timed change program");

   state_timed_change_t *state = (state_timed_change_t *)malloc(sizeof (state_timed_change_t));

-  DEBUG_VALUE(DEBUG_HIGH, " msgsz=", sizeof (state->msg));
+  DEBUG_VALUE(DEBUG_MID, " msgsz=", sizeof (state->msg));

   memcpy(&state->msg, msg->values, sizeof (state->msg)); // ??? Correct size?
   state->change_time = 0;

   tracker->state = state;

-  DEBUG_VALUELN(DEBUG_HIGH, " change_period:", state->msg.change_period);
+  DEBUG_VALUELN(DEBUG_MID, " change_period:", state->msg.change_period);

   return true;
 }


Extended Blynk notification text with object prefixes.

- Added rain status for downpour.

--- watertank.ino
+++ watertank.ino
@@ -73,7 +73,7 @@
 //------------------------------------------------------------------------
 // Water tank sensing and publishing to clouds (ThinkSpeak, Blynk)
 //-------------------------------------------------------------------------
-#define SKETCH "WATERTANK 1.3.1"
+#define SKETCH "WATERTANK 1.3.2"
 #include "credentials.h"

 const unsigned int TIMEOUT_WATCHDOG = 10000;  // Watchdog timeout in milliseconds
@@ -141,7 +141,11 @@
 // Blynk variables
 WidgetLED ledWaterPump(VPIN_WATER_PUMP);
 #if defined(BLYNK_NOTIFY_LIGHT) || defined(BLYNK_NOTIFY_RAIN) || defined(BLYNK_NOTIFY_WATER)
-String BLYNK_LABEL = String("Chalupa -- ");
+String BLYNK_LABEL_GLUE = String(" -- ");
+String BLYNK_LABEL_PREFIX = String("Chalupa");
+String BLYNK_LABEL_LIGHT = String("Light");
+String BLYNK_LABEL_RAIN = String("Rain");
+String BLYNK_LABEL_WATER = String("Watertank");
 #endif

 // Measured values
@@ -185,6 +189,7 @@
 const int RAIN_VALUE_DEW    = 128;
 const int RAIN_VALUE_RAIN   = 512;
 const int RAIN_VALUE_SHOWER = 1024;
+const int RAIN_VALUE_STORM  = 2048;
 const int RAIN_VALUE_MARGIN = 4;         // Difference in value for status hysteresis
 //
 const unsigned char RAIN_STATUS_DRY    = 1;
@@ -192,6 +197,7 @@
 const unsigned char RAIN_STATUS_RAIN   = 3;
 const unsigned char RAIN_STATUS_SHOWER = 4;
 const unsigned char RAIN_STATUS_STORM  = 5;
+const unsigned char RAIN_STATUS_POUR   = 6;

 // Water level
 const int SONAR_DISTANCE_MAX = 95;          // Maximal valid measured distance (to tank bottom)
@@ -300,7 +306,7 @@
                             txtStatus = String("Sunny weather");
                             break;
                     }
-                    Blynk.notify(BLYNK_LABEL + txtStatus);
+                    Blynk.notify(BLYNK_LABEL_PREFIX + BLYNK_LABEL_GLUE + BLYNK_LABEL_LIGHT + BLYNK_LABEL_GLUE + txtStatus);
 #endif
                     lightStatusOld = lightStatus;
                 }
@@ -343,8 +349,10 @@
                     rainStatus = RAIN_STATUS_RAIN;
                 } else if (rainValue <= RAIN_VALUE_SHOWER) {
                     rainStatus = RAIN_STATUS_SHOWER;
+                } else if (rainValue <= RAIN_VALUE_STORM) {
+                    rainStatus = RAIN_STATUS_STORM;
                 } else {
-                    rainStatus = RAIN_STATUS_STORM;
+                    rainStatus = RAIN_STATUS_POUR;
                 }
                 // Notify at status change
                 if (rainStatusOld != rainStatus && rainDiff >= RAIN_VALUE_MARGIN) {
@@ -352,22 +360,25 @@
                     String txtStatus;
                     switch (rainStatus) {
                         case RAIN_STATUS_DRY:
-                          txtStatus = String("Dry whether");
+                          txtStatus = String("None");
                           break;
                         case RAIN_STATUS_DEW:
-                          txtStatus = String("Moisture or dew");
+                          txtStatus = String("Dew");
                           break;
                         case RAIN_STATUS_RAIN:
-                          txtStatus = String("Still rain");
+                          txtStatus = String("Still");
                           break;
                         case RAIN_STATUS_SHOWER:
-                          txtStatus = String("Heavy rain");
+                          txtStatus = String("Heavy");
                           break;
                         case RAIN_STATUS_STORM:
-                          txtStatus = String("Rain storm");
+                          txtStatus = String("Storm");
+                          break;
+                        case RAIN_STATUS_POUR:
+                          txtStatus = String("Downpour");
                           break;
                     }
-                    Blynk.notify(BLYNK_LABEL + txtStatus);
+                    Blynk.notify(BLYNK_LABEL_PREFIX + BLYNK_LABEL_GLUE + BLYNK_LABEL_RAIN + BLYNK_LABEL_GLUE + txtStatus);
 #endif
                     rainStatusOld = rainStatus;
                 }
@@ -412,16 +423,16 @@
                     String txtStatus;
                     switch (waterStatus) {
                         case WATER_STATUS_STABLE:
-                            txtStatus = String("stabilized");
+                            txtStatus = String("Stabile");
                             break;
                         case WATER_STATUS_FILLING:
-                            txtStatus = String("filled");
+                            txtStatus = String("Filling");
                             break;
                         case WATER_STATUS_PUMPING:
-                            txtStatus = String("pumping out");
+                            txtStatus = String("Pumping");
                             break;
                     }
-                    Blynk.notify(BLYNK_LABEL + String("Water tank has been ") + txtStatus);
+                    Blynk.notify(BLYNK_LABEL_PREFIX + BLYNK_LABEL_GLUE + BLYNK_LABEL_WATER + BLYNK_LABEL_GLUE + txtStatus);
                     // Signal LED
                     switch (waterStatus) {
                         case WATER_STATUS_PUMPING:


Made a handler for '/filemanager' web call.

--- webserver.ino
+++ webserver.ino
@@ -15,6 +15,16 @@
   } else {
     webServer.on( "/", []() {
       webServer.send( 200, "text/plain", "No index.htm present during boot.\nUpload index.htm and reset controller" );
+    });
+  }
+
+  //handle the filemanager
+  if ( SPIFFS.exists( "/filemanager.htm" ) ) {
+    webServer.serveStatic( "/filemanager", SPIFFS, "/filemanager.htm" );
+    webServer.serveStatic( "/filemanager.htm", SPIFFS, "/filemanager.htm" );
+  } else {
+    webServer.on( "/filemanager", []() {
+      webServer.send( 200, "text/plain", "No filemanager present during boot.\nUpload index.htm and reset controller" );
     });
   }


Pointing to the server instead of a dev machine. Also added a DEBUG option for serial "waiting" - Arduino Leonardo known issue.

--- src/code.ino
+++ src/code.ino
@@ -1,6 +1,7 @@
 #include <EtherCard.h>
 #include <dht.h>
 #define DHT11_PIN 5
+#define DEBUG true

 static uint32_t timer;
 dht DHT;
@@ -13,8 +14,7 @@
 static byte gwip[] = { 172,16,2,1 };
 static byte dnsip[] = { 172,16,0,3 };
 static byte mymac[] = { 0x74,0x69,0x69,0x2D,0x30,0x31 };
-const char website[] PROGMEM = "172.16.0.8";
-static byte api[] = { 172,16,1,25 };
+const char website[] PROGMEM = "adb.dokku.d.h";

 static void my_callback (byte status, word off, word len)
 {
@@ -60,8 +60,8 @@
 {
     Serial.begin(9600);

-    // while the serial stream is not open, do nothing:
-    while (!Serial) ;
+    if (DEBUG)
+        while (!Serial) ;

     if (ether.begin(sizeof Ethernet::buffer, mymac) == 0)
         Serial.println(F("Failed to access Ethernet controller"));
@@ -74,9 +74,6 @@

     if (!ether.dnsLookup(website))
         Serial.println("DNS failed");
-
-    ether.copyIp(ether.hisip, api);
-    ether.hisport = 5000;

     ether.printIp("SRV:", ether.hisip);
     sendData();


Update sgp.ino

Update sgp.ino

--- sgp/sgp.ino
+++ sgp/sgp.ino
@@ -1 +1,32 @@
 // Simple graph processor that executes a graph in the Get,Process,Set&Transition style.
+#include <stdio.h>
+#include <assert.h>
+#include <stdlib.h>
+#include <string.h>
+
+#define NUM_PROC_NODES 7
+#define NUM_DATA_NODES 12
+
+// Value union
+typedef union Value {
+  int i;
+  float f;
+  char str[32];
+} dn_value;
+
+// Data Node struct
+typedef struct DN
+{
+  dn_value key;
+  dn_value value;
+} dn;
+// pointer to a nodes process function
+typedef node_data (*node_proc)(node_data nd);
+
+// all process nodes have a pointer to a function or null
+int p[3][4] = {
+   {0, 1, 2, 3} ,   /*  initializers for row indexed by 0 */
+   {4, 5, 6, 7} ,   /*  initializers for row indexed by 1 */
+   {8, 9, 10, 11}   /*  initializers for row indexed by 2 */
+};
+


Fix bug that wasn't receiving last field of waypoint path

--- src/src.ino
+++ src/src.ino
@@ -296,11 +296,13 @@
         bluetooth_poll(bluetooth);
         status = bluetooth_get_status(bluetooth);

-        if (STANDBY == status) {
+        /* make sure to check for message before standby, because bluetooth may still have
+           a message even though it has gone into standby */
+        if (bluetooth_has_message(bluetooth)) {
+            waypoint_writer_write(&waypoint_writer, bluetooth_get_message(bluetooth));
+        } else if (STANDBY == status) {
             /* device returns to standby after transaction is complete */
             return;
-        } else if (bluetooth_has_message(bluetooth)) {
-            waypoint_writer_write(&waypoint_writer, bluetooth_get_message(bluetooth));
         } else if (CONNECTED == status || ADVERTISING == status) {
             /* keep waiting for message or connection */
             continue;


fixed graphical bug for battery indicator when battery level was less than 10 percent.

--- Solar_Gas_Detector.ino
+++ Solar_Gas_Detector.ino
@@ -280,11 +280,20 @@
   double battLevel = fuelGauge.stateOfCharge();
   //Serial.print("global ");
   //Serial.println(battLevel);
-  if (battLevel < 100 && battLevel > -0.01)
+  if (battLevel < 100 && battLevel >= 10)
   {
     LCDsetPosition(1,15);
     myLCD.print("B"); //batt logo;
     LCDsetPosition(1,16); //16
+    myLCD.print(battLevel,1); //[,1]=.1 (include decimal)
+    LCDsetPosition(1,20);
+    myLCD.print("%");
+  }
+  else if (battLevel < 10 && battLevel > -0.01)
+  {
+    LCDsetPosition(1,15);
+    myLCD.print("B0"); //batt logo;
+    LCDsetPosition(1,17); //16+1 for B"zero"
     myLCD.print(battLevel,1); //[,1]=.1 (include decimal)
     LCDsetPosition(1,20);
     myLCD.print("%");


Added code to control excavator conveyor belt.

--- src/ExcavatorDriverROS/ExcavatorDriverROS.ino
+++ src/ExcavatorDriverROS/ExcavatorDriverROS.ino
@@ -27,6 +27,9 @@
 //<---------------- Set Up ------------------------------->
 command2ros::ExcavatorCommand excavatorStatus;

+// set up the default values for the current excavator
+// settings (drive speed/duration, excavate speed/duration,
+// bucket height, conveyor speed/duruation)
 void setupExcavatorStatus(){
   excavatorStatus.drive_speed = 0;
   excavatorStatus.drive_duration = 0;
@@ -36,7 +39,6 @@
   excavatorStatus.e_stop = false;
 }

-
 //<---------------- Bucket Wheel Actuation --------------->
 const int ERROR_OUT_OF_RANGE = - 1;
 const int FULL_STEPS = 31914;
@@ -55,7 +57,6 @@

 //variable which disables all motor movement when set to TRUE.
 boolean e_stop = false;
-

 //<----------------- Excavator State machine ------------->
@@ -79,10 +80,10 @@
 int currentStatus = STOPPED;
 int currentConveyorStatus = STOPPED;

-
 unsigned long driveStopTime = 0;
 int conveyorRotationTime = 0;
 long conveyorStopTime = 0;
+int bucketRotationTime = 0;
 long bucketStopTime = 0;

 //<---------------------- ROS variables ------------------->
@@ -111,11 +112,11 @@
 }

 //
-// ROS Subsribers
+// ROS Subscribers
 //
 command2ros::ExcavatorCommand currentExcavatorCommand;

-void newExcavatorCommandCallback(const command2ros::ExcavatorCommand& newManualCommand)
+void newExcavatorCommandCallback(const command2ros::ExcavatorCommand &newManualCommand)
 {
   currentExcavatorCommand.drive_speed = newManualCommand.drive_speed;
   currentExcavatorCommand.drive_duration = newManualCommand.drive_duration;
@@ -135,6 +136,24 @@
 }

 ros::Subscriber<command2ros::ExcavatorCommand> commandSubscriber("ExcavatorCommand", &newExcavatorCommandCallback);
+
+
+// Listen for new conveyor commands
+void newConveyorCommandCallback(const std_msgs::Int16& newConveyorCommand){
+  if(newConveyorCommand.data != 0){
+    currentStatus = START_ROTATING_CONVEYOR;
+    conveyorRotationTime = newConveyorCommand.data;
+  }
+}
+ros::Subscriber<std_msgs::Int16> conveyorSubscriber("ExcavatorConveyorCommand", &newConveyorCommandCallback);
+
+// Reset the current position of the bucketwheel
+void setActualStepCountCallback(const std_msgs::Int16& newConveyorCommand){
+  currentSteps = newConveyorCommand.data;
+}
+ros::Subscriber<std_msgs::Int16> setActualStepCount("SetActualStepCount", &setActualStepCountCallback);
+
+

 void stopMovementMotors()
@@ -494,6 +513,8 @@
   // Initialize ROS stuff
   excavatorNode.initNode();
   excavatorNode.subscribe(commandSubscriber);
+  excavatorNode.subscribe(conveyorSubscriber);
+  excavatorNode.subscribe(setActualStepCount);
   setupExcavatorStatus();

   pinMode(DIRECTION_PIN, OUTPUT);
@@ -523,6 +544,18 @@
     //TODO: This will never happen right now, may want for competition though
     return;
   }
+
+  if(currentConveyorStatus == START_ROTATING_CONVEYOR){
+    conveyorStopTime = millis() + (long)abs(conveyorRotationTime);
+    driveConveyor();
+    currentConveyorStatus = ROTATING_CONVEYOR;
+  }
+
+  if(currentConveyorStatus == ROTATING_CONVEYOR){
+    if(millis() >= conveyorStopTime){
+      stopConveyor();
+    }
+  }

   if (currentStatus == START_DRIVING) {
     print("current status: start_driving");
@@ -576,7 +609,7 @@
   }

   if(currentConveyorStatus == START_ROTATING_CONVEYOR){
-    conveyorStopTime = millis() + (long)abs(conveyorRotationTime);
+    conveyorStopTime = millis() + (long)currentConveyorCommand.duration*1000;
     driveConveyor();
     currentConveyorStatus = ROTATING_CONVEYOR;
   }


Add code to convert time to UNIX time (for datalogging)

--- src/src.ino
+++ src/src.ino
@@ -12,7 +12,7 @@
 #define USBSerial Serial

 #define ZERO  1
-#define GPSECHO  true
+#define GPSECHO  false
 #define MEAN_EARTH_RADIUS 6371e3
 #define M_TO_FT 3.28084

@@ -38,8 +38,6 @@
   lcd_clear_display() ;

   fram.begin() ;
-  fram_write_str(0,"hello world") ;
-  fram_read_len(0, 11) ;
 }

 void loop(void)
@@ -52,8 +50,8 @@
    }

    if (GPS.newNMEAreceived()) {
-
-     if (GPS.parse(GPS.lastNMEA()) && GPS.fix) {
+     // add back in && GPS.fix
+     if (GPS.parse(GPS.lastNMEA()) ) {
        print_GPS_results() ;
      }
    }
@@ -94,6 +92,9 @@

   lcd_pos(0,4) ;
   lcd_print_float(speed) ;
+
+  get_unix_time(GPS.hour, GPS.minute, GPS.seconds,
+                GPS.day, GPS.month, GPS.year) ;
 }

 bool debounce(int pin)
@@ -108,9 +109,43 @@
   return flag ;
 }

+uint32_t get_unix_time(uint32_t hh, uint32_t mm, uint32_t ss,
+                       uint32_t dd, uint32_t mo, uint32_t yy)
+{
+  uint32_t unix_time = 0 ;
+  uint32_t mo_arr [12] = {0,2678400,5097600,7776000,10368000,13046400,
+                         15638400,18316800,20995200,23587200,26265600,
+                         28857600} ;
+  uint32_t day_sum = 0 ;
+  uint32_t leap_days = 0 ;
+  uint32_t cur_leap = 0 ;
+
+  unix_time = (2000-1970+yy)*31536000 ;
+  unix_time += mo_arr[mo-1] ;
+
+   /* Determine leap days */
+  leap_days = (2000+yy-1972)/4 + 1 ;
+  cur_leap = (2000+yy)/4 ;
+
+  /* Subtract a leap day if it hasn't occurred in current year yet */
+  if (cur_leap == leap_days) {
+    if (mo <= 2)
+      leap_days-- ;
+  }
+
+  day_sum = dd+leap_days-1 ;
+  unix_time += (day_sum*86400) ;
+
+  unix_time += (mm*60) ;
+  unix_time += ss ;
+  unix_time += 3600*hh ;
+
+  return unix_time ;
+}
+
 void fram_write_str(uint16_t addr, char *str)
 {
-  uint8_t i = addr ;
+  uint16_t i = addr ;
   while(*str) {
     fram.write8(i,*str++) ;
     i++ ;
@@ -119,12 +154,14 @@

 void fram_read_len(uint16_t base_addr, uint16_t len)
 {
-  uint8_t value = 0 ;
-  int i = base_addr ;
+  uint16_t value = 0 ;
+  uint16_t i = base_addr ;
   while(i < (base_addr + len)) {
     value = fram.read8(i++) ;
     Serial.print(value, HEX) ;
     Serial.print(" ") ;
   }
 }
+
+


Send wakeup message before reading sensors.

--- src/wxs.ino
+++ src/wxs.ino
@@ -118,8 +118,8 @@
 void
 loop()
 {
+	Particle.publish("kisom/wxs/v1/wakeup", NULL, 30, PUBLIC);
 	takeMeasurements("");
-	Particle.publish("kisom/wxs/v1/wakeup", NULL, 30, PUBLIC);

 	// Stay awake for one minute afterwards to give the system time to
 	// flush pending messages. This also gives us time to kick off a


Units are determained and set properly.

Units are determained and set properly.

--- smc/debug/debug.ino
+++ smc/debug/debug.ino
@@ -1,102 +1,81 @@
-// I2C device class (I2Cdev) demonstration Arduino sketch for MPU9150
-// 1/4/2013 original by Jeff Rowberg <jeff@rowberg.net> at https://github.com/jrowberg/i2cdevlib
-//          modified by Aaron Weiss <aaron@sparkfun.com>
-//
-// Changelog:
-//     2011-10-07 - initial release
-//     2013-1-4 - added raw magnetometer output
-
-/* ============================================
-I2Cdev device library code is placed under the MIT license
-
-Permission is hereby granted, free of charge, to any person obtaining a copy
-of this software and associated documentation files (the "Software"), to deal
-in the Software without restriction, including without limitation the rights
-to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
-copies of the Software, and to permit persons to whom the Software is
-furnished to do so, subject to the following conditions:
-
-The above copyright notice and this permission notice shall be included in
-all copies or substantial portions of the Software.
-
-THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
-IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
-FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
-AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
-LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
-OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
-THE SOFTWARE.
-===============================================
-*/
-
-// Arduino Wire library is required if I2Cdev I2CDEV_ARDUINO_WIRE implementation
-// is used in I2Cdev.h
 #include "Wire.h"
-
-// I2Cdev and MPU6050 must be installed as libraries, or else the .cpp/.h files
-// for both classes must be in the include path of your project
 #include "I2Cdev.h"
 #include "MPU6050.h"

-// class default I2C address is 0x68
-// specific I2C addresses may be passed as a parameter here
-// AD0 low = 0x68 (default for InvenSense evaluation board)
-// AD0 high = 0x69
-MPU6050 accelgyro;
+MPU6050 imu;

-int16_t ax, ay, az;
-int16_t gx, gy, gz;
-int16_t mx, my, mz;
+// Set the full scale range for the components of the IMU.
+#define ACCEL_FULL_SCALE_RANGE MPU6050_ACCEL_FS_8
+#define GYRO_FULL_SCALE_RANGE  MPU6050_GYRO_FS_500

-#define LED_PIN 13
-bool blinkState = false;
+float ACCEL_SCALE;
+float GYRO_SCALE;

 void setup() {
-    // join I2C bus (I2Cdev library doesn't do this automatically)
-    Wire.begin();
+  // join I2C bus (I2Cdev library doesn't do this automatically)
+  Wire.begin();

-    // initialize serial communication
-    // (38400 chosen because it works as well at 8MHz as it does at 16MHz, but
-    // it's really up to you depending on your project)
-    Serial.begin(38400);
+  // initialize serial communication
+  // (38400 chosen because it works as well at 8MHz as it does at 16MHz)
+  Serial.begin(38400);

-    // initialize device
-//    Serial.println("Initializing I2C devices...");
-    accelgyro.initialize();
+  // initialize device
+  imu.initialize();

-    // verify connection
-//    Serial.println("Testing device connections...");
-//    Serial.println(accelgyro.testConnection() ? "MPU6050 connection successful" : "MPU6050 connection failed");
+  /* set accelerometer range.
+   * MPU6050_ACCEL_FS_2(0)  : 2 g max  : Scale 16384
+   * MPU6050_ACCEL_FS_4(1)  : 4 g max  : Scale 8192
+   * MPU6050_ACCEL_FS_8(2) : 8 g max   : Scale 4096
+   * MPU6050_ACCEL_FS_16(3) : 16 g max : Scale 2048
+   */
+  imu.setFullScaleAccelRange(ACCEL_FULL_SCALE_RANGE);
+  ACCEL_SCALE = 16384 / pow(2, ACCEL_FULL_SCALE_RANGE);

-    // configure Arduino LED for
-    pinMode(LED_PIN, OUTPUT);
+  /* set gyro range.
+   * MPU6050_GYRO_FS_250(0)  : 250 deg/sec max  : Scale 131.0
+   * MPU6050_GYRO_FS_500(1)  : 500 deg/sec max  : Scale 65.5
+   * MPU6050_GYRO_FS_1000(2) : 1000 deg/sec max : Scale 32.8
+   * MPU6050_GYRO_FS_2000(3) : 2000 deg/sec max : Scale 16.4
+   */
+  imu.setFullScaleGyroRange(GYRO_FULL_SCALE_RANGE);
+  GYRO_SCALE = 131 / pow(2, GYRO_FULL_SCALE_RANGE);
 }

-
+void loop() {
+  int16_t ax, ay, az;  // g forces
+  int16_t gx, gy, gz;  // degrees/second
+  int16_t mx, my, mz;  // TODO: learn wtf data this is.

-void loop() {
-    // read raw accel/gyro measurements from device
-    accelgyro.getMotion9(&ax, &ay, &az, &gx, &gy, &gz, &mx, &my, &mz);
+  // read raw accel/gyro measurements from device
+  imu.getMotion9(&ax, &ay, &az, &gx, &gy, &gz, &mx, &my, &mz);

-    // these methods (and a few others) are also available
-    //accelgyro.getAcceleration(&ax, &ay, &az);
-    //accelgyro.(&gx, &gy, &gz);
+  // write accelerometer values (g)
+  Serial.print(scale(ax, ACCEL_SCALE));
+  Serial.print("\t");
+  Serial.print(scale(ay, ACCEL_SCALE));
+  Serial.print("\t");
+  Serial.print(scale(az, ACCEL_SCALE));
+  Serial.print("\t");

-    Serial.print(ax);
-    Serial.print(" ");
-    Serial.print(ay);
-    Serial.print(" ");
-    Serial.print(az);
-    Serial.print(" ");
-    Serial.print(gx);
-    Serial.print(" ");
-    Serial.print(gy);
-    Serial.print(" ");
-    Serial.print(gz);
-    Serial.print(" ");
-    Serial.print(mx);
-    Serial.print(" ");
-    Serial.print(my);
-    Serial.print(" ");
-    Serial.println(mz);
+  // write gyroscope values (degrees/second)
+  Serial.print(scale(gx, GYRO_SCALE));
+  Serial.print("\t");
+  Serial.print(scale(gy, GYRO_SCALE));
+  Serial.print("\t");
+  Serial.print(scale(gz, GYRO_SCALE));
+  Serial.print("\t");
+
+  // TODO: complete this.
+  // write raw magnetometer values (??)
+  Serial.print(mx);
+  Serial.print("\t");
+  Serial.print(my);
+  Serial.print("\t");
+  Serial.print(mz);
+
+  Serial.println("");
 }
+
+float scale(int16_t value, float scale_factor) {
+  return value / scale_factor;
+}


version 0.2

version 0.2

Désactivation du debug par défaut
Correction de la déclaration du type des données de l’info ADPS

--- teleInfo.ino
+++ teleInfo.ino
@@ -8,23 +8,15 @@
 #define TI_TX 5

 // uncomment to enable debuging
-#define DEBUG_ENABLED
-
-// longueur max des données qu'on recoi
+//#define DEBUG_ENABLED
+
+#define VERSION "0.2"
+
+// longueur max des données qu'on recoit
 #define BUFSIZE 15

 // durée entre 2 rafraichissements des données
-#define SLEEP_TIME (60 * 1000)
-
-// battery voltage calculator
-// mmm la téléinfo emet un signal carré entre -25v et 25v a 1200bps, une diode, une capa, le regul du duino et hop non ?
-#define BATTERY_VOLTAGE 9.0
-#define BATTERY_SENSE_PIN A0
-// pont diviseur de tension
-#define VDIV_R1 100e3
-#define VDIV_R2 10e3
-// vdiv est la sensibilité de mon pont diviseur de tension
-#define VDIV ( ( VDIV_R1 + VDIV_R2 ) / VDIV_R2 ) * 1.1 / 1023
+#define SLEEP_TIME (30 * 1000)

 MySensor gw;

@@ -51,7 +43,7 @@
 MyMessage msgIINST( CHILD_ID_IINST, V_CURRENT );

 #define CHILD_ID_ADPS 5
-MyMessage msgADPS( CHILD_ID_ADPS, V_KWH );
+MyMessage msgADPS( CHILD_ID_ADPS, V_CURRENT );

 #define CHILD_ID_IMAX 6
 MyMessage msgIMAX( CHILD_ID_IMAX, V_CURRENT );
@@ -80,7 +72,7 @@
 MyMessage msgEJP_HPM( CHILD_ID_EJP_HPM, V_KWH );

 #define CHILD_ID_PEJP 32
-MyMessage msgPEJP( CHILD_ID_PEJP, V_KWH );
+MyMessage msgPEJP( CHILD_ID_PEJP, V_KWH ); // ya pas de type pour des durées...

 // infos tarif BBR (tempo)
 ///////////////////////////////////
@@ -124,11 +116,8 @@

 	tiSerial.begin( 1200 );

-	// use the 1.1 V internal reference
-	analogReference( INTERNAL );
-
 	gw.begin();
-	gw.sendSketchInfo( "Teleinfo Sensor", "0.1" );
+	gw.sendSketchInfo( "Teleinfo Sensor", VERSION );

 	gw.present( CHILD_ID_ADCO, S_POWER );
 	gw.present( CHILD_ID_OPTARIF, S_POWER );
@@ -158,44 +147,6 @@

 	gw.present( CHILD_ID_HHPHC, S_POWER );
 }
-
-/*
-void readBatteryLevel( MySensor &mygw ) {
-	static int oldBatteryPcnt = 0;
-
-	// get the battery Voltage
-	int sensorValue = analogRead( BATTERY_SENSE_PIN );
-
-#ifdef DEBUG_ENABLED
-	Serial.print( F("Sensor Value: ") );
-	Serial.println(sensorValue);
-#endif
-
-	float batteryV = sensorValue * VDIV;
-
-#ifdef DEBUG_ENABLED
-	Serial.print( F("Battery Voltage: ") );
-	Serial.print( batteryV );
-	Serial.println( F(" V") );
-#endif
-
-	int batteryPcnt = batteryV * 100 / BATTERY_VOLTAGE;
-	if (batteryPcnt > 100)
-		batteryPcnt = 100;
-
-#ifdef DEBUG_ENABLED
-	Serial.print( F("Battery percent: ") );
-	Serial.print(batteryPcnt);
-	Serial.println( F(" %") );
-#endif
-
-	if ( oldBatteryPcnt != batteryPcnt ) {
-		// Power up radio after sleep
-		mygw.sendBatteryLevel( batteryPcnt );
-		oldBatteryPcnt = batteryPcnt;
-	}
-}
-*/

 typedef struct TeleInfo TeleInfo;
 struct TeleInfo {
@@ -480,7 +431,6 @@
 }

 void loop() {
-	//readBatteryLevel( gw );
 	getTI();

 	// attendre avant prochaine lecture


Update Arduino.ino

Update Arduino.ino

--- Arduino/Arduino.ino
+++ Arduino/Arduino.ino
@@ -37,7 +37,7 @@
       parseBuffer();
     }
   }
-  //joystickUpdate();
+  joystickUpdate();
 }
 void parseBuffer(){
   int startIndex = 0,endIndex = 0,index = 0,len = _buffer.length(),maxCmdLen = 0;