Fixed shu_timer_v2

Fixed shu_timer_v2

--- shu_timer_v2/shu_timer_v2.ino
+++ shu_timer_v2/shu_timer_v2.ino
@@ -6,6 +6,7 @@
  */

 // melody notes
+#define _0 0
 #define _C 262
 #define _D 294
 #define _E 330
@@ -22,7 +23,7 @@
 const int SPEAKER_OUT = 1; // blinker LED and speaker output at D1
 const int COUNTER_LED = 5; // counter 7-seg LED output at D5
 const int CLOUDBIT_OUT = 9; // cloudBit output at D9
-const int START_TIMER_VAL = 5; // the unit amount for starting timer in seconds
+const int START_TIMER_VAL = 20 * 60; // the unit amount for starting timer in seconds
 const int MAX_TIMER_VAL = 99 * 60; // max amount of timer in seconds
 const int ANALOG_HIGH_THRETHOLD = 100; // threshold to determine an analog value is HIGH
 const int MAX_MELODY_COUNT = 1; // how many times melody will be played at alarming
@@ -32,20 +33,17 @@
  {_B, _A, _G, _F, _D, _C, _D, _C,
   _A, _B, _A, _G, _F, _G, _A,
   _C, _B, _A, _G, _F, _G, _c, _A, _F,
-  _C, _D, _E, _F, _E, _D, _C, _F};
+  _C, _D, _E, _F, _E, _D, _C, _F, _0};

 // durations of the melody
 const int duration[] =
  {1, 1, 1, 2, 1, 2, 1, 2,
   1, 1, 1, 1, 2, 1, 4,
   1, 1, 1, 1, 2, 1, 2, 1, 2,
-  1, 1, 1, 1, 1, 1, 1, 4};
-
-// total number of notes
-const int NOTES_COUNT = 4;
-
-// duration of each note
-const int NOTE_DUR = 200;
+  1, 1, 1, 1, 1, 1, 1, 4, 8};
+const int NOTES_COUNT = 33; // total number of notes
+const int NOTE_DUR = 200; // duration of each note
+const float NOTE_DUTY = 0.7; // duty ratio of each note

 // states
 int timerValue = 0; // current timer value
@@ -80,7 +78,7 @@
   checkTimerTimeout();
   checkCloudBitInput();
   playClick();
-  playMelody();
+  playNextTone();
 }

 // decrease timerValue every one sec if timer is not stopped
@@ -117,9 +115,7 @@
   timerValuePrev = 0;
   isCloudBitInputHigh = false;
   melodyCount = 0;
-  noteIndex = 0;
-  nextToneTime = 0;
-  nextNoToneTime = 0;
+  resetMelody();
 }

 // if start button is pressed, increase timerValue by START_VAL
@@ -138,27 +134,28 @@

 // output to counter 7seg LED
 void displayCounter() {
-  // maps 6000 sec to 100 minutes on littleBits LED
-  analogWrite(COUNTER_LED, map(timerValue, 0, 59, 0, 255));
-//  analogWrite(COUNTER_LED, map(timerValue, 0, 5999, 0, 255));
-}
-
-// output to cloudBit when timer counting is finished
+  // output only when it's not playing melody (to avoid internal timer conflict)
+  if (melodyCount == 0) {
+    analogWrite(COUNTER_LED, map(timerValue, 0, 5999, 0, 255)); // maps 6000 sec to 100 minutes on littleBits LED
+  }
+}
+
+// output to cloudBit and play melody when timer counting is finished
 void checkTimerTimeout() {
-  if (false && timerValue == 0 && timerValuePrev == 1) {
+  if (timerValue == 0 && timerValuePrev == 1) {
     analogWrite(CLOUDBIT_OUT, 255);
     delay(100);
     analogWrite(CLOUDBIT_OUT, 0);
-    melodyCount = MAX_MELODY_COUNT;
-  }
-}
-
-// check input from cloudBit to play alarm
+    startPlayingMelody();
+  }
+}
+
+// check input from cloudBit to play melody
 void checkCloudBitInput() {
   int cloudBitInput = analogRead(CLOUDBIT_IN);
   if (cloudBitInput >= ANALOG_HIGH_THRETHOLD && !isCloudBitInputHigh) {
     isCloudBitInputHigh = true;
-    melodyCount = MAX_MELODY_COUNT;
+    startPlayingMelody();
   }
   if (cloudBitInput < ANALOG_HIGH_THRETHOLD) {
     isCloudBitInputHigh = false;
@@ -185,7 +182,7 @@

   // if timer is ticking, blink it
   int blinkerValue = LOW;
-  if(timerValue % 2 == 0) {
+  if (timerValue % 2 == 0) {
     blinkerValue = LOW;
   } else {
     blinkerValue = HIGH;
@@ -193,17 +190,28 @@
   digitalWrite(SPEAKER_OUT, blinkerValue);
 }

-// play the melody if melodyCount > 0
-void playMelody() {
-
-  // if melody is not playing, return
+// start playing melody for MAX_MELODY_COUNT times
+void startPlayingMelody() {
+  melodyCount = MAX_MELODY_COUNT;
+  analogWrite(COUNTER_LED, 0); // to avoid conflict with tone()
+}
+
+// play next tone if melodyCount > 0
+void playNextTone() {
+
+  // if it is not playing melody, return
   if (melodyCount == 0) return;

   // if next tone time has reached, play next note
   if (millis() > nextToneTime) {
-    tone(SPEAKER_OUT, pooh_melody[noteIndex]);
+    int nextTone = pooh_melody[noteIndex];
+    if (nextTone != _0) {
+      tone(SPEAKER_OUT, nextTone);
+    } else {
+      noTone(SPEAKER_OUT);
+    }
     nextToneTime = millis() + (duration[noteIndex] * NOTE_DUR);
-    nextNoToneTime = millis() + (duration[noteIndex] * NOTE_DUR * 0.7);
+    nextNoToneTime = millis() + (duration[noteIndex] * NOTE_DUR * NOTE_DUTY);
     noteIndex++;
   }

@@ -211,13 +219,26 @@
   if (millis() > nextNoToneTime) {
     noTone(SPEAKER_OUT);

-    // if all notes has been played, decrease melodyCount.
+    // if all notes has been played, stop the melody and decrease melodyCount.
     if (noteIndex == NOTES_COUNT) {
-      noteIndex = 0;
-      nextToneTime = 0;
-      nextNoToneTime = 0;
+      resetMelody();
       melodyCount--;
     }
   }
 }

+// reset states for playing melody
+void resetMelody() {
+
+  // reset variables for tone generation
+  noteIndex = 0;
+  nextToneTime = 0;
+  nextNoToneTime = 0;
+
+  // reset internal timer after using tone()/noTone()
+  // see http://discuss.littlebits.cc/t/analogwrite-on-d5-doesnt-work-after-using-tone/7833
+  noTone(SPEAKER_OUT);
+  TCCR3A = 1;
+  TCCR3B = 3;
+}
+


Update SGANT.ino

Update SGANT.ino

Updating for new servo on EL gimbal

--- Arduino/MIMIC_Extras/SGANT/SGANT.ino
+++ Arduino/MIMIC_Extras/SGANT/SGANT.ino
@@ -27,7 +27,7 @@
   EL_servo.attach(10);
   XEL_servo.attach(9);

-  EL_servo.write(map(0, -90, 90, 25, 155)); //custom mapping the servo motion to the sgant elevation motion
+  EL_servo.write(map(0, -90, 90, 152, 30)); //custom mapping the servo motion to the sgant elevation motion
   XEL_servo.write(map(0, -90, 90, 28, 160)); //custom mapping the servo motion to the sgant cross elevation motion

   EL_servo.detach();
@@ -69,7 +69,7 @@
     XEL_servo.attach(9);

-    int newEL = map(EL, -90, 90, 25, 155);
+    int newEL = map(EL, -90, 90, 152, 30);
     int newXEL = map(XEL, -90, 90, 28, 160);

     EL_servo.write(newEL);


added gyroCalibration function

added gyroCalibration function

--- Arduino/sketches/TGimbal/Sensors.ino
+++ Arduino/sketches/TGimbal/Sensors.ino
@@ -365,3 +365,15 @@
   if (ACC) {ACC_init();acc_25deg = acc_1G * 0.423;}
   //f.I2C_INIT_DONE = 1;
 }
+
+void gyroCalibration(){
+  for(uint8_t axis = 0; axis < 3; axis++){ //calculate offsets to zeros gyros
+    for(int i = 0; i < 400; i++){ //averages 400 readings for each axis
+      Gyro_getADC();
+      calSum += gyroADC[axis];
+      delay(1);
+    }
+    gyroZero[axis] = calSum/400.f;
+    calSum = 0;
+  }
+}


Changed the two conveyors servos for DC Motors with mosfets. Also fixed a bug where the first conveyor wouldn't start when the switches were pressed.

--- Arduino/LoadingStation/LoadingStation.ino
+++ Arduino/LoadingStation/LoadingStation.ino
@@ -10,21 +10,14 @@
 #define CONVEYOR2_PIN           7

 //////// PWM ////////
-#define ELEVATOR_STOP  1500
-#define ELEVATOR_RUN   1400
-#define DOOR_STOP      1500
-#define DOOR_RUN       1400
 #define CONVEYOR_RUN   1400
 #define CONVEYOR_STOP  1500

 //////// Variables ////////
 LimitSwitch elevatorSwitch(ELEVATOR_SWITCH_PIN);
 LimitSwitch doorSwitch(DOOR_SWITCH_PIN);
-Servo elevator;
-Servo door;
 Servo conveyor1;
 Servo conveyor2;
-

 void setup() {
   Serial.begin(9600);
@@ -32,18 +25,16 @@
   elevatorSwitch.Setup();
   doorSwitch.Setup();

-  elevator.attach(ELEVATOR_PIN);
-  elevator.writeMicroseconds(ELEVATOR_STOP);
+  pinMode(ELEVATOR_PIN, OUTPUT);
+  pinMode(DOOR_PIN, OUTPUT);
+  digitalWrite(ELEVATOR_PIN, LOW);
+  digitalWrite(DOOR_PIN, LOW);

-  door.attach(DOOR_PIN);
-  door.writeMicroseconds(DOOR_STOP);
+  conveyor1.writeMicroseconds(CONVEYOR_STOP); // Set initial position
+  conveyor1.attach(CONVEYOR1_PIN);

-  conveyor1.attach(CONVEYOR1_PIN);
-  Serial.print("Starting fixed conveyor belt.");
-  conveyor1.writeMicroseconds(CONVEYOR_RUN);
-
+  conveyor2.writeMicroseconds(CONVEYOR_STOP); // Set initial position
   conveyor2.attach(CONVEYOR2_PIN);
-  conveyor2.writeMicroseconds(CONVEYOR_STOP);
 }

 void loop(){
@@ -52,28 +43,29 @@
   {
     Serial.print("Elevator door opened. Closing...");
     // On la ferme et on attend
-    door.writeMicroseconds(DOOR_RUN);
+    digitalWrite(DOOR_PIN, HIGH);
     doorSwitch.WaitForPress();
-    door.writeMicroseconds(DOOR_STOP);
+    digitalWrite(DOOR_PIN, LOW);
     Serial.print("Elevator door closed.");
   }
-
-  // L'ascenseur n'est pas en haut
-  if ( ! elevatorSwitch.ReadInput() )
-  {
-    // Arreter le tapis sur l'ascenseur (au cas ou il roulerait...)
-    conveyor2.writeMicroseconds(CONVEYOR_STOP);
-    // On monte l'ascenseur et on attend
-    Serial.print("Starting elevator.");
-    elevator.writeMicroseconds(ELEVATOR_RUN);
-    elevatorSwitch.WaitForPress();
-    // Arreter l'ascenseur
-    elevator.writeMicroseconds(ELEVATOR_STOP);
-    Serial.print("Stopping elevator.");
+  else{
+    // L'ascenseur n'est pas en haut
+    if ( ! elevatorSwitch.ReadInput() )
+    {
+      // Arreter le tapis sur l'ascenseur (au cas ou il roulerait...)
+      conveyor2.writeMicroseconds(CONVEYOR_STOP);
+      // On monte l'ascenseur et on attend
+      Serial.print("Starting elevator.");
+      digitalWrite(ELEVATOR_PIN, HIGH);
+      elevatorSwitch.WaitForPress();
+      // Arreter l'ascenseur
+      digitalWrite(ELEVATOR_PIN, LOW);
+      Serial.print("Stopping elevator.");
+    }
+    else{
+      // Si les deux switches sont appuyées, on roule les deux tapis.
+      conveyor1.writeMicroseconds(CONVEYOR_RUN);
+      conveyor2.writeMicroseconds(CONVEYOR_RUN);
+    }
   }
-
-  // Demarrer le tapis de l'ascenseur
-  Serial.print("Starting elevator's conveyor belt.");
-  conveyor2.writeMicroseconds(CONVEYOR_RUN);
-
 }


remove delay() function from motor control and use millis time compare instead.

--- arduinoTest/USB_FocusST/USB_FocusST.ino
+++ arduinoTest/USB_FocusST/USB_FocusST.ino
@@ -44,6 +44,8 @@
 int dataPin = 4;

 int motorPin = 5;
+long motor_time = 500; //number of milliseconds the motor vibrates
+
 int redLED = 9; //pwm
 int blueLED = 10; //pwm
 int greenLED = 11; //pwm
@@ -51,6 +53,7 @@
 String inputString = "";
 boolean stringComplete = false;
 boolean USB_connected = false;
+unsigned long time = 0;

 void setup() {
   //set pins to output so you can control the shift register
@@ -67,6 +70,9 @@
 }

 void loop() {
+
+  if (millis() - time >= motor_time) analogWrite(motorPin, 0);
+
   if (!USB_connected) {
     for (int c = 0; c < 6; c++) {
       sendDigit(circle[c]);
@@ -85,8 +91,7 @@

     if (inputString[inputString.length()-1] == ']') {
       analogWrite(motorPin, 255);
-      delay(500);
-      analogWrite(motorPin, 0);
+      time = millis();
     }

     if (inputString[inputString.length()-1] == ')') {


Moved output logic to separate function

Moved output logic to separate function

OO OO OO OO etc


make lcd work

make lcd work

--- engine-room/engine_arduino/engine_arduino.ino
+++ engine-room/engine_arduino/engine_arduino.ino
@@ -15,8 +15,8 @@
 const int NO = -1;  // Represents no pin
 const int SWITCH_PINS_OFFSET = 0;
 const int SWITCH_PINS[] = {
-   2,  3,  4,  5,  6,  7,  8,
-   9, 10, 11, 12, 13, 14, 15,
+   A0,  A1,  A2,  A4,  6,  7,  8,
+   9, 10, A5, A6, 13, 14, 15,
   16, 17, 18, 19, 20, 21, 22,
   23, 24, 25, 26, 27, 28, 29,
   30, 31, 32, 33, 34, 35, 36,
@@ -198,7 +198,7 @@
 }

 // TODO(bhomberg): update pin numbers
-LiquidCrystal lcd(2, 3, 4, 5, 6, 7);
+LiquidCrystal lcd(12, 11, 5, 4, 3, 2);

 // Arduino setup() and loop()
 void setup() {
@@ -211,7 +211,7 @@
     pinMode(pin, INPUT);
   }

-  lcd.begin(16, 2);
+  lcd.begin(20, 4);
   lcd.print("turn the lights on!  but do it right!");
 }


Due FirmataPlus Special

Due FirmataPlus Special

--- FirmataPlus/source/libraries/FirmataPlusDue/examples/FirmataPlusDue/FirmataPlusDue.ino
+++ FirmataPlus/source/libraries/FirmataPlusDue/examples/FirmataPlusDue/FirmataPlusDue.ino
@@ -902,9 +902,9 @@
       // turns off pullup, configures everything
       setPinModeCallback(i, PIN_MODE_ANALOG);
     }
-    else if ( IS_PIN_TONE(i)) {
-      noTone(i) ;
-    }
+//    else if ( IS_PIN_TONE(i)) {
+//      noTone(i) ;
+//    }
     else {
       // sets the output to 0, configures portConfigInputs
       setPinModeCallback(i, OUTPUT);


Atualização do sketch.

Atualização do sketch.

--- sketch/LM35.ino
+++ sketch/LM35.ino
@@ -9,8 +9,7 @@

 void loop()
 {
-	Serial.print((analogRead(temp) * 500.0) / 1024);
+	Serial.print((analogRead(temp) * 500.0) / 1023);
 	Serial.println();
 	delay(1000);
 }
-


Improve comments for AutoConnectWithStaticIP example

--- examples/AutoConnectWithStaticIP/AutoConnectWithStaticIP.ino
+++ examples/AutoConnectWithStaticIP/AutoConnectWithStaticIP.ino
@@ -35,16 +35,21 @@
   //reset settings - for testing
   //wifiManager.resetSettings();

-  //set static ip
-  //the commented bit only works for ESP8266 core 2.1.0 or newer
-  /*IPAddress _ip,_gw,_sn;
-  _ip.fromString(static_ip);
-  _gw.fromString(static_gw);
-  _sn.fromString(static_sn);
-*/
+  //set static ip
+  //block1 should be used for ESP8266 core 2.1.0 or newer, otherwise use block2
+
+  //start-block1
+  //IPAddress _ip,_gw,_sn;
+  //_ip.fromString(static_ip);
+  //_gw.fromString(static_gw);
+  //_sn.fromString(static_sn);
+  //end-block1
+
+  //start-block2
   IPAddress _ip = IPAddress(10, 0, 1, 78);
   IPAddress _gw = IPAddress(10, 0, 1, 1);
   IPAddress _sn = IPAddress(255, 255, 255, 0);
+  //end-block2

   wifiManager.setSTAStaticIPConfig(_ip, _gw, _sn);


Now sensor sends id and value eg: 1100123 where 11 is id and 123 is value

--- HomeBot.Arduino/Sensors/Motion/Motion.ino
+++ HomeBot.Arduino/Sensors/Motion/Motion.ino
@@ -2,11 +2,12 @@
 #include <RCSwitch.h> // https://code.google.com/p/rc-switch/
 #include <PinChangeInt.h>

-RCSwitch rf = RCSwitch();
-ISR(WDT_vect) {Sleepy::watchdogEvent();}  // Setup for low power waiting
+long sensorId = 11;         // sensor identifier - from 1 to 99
+long sensorAlertCode = 1;  // value send by sensor from 1 to 99999

-int calibrationTime = 10;        //the time we give the sensor to calibrate (10-60 secs according to the datasheet)
-int rfPacketsToSend = 10;
+int rfAlertCode = 1;     // must be in 24 bit so max 16777215 , should containd sensor id sensor value
+int calibrationTime = 12;  //the time we give the sensor to calibrate (10-60 secs according to the datasheet)
+int rfPacketsToSend = 7;   // to be sure message is received I send messge few times

 // Pins
 int PIR = 2;
@@ -14,7 +15,8 @@
 int RFTX = 9;
 int RFPOWER = 8;// do tranzystora

-int rfAlertCode = 666; // code send when motion detected
+RCSwitch rf = RCSwitch();
+ISR(WDT_vect) {Sleepy::watchdogEvent();}  // Setup for low power waiting

 void setup() {
   Serial.begin(9600);
@@ -31,38 +33,38 @@
 }

 void loop() {
-  int ll = HIGH;
+  Serial.print("<"); // Motion detected
+  digitalWrite(LED, HIGH);
   digitalWrite(RFPOWER, HIGH);// wlacz zasilanie w rf
   delay(100);
-  Serial.println("Motion detected");
+  digitalWrite(LED, LOW);
+
   for (int i = 0; i < rfPacketsToSend; i++)
   {
+    rf.send((sensorId * 100000) + sensorAlertCode, 24); // it will send 11 00001 where 11 is sensor id and 1 is motion detected
     Serial.print(".");
-    rf.send(rfAlertCode, 24);
-    digitalWrite(LED, ll);
-    ll = ll == HIGH ? LOW : HIGH;
   }
-  digitalWrite(RFPOWER, LOW); // wylacz rf
-  Serial.println("");
-
+  digitalWrite(RFPOWER, LOW); // wylacz zasialnie rf
+  Serial.println(">");
+  delay(100);
   Sleepy::powerDown();
 }

-void wakeUp() {}
+void wakeUp() { }

 void CalibratePirSensor()
 {
-  int ll = HIGH;
+
   Serial.println("Calibrating PIR sensor ");
   for (int i = 0; i < calibrationTime; i++) {
     Serial.print(".");
-    delay(1000);
-    digitalWrite(LED, ll);
-    ll = ll == HIGH ? LOW : HIGH;
+    digitalWrite(LED, HIGH);
+    delay(100);
+    digitalWrite(LED, LOW);
+    delay(900);
   }
   Serial.println("");
   Serial.println("Sensor active");
   digitalWrite(LED, LOW);
   delay(50);
 }
-


Added support for the radio enable pin

Added support for the radio enable pin

--- Balloon/Balloon.ino
+++ Balloon/Balloon.ino
@@ -63,7 +63,8 @@
 // *********************************************************************
 // NTX2 Transmitter settings
 #define RADIO_PIN 4
-#define CALL_SIGN "KD8VZA"
+#define RADIO_ENABLE_PIN 5
+#define CALL_SIGN "KD8VZA-KD8VZA-KD8VZA"
 #define TRANSMIT_EVERY_Nth_READING 10
 char TimeStampBuffer[20], AltitudeBuffer[20], LatitudeBuffer[20], LongitudeBuffer[20];
 char TransmitBuffer[100];
@@ -95,6 +96,7 @@
   HasGoodTempReading = false;

   pinMode(RADIO_PIN,OUTPUT);
+  pinMode(RADIO_ENABLE_PIN,INPUT);
   TransmitNumber = 0;
 }

@@ -219,6 +221,10 @@

 void TransmitDataToGround(float TimeStamp, float Altitude, float Latitude, float Longitude) {
+
+  // Build the string to transmit
+  digitalWrite(RADIO_ENABLE_PIN, HIGH);
+  delay(3000);
   dtostrf(TimeStamp, 20, 3, TimeStampBuffer);
   dtostrf(Altitude, 20, 3, AltitudeBuffer);
   dtostrf(Latitude, 20, 5, LatitudeBuffer);
@@ -231,14 +237,12 @@
   TransmitIndex = TransferBuffer(LatitudeBuffer, sizeof(LatitudeBuffer), TransmitBuffer, TransmitIndex, true);
   TransmitIndex = TransferBuffer(LongitudeBuffer, sizeof(LongitudeBuffer), TransmitBuffer, TransmitIndex, true);

-
   unsigned int CHECKSUM = gps_CRC16_checksum(TransmitBuffer);  // Calculates the checksum for this datastring
   sprintf(TransmitBufferChecksum, "*%04X\n", CHECKSUM);
   TransmitIndex = TransferBuffer(TransmitBufferChecksum, sizeof(TransmitBufferChecksum), TransmitBuffer, TransmitIndex, false);

-  // TODO: Write data to radio
-  //Serial.println(TransmitBuffer);
   rtty_txstring (TransmitBuffer);
+  digitalWrite(RADIO_ENABLE_PIN, LOW);
 }


example: add comment describing serial commands

--- examples/MAX1464_example.ino
+++ examples/MAX1464_example.ino
@@ -1,5 +1,5 @@
 /*
-  Example sketch for the MAX1464 library.
+  Example sketch for the Arduino MAX1464 library.
   Copyright (C) 2016 Giacomo Mazzamuto <gmazzamuto@gmail.com>

   This program is free software; you can redistribute it and/or
@@ -18,6 +18,24 @@

 /**
  * \file
+ * \brief Example sketch for the Arduino MAX1464 library
+ *
+ * This example sketch implements a serial terminal.
+ * This is a list of the serial commands available in the example:
+ * - `IDEN` print an identification string
+ * - `RFW [N]` read firmware (partition `N`)
+ * - `HALTCPU`
+ * - `RESETCPU`
+ * - `RELEASECPU`
+ * - `RP N` read CPU port number `N` (0-15)
+ * - `STEP` single step the CPU, useful for debugging
+ * - `!ERASEFLASHMEMORY!` (both partitions)
+ * - `!WRITEFLASHMEMORY!` enter firmware flashing mode. From now on, only HEX
+ *    lines are expected from the serial port. You can then send a whole HEX
+ *    file using your terminal emulator. Normal command mode is resumed after
+ *    the last HEX line has been sent, or alternatively by issuing the
+ *    `!ABORTWRITEFLASHMEMORY!` command.
+ * - `!ABORTWRITEFLASHMEMORY!` see above
  */

 #include "MAX1464.h"


fix error in console example

fix error in console example

--- examples/console/console.ino
+++ examples/console/console.ino
@@ -32,5 +32,5 @@
 }

 void loop() {
-  console->loop();
+  console.loop();
 }


Improved documentation

Improved documentation

--- EmbedVM_Arduino.ino
+++ EmbedVM_Arduino.ino
@@ -12,8 +12,8 @@
 #define BAUDRATE 9600 //UART baudrate
 #define VERBOSE false //verbose mode

-boolean stop = false;
-byte memory[MEMORY_SIZE];
+boolean stop = false; //whether the VM should skip execution of program
+byte memory[MEMORY_SIZE]; //VM memory

 //put in seperate namespace to prevent Arduino IDE from preprocessing it; Arduino preprocessor is ST00PID
 namespace no {
@@ -26,9 +26,11 @@
 void setup()
 {
   Serial.begin(BAUDRATE);
+
+  //copy program from EEPROM to RAM; EmbedVM can read program from RAM only
   for(int address = 0; address < PROGRAM_LENGTH; address++)
     memory[address] = EEPROM.read(address + PROGRAM_OFFSET);
-  embedvm_interrupt(&no::vm, PROGRAM_ENTRY);
+  embedvm_interrupt(&no::vm, PROGRAM_ENTRY); //start EmbedVM
 }

 void loop()
@@ -58,7 +60,7 @@
   embedvm_exec(&no::vm); //execute next instruction
 }

-
+//callback used by EmbedVM to read memory
 static int16_t memoryRead(uint16_t address, bool is16bit, void *ctx UNUSED)
 {
   if (is16bit)
@@ -66,6 +68,7 @@
   return memory[address];
 }

+//callback used by EmbedVM to write memory
 static void memoryWrite(uint16_t address, int16_t value, bool is16bit, void *ctx UNUSED)
 {
   if (is16bit) {
@@ -76,11 +79,13 @@
     memory[address] = value;
 }

+//callback used by EmbedVM to call user functions
 static int16_t callUserFunction(uint8_t function, uint8_t argc, int16_t *argv, void *ctx UNUSED)
 {
   int16_t ret = 0;
   int i;

+  //user function ID 0 = stop
   if (function == 0) {
     stop = true;
     Serial.println("Called user function 0 => stop.");
@@ -88,8 +93,8 @@
     return ret;
   }

+  //print user function call details (function ID, argument count, argument list)
   Serial.print("Called user function " + String(function) + " with " + String(argc) + " args:");
-
   for (i = 0; i < argc; i++) {
     Serial.print(" " + argv[i]);
     ret += argv[i];


Implement the rest of the alphabet

Implement the rest of the alphabet

--- software/firmware/LogoBotWifiScribbler/LogoBotWifiScribbler.ino
+++ software/firmware/LogoBotWifiScribbler/LogoBotWifiScribbler.ino
@@ -373,20 +373,83 @@
 void writeChar(char c) {

     switch(c) {
+      case 'A':
+        writeA();
+        break;
       case 'B':
         writeB();
         break;
+      case 'C':
+        writeC();
+        break;
+      case 'D':
+        writeD();
+        break;
+      case 'E':
+        writeE();
+        break;
+      case 'F':
+        writeF();
+        break;
       case 'G':
         writeG();
         break;
+      case 'H':
+        writeH();
+        break;
+      case 'I':
+        writeI();
+        break;
+      case 'J':
+        writeJ();
+        break;
+      case 'K':
+        writeK();
+        break;
       case 'L':
         writeL();
         break;
+      case 'M':
+        writeM();
+        break;
+      case 'N':
+        writeN();
+        break;
       case 'O':
         writeO();
         break;
+      case 'P':
+        writeP();
+        break;
+      case 'Q':
+        writeQ();
+        break;
+      case 'R':
+        writeR();
+        break;
+      case 'S':
+        writeS();
+        break;
       case 'T':
         writeT();
+        break;
+      case 'U':
+        writeU();
+        break;
+      case 'V':
+        writeV();
+        break;
+      case 'W':
+        writeW();
+        break;
+      case 'X':
+        writeX();
+        break;
+      case 'Y':
+        writeY();
+        break;
+      case 'Z':
+        writeZ();
         break;

       default:
@@ -407,7 +470,29 @@

 // Alphabet

-#define NEXTLETTER pushTo(x + w + letterSpacing, y);
+#define NEXTLETTER nextLetter(x + w + letterSpacing, y);
+
+void nextLetter(float x, float y)
+{
+  pushCmd("PU");
+  pushTo(x, y);
+}
+
+void writeA()
+{
+  float x = position.x;
+  float y = position.y;
+  float w = fontSize * 0.5;
+
+  pushCmd("PD");
+  pushTo(x + w/2, y + capHeight);
+  pushTo(x + w, y);
+  pushCmd("PU");
+  pushTo(x + w / 4, y + capHeight / 2);
+  pushCmd("PD");
+  pushTo(x + 3 * w / 4, y + capHeight / 2 );
+  NEXTLETTER
+}

 void writeB()
 {
@@ -423,7 +508,70 @@
   pushTo(x + 2 * w / 3, y + capHeight);
   pushTo(x, y + capHeight);
   pushTo(x, y);
+  NEXTLETTER
+}
+
+void writeC()
+{
+  float x = position.x;
+  float y = position.y;
+  float w = fontSize * 0.5;
+
+  pushTo(x + w, y + capHeight);
+  pushCmd("PD");
+  pushTo(x, y + capHeight);
+  pushTo(x, y);
+  pushTo(x + w, y);
+  NEXTLETTER
+}
+
+void writeD()
+{
+  float x = position.x;
+  float y = position.y;
+  float w = fontSize * 0.5;
+
+  pushCmd("PD");
+  pushTo(x + 3 * w / 4, y);
+  pushTo(x + w, y + capHeight / 4);
+  pushTo(x + w, y + 3 * capHeight / 4);
+  pushTo(x + 3 * w / 4, y + capHeight);
+  pushTo(x, y + capHeight);
+  pushTo(x, y);
+  NEXTLETTER
+}
+
+void writeE()
+{
+  float x = position.x;
+  float y = position.y;
+  float w = fontSize * 0.5;
+
+  pushCmd("PD");
+  pushTo(x, y + capHeight);
+  pushTo(x + w, y + capHeight);
   pushCmd("PU");
+  pushTo(x + w, y + capHeight / 2);
+  pushCmd("PD");
+  pushTo(x, y + capHeight / 2);
+  pushTo(x, y);
+  pushTo(x + w, y);
+  NEXTLETTER
+}
+
+void writeF()
+{
+  float x = position.x;
+  float y = position.y;
+  float w = fontSize * 0.5;
+
+  pushCmd("PD");
+  pushTo(x, y + capHeight);
+  pushTo(x + w, y + capHeight);
+  pushCmd("PU");
+  pushTo(x + w, y + capHeight / 2);
+  pushCmd("PD");
+  pushTo(x, y + capHeight / 2);
   NEXTLETTER
 }

@@ -432,6 +580,7 @@
   float x = position.x;
   float y = position.y;
   float w = fontSize * 0.5;
+
   pushTo(x + w, y + capHeight);
   pushCmd("PD");
   pushTo(x, y + capHeight);
@@ -439,7 +588,63 @@
   pushTo(x + w, y);
   pushTo(x + w, y + capHeight/3);
   pushTo(x + w/3, y + capHeight/3);
+  NEXTLETTER
+}
+
+void writeH()
+{
+  float x = position.x;
+  float y = position.y;
+  float w = fontSize * 0.5;
+
+  pushCmd("PD");
+  pushTo(x, y + capHeight);
+  pushTo(x, y + capHeight / 2);
+  pushTo(x + w, y + capHeight / 2);
+  pushTo(x + w, y + capHeight);
+  pushTo(x + w, y);
+  NEXTLETTER
+}
+
+void writeI()
+{
+  float x = position.x;
+  float y = position.y;
+  float w = fontSize * 0.5;
+
+  pushTo(x + w / 2, y);
+  pushCmd("PD");
+  pushTo(x + w / 2, y + capHeight);
+  NEXTLETTER
+}
+
+void writeJ()
+{
+  float x = position.x;
+  float y = position.y;
+  float w = fontSize * 0.5;
+
+  pushTo(x, y + capHeight / 4);
+  pushCmd("PD");
+  pushTo(x, y);
+  pushTo(x + w, y);
+  pushTo(x + w, y + capHeight);
+  NEXTLETTER
+}
+
+void writeK()
+{
+  float x = position.x;
+  float y = position.y;
+  float w = fontSize * 0.5;
+
+  pushCmd("PD");
+  pushTo(x, y + capHeight);
   pushCmd("PU");
+  pushTo(x + w, y + capHeight);
+  pushCmd("PD");
+  pushTo(x, y + capHeight / 2);
+  pushTo(x + w, y);
   NEXTLETTER
 }

@@ -448,43 +653,216 @@
   float x = position.x;
   float y = position.y;
   float w = fontSize * 0.5;
+
   pushCmd("PD");
   pushTo(x, y + capHeight);
   pushTo(x,y);
   pushTo(x + w, y);
+  NEXTLETTER
+}
+
+void writeM()
+{
+  float x = position.x;
+  float y = position.y;
+  float w = fontSize * 0.5;
+
+  pushCmd("PD");
+  pushTo(x, y + capHeight);
+  pushTo(x + w / 2, y + capHeight / 2);
+  pushTo(x + w, y + capHeight);
+  pushTo(x + w, y);
+  NEXTLETTER
+}
+
+void writeN()
+{
+  float x = position.x;
+  float y = position.y;
+  float w = fontSize * 0.5;
+
+  pushCmd("PD");
+  pushTo(x, y + capHeight);
+  pushTo(x + w, y);
+  pushTo(x + w, y + capHeight);
+  NEXTLETTER
+}
+
+void writeO()
+{
+  float x = position.x;
+  float y = position.y;
+  float w = fontSize * 0.5;
+
+  pushCmd("PD");
+  pushTo(x + w, y);
+  pushTo(x + w, y + capHeight);
+  pushTo(x, y + capHeight);
+  pushTo(x, y);
+  NEXTLETTER
+}
+
+void writeP()
+{
+  float x = position.x;
+  float y = position.y;
+  float w = fontSize * 0.5;
+
+  pushCmd("PD");
+  pushTo(x, y + capHeight);
+  pushTo(x + w, y + capHeight);
+  pushTo(x + w, y + capHeight / 2);
+  pushTo(x, y + capHeight / 2);
+  NEXTLETTER
+}
+
+void writeQ()
+{
+  float x = position.x;
+  float y = position.y;
+  float w = fontSize * 0.5;
+
+  pushCmd("PD");
+  pushTo(x + w / 2, y);
+  pushTo(x + w, y + capHeight / 2);
+  pushTo(x + w, y + capHeight);
+  pushTo(x, y + capHeight);
+  pushTo(x, y);
   pushCmd("PU");
-  NEXTLETTER
-}
-
-void writeO()
-{
-  float x = position.x;
-  float y = position.y;
-  float w = fontSize * 0.5;
-  pushCmd("PD");
-  pushTo(x + w, y);
-  pushTo(x + w, y + capHeight);
-  pushTo(x, y + capHeight);
-  pushTo(x, y);
+  pushTo(x + w / 2, y + capHeight / 2);
+  pushCmd("PD");
+  pushTo(x + w, y);
+  NEXTLETTER
+}
+
+void writeR()
+{
+  float x = position.x;
+  float y = position.y;
+  float w = fontSize * 0.5;
+
+  pushCmd("PD");
+  pushTo(x, y + capHeight);
+  pushTo(x + w, y + capHeight);
+  pushTo(x + w, y + capHeight / 2);
+  pushTo(x, y + capHeight / 2);
+  pushTo(x + w, y);
+  NEXTLETTER
+}
+
+void writeS()
+{
+  float x = position.x;
+  float y = position.y;
+  float w = fontSize * 0.5;
+
+  pushCmd("PD");
+  pushTo(x + w, y);
+  pushTo(x + w, y + capHeight / 2);
+  pushTo(x, y + capHeight / 2);
+  pushTo(x, y + capHeight);
+  pushTo(x + w, y + capHeight);
+  NEXTLETTER
+}
+
+void writeT()
+{
+  float x = position.x;
+  float y = position.y;
+  float w = fontSize * 0.5;
+  pushTo(x + w/2, y);
+  pushCmd("PD");
+  pushTo(x + w/2, y + capHeight);
+  pushTo(x, y + capHeight);
+  pushTo(x + w, y + capHeight);
+  NEXTLETTER
+}
+
+void writeU()
+{
+  float x = position.x;
+  float y = position.y;
+  float w = fontSize * 0.5;
+
+  pushTo(x, y + capHeight);
+  pushCmd("PD");
+  pushTo(x, y);
+  pushTo(x + w, y);
+  pushTo(x + w, y + capHeight);
+  NEXTLETTER
+}
+
+void writeV()
+{
+  float x = position.x;
+  float y = position.y;
+  float w = fontSize * 0.5;
+
+  pushTo(x, y + capHeight);
+  pushCmd("PD");
+  pushTo(x + w / 2, y);
+  pushTo(x + w, y + capHeight);
+  NEXTLETTER
+}
+
+void writeW()
+{
+  float x = position.x;
+  float y = position.y;
+  float w = fontSize * 0.5;
+
+  pushTo(x, y + capHeight);
+  pushCmd("PD");
+  pushTo(x + w / 4, y);
+  pushTo(x + w / 2, y + capHeight / 2);
+  pushTo(x + 3 * w / 4, y);
+  pushTo(x + w, y + capHeight);
+  NEXTLETTER
+}
+
+void writeX()
+{
+  float x = position.x;
+  float y = position.y;
+  float w = fontSize * 0.5;
+
+  pushCmd("PD");
+  pushTo(x + w, y + capHeight);
   pushCmd("PU");
-  NEXTLETTER
-}
-
-void writeT()
-{
-  float x = position.x;
-  float y = position.y;
-  float w = fontSize * 0.5;
-  pushTo(x + w/2, y);
-  pushCmd("PD");
-  pushTo(x + w/2, y + capHeight);
-  pushTo(x, y + capHeight);
+  pushTo(x, y + capHeight);
+  pushCmd("PD");
+  pushTo(x + w, y);
+  NEXTLETTER
+}
+
+void writeY()
+{
+  float x = position.x;
+  float y = position.y;
+  float w = fontSize * 0.5;
+
+  pushCmd("PD");
   pushTo(x + w, y + capHeight);
   pushCmd("PU");
-  NEXTLETTER
-}
-
-
+  pushTo(x, y + capHeight);
+  pushCmd("PD");
+  pushTo(x + w / 2, y + capHeight / 2);
+  NEXTLETTER
+}
+
+void writeZ()
+{
+  float x = position.x;
+  float y = position.y;
+  float w = fontSize * 0.5;
+
+  pushTo(x, y + capHeight);
+  pushCmd("PD");
+  pushTo(x + w, y + capHeight);
+  pushTo(x, y);
+  pushTo(x + w, y);
+  NEXTLETTER
+}

 long sqr(long v) {
   return v*v;


added EEPROM writing

added EEPROM writing

--- firmware/beer/beersensor.ino
+++ firmware/beer/beersensor.ino
@@ -15,9 +15,10 @@
 // #include "neopixel/neopixel.h"
 #include "neopixel.h"

-#define EEPROM_ADDR_T0 0
-#define EEPROM_ADDR_T1 20
-#define EEPROM_ADDR_T2 40
+//photon has 2048 bytes of emulated EEPROM
+#define EEPROM_ADDR_T0 0 //400 bytes per tap
+#define EEPROM_ADDR_T1 400
+#define EEPROM_ADDR_T2 800

 #define PIXEL_TYPE WS2812B
 #define PIXEL_COUNT 14
@@ -78,10 +79,10 @@

   pinMode(ledPin, OUTPUT);

-  //read any values set in the EEPROM
-  // maxPulseCount = EEPROM.read(EEPROM_ADDR_MAX_PULSE_COUNT);
-  // pulseCount = EEPROM.read(EEPROM_ADDR_PULSE_COUNT);
-  // percentFull = EEPROM.read(EEPROM_ADDR_PERCENT_FULL);
+  //read any objects set in the EEPROM
+  EEPROM.get(EEPROM_ADDR_T0, T0);
+  EEPROM.get(EEPROM_ADDR_T1, T1);
+  EEPROM.get(EEPROM_ADDR_T2, T2);

   //https://api.particle.io/v1/devices/<device_id>/<variable_name>?access_token=<access_token>
   Particle.variable("maxPCntT0", &T0.maxPulseCount, INT);
@@ -89,15 +90,15 @@
   Particle.variable("pulseCntT0", &T0.pulseCount, INT);
   Particle.variable("perFullT0", &T0.percentFull, INT);

-  // Particle.variable("maxPCntT1", &maxPulseCountT1, INT);
-  // Particle.variable("instPCntT1", &instantPulseCountT1, INT);
-  // Particle.variable("pulseCntT1", &pulseCountT1, INT);
-  // Particle.variable("perFullT1", &percentFullT1, INT);
-
-  // Particle.variable("maxPCntT2", &maxPulseCountT2, INT);
-  // Particle.variable("instPCntT2", &instantPulseCountT2, INT);
-  // Particle.variable("pulseCntT2", &pulseCountT2, INT);
-  // Particle.variable("perFullT2", &percentFullT2, INT);
+  Particle.variable("maxPCntT1", &T1.maxPulseCount, INT);
+  Particle.variable("instPCntT1", &T1.instantPulseCount, INT);
+  Particle.variable("pulseCntT1", &T1.pulseCount, INT);
+  Particle.variable("perFullT1", &T0.percentFull, INT);
+
+  Particle.variable("maxPCntT2", &T2.maxPulseCount, INT);
+  Particle.variable("instPCntT2", &T2.instantPulseCount, INT);
+  Particle.variable("pulseCntT2", &T2.pulseCount, INT);
+  Particle.variable("perFullT2", &T2.percentFull, INT);

   //cloud functions - handle a cloud POST(data)
   //curl https://api.particle.io/v1/devices/<device_id>/post \
@@ -116,7 +117,6 @@
   Serial.println("SETUP DONE");
 }

-//TODO: make this work for 3 taps
 int handlePost(String postData)
 {
   String* args = stringSplit(postData, ',');
@@ -126,14 +126,15 @@

   if(command.equals("reset"))
   { //reset data
-    Serial.println("reset pulse count");
-    return resetPulseCount();
+    //args[1] == tap number to reset (0-3)
+    //this function resets pulseCount to maxPulseCount and writes the EEPROM
+    return resetPulseCount(args[1].toInt());
   }
   else if(command.equals("setCalibration"))
   {
-    //takes an int as an argument.  args[1] should be the total number of pulses in a given keg.
-    //i.e. pulseCount / args[1] == percentFull
-    setCalibration(args[1].toInt());
+    //args[1] == tap you want to set (0-3)
+    //args[2] == calibration value (total number of pulses in a keg)
+    setCalibration(args[1].toInt(), args[2].toInt());
   }

   return 1;
@@ -154,19 +155,19 @@
   T0.percentFull = (int)(percentT0 * 100.0f);
   if(T0.percentFull > 100)
     T0.percentFull = 100;
-  // EEPROM.update(EEPROM_ADDR_PERCENT_FULL, percentFull);
+  EEPROM.put(EEPROM_ADDR_T0, T0);

   float percentT1 = (float)T1.pulseCount / (float)T1.maxPulseCount;
   T1.percentFull = (int)(percentT1 * 100.0f);
   if(T1.percentFull > 100)
     T1.percentFull = 100;
-  // EEPROM.update(EEPROM_ADDR_PERCENT_FULL, percentFull);
+  EEPROM.put(EEPROM_ADDR_T1, T1);

   float percentT2 = (float)T2.pulseCount / (float)T2.maxPulseCount;
   T2.percentFull = (int)(percentT2 * 100.0f);
   if(T2.percentFull > 100)
     T2.percentFull = 100;
-  // EEPROM.update(EEPROM_ADDR_PERCENT_FULL, percentFull);
+  EEPROM.put(EEPROM_ADDR_T2, T2);

   Serial.println("flowingT0: " + String(T0.flowing));
   Serial.println("flowingT1: " + String(T1.flowing));
@@ -180,7 +181,7 @@
   {
     if(T0.pulseCount > T0.maxPulseCount)
       T0.pulseCount = T0.maxPulseCount;
-    // EEPROM.update(EEPROM_ADDR_PULSE_COUNT, pulseCount);
+    EEPROM.put(EEPROM_ADDR_T0, T0);
     recalculateTapColor(0);
   }

@@ -192,7 +193,7 @@
   {
     if(T1.pulseCount > T1.maxPulseCount)
       T1.pulseCount = T1.maxPulseCount;
-    // EEPROM.update(EEPROM_ADDR_PULSE_COUNT, pulseCount);
+    EEPROM.put(EEPROM_ADDR_T1, T1);
     recalculateTapColor(1);
   }

@@ -204,22 +205,49 @@
   {
     if(T2.pulseCount > T2.maxPulseCount)
       T2.pulseCount = T2.maxPulseCount;
-    // EEPROM.update(EEPROM_ADDR_PULSE_COUNT, pulseCount);
+    EEPROM.put(EEPROM_ADDR_T1, T1);
     recalculateTapColor(2);
   }
 }

-int resetPulseCount()
-{
-  // pulseCount = maxPulseCount;
-  // EEPROM.update(EEPROM_ADDR_PULSE_COUNT, pulseCount);
+int resetPulseCount(int tap)
+{
+  if(tap == 0)
+  {
+    T0.pulseCount = T0.maxPulseCount;
+    EEPROM.put(EEPROM_ADDR_T0, T0);
+  }
+  else if(tap == 1)
+  {
+    T1.pulseCount = T1.maxPulseCount;
+    EEPROM.put(EEPROM_ADDR_T1, T1);
+  }
+  else if(tap == 2)
+  {
+    T2.pulseCount = T2.maxPulseCount;
+    EEPROM.put(EEPROM_ADDR_T2, T2);
+  }
+
   return 1;
 }

-int setCalibration(int val)
-{
-  // maxPulseCount = val;
-  // EEPROM.update(EEPROM_ADDR_MAX_PULSE_COUNT, maxPulseCount);
+int setCalibration(int tap, int val)
+{
+  if(tap == 0)
+  {
+    T0.maxPulseCount = val;
+    EEPROM.put(EEPROM_ADDR_T0, T0);
+  }
+  else if(tap == 1)
+  {
+    T1.maxPulseCount = val;
+    EEPROM.put(EEPROM_ADDR_T1, T1);
+  }
+  else if(tap == 2)
+  {
+    T2.maxPulseCount = val;
+    EEPROM.put(EEPROM_ADDR_T2, T2);
+  }
   return 1;
 }


indent of { and display on change

indent of { and display on change

--- _56-gopro-control/a-93-config-on-rtc-with-external-poweron-signal-autoexec/a-93-config-on-rtc-with-external-poweron-signal-autoexec.ino
+++ _56-gopro-control/a-93-config-on-rtc-with-external-poweron-signal-autoexec/a-93-config-on-rtc-with-external-poweron-signal-autoexec.ino
@@ -27,8 +27,10 @@
 // https://github.com/Makuna/Rtc
 #include <RtcDS3231.h>
 /* -- */
-extern "C" {
-  typedef struct {
+extern "C"
+{
+  typedef struct
+  {
     uint32_t Intermediate_Hash[SHA1_SIZE / 4];  /* Message Digest */
     uint32_t Length_Low;                        /* Message length in bits */
     uint32_t Length_High;                       /* Message length in bits */
@@ -116,7 +118,8 @@
 IPAddress mqtt_server = MQTT_SERVER;
 IPAddress time_server = MQTT_SERVER;
 /* ---- */
-struct {
+typedef struct
+{
   float Temperature1;
   float Temperature2;
   float Humidity;
@@ -126,9 +129,11 @@
   float data4;
   uint16_t powerAvg;
   uint16_t pir;
-} solar_data;
+} lcd_data;
+lcd_data solar_data, curr_data;
 /* ---- */
-struct {
+struct
+{
   uint32_t hash;
   bool gopro_mode;
   bool formatspiffs;
@@ -213,7 +218,8 @@
 //
 bool x;

-static uint32_t fnv_1_hash_32(uint8_t *bytes, size_t length) {
+static uint32_t fnv_1_hash_32(uint8_t *bytes, size_t length)
+{
   static const uint32_t FNV_OFFSET_BASIS_32 = 2166136261U;
   static const uint32_t FNV_PRIME_32 = 16777619U;
   uint32_t hash = FNV_OFFSET_BASIS_32;
@@ -221,18 +227,22 @@
   return hash;
 }

-template <class T> uint32_t calc_hash(T& data) {
+template <class T> uint32_t calc_hash(T& data)
+{
   return fnv_1_hash_32(((uint8_t*)&data) + sizeof(data.hash), sizeof(T) - sizeof(data.hash));
 }

-void alm_isr() {
+void alm_isr()
+{
   balm_isr = true;
 }

-bool rtc_config_read() {
+bool rtc_config_read()
+{
   bool ok = system_rtc_mem_read(65, &rtc_boot_mode, sizeof(rtc_boot_mode));
   uint32_t hash = calc_hash(rtc_boot_mode);
-  if (!ok || rtc_boot_mode.hash != hash) {
+  if (!ok || rtc_boot_mode.hash != hash)
+  {
     rtc_boot_mode.gopro_mode     = false;
     rtc_boot_mode.formatspiffs   = false;
     rtc_boot_mode.Temperature    = 0;
@@ -244,7 +254,9 @@
     rtc_boot_mode.attempt_detail = 0;
     rtc_boot_mode.pic_taken      = 0;
     ok = false;
-  } else {
+  }
+  else
+  {
     gopro_dir  = rtc_boot_mode.gopro_dir;
     gopro_file = rtc_boot_mode.gopro_file;
     media_id  = rtc_boot_mode.media_id;
@@ -252,13 +264,15 @@
   return ok;
 }

-bool rtc_config_save() {
+bool rtc_config_save()
+{
   strncpy(rtc_boot_mode.gopro_dir, gopro_dir.c_str(), sizeof(rtc_boot_mode.gopro_dir));
   strncpy(rtc_boot_mode.gopro_file, gopro_file.c_str(), sizeof(rtc_boot_mode.gopro_file));
   strncpy(rtc_boot_mode.media_id, media_id.c_str(), sizeof(rtc_boot_mode.media_id));
   rtc_boot_mode.hash = calc_hash(rtc_boot_mode);
   bool ok = system_rtc_mem_write(65, &rtc_boot_mode, sizeof(rtc_boot_mode));
-  if (!ok) {
+  if (!ok)
+  {
     ok = false;
   }
   return ok;
@@ -277,19 +291,24 @@
   }
 */

-void saveConfig_helper() {
+void saveConfig_helper()
+{
   lcd.clear();
   lcd.setCursor(0, 0);
-  if (!rtc_config_save()) {
+  if (!rtc_config_save())
+  {
     lcd.print("[CONFIG] save fail");
-  } else {
+  }
+  else
+  {
     lcd.print("[CONFIG] saved");
   }
   delay(2000);
 }

-void lcd_redraw() {
+void lcd_redraw()
+{
   lcd.clear();
   lcd.setCursor(0, 1);
   lcd.write(1);
@@ -313,7 +332,8 @@
   lcd.print((char)223);
 }

-void gopro_connect() {
+void gopro_connect()
+{
 #define GIPSET_STATIC { 10, 5, 5, 109 }
 #define GIPSET_GATEWAY { 10, 5, 5, 9 }
 #define GIPSET_SUBNET { 255, 255, 255, 0 }
@@ -336,8 +356,68 @@
   lcd.print(goprossid);

   int Attempt = 0;
-  while (WiFi.status() != WL_CONNECTED) {
+  while (WiFi.status() != WL_CONNECTED)
+  {
     delay(200);
+
+    int n = (Attempt % 20);
+    lcd.setCursor(n, 1);
+    lcd.print("*");
+    if (n < 19)
+    {
+      lcd.setCursor((n + 1), 1);
+      lcd.print(" ");
+    }
+    Attempt++;
+    if (Attempt == 300)
+    {
+      rtc_boot_mode.attempt_this++;
+      if ( rtc_boot_mode.attempt_this > 1)
+      {
+        rtc_boot_mode.attempt_phase = 0;
+        rtc_boot_mode.attempt_detail = 1;
+        rtc_boot_mode.twitter_phase = 8;
+      }
+      saveConfig_helper();
+      delay(200);
+      ESP.restart();
+    }
+  }
+  lcd.setCursor(0, 2);
+  lcd.print("ip: ");
+  lcd.print(WiFi.localIP());
+  delay(1000);
+}
+
+void wifi_connect()
+{
+
+#define IPSET_STATIC { 192, 168, 10, 60 }
+#define IPSET_GATEWAY { 192, 168, 10, 1 }
+#define IPSET_SUBNET { 255, 255, 255, 0 }
+#define IPSET_DNS { 192, 168, 10, 1 }
+
+  IPAddress ip_static = IPSET_STATIC;
+  IPAddress ip_gateway = IPSET_GATEWAY;
+  IPAddress ip_subnet = IPSET_SUBNET;
+  IPAddress ip_dns = IPSET_DNS;
+
+  wifi_set_phy_mode(PHY_MODE_11N);
+  WiFi.mode(WIFI_STA);
+  wifi_station_connect();
+  WiFi.begin(ssid, password);
+  WiFi.config(IPAddress(ip_static), IPAddress(ip_gateway), IPAddress(ip_subnet), IPAddress(ip_dns));
+  WiFi.hostname("esp-solar");
+
+  lcd.clear();
+  lcd.setCursor(0, 0);
+  lcd.print("conn to: ");
+  lcd.print(ssid);
+
+  int Attempt = 0;
+  while (WiFi.status() != WL_CONNECTED)
+  {
+    delay(100);

     int n = (Attempt % 20);
     lcd.setCursor(n, 1);
@@ -348,14 +428,6 @@
     }
     Attempt++;
     if (Attempt == 300) {
-      rtc_boot_mode.attempt_this++;
-      if ( rtc_boot_mode.attempt_this > 1) {
-        rtc_boot_mode.attempt_phase = 0;
-        rtc_boot_mode.attempt_detail = 1;
-        rtc_boot_mode.twitter_phase = 8;
-      }
-      saveConfig_helper();
-      delay(200);
       ESP.restart();
     }
   }
@@ -363,57 +435,12 @@
   lcd.print("ip: ");
   lcd.print(WiFi.localIP());
   delay(1000);
-}
-
-void wifi_connect() {
-
-#define IPSET_STATIC { 192, 168, 10, 60 }
-#define IPSET_GATEWAY { 192, 168, 10, 1 }
-#define IPSET_SUBNET { 255, 255, 255, 0 }
-#define IPSET_DNS { 192, 168, 10, 1 }
-
-  IPAddress ip_static = IPSET_STATIC;
-  IPAddress ip_gateway = IPSET_GATEWAY;
-  IPAddress ip_subnet = IPSET_SUBNET;
-  IPAddress ip_dns = IPSET_DNS;
-
-  wifi_set_phy_mode(PHY_MODE_11N);
-  WiFi.mode(WIFI_STA);
-  wifi_station_connect();
-  WiFi.begin(ssid, password);
-  WiFi.config(IPAddress(ip_static), IPAddress(ip_gateway), IPAddress(ip_subnet), IPAddress(ip_dns));
-  WiFi.hostname("esp-solar");
-
-  lcd.clear();
-  lcd.setCursor(0, 0);
-  lcd.print("conn to: ");
-  lcd.print(ssid);
-
-  int Attempt = 0;
-  while (WiFi.status() != WL_CONNECTED) {
-    delay(100);
-
-    int n = (Attempt % 20);
-    lcd.setCursor(n, 1);
-    lcd.print("*");
-    if (n < 19) {
-      lcd.setCursor((n + 1), 1);
-      lcd.print(" ");
-    }
-    Attempt++;
-    if (Attempt == 300) {
-      ESP.restart();
-    }
-  }
-  lcd.setCursor(0, 2);
-  lcd.print("ip: ");
-  lcd.print(WiFi.localIP());
-  delay(1000);

   lcd_redraw();
 }

-void spiffs_format() {
+void spiffs_format()
+{
   lcd.clear();
   lcd.setCursor(0, 0);
   lcd.print("[SPIFFS] format ....");
@@ -424,7 +451,8 @@
 }

 /* ----------------------------------- */
-String make_signature(const char* secret_one, const char* secret_two, String base_string) {
+String make_signature(const char* secret_one, const char* secret_two, String base_string)
+{

   String signing_key = URLEncode(secret_one);
   signing_key += "&";
@@ -446,17 +474,21 @@

 // from http://hardwarefun.com/tutorials/url-encoding-in-arduino
 // modified by chaeplin
-String URLEncode(const char* msg) {
+String URLEncode(const char* msg)
+{
   const char *hex = "0123456789ABCDEF";
   String encodedMsg = "";

-  while (*msg != '\0') {
+  while (*msg != '\0')
+  {
     if ( ('a' <= *msg && *msg <= 'z')
          || ('A' <= *msg && *msg <= 'Z')
          || ('0' <= *msg && *msg <= '9')
          || *msg  == '-' || *msg == '_' || *msg == '.' || *msg == '~' ) {
       encodedMsg += *msg;
-    } else {
+    }
+    else
+    {
       encodedMsg += '%';
       encodedMsg += hex[*msg >> 4];
       encodedMsg += hex[*msg & 0xf];
@@ -467,7 +499,8 @@
 }

 // https://github.com/igrr/axtls-8266/blob/master/crypto/hmac.c
-void ssl_hmac_sha1(const uint8_t *msg, int length, const uint8_t *key, int key_len, uint8_t *digest) {
+void ssl_hmac_sha1(const uint8_t *msg, int length, const uint8_t *key, int key_len, uint8_t *digest)
+{
   SHA1_CTX context;
   uint8_t k_ipad[64];
   uint8_t k_opad[64];
@@ -494,21 +527,27 @@
   SHA1_Final(digest, &context);
 }
 /* -- */
-void sendmqttMsg(char* topictosend, String topicpayload) {
+
+void sendmqttMsg(char* topictosend, String topicpayload)
+{
   unsigned int msg_length = topicpayload.length();

   byte* p = (byte*)malloc(msg_length);
   memcpy(p, (char*) topicpayload.c_str(), msg_length);

-  if (mqttclient.publish(topictosend, p, msg_length, 1)) {
+  if (mqttclient.publish(topictosend, p, msg_length, 1))
+  {
     free(p);
-  } else {
+  }
+  else
+  {
     free(p);
   }
   mqttclient.loop();
 }

-void sendUdpSyslog(String msgtosend) {
+void sendUdpSyslog(String msgtosend)
+{
   unsigned int msg_length = msgtosend.length();
   byte* p = (byte*)malloc(msg_length);
   memcpy(p, (char*) msgtosend.c_str(), msg_length);
@@ -520,7 +559,8 @@
   free(p);
 }

-void sendUdpmsg(String msgtosend) {
+void sendUdpmsg(String msgtosend)
+{
   unsigned int msg_length = msgtosend.length();
   byte* p = (byte*)malloc(msg_length);
   memcpy(p, (char*) msgtosend.c_str(), msg_length);
@@ -530,12 +570,14 @@
   udp.endPacket();
   free(p);
 }
-/* -- */
-time_t requestSync() {
+
+time_t requestSync()
+{
   return 0;
 }

-time_t requestRtc() {
+time_t requestRtc()
+{
   RtcDateTime Epoch32Time = Rtc.GetDateTime();
   return (Epoch32Time + 946684800);
 }
@@ -544,7 +586,8 @@
 const int NTP_PACKET_SIZE = 48;
 byte packetBuffer[NTP_PACKET_SIZE];

-void sendNTPpacket(IPAddress & address) {
+void sendNTPpacket(IPAddress & address)
+{
   memset(packetBuffer, 0, NTP_PACKET_SIZE);
   packetBuffer[0] = 0b11100011;
   packetBuffer[1] = 0;
@@ -559,13 +602,16 @@
   udp.endPacket();
 }

-time_t getNtpTime() {
+time_t getNtpTime()
+{
   while (udp.parsePacket() > 0) ;
   sendNTPpacket(time_server);
   uint32_t beginWait = millis();
-  while (millis() - beginWait < 2500) {
+  while (millis() - beginWait < 2500)
+  {
     int size = udp.parsePacket();
-    if (size >= NTP_PACKET_SIZE) {
+    if (size >= NTP_PACKET_SIZE)
+    {
       udp.read(packetBuffer, NTP_PACKET_SIZE);
       unsigned long secsSince1900;
       secsSince1900 =  (unsigned long)packetBuffer[40] << 24;
@@ -579,9 +625,11 @@
 }

 /* --- */
-String macToStr(const uint8_t* mac) {
+String macToStr(const uint8_t* mac)
+{
   String result;
-  for (int i = 0; i < 6; ++i) {
+  for (int i = 0; i < 6; ++i)
+  {
     result += String(mac[i], 16);
     if (i < 5)
       result += ':';
@@ -589,15 +637,21 @@
   return result;
 }

-boolean reconnect() {
-  if (!mqttclient.connected()) {
-    if (mqttclient.connect((char*) clientName.c_str())) {
+boolean reconnect()
+{
+  if (!mqttclient.connected())
+  {
+    if (mqttclient.connect((char*) clientName.c_str()))
+    {

       mqttclient.loop();
-
-      for (int i = 0; i < 6; ++i) {
+      yield();
+
+      for (int i = 0; i < 6; ++i)
+      {
         mqttclient.subscribe(substopic[i]);
         mqttclient.loop();
+        yield();
       }
     } //else {
     //}
@@ -605,11 +659,13 @@
   return mqttclient.connected();
 }

-void callback(char* intopic, byte* inpayload, unsigned int length) {
+void callback(char* intopic, byte* inpayload, unsigned int length)
+{
   String receivedtopic = intopic;
   String receivedpayload ;

-  for (int i = 0; i < length; i++) {
+  for (int i = 0; i < length; i++)
+  {
     receivedpayload += (char)inpayload[i];
   }
   parseMqttMsg(receivedpayload, receivedtopic);
@@ -622,55 +678,72 @@
   StaticJsonBuffer<400> jsonBuffer;
   JsonObject& root = jsonBuffer.parseObject(json);

-  if (!root.success()) {
+  if (!root.success())
+  {
     return;
   }

-  if ( receivedtopic == substopic[0] ) {
-    if (root.containsKey("data1")) {
+  if ( receivedtopic == substopic[0] )
+  {
+    if (root.containsKey("data1"))
+    {
       solar_data.data1 = root["data1"];
     }
-    if (root.containsKey("data2")) {
+    if (root.containsKey("data2"))
+    {
       solar_data.data2 = root["data2"];
     }
     lastTime = millis();
   }

-  if ( receivedtopic == substopic[1] ) {
-    if (root.containsKey("Humidity")) {
+  if ( receivedtopic == substopic[1] )
+  {
+    if (root.containsKey("Humidity"))
+    {
       solar_data.Humidity = root["Humidity"];
     }

-    if (root.containsKey("Temperature")) {
+    if (root.containsKey("Temperature"))
+    {
       solar_data.Temperature1 = root["Temperature"];
     }
   }

-  if ( receivedtopic == substopic[2] ) {
-    if (root.containsKey("powerAvg")) {
+  if ( receivedtopic == substopic[2] )
+  {
+    if (root.containsKey("powerAvg"))
+    {
       solar_data.powerAvg = root["powerAvg"];
     }
   }

-  if ( receivedtopic == substopic[3] ) {
-    if (root.containsKey("data1")) {
+  if ( receivedtopic == substopic[3] )
+  {
+    if (root.containsKey("data1"))
+    {
       solar_data.Temperature2 = root["data1"];
     }
   }

-  if ( receivedtopic == substopic[4] ) {
-    if (root.containsKey("DOORPIR")) {
-      if (solar_data.pir != root["DOORPIR"]) {
+  if ( receivedtopic == substopic[4] )
+  {
+    if (root.containsKey("DOORPIR"))
+    {
+      if (solar_data.pir != root["DOORPIR"])
+      {
         solar_data.pir  = int(root["DOORPIR"]);
       }
     }
   }

-  if ( receivedtopic == substopic[5] ) {
-    if (root.containsKey("data1")) {
+  if ( receivedtopic == substopic[5] )
+  {
+    if (root.containsKey("data1"))
+    {
       solar_data.data3 = root["data1"];
     }
-    if (root.containsKey("data2")) {
+    if (root.containsKey("data2"))
+    {
       solar_data.data4 = root["data2"];
     }
     lastTime2 = millis();
@@ -679,7 +752,8 @@
   msgcallback = !msgcallback;
 }

-void setup() {
+void setup()
+{
   Serial.swap();
   system_update_cpu_freq(SYS_CPU_160MHz);
   WiFi.mode(WIFI_OFF);
@@ -706,8 +780,26 @@
   getResetInfo += ESP.getResetInfo().substring(0, 80);

   //
-  solar_data.Temperature1 = solar_data.Temperature2 = solar_data.Humidity = 0;
-  solar_data.data1 = solar_data.data2 = solar_data.data3 = solar_data.data4 = solar_data.powerAvg = 0;
+  solar_data.Temperature1 = 0;
+  solar_data.Temperature2 = 0;
+  solar_data.Humidity     = 0;
+  solar_data.data1        = 0;
+  solar_data.data2        = 0;
+  solar_data.data3        = 0;
+  solar_data.data4        = 0;
+  solar_data.powerAvg     = 0;
+  solar_data.pir          = 0;
+
+  curr_data.Temperature1 = 0;
+  curr_data.Temperature2 = 0;
+  curr_data.Humidity     = 0;
+  curr_data.data1        = 0;
+  curr_data.data2        = 0;
+  curr_data.data3        = 0;
+  curr_data.data4        = 0;
+  curr_data.powerAvg     = 0;
+  curr_data.pir          = 0;
+
   lastTime = lastTime2 = millis();

   // lcd
@@ -723,14 +815,16 @@
   lcd.createChar(6, powericon);
   lcd.createChar(7, valueisinvalid);

-  for ( int i = 1 ; i < 19 ; i++) {
+  for ( int i = 1 ; i < 19 ; i++)
+  {
     lcd.setCursor(i, 0);
     lcd.write(4);
     lcd.setCursor(i, 3);
     lcd.write(4);
   }

-  for ( int i = 0 ; i < 4 ; i++) {
+  for ( int i = 0 ; i < 4 ; i++)
+  {
     lcd.setCursor(0, i);
     lcd.write(4);
     lcd.setCursor(19, i);
@@ -738,33 +832,42 @@
   }

   lcd.setCursor(4, 1);
-  if (rtc_boot_mode.gopro_mode) {
+  if (rtc_boot_mode.gopro_mode)
+  {
     lcd.print("[Gopro mode]");
-  } else {
+  }
+  else
+  {
     lcd.print("[Clock mode]");
   }

   delay(1000);
   lcd.clear();

-  if (!SPIFFS.begin()) {
+  if (!SPIFFS.begin())
+  {
     lcd.setCursor(0, 0);
     lcd.print("[SPIFFS] mnt fail");
     delay(1000);
     return;
   }

-  if (rtc_boot_mode.formatspiffs) {
+  if (rtc_boot_mode.formatspiffs)
+  {
     spiffs_format();
     rtc_boot_mode.formatspiffs = false;
     saveConfig_helper();
   }

-  if (rtc_boot_mode.gopro_mode) {
+  if (rtc_boot_mode.gopro_mode)
+  {
     lcd.setCursor(0, 1);
-    if (!rtc_config_read()) {
+    if (!rtc_config_read())
+    {
       lcd.print("[CONFIG] load fail");
-    } else {
+    }
+    else
+    {
       lcd.print("[CONFIG] loaded");
       lcd.setCursor(0, 2);
       lcd.print("[CONFIG] [PH] : ");
@@ -773,7 +876,8 @@
     delay(1000);

     // check fie size in config
-    if ( rtc_boot_mode.twitter_phase != 0 && rtc_boot_mode.gopro_size == 0 && rtc_boot_mode.twitter_phase != 8) {
+    if ( rtc_boot_mode.twitter_phase != 0 && rtc_boot_mode.gopro_size == 0 && rtc_boot_mode.twitter_phase != 8)
+    {
       rtc_boot_mode.attempt_this  = 0;
       rtc_boot_mode.twitter_phase = 0;
       saveConfig_helper();
@@ -781,25 +885,35 @@
       ESP.reset();
     }

-    if ( rtc_boot_mode.twitter_phase == 0) {
+    if ( rtc_boot_mode.twitter_phase == 0)
+    {
       Dir dir = SPIFFS.openDir("/");
-      while (dir.next()) {
-        if ( dir.fileName().startsWith("/GOPR")) {
+      while (dir.next())
+      {
+        if ( dir.fileName().startsWith("/GOPR"))
+        {
           SPIFFS.remove(dir.fileName());
         }
-        if ( dir.fileName().startsWith("/config")) {
+        if ( dir.fileName().startsWith("/config"))
+        {
           SPIFFS.remove(dir.fileName());
         }
       }
     }
   }

-  if (!rtc_boot_mode.gopro_mode || rtc_boot_mode.attempt_this > 4) {
+  if (!rtc_boot_mode.gopro_mode || rtc_boot_mode.attempt_this > 4)
+  {
     wifi_connect();
-  } else {
-    if ( rtc_boot_mode.twitter_phase > 1 ) {
+  }
+  else
+  {
+    if ( rtc_boot_mode.twitter_phase > 1 )
+    {
       wifi_connect();
-    } else {
+    }
+    else
+    {
       digitalWrite(goproPowerPin, HIGH);
       delay(200);
       digitalWrite(goproPowerPin, LOW);
@@ -812,10 +926,12 @@
     }
   }

-  if (!rtc_boot_mode.gopro_mode || rtc_boot_mode.twitter_phase > 1) {
+  if (!rtc_boot_mode.gopro_mode || rtc_boot_mode.twitter_phase > 1)
+  {
     udp.begin(localPort);

-    if (!Rtc.IsDateTimeValid()) {
+    if (!Rtc.IsDateTimeValid())
+    {
       lcd.setCursor(0, 3);
       lcd.print("RTC is inValid");
       delay(1000);
@@ -823,26 +939,32 @@
       setSyncProvider(requestSync);

       int Attempt = 0;
-      while ( timeStatus() == timeNotSet ) {
+      while ( timeStatus() == timeNotSet )
+      {
         setSyncProvider(getNtpTime);
         Attempt++;
-        if (Attempt > 3) {
+        if (Attempt > 3)
+        {
           break;
         }
         yield();
       }

-      if (timeStatus() == timeSet) {
+      if (timeStatus() == timeSet)
+      {
         lcd.setCursor(0, 3);
         lcd.print("ntp synced");

         Rtc.SetDateTime(now() - 946684800);
-        if (!Rtc.GetIsRunning()) {
+        if (!Rtc.GetIsRunning())
+        {
           Rtc.SetIsRunning(true);
         }
       } //else {
       // }
-    } else {
+    }
+    else
+    {
       lcd.setCursor(0, 3);
       lcd.print("RTC is Valid");
       delay(1000);
@@ -854,7 +976,8 @@

   Rtc.Enable32kHzPin(false);

-  if (!rtc_boot_mode.gopro_mode) {
+  if (!rtc_boot_mode.gopro_mode)
+  {
     /*
       Rtc.SetSquareWavePin(DS3231SquareWavePin_ModeAlarmBoth);

@@ -891,27 +1014,34 @@
       DS3231AlarmTwoControl_MinutesMatch);
     Rtc.SetAlarmTwo(alarm1);
     Rtc.LatchAlarmsTriggeredFlags();
-  } else {
+  }
+  else
+  {
     Rtc.SetSquareWavePin(DS3231SquareWavePin_ModeNone);
   }

   //OTA
-  if (!rtc_boot_mode.gopro_mode) {
+  if (!rtc_boot_mode.gopro_mode)
+  {
     ArduinoOTA.setPort(8266);
     ArduinoOTA.setHostname("esp-solar");
     ArduinoOTA.setPassword(otapassword);
-    ArduinoOTA.onStart([]() {
+    ArduinoOTA.onStart([]()
+    {
       sendUdpSyslog("ArduinoOTA Start");
     });
-    ArduinoOTA.onEnd([]() {
+    ArduinoOTA.onEnd([]()
+    {
       sendUdpSyslog("ArduinoOTA End");
     });
-    ArduinoOTA.onProgress([](unsigned int progress, unsigned int total) {
+    ArduinoOTA.onProgress([](unsigned int progress, unsigned int total)
+    {
       syslogPayload = "Progress: ";
       syslogPayload += (progress / (total / 100));
       sendUdpSyslog(syslogPayload);
     });
-    ArduinoOTA.onError([](ota_error_t error) {
+    ArduinoOTA.onError([](ota_error_t error)
+    {
       if (error == OTA_AUTH_ERROR) abort();
       else if (error == OTA_BEGIN_ERROR) abort();
       else if (error == OTA_CONNECT_ERROR) abort();
@@ -934,10 +1064,13 @@
 time_t prevDisplay = 0;

 void loop() {
-  if (!rtc_boot_mode.gopro_mode) {
-    if (balm_isr) {
+  if (!rtc_boot_mode.gopro_mode)
+  {
+    if (balm_isr)
+    {
       DS3231AlarmFlag flag = Rtc.LatchAlarmsTriggeredFlags();
-      if (flag & DS3231AlarmFlag_Alarm2) {
+      if (flag & DS3231AlarmFlag_Alarm2)
+      {
         rtc_boot_mode.gopro_mode  = true;
         rtc_boot_mode.Temperature = solar_data.Temperature2 ;
         rtc_boot_mode.attempt_this  = 0;
@@ -952,57 +1085,117 @@
       balm_isr = false;
     }

-    if (WiFi.status() == WL_CONNECTED) {
-      if (!mqttclient.connected()) {
+    if (WiFi.status() == WL_CONNECTED)
+    {
+      if (!mqttclient.connected())
+      {
         unsigned long now = millis();
-        if (now - lastReconnectAttempt > 100) {
+        if (now - lastReconnectAttempt > 100)
+        {
           lastReconnectAttempt = now;
-          if (reconnect()) {
+          if (reconnect())
+          {
             lastReconnectAttempt = 0;
           }
         }
-      } else {
-        if (timeStatus() != timeNotSet) {
-          if (now() != prevDisplay) {
+      }
+      else
+      {
+        if (timeStatus() != timeNotSet)
+        {
+          if (
+            curr_data.Temperature1 != solar_data.Temperature1 ||
+            curr_data.Temperature2 != solar_data.Temperature2 ||
+            curr_data.Humidity     != solar_data.Humidity
+          )
+          {
+            displayTemperature();
+            curr_data.Temperature1 = solar_data.Temperature1;
+            curr_data.Temperature2 = solar_data.Temperature2;
+            curr_data.Humidity     = solar_data.Humidity;
+          }
+
+          if (curr_data.powerAvg != solar_data.powerAvg)
+          {
+            displaypowerAvg();
+            curr_data.powerAvg = solar_data.powerAvg;
+          }
+
+          if (curr_data.pir != solar_data.pir)
+          {
+            displaypir();
+            curr_data.pir = solar_data.pir ;
+          }
+
+          if (
+            curr_data.data1 != solar_data.data1 ||
+            curr_data.data2 != solar_data.data2
+            )
+          {
+            displayData();
+            curr_data.data1 = solar_data.data1;
+            curr_data.data2 = solar_data.data2;
+          }
+
+          if (
+            curr_data.data3 != solar_data.data3 ||
+            curr_data.data4 != solar_data.data4
+          )
+          {
+            displayData2();
+            curr_data.data3 = solar_data.data3;
+            curr_data.data4 = solar_data.data4;
+          }
+
+          if (now() != prevDisplay)
+          {
+
+            digitalClockDisplay();
             prevDisplay = now();
-            digitalClockDisplay();
-            displayTemperature();
-            displaypowerAvg();
-            displaypir();
-
-            if (second() % 10 == 0) {
-              displayData();
-              displayData2();
-
-              if (( millis() - lastTime ) > 120000 ) {
+
+            if (second() % 10 == 0)
+            {
+              if (( millis() - lastTime ) > 120000 )
+              {
                 lcd.setCursor(7, 2);
                 lcd.write(7);
-              } else {
+              }
+              else
+              {
                 lcd.setCursor(7, 2);
                 lcd.print(" ");
               }

-              if (( millis() - lastTime2 ) > 120000 ) {
+              if (( millis() - lastTime2 ) > 120000 )
+              {
                 lcd.setCursor(7, 3);
                 lcd.write(7);
-              } else {
+              }
+              else
+              {
                 lcd.setCursor(7, 3);
                 lcd.print(" ");
               }
             }

-            if (!Rtc.IsDateTimeValid()) {
+            if (!Rtc.IsDateTimeValid())
+            {
               lcd.setCursor(18, 0);
               lcd.write(7);
-            } else {
+            }
+            else
+            {
               lcd.setCursor(18, 0);
               lcd.print(" ");
             }

-            if (msgcallback) {
+            if (msgcallback)
+            {
               lcd.setCursor(19, 0);
               lcd.write(5);
-            } else {
+            }
+            else
+            {
               lcd.setCursor(19, 0);
               lcd.print(" ");
             }
@@ -1011,28 +1204,38 @@
         mqttclient.loop();
       }
       ArduinoOTA.handle();
-    } else {
+    }
+    else
+    {
       wifi_connect();
     }
-  } else {
-
-    if (WiFi.status() == WL_CONNECTED) {
+  }
+  else
+  {
+
+    if (WiFi.status() == WL_CONNECTED)
+    {
       // gopro mode

-      if (x) {
+      if (x)
+      {
         // switch todo

         value_timestamp  = now();
         value_nonce      = *(volatile uint32_t *)0x3FF20E44;

-        if ( rtc_boot_mode.twitter_phase == 8 ) {
-          if (rtc_boot_mode.attempt_phase == 0 && rtc_boot_mode.attempt_detail == 1) {
+        if ( rtc_boot_mode.twitter_phase == 8 )
+        {
+          if (rtc_boot_mode.attempt_phase == 0 && rtc_boot_mode.attempt_detail == 1)
+          {
             value_status  = "esp-01 / ";
             value_status += hour();
             value_status += ":";
             value_status += minute();
             value_status += " gopro wifi err, check plz";
-          } else {
+          }
+          else
+          {
             value_status  = "esp-01 / ";
             value_status += hour();
             value_status += ":";
@@ -1041,7 +1244,9 @@
             value_status += rtc_boot_mode.attempt_phase;
             value_status += " err, check plz";
           }
-        } else {
+        }
+        else
+        {
           value_status  = "esp-01 / ";
           value_status += rtc_boot_mode.Temperature;
           value_status += "C / ";
@@ -1054,7 +1259,8 @@
           value_status += minute();
         }

-        switch (rtc_boot_mode.twitter_phase) {
+        switch (rtc_boot_mode.twitter_phase)
+        {

           case 0:
             // WIFI : GOPRO
@@ -1121,11 +1327,13 @@
   }
 }

-void displayData() {
+void displayData()
+{
   lcd.setCursor(7, 2);
   lcd.print("    ");
   lcd.setCursor(7, 2);
-  if ( solar_data.data1 < 1000 ) {
+  if ( solar_data.data1 < 1000 )
+  {
     lcd.print(" ");
   }
   lcd.print(solar_data.data1, 0);
@@ -1136,11 +1344,13 @@
   lcd.print(solar_data.data2, 2);
 }

-void displayData2() {
+void displayData2()
+{
   lcd.setCursor(7, 3);
   lcd.print("    ");
   lcd.setCursor(7, 3);
-  if ( solar_data.data3 < 1000 ) {
+  if ( solar_data.data3 < 1000 )
+  {
     lcd.print(" ");
   }
   lcd.print(solar_data.data3, 0);
@@ -1152,56 +1362,71 @@
   //lcd.print((solar_data.data4 * 100000), 0);
 }

-void displaypir() {
-  if ( solar_data.pir == 1) {
-    for ( int i = 0 ; i <= 2 ; i ++ ) {
+void displaypir()
+{
+  if ( solar_data.pir == 1)
+  {
+    for ( int i = 0 ; i <= 2 ; i ++ )
+    {
       lcd.setCursor(19, i);
       lcd.write(5);
     }
-  } else {
-    for ( int i = 0 ; i <= 2 ; i ++ ) {
+  }
+  else
+  {
+    for ( int i = 0 ; i <= 2 ; i ++ )
+    {
       lcd.setCursor(19, i);
       lcd.print(" ");
     }
   }
 }

-void displaypowerAvg() {
-  if (solar_data.powerAvg < 9999) {
+void displaypowerAvg()
+{
+  if (solar_data.powerAvg < 9999)
+  {
     String str_Power = String(solar_data.powerAvg);
     int length_Power = str_Power.length();

     lcd.setCursor(2, 3);
-    for ( int i = 0; i < ( 4 - length_Power ) ; i++ ) {
+    for ( int i = 0; i < ( 4 - length_Power ) ; i++ )
+    {
       lcd.print(" ");
     }
     lcd.print(str_Power);
   }
 }

-void displayTemperaturedigit(float Temperature) {
+void displayTemperaturedigit(float Temperature)
+{
   String str_Temperature = String(int(Temperature)) ;
   int length_Temperature = str_Temperature.length();

-  for ( int i = 0; i < ( 3 - length_Temperature ) ; i++ ) {
+  for ( int i = 0; i < ( 3 - length_Temperature ) ; i++ )
+  {
     lcd.print(" ");
   }
   lcd.print(Temperature, 1);
 }

-void displayTemperature() {
+void displayTemperature()
+{
   lcd.setCursor(1, 1);
   displayTemperaturedigit(solar_data.Temperature1);

   lcd.setCursor(7, 1);

-  float tempdiff = solar_data.Temperature2 - solar_data.Temperature1 ;
+  float tempdiff = solar_data.Temperature2 - solar_data.Temperature1;
   displayTemperaturedigit(solar_data.Temperature2);

   lcd.setCursor(14, 1);
-  if ( tempdiff > 0 ) {
+  if ( tempdiff > 0 )
+  {
     lcd.print("+");
-  } else if ( tempdiff < 0 ) {
+  }
+  else if ( tempdiff < 0 )
+  {
     lcd.print("-");
   }

@@ -1210,19 +1435,24 @@

   lcd.setCursor(15, 1);
   lcd.print(abs(tempdiff), 1);
-  if ( length_tempdiff == 1) {
+  if ( length_tempdiff == 1)
+  {
     lcd.print(" ");
   }

   lcd.setCursor(2, 2);
-  if ( solar_data.Humidity >= 10 ) {
+  if ( solar_data.Humidity >= 10 )
+  {
     lcd.print(solar_data.Humidity, 1);
-  } else {
+  }
+  else
+  {
     lcd.print(" ");
     lcd.print(solar_data.Humidity, 1);
   }
 }
-void digitalClockDisplay() {
+void digitalClockDisplay()
+{
   // digital clock display of the time
   lcd.setCursor(0, 0);
   printDigitsnocolon(month());
@@ -1237,34 +1467,43 @@
   printDigits(second());
 }

-void printDigitsnocolon(int digits) {
-  if (digits < 10) {
+void printDigitsnocolon(int digits)
+{
+  if (digits < 10)
+  {
     lcd.print('0');
   }
   lcd.print(digits);
 }

-void printDigits(int digits) {
+void printDigits(int digits)
+{
   // utility for digital clock display: prints preceding colon and leading 0
   lcd.print(":");
-  if (digits < 10) {
+  if (digits < 10)
+  {
     lcd.print('0');
   }
   lcd.print(digits);
 }

 /* ------------------------------- */
-String get_hash_str(String content_more, String content_last, int positionofchunk, int get_size, bool bpost = false) {
+String get_hash_str(String content_more, String content_last, int positionofchunk, int get_size, bool bpost = false)
+{

   File f = SPIFFS.open("/" + gopro_file, "r");
-  if (!f) {
+  if (!f)
+  {
     return "0";
-  } else {
+  }
+  else
+  {
     f.seek(positionofchunk, SeekSet);
   }

-  if ( !bpost ) {
+  if ( !bpost )
+  {

     char buff[1400] = { 0 };
     int len = get_size; // file size
@@ -1275,18 +1514,22 @@

     SHA1_Update(&context, (uint8_t*) content_more.c_str(), content_more.length());

-    while (f.available()) {
+    while (f.available())
+    {
       int c = f.readBytes(buff, ((len > sizeof(buff)) ? sizeof(buff) : len));

-      if ( c > 0 ) {
+      if ( c > 0 )
+      {
         SHA1_Update(&context, (uint8_t*) buff, c);
       }

-      if (len > 0) {
+      if (len > 0)
+      {
         len -= c;
       }

-      if (c == 0) {
+      if (c == 0)
+      {
         break;
       }
     }
@@ -1297,7 +1540,9 @@

     return URLEncode(base64::encode(digestkey, 20).c_str());

-  } else {
+  }
+  else
+  {

     char buff[1400] = { 0 };
     int len = get_size;
@@ -1310,16 +1555,20 @@
     int pre_progress = 0;
     int count = 0;

-    while (f.available()) {
+    while (f.available())
+    {
       int c = f.readBytes(buff, ((len > sizeof(buff)) ? sizeof(buff) : len));
-      if ( c > 0 ) {
+      if ( c > 0 )
+      {
         sslclient.write((const uint8_t *) buff, c);
       }

       float progress = ((get_size - len) / (get_size / 100));
-      if (int(progress) != pre_progress ) {
+      if (int(progress) != pre_progress )
+      {
         lcd.setCursor(13, 3);
-        if (progress < 10) {
+        if (progress < 10)
+        {
           lcd.print(" ");
         }

@@ -1328,15 +1577,18 @@
         pre_progress = int(progress);
       }

-      if (len > 0) {
+      if (len > 0)
+      {
         len -= c;
       }

-      if (c == 0) {
+      if (c == 0)
+      {
         break;
       }

-      if (!sslclient.connected()) {
+      if (!sslclient.connected())
+      {
         f.close();
         return "0";
         break;
@@ -1348,7 +1600,8 @@
       count++;

       // up error
-      if (count > 300) {
+      if (count > 300)
+      {
         rtc_boot_mode.attempt_this++;
         saveConfig_helper();

@@ -1363,13 +1616,16 @@
   }
 }

-bool do_http_append_post(String content_header, String content_more, String content_last, int positionofchunk, int get_size) {
-  if (!sslclient.connect(UPLOAD_BASE_HOST, HTTPSPORT)) {
+bool do_http_append_post(String content_header, String content_more, String content_last, int positionofchunk, int get_size)
+{
+  if (!sslclient.connect(UPLOAD_BASE_HOST, HTTPSPORT))
+  {
     return false;
   }

-  if (!sslclient.verify(upload_fingerprint, UPLOAD_BASE_HOST)) {
+  if (!sslclient.verify(upload_fingerprint, UPLOAD_BASE_HOST))
+  {
     lcd.setCursor(0, 2);
     lcd.print("[P:3] ssl fail");
     return false;
@@ -1381,7 +1637,8 @@
   sslclient.print(content_header);

   String ok = get_hash_str(content_more, content_last, positionofchunk, get_size, true);
-  if (ok == "0") {
+  if (ok == "0")
+  {
     lcd.setCursor(0, 2);
     lcd.print("[P:3] put err, reset");
     delay(2000);
@@ -1389,37 +1646,45 @@
   }

   int _returnCode = 0;
-  while (sslclient.connected()) {
+  while (sslclient.connected())
+  {
     String line = sslclient.readStringUntil('\n');
-    if (line.startsWith("HTTP/1.")) {
+    if (line.startsWith("HTTP/1."))
+    {
       _returnCode = line.substring(9, line.indexOf(' ', 9)).toInt();
       break;
     }
   }

-  if (_returnCode >= 200 && _returnCode < 400) {
+  if (_returnCode >= 200 && _returnCode < 400)
+  {
     rtc_boot_mode.chunked_no++;
     rtc_boot_mode.attempt_this = 0;
     saveConfig_helper();
     return true;
-  } else {
+  }
+  else
+  {
     return false;
   }
 }

-bool do_http_text_post(String OAuth_header) {
+bool do_http_text_post(String OAuth_header)
+{
   String httppayload = "";
   String req_body_to_post;

   String uri_to_post = UPLOAD_BASE_URI;

-  if (rtc_boot_mode.twitter_phase == 6) {
+  if (rtc_boot_mode.twitter_phase == 6)
+  {
     uri_to_post = BASE_URI;
     uri_to_post += "?media_ids=";
     uri_to_post += media_id;
   }

-  if (rtc_boot_mode.twitter_phase == 8) {
+  if (rtc_boot_mode.twitter_phase == 8)
+  {
     uri_to_post = BASE_URI;
   }

@@ -1429,7 +1694,8 @@
   lcd.print("case ");
   lcd.print(rtc_boot_mode.twitter_phase);
   lcd.print(" : ");
-  switch (rtc_boot_mode.twitter_phase) {
+  switch (rtc_boot_mode.twitter_phase)
+  {
     case 2:
       req_body_to_post = "command=INIT&media_type=image%2Fjpeg&total_bytes=";
       req_body_to_post += rtc_boot_mode.gopro_size;
@@ -1464,16 +1730,20 @@
   http.addHeader("Content-Type", "application/x-www-form-urlencoded");
   int httpCode = http.POST(req_body_to_post);

-  if (httpCode > 0) {
-    if (rtc_boot_mode.twitter_phase == 2 || rtc_boot_mode.twitter_phase == 4) {
-      if ((httpCode >= 200) && (httpCode < 400)) {
+  if (httpCode > 0)
+  {
+    if (rtc_boot_mode.twitter_phase == 2 || rtc_boot_mode.twitter_phase == 4)
+    {
+      if ((httpCode >= 200) && (httpCode < 400))
+      {
         httppayload = http.getString();
       }
     }
     http.end();
     delay(100);

-    if (rtc_boot_mode.twitter_phase == 6) {
+    if (rtc_boot_mode.twitter_phase == 6)
+    {
       syslogPayload = "do_http_text_post 1: ";
       syslogPayload += " - httpCode : ";
       syslogPayload += httpCode;
@@ -1484,9 +1754,12 @@
     lcd.print(httpCode);
     lcd.setCursor(0, 2);

-  } else {
+  }
+  else
+  {
     http.end();
-    if (rtc_boot_mode.twitter_phase == 6) {
+    if (rtc_boot_mode.twitter_phase == 6)
+    {
       syslogPayload = "do_http_text_post 2: ";
       syslogPayload += " - httpCode : ";
       syslogPayload += httpCode;
@@ -1497,7 +1770,8 @@
       delay(200);
     }

-    if (rtc_boot_mode.twitter_phase == 2 ) {
+    if (rtc_boot_mode.twitter_phase == 2 )
+    {
       rtc_boot_mode.attempt_this++;
       saveConfig_helper();
       delay(200);
@@ -1509,16 +1783,21 @@

   delay(1000);

-  if (rtc_boot_mode.twitter_phase == 6 || rtc_boot_mode.twitter_phase == 8) {
-    if ((httpCode >= 200) && (httpCode < 400)) {
+  if (rtc_boot_mode.twitter_phase == 6 || rtc_boot_mode.twitter_phase == 8)
+  {
+    if ((httpCode >= 200) && (httpCode < 400))
+    {
       rtc_boot_mode.attempt_this  = 0;
       rtc_boot_mode.twitter_phase = 7;
       rtc_boot_mode.attempt_phase = 7;
       saveConfig_helper();
       delay(200);
       return true;
-    } else {
-      if (rtc_boot_mode.twitter_phase == 6) {
+    }
+    else
+    {
+      if (rtc_boot_mode.twitter_phase == 6)
+      {
         rtc_boot_mode.attempt_this   = 0;
         rtc_boot_mode.attempt_phase  = 6;
         rtc_boot_mode.attempt_detail = 1;
@@ -1530,18 +1809,22 @@
     }
   }

-  if (rtc_boot_mode.twitter_phase == 2 || rtc_boot_mode.twitter_phase == 4) {
+  if (rtc_boot_mode.twitter_phase == 2 || rtc_boot_mode.twitter_phase == 4)
+  {
     char json[] = "{\"media_id\":000000000000000000,\"media_id_string\":\"000000000000000000\",\"size\":0000000,\"expires_after_secs\":86400,\"image\":{\"image_type\":\"image\\/jpeg\",\"w\":0000,\"h\":0000}}" ;
     httppayload.toCharArray(json, 200);
     StaticJsonBuffer<200> jsonBuffer;
     JsonObject& root = jsonBuffer.parseObject(json);

-    if (!root.success()) {
+    if (!root.success())
+    {
       return false;
     }

-    if (rtc_boot_mode.twitter_phase == 2) {
-      if (root.containsKey("media_id_string")) {
+    if (rtc_boot_mode.twitter_phase == 2)
+    {
+      if (root.containsKey("media_id_string"))
+      {
         media_id = root["media_id_string"].asString();
         rtc_boot_mode.attempt_this  = 0;
         rtc_boot_mode.twitter_phase = 3;
@@ -1549,8 +1832,11 @@
         saveConfig_helper();
         return true;
       }
-    } else {
-      if (root.containsKey("media_id_string")) {
+    }
+    else
+    {
+      if (root.containsKey("media_id_string"))
+      {
         /*
           if (media_id == root["media_id_string"].asString()) {
           if (root.containsKey("processing_info")) {
@@ -1577,9 +1863,11 @@
   }
 }

-String make_OAuth_header(String oauth_signature, String hashStr = "0") {
+String make_OAuth_header(String oauth_signature, String hashStr = "0")
+{
   String OAuth_header = "OAuth ";
-  if (rtc_boot_mode.twitter_phase == 3) {
+  if (rtc_boot_mode.twitter_phase == 3)
+  {
     OAuth_header += UPLOAD_OAUTH_KEY;
     OAuth_header += "=\"";
     OAuth_header += hashStr;
@@ -1619,11 +1907,13 @@

 }

-String make_base_string(String para_string) {
+String make_base_string(String para_string)
+{
   String base_string = KEY_HTTP_METHOD;
   base_string += "&";

-  switch (rtc_boot_mode.twitter_phase) {
+  switch (rtc_boot_mode.twitter_phase)
+  {
     case 6:
       base_string += URLEncode(BASE_URL);
       break;
@@ -1643,10 +1933,12 @@
   return base_string;
 }

-String make_para_string(String hashStr = "0") {
+String make_para_string(String hashStr = "0")
+{
   String para_string;

-  switch (rtc_boot_mode.twitter_phase) {
+  switch (rtc_boot_mode.twitter_phase)
+  {
     case 2: // INIT
       para_string += URLEncode(UPLOAD_COMMAND);
       para_string += "=" ;
@@ -1721,7 +2013,8 @@
   para_string += "=";
   para_string += VALUE_VERSION;

-  switch (rtc_boot_mode.twitter_phase) {
+  switch (rtc_boot_mode.twitter_phase)
+  {
     case 2:
       para_string += "&";
       para_string += UPLOAD_MEDIA_SIZE;
@@ -1754,7 +2047,8 @@
 }

 /* PHASE 8 : TWEET error*/
-bool tweet_error() {
+bool tweet_error()
+{
   bool rtn = false;

   lcd.clear();
@@ -1768,9 +2062,12 @@
   rtn                    = do_http_text_post(OAuth_header);

   lcd.setCursor(0, 2);
-  if (rtn) {
+  if (rtn)
+  {
     lcd.print("[P:8] OK");
-  } else {
+  }
+  else
+  {
     lcd.print("[P:8] FAIL");
   }
   delay(2000);
@@ -1780,10 +2077,12 @@

 /* PHASE 6 : TWEET */
-bool tweet_status() {
+bool tweet_status()
+{
   bool rtn = false;

-  if ( rtc_boot_mode.attempt_this > 4) {
+  if ( rtc_boot_mode.attempt_this > 4)
+  {
     rtc_boot_mode.attempt_this  = 0;
     rtc_boot_mode.twitter_phase = 8;
     saveConfig_helper();
@@ -1802,9 +2101,12 @@
   rtn                    = do_http_text_post(OAuth_header);

   lcd.setCursor(0, 2);
-  if (rtn) {
+  if (rtn)
+  {
     lcd.print("[P:6] OK");
-  } else {
+  }
+  else
+  {
     lcd.print("[P:6] FAIL");
   }
   delay(2000);
@@ -1813,7 +2115,8 @@
 }

 /* PHASE 5 : STATUS CHECK */
-void tweet_check() {
+void tweet_check()
+{
   lcd.clear();
   lcd.setCursor(0, 0);
   lcd.print("[P:5] CHECKING");
@@ -1824,10 +2127,12 @@
 }

 /* PHASE 4 : FINALIZE */
-bool tweet_fin() {
+bool tweet_fin()
+{
   bool rtn = false;

-  if ( rtc_boot_mode.attempt_this > 4) {
+  if ( rtc_boot_mode.attempt_this > 4)
+  {
     rtc_boot_mode.attempt_this  = 0;
     rtc_boot_mode.twitter_phase = 8;
     saveConfig_helper();
@@ -1846,9 +2151,12 @@
   rtn                    = do_http_text_post(OAuth_header);

   lcd.setCursor(0, 1);
-  if (rtn) {
+  if (rtn)
+  {
     lcd.print("[P:4] OK");
-  } else {
+  }
+  else
+  {
     lcd.print("[P:4] FAIL");
   }
   delay(2000);
@@ -1856,10 +2164,12 @@
 }

 /* PHASE 3 : APPEND */
-bool tweet_append() {
+bool tweet_append()
+{
   bool rtn = false;

-  if ( rtc_boot_mode.attempt_this > 4) {
+  if ( rtc_boot_mode.attempt_this > 4)
+  {
     rtc_boot_mode.attempt_this  = 0;
     rtc_boot_mode.twitter_phase = 8;
     saveConfig_helper();
@@ -1877,13 +2187,15 @@
   int get_size = CHUNKED_FILE_SIZE;
   int positionofchunk = (CHUNKED_FILE_SIZE * rtc_boot_mode.chunked_no);

-  if (positionofchunk >= rtc_boot_mode.gopro_size) {
+  if (positionofchunk >= rtc_boot_mode.gopro_size)
+  {
     rtc_boot_mode.twitter_phase = 4;
     saveConfig_helper();
     return true;
   }

-  if (( positionofchunk + get_size) > rtc_boot_mode.gopro_size) {
+  if (( positionofchunk + get_size) > rtc_boot_mode.gopro_size)
+  {
     get_size = rtc_boot_mode.gopro_size - positionofchunk;
   }

@@ -1930,11 +2242,14 @@
   lcd.setCursor(0, 0);
   lcd.print("[P:3] APPEND");
   lcd.setCursor(0, 1);
-  if (rtn) {
+  if (rtn)
+  {
     lcd.print("[P:3] chk : ");
     lcd.print(rtc_boot_mode.chunked_no - 1);
     lcd.print(" OK");
-  } else {
+  }
+  else
+  {
     lcd.print(" FAIL");
   }

@@ -1948,10 +2263,12 @@
 }

 /* PHASE 2 : INIT */
-bool tweet_init() {
+bool tweet_init()
+{
   bool rtn = false;

-  if ( rtc_boot_mode.attempt_this > 4) {
+  if ( rtc_boot_mode.attempt_this > 4)
+  {
     rtc_boot_mode.attempt_this  = 0;
     rtc_boot_mode.twitter_phase = 8;
     saveConfig_helper();
@@ -1971,11 +2288,14 @@

   lcd.clear();
   lcd.setCursor(0, 0);
-  if (rtn) {
+  if (rtn)
+  {
     lcd.print("[P:2] ");
     lcd.setCursor(0, 1);
     lcd.print(media_id);
-  } else {
+  }
+  else
+  {
     lcd.print("[P:2] FAIL");
   }
   delay(2000);
@@ -1983,7 +2303,8 @@
   return rtn;
 }

-bool gopro_poweroff() {
+bool gopro_poweroff()
+{
   /*
     bool rtn = false;
     HTTPClient http;
@@ -2021,7 +2342,8 @@
   return true;
 }

-bool gopro_poweron() {
+bool gopro_poweron()
+{
   bool rtn = false;
   HTTPClient http;

@@ -2036,7 +2358,8 @@
   lcd.print(httpCode);
   delay(2000);

-  if (httpCode == HTTP_CODE_OK) {
+  if (httpCode == HTTP_CODE_OK)
+  {
     http.end();
     delay(3000);
     // 5MP
@@ -2048,7 +2371,8 @@
     lcd.print(" ");
     lcd.print(httpCode2);

-    if (httpCode2 == HTTP_CODE_OK) {
+    if (httpCode2 == HTTP_CODE_OK)
+    {
       http.end();
       delay(2000);
       http.begin("http://10.5.5.9:80/bacpac/SH?t=" + String(gopropassword) + "&p=%01");
@@ -2057,7 +2381,8 @@
       lcd.print(" ");
       lcd.print(httpCode3);

-      if (httpCode3 == HTTP_CODE_OK) {
+      if (httpCode3 == HTTP_CODE_OK)
+      {
         rtn = true;
       }
     }
@@ -2069,8 +2394,10 @@

 /* PHASE 1 : start : get last file */
-bool get_gopro_file() {
-  if ( rtc_boot_mode.attempt_this > 2) {
+bool get_gopro_file()
+{
+  if ( rtc_boot_mode.attempt_this > 2)
+  {
     rtc_boot_mode.attempt_this  = 0;
     rtc_boot_mode.twitter_phase = 8;
     saveConfig_helper();
@@ -2097,12 +2424,15 @@
   http.begin(url);

   int httpCode = http.GET();
-  if (httpCode > 0) {
-    if (httpCode == HTTP_CODE_OK) {
+  if (httpCode > 0)
+  {
+    if (httpCode == HTTP_CODE_OK)
+    {
       int len = http.getSize();
       uint8_t buff[1460] = { 0 };

-      if ( len != rtc_boot_mode.gopro_size ) {
+      if ( len != rtc_boot_mode.gopro_size )
+      {
         http.end();
         rtc_boot_mode.twitter_phase = 0;
         rtc_boot_mode.attempt_this++;
@@ -2120,7 +2450,8 @@
       WiFiClient * stream = http.getStreamPtr();
       //stream->setTimeout(1000);
       File f = SPIFFS.open("/" + gopro_file, "w");
-      if (!f) {
+      if (!f)
+      {
         lcd.setCursor(0, 1);
         lcd.print("[P:1] SPIFFS err");
         delay(1000);
@@ -2138,16 +2469,20 @@

       unsigned long dnstart = millis();

-      while (http.connected() && (len > 0 || len == -1)) {
+      while (http.connected() && (len > 0 || len == -1))
+      {
         size_t size = stream->available();
-        if (size) {
+        if (size)
+        {
           int c = stream->readBytes(buff, ((size > sizeof(buff)) ? sizeof(buff) : size));
           f.write(buff, c);

           float progress = ((rtc_boot_mode.gopro_size - len) / (rtc_boot_mode.gopro_size / 100));
-          if (int(progress) != pre_progress ) {
+          if (int(progress) != pre_progress )
+          {
             lcd.setCursor(13, 1);
-            if (progress < 10) {
+            if (progress < 10)
+            {
               lcd.print(" ");
             }

@@ -2156,17 +2491,20 @@
             pre_progress = int(progress);
           }

-          if (len > 0) {
+          if (len > 0)
+          {
             len -= c;
           }
         }
+
         lcd.setCursor(0, 2);
         lcd.print("[P:1] cnt : ");
         lcd.print(count);
         count++;

         // download error
-        if ( count > 1800 ) {
+        if ( count > 1800 )
+        {
           rtc_boot_mode.formatspiffs = true;
           rtc_boot_mode.attempt_this++;
           rtc_boot_mode.twitter_phase = 0;
@@ -2196,7 +2534,8 @@

       delay(2000);
       File fr = SPIFFS.open("/" + gopro_file, "r");
-      if (!fr || fr.size() != rtc_boot_mode.gopro_size ) {
+      if (!fr || fr.size() != rtc_boot_mode.gopro_size )
+      {
         lcd.print("err");
         delay(1000);

@@ -2220,16 +2559,21 @@

       rtn = true;
     }
-  } else {
+  }
+  else
+  {
     rtn = false;
   }
   http.end();

   lcd.clear();
   lcd.setCursor(0, 0);
-  if (rtn) {
+  if (rtn)
+  {
     lcd.print("[P:1] OK");
-  } else {
+  }
+  else
+  {
     lcd.print("[P:1] FAIL");
   }

@@ -2238,8 +2582,10 @@
 }

 /* PHASE 0 : start : get gopro file list */
-bool get_gpro_list() {
-  if ( rtc_boot_mode.attempt_this > 4) {
+bool get_gpro_list()
+{
+  if ( rtc_boot_mode.attempt_this > 4)
+  {
     rtc_boot_mode.twitter_phase = 8;
     rtc_boot_mode.attempt_this  = 0;
     saveConfig_helper();
@@ -2254,19 +2600,24 @@
   lcd.setCursor(0, 0);
   lcd.print("[P:0] POWER ON ");
   int Attempt = 0;
-  while (1) {
-    if (gopro_poweron()) {
+  while (1)
+  {
+    if (gopro_poweron())
+    {
       lcd.setCursor(0, 2);
       lcd.print("---> OK");
       delay(3000);

       break;
-    } else {
+    }
+    else
+    {
       delay(1000);
     }

     Attempt++;
-    if (Attempt > 5) {
+    if (Attempt > 5)
+    {
       lcd.setCursor(0, 2);
       lcd.print("---> FAIL");
       delay(1000);
@@ -2286,9 +2637,12 @@
   HTTPClient http;
   http.begin("http://10.5.5.9:8080/gp/gpMediaList");
   int httpCode = http.GET();
-  if (httpCode > 0) {
-    if (httpCode == HTTP_CODE_OK) {
-      while (http.connected()) {
+  if (httpCode > 0)
+  {
+    if (httpCode == HTTP_CODE_OK)
+    {
+      while (http.connected())
+      {
         int len = http.getSize();
         WiFiClient * stream = http.getStreamPtr();

@@ -2296,7 +2650,8 @@
         String filename;
         String filesize;

-        while (http.connected() && (len > 0 || len == -1)) {
+        while (http.connected() && (len > 0 || len == -1))
+        {
           //stream->setTimeout(500);
           String line = stream->readStringUntil(',');

@@ -2307,17 +2662,20 @@
           line.replace("}", "");
           line.replace("]]", "");

-          if (line.startsWith("d:")) {
+          if (line.startsWith("d:"))
+          {
             line.replace("d:", "");
             directory = line;
           }

-          if (line.startsWith("n:")) {
+          if (line.startsWith("n:"))
+          {
             line.replace("n:", "");
             filename = line;
           }

-          if (line.startsWith("s:")) {
+          if (line.startsWith("s:"))
+          {
             line.replace("s:", "");
             filesize = line;
           }
@@ -2326,7 +2684,8 @@
         lcd.setCursor(0, 1);
         lcd.print(filesize.toInt());

-        if ( filesize.toInt() < 2600000 ) {
+        if ( filesize.toInt() < 2600000 )
+        {
           gopro_dir     = directory.c_str();
           gopro_file    = filename.c_str();
           media_id      = "0000000000000000000";
@@ -2340,8 +2699,9 @@
           saveConfig_helper();

           rtn = true;
-        } else {
-
+        }
+        else
+        {
           lcd.setCursor(0, 2);
           lcd.print("[P:0] big file");
           delay(2000);
@@ -2352,17 +2712,22 @@
         }
       }
     }
-  } else {
+  }
+  else
+  {
     rtn = false;
   }
   http.end();

   //lcd.clear();
   lcd.setCursor(0, 3);
-  if (rtn) {
+  if (rtn)
+  {
     lcd.print("[P:0] ");
     lcd.print(gopro_file);
-  } else {
+  }
+  else
+  {
     lcd.print("[P:0] FAIL");
   }
   delay(2000);
@@ -2371,4 +2736,3 @@
 }

 // end
-


amended function name

amended function name

--- arduino/opencr_arduino/opencr/libraries/OpenManipulator/example/OPM_for_Arduino/Chain/d_open_manipulator_chain/d_open_manipulator_chain.ino
+++ arduino/opencr_arduino/opencr/libraries/OpenManipulator/example/OPM_for_Arduino/Chain/d_open_manipulator_chain/d_open_manipulator_chain.ino
@@ -36,9 +36,9 @@
   MY_ROBOT::initManipulator();
   MY_ROBOT::initActuator(ACTUATOR_ENABLE);

-  OPEN_MANIPULATOR::linkSetAllJointAnglefunctionToAPI(MY_ROBOT::setAllJointAngle);
-  OPEN_MANIPULATOR::linkSetJointAnglefunctionToAPI(MY_ROBOT::setJointAngle);
-  OPEN_MANIPULATOR::linkSetGetAnglefunctionToAPI(MY_ROBOT::getAngle);
+  OPEN_MANIPULATOR::connectSetAllJointAngleToAPI(MY_ROBOT::setAllJointAngle);
+  OPEN_MANIPULATOR::connectSetJointAngleToAPI(MY_ROBOT::setJointAngle);
+  OPEN_MANIPULATOR::connectSetGetAngleToAPI(MY_ROBOT::getAngle);

   initThread();
   startThread();


Update ArduCAM_Mini_5MP_Plus_OV5642_RAW.ino

--- ArduCAM/examples/mini/ArduCAM_Mini_5MP_Plus_OV5642_RAW/ArduCAM_Mini_5MP_Plus_OV5642_RAW.ino
+++ ArduCAM/examples/mini/ArduCAM_Mini_5MP_Plus_OV5642_RAW/ArduCAM_Mini_5MP_Plus_OV5642_RAW.ino
@@ -39,8 +39,16 @@
 Serial.println(F("ArduCAM Start!"));
 // set the CS as an output:
 pinMode(CS, OUTPUT);
+digitalWrite(CS, HIGH);
 // initialize SPI:
 SPI.begin();
+
+//Reset the CPLD
+myCAM.write_reg(0x07, 0x80);
+delay(100);
+myCAM.write_reg(0x07, 0x00);
+delay(100);
+
 while(1){
   //Check if the ArduCAM SPI bus is OK
   myCAM.write_reg(ARDUCHIP_TEST1, 0x55);


1.0 RC2

1.0 RC2

-RGB Led (Luxeon styled) support
- Add ledstring blaster effect ( randomly shut down one segment for a
short amount of time - I forgot that one :P)
- Add some sounds to config Mode (to signal you reached min/max value)
- Add boot sounds of soundfont when selecting them in config mode.
- Make powerOn/powerOff ledstring effect sync to soundfont  soundfiles
play time.

--- Lightsaber.ino
+++ Lightsaber.ino
@@ -629,13 +629,9 @@
 					 * Last soundfile is over and has stopped :
 					 * We relaunch the hum !
 					 */
-<<<<<<< HEAD
 #ifdef LUXEON
 					lightChangeColor(storage.mainColor,true);
 #endif
-=======
-					lightChangeColor(storage.mainColor,true);
->>>>>>> refs/remotes/origin/RGB-fork
 #ifdef LS_RELAUNCH_DEBUG
 					Serial.print(F("MP3 stopped :"));
 					Serial.print(millis());
@@ -727,11 +723,7 @@
 			if (enterMenu) {
 				mp3.playTrackFromDir(4, 1/*, false*/);
 #ifdef LS_INFO
-<<<<<<< HEAD
 				Serial.print(F("VOLUME\nCur:"));
-=======
-				Serial.print(F("VOLUME\nCurrent:"));
->>>>>>> refs/remotes/origin/RGB-fork
 				Serial.println(storage.volume);
 #endif
 				enterMenu = false;
@@ -762,11 +754,7 @@
 			if (enterMenu) {
 				mp3.playTrackFromDir(5, 1);
 #ifdef LS_INFO
-<<<<<<< HEAD
 				Serial.println(F("SOUNDFONT\nCur:"));
-=======
-				Serial.println(F("SOUNDFONT\nCurrent:"));
->>>>>>> refs/remotes/origin/RGB-fork
 				Serial.println(soundFont.getFolder());
 #endif
 				enterMenu = false;
@@ -782,28 +770,17 @@
 			} else if (value == 2 and play) {
 				play = false;
 				mp3.playTrackFromDir(15, 1/*, false*/);
-<<<<<<< HEAD
 				delay(500);
 			} else if (value == SOUNDFONT_QUANTITY + 1 and play) {
 				play = false;
 				mp3.playTrackFromDir(14, 1/*, false*/);
 				delay(500);
-=======
-				//delay(100);
-			} else if (value == SOUNDFONT_QUANTITY + 1 and play) {
-				play = false;
-				mp3.playTrackFromDir(14, 1/*, false*/);
-				//delay(100);
->>>>>>> refs/remotes/origin/RGB-fork
 			}
 			if (value != lastValue) {
 				storage.soundFont = value;
 				soundFont.setFolder(value);
-<<<<<<< HEAD
 				mp3.playTrackFromDir(soundFont.getBoot(), soundFont.getFolder()/*, false*/);
 				delay(500);
-=======
->>>>>>> refs/remotes/origin/RGB-fork
 				//mp3.playTrackFromDir(soundFont.getBoot(),soundFont.getFolder()/*, false*/);
 #ifdef LUXEON
 				storage.mainColor[3] = storage.soundFontColorPreset[value][0];
@@ -828,11 +805,7 @@
 				ledOff(ledPins);
 				lightChangeColor(storage.mainColor,true);
 #ifdef LS_INFO
-<<<<<<< HEAD
 				Serial.print(F("COLOR1\nCur:"));
-=======
-				Serial.print(F("MAIN COLOR\nCurrent:"));
->>>>>>> refs/remotes/origin/RGB-fork
 				Serial.println(storage.mainColor[3]);
 #endif
 				enterMenu = false;
@@ -869,11 +842,7 @@
 				ledOff(ledPins);
 				lightChangeColor(storage.clashColor,true);
 #ifdef LS_INFO
-<<<<<<< HEAD
 				Serial.print(F("COLOR2\nCur:"));
-=======
-				Serial.print(F("CLASH  COLOR\nCurrent:"));
->>>>>>> refs/remotes/origin/RGB-fork
 				Serial.println(storage.clashColor[3]);
 #endif
 				enterMenu = false;
@@ -944,11 +913,7 @@
 			if (enterMenu) {
 				mp3.playTrackFromDir(6, 1);
 #ifdef LS_INFO
-<<<<<<< HEAD
 				Serial.print(F("SWING\nCur:"));
-=======
-				Serial.print(F("SWING\nCurrent:"));
->>>>>>> refs/remotes/origin/RGB-fork
 				Serial.print(storage.swingTreshold);
 #endif
 				enterMenu = false;
@@ -979,11 +944,7 @@
 			if (enterMenu) {
 				mp3.playTrackFromDir(7, 1);
 #ifdef LS_INFO
-<<<<<<< HEAD
 				Serial.print(F("CLASH1\nCur:"));
-=======
-				Serial.print(F("CLASH  ACCEL\nCurrent:"));
->>>>>>> refs/remotes/origin/RGB-fork
 				Serial.print(storage.clashAccelTreshold);
 #endif
 				enterMenu = false;
@@ -1013,11 +974,7 @@
 			if (enterMenu) {
 				mp3.playTrackFromDir(8, 1);
 #ifdef LS_INFO
-<<<<<<< HEAD
 				Serial.print(F("CLASH2\nCur:"));
-=======
-				Serial.print(F("CLASH  BRAKE\nCurrent:"));
->>>>>>> refs/remotes/origin/RGB-fork
 				Serial.print(storage.clashBrakeTreshold);
 #endif
 				enterMenu = false;


Update _04-mqtt-lcd-dust-sensor-esp-12.ino

--- _04-mqtt-lcd-dust-sensor/_04-mqtt-lcd-dust-sensor-esp-12/_04-mqtt-lcd-dust-sensor-esp-12.ino
+++ _04-mqtt-lcd-dust-sensor/_04-mqtt-lcd-dust-sensor-esp-12/_04-mqtt-lcd-dust-sensor-esp-12.ino
@@ -236,12 +236,10 @@
   client.set_callback(callback);

   WiFi.mode(WIFI_STA);
-
+  WiFi.begin(ssid, password);
+
 #ifdef __IS_MY_HOME
-  WiFi.begin(ssid, password, channel, bssid);
   WiFi.config(IPAddress(192, 168, 10, 12), IPAddress(192, 168, 10, 1), IPAddress(255, 255, 255, 0));
-#else
-  WiFi.begin(ssid, password);
 #endif

   while (WiFi.status() != WL_CONNECTED) {


Fix traits error for arduino examples (#400)

--- arduino/examples/Vector_Examples/Example_Vector_1_simple_use/Example_Vector_1_simple_use.ino
+++ arduino/examples/Vector_Examples/Example_Vector_1_simple_use/Example_Vector_1_simple_use.ino
@@ -1,3 +1,6 @@
+// make sure that we do not rely on the STL
+#define ETL_NO_STL
+
 #include "Embedded_Template_Library.h"
 #include "etl/vector.h"


Time scaled yaw target tracking; calculate altitude even in standby

--- examples/quadcopter/quadcopter.ino
+++ examples/quadcopter/quadcopter.ino
@@ -100,6 +100,7 @@
     const float yawCmd   = ((float)APMRadio::get(RADIO_YAW)-90)   / 90.0;
     const float throttle = ((float)APMRadio::get(RADIO_THROTTLE)-25)/130.0;
     const bool  gearCmd  = (APMRadio::get(RADIO_GEAR) > 90);
+    altitudeCalculation();

     // check for low throttle standby mode
     if(APMRadio::get(RADIO_THROTTLE) <= CHANNEL_MIN){
@@ -121,11 +122,12 @@

     // update yaw target
     if(fabs(yawCmd) > 0.1){
-        yawTarget += yawCmd/160.0;
+        static uint32_t integrationTimer = micros();
+        float dt = (micros() - integrationTimer)/1e6;
+        yawTarget += yawCmd*dt;
         yawTarget = truncateRadian(yawTarget);
     }

-    altitudeCalculation();
     // calculate target throttle
     float throttleOut = (altHold)? altHoldUpdate(throttle) :
                                    throttleCurve.get(throttle);
@@ -197,17 +199,6 @@
     }

     return throttleOutput;
-}
-
-float dVdA(float v, float a){
-    static float pv, pa;
-    static float ave;
-    float dv = v-pv;
-    float da = a-pa;
-    pv = v;
-    pa = a;
-    ave = 0.95 * ave + 0.05 * (dv/da);
-    return ave;
 }

 void sendTelemetry(){


added aparent power readings tu debug

added aparent power readings tu debug

--- utils/emontxv3_firmware/raspimon_firmware/DiscreteSampling/DiscreteSampling.ino
+++ utils/emontxv3_firmware/raspimon_firmware/DiscreteSampling/DiscreteSampling.ino
@@ -398,9 +398,13 @@

   if (debug==1) {
     Serial.print(emontx.power1); Serial.print(" ");
+    Serial.print(emontx.aPower1); Serial.print(" ");                                  //ADDED aPower readings to debug
     Serial.print(emontx.power2); Serial.print(" ");
+    Serial.print(emontx.aPower2); Serial.print(" ");
     Serial.print(emontx.power3); Serial.print(" ");
+    Serial.print(emontx.aPower3); Serial.print(" ");
     Serial.print(emontx.power4); Serial.print(" ");
+    Serial.print(emontx.aPower4); Serial.print(" ");
     Serial.print(emontx.Vrms); Serial.print(" ");
     Serial.print(emontx.pulseCount); Serial.print(" ");
     if (DS18B20_STATUS==1){


PCB v11 LCD updates

PCB v11 LCD updates

--- jemmaclock/jemmaclock.ino
+++ jemmaclock/jemmaclock.ino
@@ -27,6 +27,7 @@
 #define PCB01 0
 #define PCB04 0
 #define PCB10 1
+#define PCB11 0

 /*
  * http://a-control.de/arduino-fehler/?lang=en
@@ -119,16 +120,19 @@
  * pot to LCD VO pin (pin 3)
 */

+
+#if PCB01
+  LiquidCrystal lcd(7, 8, 9, 10, 11, 12);
 #define REDLCDLED 3
 #define GREENLCDLED 5
 #define BLUELCDLED 6
-
-#if PCB01
-  LiquidCrystal lcd(7, 8, 9, 10, 11, 12);
 #endif

 #if PCB04
   LiquidCrystal lcd(7, 8, 9, 10, 11, 12);
+#define REDLCDLED 3
+#define GREENLCDLED 5
+#define BLUELCDLED 6
 #endif

 // RS=4, En=6, db4=11, db5=12, db6=13, db7=14
@@ -138,6 +142,13 @@
 #define REDLCDLED 5
 #define GREENLCDLED 6
 #define BLUELCDLED 9
+#endif
+
+#if PCB11
+  LiquidCrystal lcd(4, 7, 8, 10, 11, 12); //D8
+#define REDLCDLED 9
+#define GREENLCDLED 6
+#define BLUELCDLED 5
 #endif

@@ -430,6 +441,11 @@
 }

 void fadeBacklight( int newColor, int oldColor = 0 ) {
+  // beware the PWM and ATMega timers.
+  // when green and blue are on different pairs, there's flicker.
+  // so v11 of the PCB puts Blue and Green on the same pair.
+  // there might be flicker with Red, but since that never gets mixed in
+  // except during a transition, it shouldn't really matter.
   if ( newColor == REDCOLOR ) {
     for (int i = 0; i < 255; i++) {
     Adafruit::setBacklight(i, 255-i, 0);
@@ -679,9 +695,10 @@
   pinMode(2, INPUT);
   // pin 13, used for antenna LED
   pinMode(LED_BUILTIN, OUTPUT);
+  digitalWrite(LED_BUILTIN, LOW);
   // pin 4, used for antenna LED
-  pinMode(4, OUTPUT);
-  digitalWrite(LED_BUILTIN, LOW);
+  pinMode(A1, OUTPUT);
+  digitalWrite(A1, LOW);
   // pins for RGB LCD colors
   pinMode(REDLCDLED, OUTPUT);
   pinMode(GREENLCDLED, OUTPUT);
@@ -860,10 +877,10 @@
     // update LED. Off with connected antenna, 3
     if (antennaStatus == 3) {
       digitalWrite(LED_BUILTIN, LOW);
-      digitalWrite(4, LOW);
+      digitalWrite(A1, LOW);
     } else {
       digitalWrite(LED_BUILTIN, HIGH);
-      digitalWrite(4, HIGH);
+      digitalWrite(A1, HIGH);
     } //endif antenna status
   }