update accel.ino

update accel.ino

--- examples/accel/accel.ino
+++ examples/accel/accel.ino
@@ -5,7 +5,7 @@
 	initialize();

 	led1.off();
-	led2.color(0);
+	led1.color(0.5);
 	led2.off();
 	led2.color(0.5);
 }
@@ -24,4 +24,4 @@
 	}

 	wait(20);
-};
+}


tracker: log, motion detect

tracker: log, motion detect

--- CarTracker/CarTracker.ino
+++ CarTracker/CarTracker.ino
@@ -45,15 +45,11 @@
 // Hardware serial is also possible!
 //  HardwareSerial *fonaSerial = &Serial1;

-// Use this for FONA 800 and 808s
 Adafruit_FONA fona = Adafruit_FONA(PIN_FONA_RST);
-// Use this one for FONA 3G
-//Adafruit_FONA_3G fona = Adafruit_FONA_3G(FONA_RST);
-
-//uint8_t readline(char *buff, uint8_t maxbuff, uint16_t timeout = 0);
-
-uint8_t type;
-
+
+//uint8_t type;
+
+#define HALT()    while(1);
 void setup()
 {
     while (!Serial)
@@ -73,16 +69,24 @@
     /////////////////////////////////////////////////////////

     // initialize device
-//    Serial.println("Initializing I2C devices...");
+    Serial.println(F("Initializing I2C devices..."));
     mpu.initialize();

     // verify connection
-//    Serial.println("Testing device connections...");
-//    Serial.println(mpu.testConnection() ? "MPU6050 connection successful" : "MPU6050 connection failed");
+    Serial.println(F("Testing device connections..."));
+    if(mpu.testConnection())
+    {
+        Serial.println(F("MPU6050 connection successful"));
+    }
+    else
+    {
+        Serial.println(F("MPU6050 connection failed"));
+        HALT();
+    }

     // enable Arduino interrupt detection
-//    Serial.print(F("Enabling interrupt detection on pin "));
-//    Serial.println(INTERRUPT_PIN);
+    Serial.print(F("Enabling interrupt detection on pin "));
+    Serial.println(INTERRUPT_PIN);
     attachInterrupt(digitalPinToInterrupt(INTERRUPT_PIN), interruptHandler, RISING);
     mpuIntStatus = mpu.getIntStatus();

@@ -91,31 +95,7 @@
     mpu.setDHPFMode(DHPF_MODE);
     mpu.setMotionDetectionCounterDecrement(MOTION_DETECTION_COUNTER_DECREMENT);
     mpu.setIntMotionEnabled(1);
-
-
-//    Serial.print("getIntEnabled ");
-//    Serial.println(mpu.getIntEnabled());
-//
-//    Serial.print("getIntMotionEnabled ");
-//    Serial.println(mpu.getIntMotionEnabled());
-//
-//    Serial.print("getMotionDetectionThreshold ");
-//    Serial.println(mpu.getMotionDetectionThreshold());
-//
-//    Serial.print("getMotionDetectionDuration ");
-//    Serial.println(mpu.getMotionDetectionDuration());
-//
-//    Serial.print("getMotionDetectionCounterDecrement ");
-//    Serial.println(mpu.getMotionDetectionCounterDecrement());
-//
-//    Serial.print("getDHPFMode ");
-//    Serial.println(mpu.getDHPFMode());
-
-//    Serial.print("getIntMotionStatus ");
-//    Serial.println(mpu.getIntMotionStatus());
-
-
-
+
     /////////////////////////////////////////////////////////
     // GSM
     /////////////////////////////////////////////////////////
@@ -129,33 +109,33 @@
         while (1)
             ;
     }
-    type = fona.type();
+//    type = fona.type();
     Serial.println(F("FONA is OK"));
-    Serial.print(F("Found "));
-    switch (type)
-    {
-    case FONA800L:
-        Serial.println(F("FONA 800L"));
-        break;
-    case FONA800H:
-        Serial.println(F("FONA 800H"));
-        break;
-    case FONA808_V1:
-        Serial.println(F("FONA 808 (v1)"));
-        break;
-    case FONA808_V2:
-        Serial.println(F("FONA 808 (v2)"));
-        break;
-    case FONA3G_A:
-        Serial.println(F("FONA 3G (American)"));
-        break;
-    case FONA3G_E:
-        Serial.println(F("FONA 3G (European)"));
-        break;
-    default:
-        Serial.println(F("???"));
-        break;
-    }
+//    Serial.print(F("Found "));
+//    switch (type)
+//    {
+//    case FONA800L:
+//        Serial.println(F("FONA 800L"));
+//        break;
+//    case FONA800H:
+//        Serial.println(F("FONA 800H"));
+//        break;
+//    case FONA808_V1:
+//        Serial.println(F("FONA 808 (v1)"));
+//        break;
+//    case FONA808_V2:
+//        Serial.println(F("FONA 808 (v2)"));
+//        break;
+//    case FONA3G_A:
+//        Serial.println(F("FONA 3G (American)"));
+//        break;
+//    case FONA3G_E:
+//        Serial.println(F("FONA 3G (European)"));
+//        break;
+//    default:
+//        Serial.println(F("???"));
+//        break;
+//    }

     // Print module IMEI number.
 //    char imei[15] =
@@ -175,17 +155,10 @@
     //fona.setGPRSNetworkSettings(F("your APN"), F("your username"), F("your password"));
     fona.setGPRSNetworkSettings(F(APN));

-    // Optionally configure HTTP gets to follow redirects over SSL.
-    // Default is not to follow SSL redirects, however if you uncomment
-    // the following line then redirects over SSL will be followed.
-    //fona.setHTTPSRedirect(true);
-
-    //printMenu();
-
-    delay(1000);
-
-    Serial.print(F("RSSI = "));
-    Serial.println(fona.getRSSI());
+//    delay(1000);
+
+//    Serial.print(F("RSSI = "));
+//    Serial.println(fona.getRSSI());

     // enable network time sync
 //	if (!fona.enableNetworkTimeSync(true))
@@ -268,6 +241,11 @@

 void loop()
 {
+    while(!mpuInterrupt)
+    {
+        delay(1000);
+    }
+
     motion=0;
     if (mpuInterrupt)
     {
@@ -295,8 +273,7 @@
     if (!fona.getBattVoltage(&vbat))
     {
         Serial.println(F("Failed to read Batt"));
-        while(1)
-            ;
+        HALT();
     }
     else
     {
@@ -321,8 +298,7 @@
     else
     {
         Serial.println(F("getGSMLoc Failed!"));
-        while(1)
-            ;
+        HALT();
     }

 //    phant.add("a", 72);
@@ -353,7 +329,7 @@

 //    Serial.print(F("url: "));
 //    Serial.println((char*) (phant.url().c_str()));
-//    while(1);
+//    HALT();
 //    return;

     if (!HTTP_GET_start(&statuscode, (uint16_t *) &length))


Speed values are never used in the animation

--- Cymatic-Triangles/Mic.ino
+++ Cymatic-Triangles/Mic.ino
@@ -17,7 +17,6 @@
 #define WISP_2_START_POS 15 /* Wisp 2 starting position */
 #define WISP_HUE_INCREMENT 2 /* How much the color of the Wisps changes per loop */
 #define BASE_TRAIL 13 /* Starting wisp trail length */
-#define BASE_SPEED 100 /* Starting wisp rotation speed */
 #define BASE_BRIGHTNESS_STEP 8 /* Starting brightness increment between wisp and trail elements */
 #define BASE_HUE_STEP 3 /* Starting hue increment between wisp and trail elements */
 #define BASE_BRIGHTNESS 100 /* Base Wisp brightness */
@@ -31,7 +30,6 @@
 Wisp wisp2(WISP_2_START_POS, BASE_TRAIL, BASE_BRIGHTNESS, WISP_2_HUE);

 /* Variables to be changed in the loop */
-int speed = BASE_SPEED; /* Speed of Wisps (as of now they share the speed globally) */
 int brightness_step = BASE_BRIGHTNESS_STEP; /* How much brightness is lost from one trail pixel to the next */
 int new_brightness; /* Temp variable for the new calculated brightness */

@@ -50,10 +48,6 @@

 void animateMic() {
   float peak = normalize((float)amp_sum_L);
-
-  /* Calculate the new speed based on the peak value (it's between 0.0 and 1.0) */
-  speed = BASE_SPEED - (int)(peak * (BASE_SPEED * 0.9));
-  if(speed < 0) speed = 0; /* In case speed drops below 0, we don't want that */

   /* Calculate new brightness, ease brightness toward the new value */
   new_brightness = BASE_BRIGHTNESS + (int)(peak * 100);


Contrast changed to 61 for power from 3.3V

--- lcd_5110_pics/lcd_5110_pics.ino
+++ lcd_5110_pics/lcd_5110_pics.ino
@@ -595,7 +595,7 @@

 void setup() {
   display.begin();
-  display.setContrast(51);
+  display.setContrast(61);
   //display.setTextSize(2);
 }


Correct wireless power-down in example sketch; CosaWirelessDS18B20.

--- examples/Wireless/CosaWirelessDS18B20/CosaWirelessDS18B20.ino
+++ examples/Wireless/CosaWirelessDS18B20/CosaWirelessDS18B20.ino
@@ -117,11 +117,14 @@

 void setup()
 {
-  // Start watchdog, real-time clock and wireless device
+  // Start watchdog and real-time clock
   Watchdog::begin(128);
   RTC::begin();
+
+  // Start the wireless device
   rf.begin();
-
+  rf.powerdown();
+
   // Connect to the temperature sensors; use active pullup
   pw.on();
   {


Vcc measurement now returns rolling average

--- arduino/serial_control/serial_control.ino
+++ arduino/serial_control/serial_control.ino
@@ -5,6 +5,7 @@
 // https://www.controleverything.com/content/Digital-Analog?sku=AD5667_I2CDAC#tabs-0-product_tabset-2

 #include<Wire.h>
+#include<RunningAverage.h>

 #ifndef SERIAL_RATE
 #define SERIAL_RATE         115200
@@ -23,6 +24,8 @@
 int value = 0;
 int cmd = 0;

+RunningAverage vcc(30);
+
 void setup()
 {
   //initialise I2C communication as Master
@@ -34,6 +37,8 @@

   //set analog reference voltage
   //analogReference(INTERNAL2V56)
+
+  vcc.clear();

   delay(300);
 }
@@ -70,12 +75,15 @@
       writeDAC(); break;
     case 8 :
       //read Vcc using 1.1 V on board reference
-      Serial.println(readVcc()); break;
+      Serial.println(vcc.getAverage()); break;
     case 99:
       //just dummy to cancel the current read, needed to prevent lock
       //when the PC side dropped the "w" that we sent
       break;
   }
+
+  vcc.addValue(readVcc());
+
 }

 char readData() {


Working on OLED screen saver.

Working on OLED screen saver.

--- src/rx5808-pro-diversity-oled/rx5808-pro-diversity-oled.ino
+++ src/rx5808-pro-diversity-oled/rx5808-pro-diversity-oled.ino
@@ -104,10 +104,11 @@
 #define STATE_SCAN 2
 #define STATE_MANUAL 3
 #ifdef USE_DIVERSITY
-#define STATE_DIVERSITY 4
+    #define STATE_DIVERSITY 4
 #endif
 #define STATE_SAVE 5
 #define STATE_RSSI_SETUP 6
+#define STATE_SCREEN_SAVER 7

 #define START_STATE STATE_SEEK
 #define MAX_STATE STATE_MANUAL
@@ -184,6 +185,7 @@
 uint8_t last_channel_index = 0;
 uint8_t force_seek=0;
 unsigned long time_of_tune = 0;        // will store last time when tuner was changed
+unsigned long time_screen_saver = 0;
 uint8_t last_maker_pos=0;
 uint8_t last_active_channel=0;
 uint8_t first_channel_marker=1;
@@ -313,7 +315,6 @@
     /*******************/
     /*   Mode Select   */
     /*******************/
-    state_last_used=state; // save save settings
     if (digitalRead(buttonMode) == LOW) // key pressed ?
     {
         beep(50); // beep & debounce
@@ -493,8 +494,8 @@
         switch (state)
         {
             case STATE_SCAN: // Band Scanner
+                state_last_used=state;
             case STATE_RSSI_SETUP: // RSSI setup
-
                 // draw selected
                 display.drawRect(0, 0, display.width(), display.height(), WHITE);
                 display.fillRect(0, 0, display.width(), 11, WHITE);
@@ -546,19 +547,22 @@
                 scan_start=1;
                 display.display();
             break;
+            case STATE_SEEK: // seek mode
             case STATE_MANUAL: // manual mode
-            case STATE_SEEK: // seek mode
+                state_last_used=state;
                 display.drawRect(0, 0, display.width(), display.height(), WHITE);
                 display.fillRect(0, 0, display.width(), 11, WHITE);
                 display.drawRect(0, 10, display.width(), 11, WHITE);
                 if (state == STATE_MANUAL)
                 {
+                    time_screen_saver=millis();
                     display.setTextColor(BLACK);
                     display.setCursor(35,2);
                     display.print("MANUAL MODE");
                 }
                 else if(state == STATE_SEEK)
                 {
+                    time_screen_saver=0; // dont show screen saver until we found a channel.
                     display.setCursor(25,2);
                     display.setTextColor(BLACK);
                     display.print("AUTO SEEK MODE");
@@ -710,6 +714,56 @@
     /*   Processing depending of state   */
     /*************************************/

+
+    if(state == STATE_SCREEN_SAVER) {
+        // simple menu
+        char menu_id=diversity_mode;
+        uint8_t in_menu=1;
+
+        display.clearDisplay();
+        display.fillRect(0, 0, display.width(), display.height()-20, WHITE);
+        display.setTextSize(6);
+        display.setTextColor(BLACK);
+        display.setCursor(1,1);
+        display.print(pgm_read_byte_near(channelNames + channelIndex), HEX);
+        display.setTextSize(1);
+        display.setCursor(101,12);
+        display.setTextColor(BLACK);
+        display.print(pgm_read_word_near(channelFreqTable + channelIndex));
+        display.setCursor(0,display.height()-19);
+        display.setTextColor(WHITE);
+        display.print("A:");
+        display.setCursor(0,display.height()-9);
+        display.print("B:");
+        do{
+            delay(10); // timeout delay
+            // show signal strength
+            wait_rssi_ready();
+            if(menu_id == useReceiverAuto) {
+                readRSSI(); // update LED
+            }
+            // read rssi A
+            rssi = random(0, 100);//readRSSI(useReceiverA);
+            #define RSSI_BAR_SIZE 113
+            rssi_scaled=map(rssi, 1, 100, 1, RSSI_BAR_SIZE);
+
+            display.fillRect(13 + rssi_scaled, display.height()-18, (RSSI_BAR_SIZE-rssi_scaled), 7, BLACK);
+            display.fillRect(13, display.height()-18, rssi_scaled, 7, WHITE);
+
+
+            // read rssi B
+            rssi = random(0, 100);//readRSSI(useReceiverB);
+            rssi_scaled=map(rssi, 1, 100, 1, RSSI_BAR_SIZE);
+            display.fillRect(13 + rssi_scaled, display.height()-8, (RSSI_BAR_SIZE-rssi_scaled), 7, BLACK);
+            display.fillRect(13, display.height()-8, rssi_scaled, 7, WHITE);
+            display.display();
+        }
+        while((digitalRead(buttonMode) == HIGH) && (digitalRead(buttonSeek) == HIGH) && (digitalRead(buttonDown) == HIGH)); // wait for next button press
+        state=state_last_used;
+        time_screen_saver=0;
+        return;
+    }
+
 #ifdef USE_DIVERSITY
     if(state == STATE_DIVERSITY) {
         // simple menu
@@ -819,9 +873,11 @@
     {
         if(state == STATE_MANUAL) // MANUAL MODE
         {
+
             // handling of keys
             if( digitalRead(buttonSeek) == LOW)        // channel UP
             {
+                time_screen_saver=millis();
                 beep(50); // beep & debounce
                 delay(KEY_DEBOUNCE); // debounce
                 channelIndex++;
@@ -833,6 +889,7 @@
             }
             if( digitalRead(buttonDown) == LOW) // channel DOWN
             {
+                time_screen_saver=millis();
                 beep(50); // beep & debounce
                 delay(KEY_DEBOUNCE); // debounce
                 channelIndex--;
@@ -939,12 +996,14 @@
                 display.setTextColor(BLACK,WHITE);
                 display.setCursor(25,2);
                 display.print("AUTO MODE LOCK");
+                time_screen_saver=millis();
                 if (digitalRead(buttonSeek) == LOW) // restart seek if key pressed
                 {
                     beep(50); // beep & debounce
                     delay(KEY_DEBOUNCE); // debounce
                     force_seek=1;
                     seek_found=0;
+                    time_screen_saver=0;

                     display.setCursor(25,2);
                     display.print("AUTO SEEK MODE");
@@ -952,6 +1011,9 @@
             }
         }
         display.display();
+        if(time_screen_saver+5000 < millis() && time_screen_saver!=0) {
+            state = STATE_SCREEN_SAVER;
+        }
     }
     /****************************/
     /*   Processing SCAN MODE   */


clean-up as prep for merge back

clean-up as prep for merge back

--- projects/YunMon_RFM12B/YunMon_RFM12B.ino
+++ projects/YunMon_RFM12B/YunMon_RFM12B.ino
@@ -1,287 +0,0 @@
-/*
-Arduino Yun - Power and temperature measurement
-
-**
-** DOES NOT WORK - ABANDONED
-**
-** - pin 7 = IRQ 4 apparently not suited for photodarlington (is attached to AR9331)
-** - RFM12B hangs ...
-**
-
-1) Interrupt-driven light pulse detection with ppwh pulses per Wh
-  - IRQ 4 = Yun pin 7 > P_prod
-  - IRQ 1 = Yun pin 2 > abs(P_prod - P_cons)
-
-2) IRQ 0 = Yun pin 3 freed up for RFM12B
-
-3) OneWire temperature measurement via Dallas DS18B20
-
-4) Plot averaged powers to plot.ly as streaming plot
-
-5) Log data to /mnt/sda1/datalogs: timestamp, production [W], abs(production - consumption) [W], temperature [°C]
-
-
-Possible improvements / backlog:
-- check power calculations for pathological cases (zero difference etc)
-
-
-History:
-
-141229
-- moved to git, personal tokens moved out
-- IRQ switch in process
-
-140927 Merged with DS18B20 temperature measurement - on port 4, writing to col 4
-
-140921 Move from appending to one single datafile datalog.txt to daily datalog files
-
-140912  timing approach adjusted: timestamp with 1s precision is logged, looping until measurementinterval with
-ms precision has passed by. Should be ok for intervals >= 10s. Not ok for sub-second measurements.
-
-140911: data logging to SD card added
-*/
-
-// plot.ly streaming tokens, gitignored, same directory
-#include "mytokens.h"
-
-#include <Bridge.h>
-#include <Console.h>
-
-#include <OneWire.h>
-#include <DallasTemperature.h>
-
-// Data wire is plugged into port 4 on the Arduino
-#define ONE_WIRE_BUS 4
-
-// Setup a oneWire instance to communicate with any OneWire devices (not just Maxim/Dallas temperature ICs)
-OneWire oneWire(ONE_WIRE_BUS);
-
-// Pass our oneWire reference to Dallas Temperature.
-DallasTemperature sensors(&oneWire);
-
-// Data logging and time stamping from http://arduino.cc/en/Tutorial/YunDatalogger
-#include <FileIO.h>
-unsigned long millis_current;
-String fileName, timeStamp, dataString;
-char __fileName[34] = "/mnt/sda1/datalogs/YYYY-MM-DD.txt";  // value as pattern only, to get size right
-
-#include <PlotlyYun.h>
-#include <YunMessenger.h>
-
-// Initialize plotly "plotters" with your stream tokens.
-// Find your stream tokens in your plotly account here: https://plot.ly/settings
-// Initialize as many plotters as you want! Each plotter will send data to the same plot as a separate line.
-// Make sure that you place these exact-same stream tokens in your `config.json` file on the Linino.
-
-plotly plotter1(PLOTLY_TOKEN_1); plotly plotter2(PLOTLY_TOKEN_2); // plot.ly tokens
-
-// Measurement interval in milliseconds
-int measurementInterval = 10000;
-
-//Number of pulses per wh - found or set on the meter. 10000 pulses/kwh = 10 pulses per wh
-int ppwh0 = 10; int ppwh1 = 10;
-
-// Number of pulses, incl. averaged pulsed, to measure energy
-long pulseCount0 = 0; long pulseCount1 = 0; long averageCount0 = 0; long averageCount1 = 0;
-
-//Used to measure power
-unsigned long pulseTime0, accumulatedPulseTime0, lastTime0, deltaTime0, pulseTime1, accumulatedPulseTime1, lastTime1, deltaTime1;
-
-//power and energy
-double power0, averagedPower0, power1, averagedPower1;
-
-// JeeLib required for RFM12B
-#include <JeeLib.h>
-
-// mesurement structure for JeeNode micro temperature node
-typedef struct
-{
-    float Vcc;  // Supply voltage
-    float T;    // Temperature reading
-} measurementStruc;
-
-measurementStruc measurement;
-
-
-void setup()
-{
-
-    // start-up the bridge
-    Bridge.begin();
-    FileSystem.begin();
-
-    delay(2000);
-    Console.begin();
-    while (!Console)
-    {
-        ; // wait for Console port to connect.
-    }
-
-    Console.buffer(64);
-    delay(2000);
-
-    // attach interrupt routines
-    attachInterrupt(4, onPulse4, FALLING); attachInterrupt(1, onPulse1, FALLING);
-
-    // Start up the OneWire library
-    sensors.begin();
-
-    // initialize RFM12B
-    rf12_initialize(1, RF12_868MHZ, 0); // group id = 0 to receive from all groups
-
-    // important for plot.ly
-    plotter1.timezone  = "Europe/Berlin"; plotter2.timezone = "Europe/Berlin";
-
-    // current time ...
-    millis_current = millis();
-
-}
-
-void loop()
-{
-    // receive RFM12B measurement data packages
-    measurement.Vcc = 0.0;
-    measurement.T = 86.0; // normally, 85.0 = "not valid" for DS18B20. Here, 86.0 = "no package received"
-    if (rf12_recvDone() && rf12_crc == 0)
-    {
-        // assuming payload structure is correct
-        measurement.Vcc = (rf12_data[0] + 256 * rf12_data[1]) / 100.0;
-        measurement.T = (rf12_data[2] + 256 * rf12_data[3]) / 100.0;
-        //Serial.print("rf12 group = "); Serial.print(rf12_grp);
-
-        // node id is in the first 5 bits of rf12_hdr --> & RF12_HDR_MASK
-        //Serial.print(", rf12 node id  = "); Serial.print(rf12_hdr & RF12_HDR_MASK);
-
-        //Serial.print(", Vcc = "); Serial.print(measurement.Vcc);
-        //Serial.print(", T = "); Serial.println(measurement.T);
-    }
-
-    // main data logging loop
-    if (millis() - millis_current > measurementInterval)
-    {
-
-        // reset timer
-        millis_current = millis();
-
-        sensors.requestTemperatures(); // Send the command to get temperatures
-
-        // Target: YY-MM-DD hh:mm:ss, elapsed Millis, analogValues
-        dataString = getTimeStamp() + ",";
-        dataString += String(averagedPower0); dataString += ",";
-        dataString += String(averagedPower1); dataString += ",";
-        dataString += String(sensors.getTempCByIndex(0));
-        dataString += String(measurement.Vcc);
-        dataString += String(measurement.T);
-
-        // open the file. note that only one file can be open at a time,
-        // so you have to close this one before opening another.
-        // The FileSystem card is mounted at the following "/mnt/sda1"
-        fileName = "/mnt/sda1/datalogs/" + getDate() + ".txt";
-        // convert fileName string to char array
-        fileName.toCharArray(__fileName, sizeof(__fileName));
-        File dataFile = FileSystem.open(__fileName, FILE_APPEND);
-
-        // if the file is available, write to it:
-        if (dataFile)
-        {
-            dataFile.println(dataString);
-            dataFile.close();
-            // print to the serial port too:
-            Console.println(dataString);
-        }
-        // if the file isn't open, pop up an error:
-        else
-        {
-            Console.println("error opening datalog.txt");
-        }
-
-        //Plot the value
-        plotter1.plot(averagedPower0); // Solar production
-        plotter2.plot(averagedPower1); // Zweirichtungszaehler
-
-        //Reset averaging
-        averageCount0 = 0; accumulatedPulseTime0 = 0;
-        averageCount1 = 0; accumulatedPulseTime1 = 0;
-    }
-}
-
-//Interrupt routine 0 - PV production
-void onPulse4()
-{
-    //pulseCounters
-    pulseCount0++; averageCount0++;
-
-    //used to measure time between pulses.
-    lastTime0 = pulseTime0;
-    pulseTime0 = micros();
-    deltaTime0 = pulseTime0 - lastTime0;
-    accumulatedPulseTime0 += deltaTime0;
-
-    //Calculate power
-    power0 = 3600000000.0 / (deltaTime0 * ppwh0);
-    averagedPower0 = (3600000000.0 * averageCount0) / (accumulatedPulseTime0 * ppwh0);
-    //  }
-}
-
-//Interrupt routine 1 - Zweirichtungszaehler
-void onPulse1()
-{
-    //pulseCounters
-    pulseCount1++; averageCount1++;
-
-    //used to measure time between pulses.
-    lastTime1 = pulseTime1;
-    pulseTime1 = micros();
-    deltaTime1 = pulseTime1 - lastTime1;
-    accumulatedPulseTime1 += deltaTime1;
-
-    //Calculate power
-    power1 = 3600000000.0 / (deltaTime1 * ppwh1);
-    averagedPower1 = (3600000000.0 * averageCount1) / (accumulatedPulseTime1 * ppwh1);
-    //  }
-}
-
-// This function returns a string with the current date
-String getDate()
-{
-    String result;
-    Process time;
-    // date is a command line utility to get the date and the time
-    // in different formats depending on the additional parameter
-    time.begin("date");
-    time.addParameter("+%Y-%m-%d");  // parameters: D for the complete date mm/dd/yy, T for the time hh:mm:ss
-    time.run();  // run the command
-
-    // read the output of the command
-    while (time.available() > 0)
-    {
-        char c = time.read();
-        if (c != '\n')
-            result += c;
-    }
-
-    return result;
-}
-
-// This function returns a string with the time stamp
-String getTimeStamp()
-{
-    String result;
-    Process time;
-    // date is a command line utility to get the date and the time
-    // in different formats depending on the additional parameter
-    time.begin("date");
-    time.addParameter("+%Y-%m-%d %T");  // parameters: D for the complete date mm/dd/yy, T for the time hh:mm:ss
-    time.run();  // run the command
-
-    // read the output of the command
-    while (time.available() > 0)
-    {
-        char c = time.read();
-        if (c != '\n')
-            result += c;
-    }
-
-    return result;
-}
-


Clean up some whitespace.

Clean up some whitespace.

--- code/LadybugAttiny85/LadybugAttiny85.ino
+++ code/LadybugAttiny85/LadybugAttiny85.ino
@@ -51,7 +51,7 @@
   strip.setPixelColor(0, 0);
   strip.show();
   sbi(GIMSK, PCIE);  // Turn on Pin Change interrupt
-  sbi(PCMSK, PCINT3); // Which pins are affected by the interru                                                                                pt
+  sbi(PCMSK, PCINT3); // Which pins are affected by the interrupt
   powerDown();
   cbi(GIMSK, PCIE);  // Turn on Pin Change interrupt
   cbi(PCMSK, PCINT3); // Which pins are affected by the interrupt
@@ -115,8 +115,4 @@
       randomizer.update();
       break;
   }
-
 }
-
-
-


Check unary encode/decode.

Check unary encode/decode.

--- test_SECFRAME/test_SECFRAME.ino
+++ test_SECFRAME/test_SECFRAME.ino
@@ -785,6 +785,18 @@
 //  Serial.println(after - before); // DHD20160207: 1442 for 8 rounds, or ~180ms per encryption.
   }

+// Test low-wear unary encoding.
+static void testUnaryEncoding()
+  {
+  Serial.println("UnaryEncoding");
+  // Check for conversion back and forth of all allowed represented values.
+  for(uint8_t i = 0; i <= 8; ++i) { AssertIsEqual(i, OTV0P2BASE::eeprom_unary_1byte_decode(OTV0P2BASE::eeprom_unary_1byte_encode(i))); }
+  for(uint8_t i = 0; i <= 16; ++i) { AssertIsEqual(i, OTV0P2BASE::eeprom_unary_2byte_decode(OTV0P2BASE::eeprom_unary_2byte_encode(i))); }
+  // Ensure that all-1s (erased) EEPROM values equate to 0.
+  AssertIsEqual(0, OTV0P2BASE::eeprom_unary_1byte_decode(0xff));
+  AssertIsEqual(0, OTV0P2BASE::eeprom_unary_1byte_decode(0xffffU));
+  }
+
 // Test some basic parameters of node associations.
 // Does not wear non-volatile memory (eg EEPROM).
 static void testNodeAssoc()
@@ -977,6 +989,7 @@
   testLibVersion();
   testLibVersions();

+  testUnaryEncoding();
   testFrameQIC();
   testFrameHeaderEncoding();
   testFrameHeaderDecoding();


Minor fixes

Minor fixes

* 改用platformio + atom进行编译，其它文件稍后上传
* 修复低级错误：c/c++中0是八进制的前缀，判断时间那里为了增加代码可读性和美观度我多加了好多个0，搞到12点和15点的铃声不能自动控制
* 代码缩进、空格之类的改进

```
Program:   17350 bytes (52.9% Full)
(.text + .data + .bootloader)

Data:        565 bytes (27.6% Full)
(.data + .bss + .noinit)

[SUCCESS] Took 17.30 seconds
```

--- smart_666.ino
+++ smart_666.ino
@@ -1,3 +1,5 @@
+#include <Arduino.h>
+
 #define AUDIO_CONTROL 4
 #include "mycard.h"
 /*#include <IRremote.h>
@@ -33,7 +35,7 @@
   digitalWrite(2, HIGH);
   /*Serial.write(26);
   Serial.println("SPG(0);");*/
-
+
   // LOGO
   delay(1500);
   Serial.begin(115200);
@@ -65,7 +67,7 @@
   delay(500);
   Serial.println(F("Initializing SPI driver ..."));
   SPI.begin();        // Init SPI bus
-  if (mfrc522.PCD_PerformSelfTest()) {
+  if (mfrc522.PCD_PerformSelfTest()) {
     key.keyByte[0] = 0x00;
     key.keyByte[1] = 0x30;
     key.keyByte[2] = 0x03;
@@ -90,7 +92,7 @@
   Serial.println(F("SPG(4);"));
   delay(100);
   Serial.print(F("DS24(80,80,'")); Serial.print(temp,1); Serial.println(F(" \\'C',0,0);"));
-  delay(100); atMain = true;
+  delay(500); atMain = true;
 }

 void on(){
@@ -134,12 +136,12 @@
   }
   if (ttl.length() > 0) {
     if (ttl != "OK" /*|| ttl != "\r\nOK" || ttl != "\r\nOK\r\n" || ttl != "OK\r\n" || ttl != "OKOK" */) {
-      int bn = 0;
+      int bn = 0;
       sscanf(ttl.c_str(), "[BN:%d]\r\n", &bn);
       //Serial.println(bn,DEC);
       if (bn == 32) atMain = true; else atMain = false;
       if (bn == 31 || bn == 1 || bn == 2 || bn == 3) {
-        atCtrl = true;
+        atCtrl = true;
         if (bn == 1) {
           autoC = false; on();
         } else if (bn == 2) {
@@ -149,11 +151,11 @@
         }
       } else atCtrl = false;
       if (bn == 29) atCard = true; else atCard = false;
-      if (bn == 25 || bn == 22 || bn == 21 || bn == 20 || bn == 19 || bn == 18 || bn == 17 || bn == 16) {
+      if (bn == 25 || bn == 22 || bn == 21 || bn == 20 || bn == 19 || bn == 18 || bn == 17 || bn == 16) {
         atRTC = true;
         DateTime now = rtc.now();
         DateTime adj;
-        if (bn == 16) { // switch datetime, 16
+        if (bn == 16 || bn == 25) { // switch datetime, 16
           showTime = !showTime;
         } else {
           if (bn == 22) { // up1
@@ -200,19 +202,19 @@
           if (bn != 0) atRTC = false;
         }
       }
-
+
       if (bn == 30) {
         if (noAuto) {
           Serial.println("DS12(0,0,'RTC\xC4\xA3\xBF\xE9\xB9\xCA\xD5\xCF',1);"); //DS12(0,0,'RTC模块故障',1);
         } else {
-          atCount = true; countLoop = 59;
+          atCount = true; countLoop = 60;
         }
       } else atCount = false;
       delay(100);
     }
     ttl = "";
   }
-
+
 // not always run code
 if (mainLoop == 65535) {
   // Judge where I am
@@ -282,6 +284,7 @@
     }
   }
   if (atCard) {
+    if (no522) { Serial.println(F("DS12(0,0,'NFC\xC4\xA3\xBF\xE9\xB9\xCA\xD5\xCF',1);")); mainLoop++; return; }
     // Look for new cards
     if (!mfrc522.PICC_IsNewCardPresent()) { mainLoop++; return; }
     if (!mfrc522.PICC_ReadCardSerial()) { mainLoop++; return; }
@@ -294,7 +297,6 @@
     }
     // In this sample we use the second sector,
     // that is: sector #1, covering block #4 up to and including block #7
-    byte sector         = 1;
     byte blockAddr      = 4;
     byte trailerBlock   = 7;
     MFRC522::StatusCode status;
@@ -316,7 +318,7 @@
       flag = 1;
     }
     float current = 0.01; float last = 0.02;
-    current = getBnc(buffer[flag]);
+    current = getBnc(buffer[flag]);
     last = getBnc(buffer[1-flag]);
     Serial.print(F("CBOF(13,54,113,154,5,3);"));
     Serial.print(F("SBC(3);"));
@@ -328,15 +330,15 @@
       Serial.print(F("BTN(26,13,54,113,154,4,138);"));
     }
     Serial.println();
-
+
     // Halt PICC
     mfrc522.PICC_HaltA();
     // Stop encryption on PCD
     mfrc522.PCD_StopCrypto1();
-  }
-
+  }
+
   // Global auto audio control
-  if (autoC) {
+  if (autoC) {
     DateTime now = rtc.now();
     byte h = now.hour(); byte m = now.minute(); byte s = now.second();
     int tc = m * 100 + s;
@@ -346,11 +348,11 @@
       case 9: if (tc >= 2003 && tc <= 2100) off(); else on(); break;
       case 10: if (tc >= 1003 && tc <= 1100) off(); else on(); break;
       case 11: if (tc >= 1503 && tc <= 1600) off(); else on(); break;
-      case 12: if (tc >= 0503 && tc <= 0600 || tc >= 5500) off(); else on(); break;
+      case 12: if ((tc >= 503 && tc <= 600) || tc >= 5500) off(); else on(); break;
       case 13: off(); break;
-      case 14: if (tc >= 0000 && tc <= 2000) off(); else on(); break;
-      case 15: if (tc >= 0503 && tc <= 0630) off(); else on(); break;
-      case 16: if (tc >= 0003 && tc <= 0100 || tc >= 5003 && tc <= 5100) off(); else on(); break;
+      case 14: if (tc >= 0 && tc <= 2000) off(); else on(); break;
+      case 15: if (tc >= 503 && tc <= 600) off(); else on(); break;
+      case 16: if ((tc >= 3 && tc <= 100) || (tc >= 5003 && tc <= 5100)) off(); else on(); break;
       case 17: if (tc >= 1000 && tc <= 2000) off(); else on(); break;
       case 18: if (tc >= 5000) off(); else on(); break;
       case 20: if (tc >= 2003 && tc <= 2100) off(); else on(); break;


Removed reset to zero on trigger interrupt

Envelope was just reseting to zero instead of retriggering so removed reset to zero on trigger interrupt.


Confused by the LED macros...

Confused by the LED macros...

--- gps-transmitter/gps_transmitter_fio/gps_transmitter_fio.ino
+++ gps-transmitter/gps_transmitter_fio/gps_transmitter_fio.ino
@@ -51,8 +51,8 @@
 }

 void setup() {
-  RXLED1;
-  TXLED1;
+  RXLED1;   // Turn off the RX light (blue) - on when there's a GPS fix
+  TXLED1;   // Turn off the TX light (yellow) - on when there's a successful XBee response

   Serial.begin(9600);

@@ -95,6 +95,7 @@
       return;
     }

+    // status bit 0 is fix status
     if (GPS.fix) {
       RXLED0;
       gps_status |= 1 << 0;
@@ -121,9 +122,9 @@
         xbee.getResponse().getTxStatusResponse(txStatus);
         if (txStatus.getStatus() == SUCCESS) {
 #endif
+          TXLED0;
+        } else {
           TXLED1;
-        } else {
-          TXLED0;
         }
       }
     }


Added comments.

Added comments.

--- MAX72xx/Demo2/Demo2.ino
+++ MAX72xx/Demo2/Demo2.ino
@@ -21,7 +21,9 @@
   Serial.print(" ");
   Serial.println(y, DEC);

-  int matrix_y = map(y, 377, 476, 7, 0);
+  int matrix_y = map(y, 377, 476, 7, 0); // Maps values in the range
+                                         // 377 to 476 to the range
+                                         // 7 to 0
   int matrix_x = map(x, 382, 479, 7, 0);

   matrix.fillScreen(0);   //Clear the screen


More credential fixes

More credential fixes


Fixed comment

Fixed comment

--- examples/AStarRPiSlave/AStarRPiSlave.ino
+++ examples/AStarRPiSlave/AStarRPiSlave.ino
@@ -152,7 +152,7 @@
   // Get current time
   unsigned long currentTime = micros();

-  // Read odometer counts
+  // Read encoder counts
   int countsLeft = encoders.getCountsLeft();
   int countsRight = encoders.getCountsRight();


Fix next flash sequence if first is interupted

Fixed the handleFlash() in case prior flash sequence got interrupted so the next sequence would count properly.
Cleaned up some useless code.

--- esp32LightServerRGB.ino
+++ esp32LightServerRGB.ino
@@ -1,633 +1,630 @@
-#include <WiFi.h>
-#include <DNSServer.h>
-#include <WebServer.h>
-#include <WiFiManager.h>
-#include <WiFiMulti.h>
-#include <HTTPClient.h>
-
-// sensors stuff
-#include <OneWire.h>
-#include <DallasTemperature.h>
-#include <DHT.h>
-#include <ESPmDNS.h>
-#define ONE_WIRE_BUS 15
-#define DHTPIN 2
-#define DHTTYPE DHT11
-DHT dht(DHTPIN, DHTTYPE);
-OneWire oneWire(ONE_WIRE_BUS);
-DallasTemperature sensors(&oneWire);
-// end of sensors
-
-// Settings you should check/change
-String resetpass = "YOURresetPASSWORD"; // password to reset wifimanager when allready connected
-const String thingkey = "YourThingSpeakApiWriteKey"; //your thingspeak API key
-const String thingchanel = "000000"; //your thingspeak Chanel #
-// other settings you might like to change
-const long interval = 60000; // interval in ms for sending temperature data to thingspeak
-const String liens = "Acceuil - Température - Version - Reset - Temp stats\n"; // html/links shown at bottom of pages
-String dernadd = "Fraichement booté"; //variable for ip logging (you can put your fresh boot mesage here in text/html)
-// led pins
-uint8_t pinRouge = 12;
-uint8_t pinVerte = 14; // internally pulled up
-uint8_t pinBleu = 13;
-// end of settings you should check/change
-
-// internally used vars
-WebServer server(80);
-String derncoul = "#000000";
-long r = 0;
-long g = 0;
-long b = 0;
-int rouge = 0;
-int vert = 0;
-int bleu = 0;
-unsigned long previousMillis = 0;
-unsigned long previousMillisr = 0;
-unsigned long previousMillisg = 0;
-unsigned long previousMillisb = 0;
-unsigned long previousMillisf = 0;
-int attendR = 70;
-int attendG = 70;
-int attendB = 70;
-int attendF = 700;
-unsigned long flashfois = 0;
-unsigned long flashrendu = 0;
-int roulepastusuite = 0;
-int flashoufade = 0;
-// end of internally used vars
-
-// stylesheet for web pages
-const String css = "\n";
-// end of stylesheet for web pages
-
-// functions used internally
-
-// used to flash leds
-void flashfunk() {
-  if (flashrendu <= flashfois) {
-    flashrendu++;
-    if (rouge == r) {
-      ledcWrite(1, 0);
-      rouge = 0;
-    } else {
-      ledcWrite(1, r);
-      rouge = r;
-    }
-    if (vert == g) {
-      ledcWrite(2, 0);
-      vert = 0;
-    } else {
-      ledcWrite(2, g);
-      vert = g;
-    }
-    if (bleu == b) {
-      ledcWrite(3, 0);
-      bleu = 0;
-    } else {
-      ledcWrite(3, b);
-      bleu = b;
-    }
-  } else {
-    r = rouge;
-    b = bleu;
-    g = vert;
-    flashoufade = 0;
-    flashrendu = 0;
-    Serial.println("Flash fini");
-  }
-}
-
-// used to fade red
-void fadeR() {
-  if (rouge < r) {
-    rouge++;
-    ledcWrite(1, rouge);
-  } else if (rouge > r) {
-    rouge--;
-    ledcWrite(1, rouge);
-  }
-}
-
-// used to fade green
-void fadeG() {
-  if (vert < g) {
-    vert++;
-    ledcWrite(2, vert);
-  } else if (vert > g) {
-    vert--;
-    ledcWrite(2, vert);
-  }
-}
-
-// used to fade blue
-void fadeB() {
-  if (bleu  b) {
-    bleu--;
-    ledcWrite(3, bleu);
-  }
-}
-
-// web page to handle flashing of leds (color/delay/number of flashes)
-void handleFlash() {
-  String addy = server.client().remoteIP().toString();
-  Serial.println("");
-  Serial.println(addy);
-  Serial.println("Flash");
-  String testteu = server.arg("COULEUR");
-  String attend = server.arg("DELAIS");
-  attendF = attend.toInt();
-  String flashnombre = server.arg("FOIS");
-  flashfois = flashnombre.toInt();
-  flashfois = flashfois * 2;
-  Serial.println(testteu);
-  Serial.print("Delais - ");
-  Serial.println(attendF);
-  Serial.print("Fois - ");
-  Serial.println(flashfois / 2);
-  if (testteu != 0) {
-    if ( (flashfois % 2) == 0) {
-      derncoul = testteu;
-    } else {
-      derncoul = "#000000";
-    }
-    long number = strtol( &testteu[1], NULL, 16);
-    r = number >> 16;
-    g = number >> 8 & 0xFF;
-    b = number & 0xFF;
-    Serial.print("Rouge = ");
-    Serial.println(r);
-    Serial.print("Vert = ");
-    Serial.println(g);
-    Serial.print("Bleu = ");
-    Serial.println(b);
-    dernadd = addy;
-    flashoufade = 1;
-    ledcWrite(1, 0);
-    ledcWrite(2, 0);
-    ledcWrite(3, 0);
-    rouge = 0;
-    bleu = 0;
-    vert = 0;
-  }
-  String contenu = "<!DOCTYPE html>\n\n\n";
-  contenu += "<meta http-equiv=\"refresh\" content=\"0;url=/\" />\n";
-  contenu += "<meta charset=\"UTF-8\" />\n<title>Que la lumiere soit</title>\n"
-             "<meta name=\"viewport\" content=\"width=device-width, initial-scale=1\">\n";
-  contenu += css;
-  contenu += "\n\n"
-             "Merci\n";
-  server.send(200, "text/html", contenu);
-}
-
-// web page to handle leds fading
-void handleLeds() {
-  String addy = server.client().remoteIP().toString();
-  Serial.println("");
-  Serial.println(addy);
-  String testteu = server.arg("COULEUR");
-  Serial.println(testteu);
-  if (testteu != 0) {
-    derncoul = testteu;
-    long number = strtol( &testteu[1], NULL, 16);
-    r = number >> 16;
-    g = number >> 8 & 0xFF;
-    b = number & 0xFF;
-    if (r != rouge) {
-      Serial.print("Rouge = ");
-      Serial.println(r);
-      dernadd = addy;
-      flashoufade = 0;
-    }
-    if (g != vert) {
-      Serial.print("Vert = ");
-      Serial.println(g);
-      dernadd = addy;
-      flashoufade = 0;
-    }
-    if (b != bleu) {
-      Serial.print("Bleu = ");
-      Serial.println(b);
-      dernadd = addy;
-      flashoufade = 0;
-    }
-  }
-  String contenu = "<!DOCTYPE html>\n\n\n";
-  contenu += "<meta http-equiv=\"refresh\" content=\"0;url=/\" />\n";
-  contenu += "<meta charset=\"UTF-8\" />\n<title>Que la lumiere soit</title>\n"
-             "<meta name=\"viewport\" content=\"width=device-width, initial-scale=1\">\n";
-  contenu += css;
-  contenu += "\n\n"
-             "Merci\n";
-  server.send(200, "text/html", contenu);
-}
-
-// index page
-void handleRoot() {
-  String addy = server.client().remoteIP().toString();
-  Serial.println("");
-  Serial.println(addy);
-  Serial.println("Page acceuil");
-  String contenu = "<!DOCTYPE html>\n\n\n";
-  contenu += "<meta charset=\"UTF-8\" />\n<title>Que la lumiere soit</title>\n"
-             "<meta name=\"viewport\" content=\"width=device-width, initial-scale=1\">\n";
-  contenu += css;
-  contenu += "\n";
-  contenu += "\n\n"
-             "
\n"
-             "<form id=\"laforme\" action=\"/leds\" method=\"post\">\n"
-             "
Change la couleur de mon bureau:
"
-             "<input id=\"colorpad\" type=\"color\" name=\"COULEUR\" class=\"color\" value=\"" + derncoul + "\">
\n"
-             "<input type=\"submit\" class=\"button1\" value=\"Changer\">\n"
-             "</form>\n"
-             "<button onclick=\"disco()\">Hazard</button>
\n"
-             "<button onclick=\"startDisco()\">Auto Disco</button>
\n"
-             "Dernier IP à avoir changé la couleur : ";
-  contenu += dernadd;
-  contenu += "
\n";
-  contenu += liens;
-  contenu += "\n"
-             "
\n";
-  server.send(200, "text/html", contenu);
-}
-
-//reset page
-void handleReset() {
-  int ouireset = 0;
-  String addy = server.client().remoteIP().toString();
-  Serial.println("");
-  Serial.println(addy);
-  Serial.println("!!! RESET PAGE !!!");
-  String testteu = server.arg("RESET");
-  String passme = server.arg("PASSME");
-  if (testteu == "OUI") {
-    if (passme == resetpass) {
-      ouireset = 1;
-    } else {
-      ouireset = 2;
-    }
-  }
-  String contenu = "<!DOCTYPE html>\n\n\n";
-  contenu += "<meta charset=\"UTF-8\" />\n<title>Que la lumiere se RESET</title>\n"
-             "<meta name=\"viewport\" content=\"width=device-width, initial-scale=1\">\n";
-  contenu += css;
-  contenu += "\n\n"
-             "
\n";
-  if (!ouireset) {
-    contenu += "<form action=\"/reset\" method=\"post\">\n"
-               "
Tu veux resetter le wifi network pour reconfigurer ?
"
-               "<input type=\"hidden\" name=\"RESET\" value=\"OUI\">
\n"
-               "<input type=\"password\" name=\"PASSME\" value=\"password\">
\n"
-               "<input type=\"submit\" class=\"button1\" value=\"Reset Wifi Network\">\n"
-               "</form>\n";
-  } else if (ouireset != 1) {
-    contenu += "<form action=\"/reset\" method=\"post\">\n"
-               "
Tu veux resetter le wifi network pour reconfigurer ?
"
-               "<input type=\"hidden\" name=\"RESET\" value=\"OUI\">
\n"
-               "<input type=\"password\" name=\"PASSME\" value=\"password\">
\n"
-               "
!!! MAUVAIS PASSWORD !!!

\n"
-               "<input type=\"submit\" class=\"button1\" value=\"Reset Wifi Network\">\n"
-               "</form>\n";
-    Serial.print("BAD PASSWORD : ");
-    Serial.println(passme);
-  } else if (ouireset == 1) {
-    contenu += "
Reset Dans 10 Secondes
\n";
-  }
-  contenu += "
Dernier IP à avoir changé la couleur :";
-  contenu += dernadd;
-  contenu += "\n
";
-  contenu += liens;
-  contenu += "\n

\n";
-  server.send(200, "text/html", contenu);
-  if (ouireset == 1) {
-    Serial.println("Reset dans 10 secondes");
-    delay(10000);
-    WiFiManager wifiManager;
-    wifiManager.resetSettings();
-    ESP.restart();
-  }
-}
-
-// 404 not found page
-void handleNotFound() {
-  String addy = server.client().remoteIP().toString();
-  Serial.println("");
-  Serial.println(addy);
-  String htmlmessage = "<!DOCTYPE html>\n\n\n";
-  htmlmessage += "<meta charset=\"UTF-8\" />\n<title>404 Not found</title>\n"
-                 "<meta name=\"viewport\" content=\"width=device-width, initial-scale=1\">\n";
-  htmlmessage += css;
-  htmlmessage += "\n\n"
-                 "
\n";
-  htmlmessage += "
404 File Not Found

\n";
-  htmlmessage += "URI: ";
-  htmlmessage += server.uri();
-  htmlmessage += "
\nMethod: ";
-  htmlmessage += (server.method() == HTTP_GET) ? "GET" : "POST";
-  htmlmessage += "
\nArguments: ";
-  htmlmessage += server.args();
-  htmlmessage += "
\n";
-  for (uint8_t i = 0; i < server.args(); i++) {
-    htmlmessage += " " + server.argName(i) + ": " + server.arg(i) + "
\n";
-  }
-  htmlmessage += "
\n";
-  htmlmessage += liens;
-  htmlmessage += "
\n
\n";
-  server.send(404, "text/html", htmlmessage);
-  String message = "404 File Not Found\n";
-  message += "URI: ";
-  message += server.uri();
-  message += "\nMethod: ";
-  message += (server.method() == HTTP_GET) ? "GET" : "POST";
-  message += "\nArguments: ";
-  message += server.args();
-  message += "\n";
-  for (uint8_t i = 0; i < server.args(); i++) {
-    message += " " + server.argName(i) + ": " + server.arg(i) + "\n";
-  }
-  Serial.print(message);
-}
-
-// function executed in main loop every minute to update sensors data to thingspeak.com
-void latemp() {
-  sensors.requestTemperatures();
-  float thetemp = sensors.getTempCByIndex(0);
-  char buffer[10];
-  String tempC = dtostrf(thetemp, 5, 2, buffer);
-  float h = dht.readHumidity();
-  float t = dht.readTemperature();
-  if (tempC != "-127.00") {
-    if (tempC != "85.00") {
-      Serial.print("Envoi de temperature et humidite: ");
-      Serial.print(tempC);
-      Serial.print(" - ");
-      HTTPClient http;
-      String webadd = "http://api.thingspeak.com/update?key=";
-      webadd += thingkey;
-      webadd += "&field1=";
-      webadd += tempC;
-      if (h == h) { // to prevent NaN
-        webadd += "&field2=";
-        webadd += h;
-        Serial.print(h);
-        webadd += "&field3=";
-        webadd += t;
-      }
-      Serial.println("");
-      http.begin(webadd);
-      int httpCode = http.GET();//Send the request
-      http.end();   //Close connection
-    }
-  }
-}
-
-// web page for showing sensors data
-void handleTemp() {
-  sensors.requestTemperatures();
-  float latemp = sensors.getTempCByIndex(0);
-  float h = dht.readHumidity();
-  while (latemp == -127.00) {
-    sensors.requestTemperatures();
-    latemp = sensors.getTempCByIndex(0);
-  }
-  String addy = server.client().remoteIP().toString();
-  Serial.println("");
-  Serial.println(addy);
-  Serial.print("Temperature : ");
-  Serial.println(latemp);
-  String contenu = "<!DOCTYPE html>\n\n\n";
-  contenu += "<meta charset=\"UTF-8\" />\n<title>Quel chaleur</title>\n"
-             "<meta name=\"viewport\" content=\"width=device-width, initial-scale=1\">\n";
-  contenu += css;
-  contenu += "\n\n"
-             "
\n";
-  contenu += "<form action=\"/\" method=\"get\">\n"
-             "
Voici la temperature
"
-             "
";
-  contenu += latemp;
-  contenu += "°C Humidité : ";
-  contenu += h;
-  contenu += "

\n"
-             ""
-             ""
-             "<input type=\"submit\" class=\"button1\" value=\"Acceuil\">\n"
-             "</form>\n"
-             "
Dernier IP à avoir changé la couleur :";
-  contenu += dernadd;
-  contenu += "\n
";
-  contenu += liens;
-  contenu += "\n

\n";
-  server.send(200, "text/html", contenu);
-}
-
-void setup() {
-  Serial.begin(115200);
-  dht.begin();
-  ledcAttachPin(pinRouge, 1); // assign RGB led pins to channels
-  ledcAttachPin(pinVerte, 2);
-  ledcAttachPin(pinBleu, 3);
-  pinMode(pinRouge, OUTPUT);
-  pinMode(pinVerte, OUTPUT);
-  pinMode(pinBleu, OUTPUT);
-  digitalWrite(pinRouge, LOW);
-  digitalWrite(pinBleu, LOW);
-  digitalWrite(pinVerte, LOW);
-  ledcSetup(1, 12000, 8); // 12 kHz PWM, 8-bit resolution
-  ledcSetup(2, 12000, 8);
-  ledcSetup(3, 12000, 8);
-  WiFiManager wifiManager;
-  wifiManager.autoConnect();
-  MDNS.begin("lumiere");
-  server.on("/", handleRoot);
-  server.on("/leds", handleLeds);
-  server.on("/flash", handleFlash);
-  server.on("/reset", handleReset);
-  server.on("/temp", handleTemp);
-  server.on("/version", []() {
-    String addy = server.client().remoteIP().toString();
-    Serial.println("");
-    Serial.println(addy);
-    Serial.println("Version request");
-    server.send(200, "text/html", "V2.0, Steve Olmstead sansillusion@gmail.com\n\n

"
-                "Added fader function\nRemoved connection watchdog (better have good signal)\n
"
-                "Removed mDns (did not work anyway)\n\n

"
-                "Added smoother fading\n\n

"
-                "Added AutoConect WifiManager !\n\n

"
-                "Added basic last IP logging\n
"
-                "Added /reset page to reset wifiManager connection settings\n\n

"
-                "Added /temp (temperature sensor read of ky-001)\n\n

"
-                "Added thingspeak support to send temperature each minute
\n\n
"
-                "Major rewrite for RGB led trip usin mosfet
\n"
-                "Removed serial to free resources for software pwm (still flikers but less than before)
\n\n
"
-                "Seperated LEDs handling page from index\n
"
-                "Added jQuery to load settings without reloading page\n
"
-                "Added random color selection button\n\n

"
-                "Added disco mode script and buttons\n\n

"
-                "Removed mDNS (does not work with esp32)\n
"
-                "        (Re-aded mDNS in 2.0 for esp32 but does not seem to work yet)\n
"
-                "Rewrite of code (removed Ticker and changed a few libraries) for esp32 !!!\n\n

"
-                "Changed fader functions for smoother fade\n
"
-                "Cleaned code\n\n

"
-                "Added Flashing function and page for smart widget usage\n
"
-                "Added var to show your thingspeak channel in /temp iframes\n\n

" + liens);
-  });
-  server.onNotFound(handleNotFound);
-  server.begin();
-  Serial.println("HTTP server started");
-  delay(100);
-  MDNS.addService("http", "tcp", 80);
-  sensors.begin();
-}
-
-void loop() {
-  server.handleClient();
-  unsigned long currentMillis = millis();
-  if (currentMillis - previousMillis >= interval) {
-    previousMillis = currentMillis;
-    latemp();
-  }
-  if (flashoufade == 1) {
-    currentMillis = millis();
-    if (currentMillis - previousMillisf >= attendF) {
-      previousMillisf = currentMillis;
-      flashfunk();
-    }
-  } else {
-    if (r != rouge) {
-      currentMillis = millis();
-      if (currentMillis - previousMillisr >= attendR) {
-        fadeR();
-        previousMillisr = currentMillis;
-        if (rouge > 0)
-          attendR = 70;
-        if (rouge > 40)
-          attendR = 60;
-        if (rouge > 80)
-          attendR = 50;
-        if (rouge > 100)
-          attendR = 40;
-        if (rouge > 120)
-          attendR = 30;
-        if (rouge > 140)
-          attendR = 20;
-        if (rouge > 180)
-          attendR = 10;
-      }
-    }
-    if (g != vert) {
-      currentMillis = millis();
-      if (currentMillis - previousMillisg >= attendG) {
-        fadeG();
-        previousMillisg = currentMillis;
-        if (vert > 0)
-          attendG = 70;
-        if (vert > 40)
-          attendG = 60;
-        if (vert > 80)
-          attendG = 50;
-        if (vert > 100)
-          attendG = 40;
-        if (vert > 120)
-          attendG = 30;
-        if (vert > 140)
-          attendG = 20;
-        if (vert > 180)
-          attendG = 10;
-      }
-    }
-    if (b != bleu) {
-      currentMillis = millis();
-      if (currentMillis - previousMillisb >= attendB) {
-        fadeB();
-        previousMillisb = currentMillis;
-        if (bleu > 0)
-          attendB = 70;
-        if (bleu > 40)
-          attendB = 60;
-        if (bleu > 80)
-          attendB = 50;
-        if (bleu > 100)
-          attendB = 40;
-        if (bleu > 120)
-          attendB = 30;
-        if (bleu > 140)
-          attendB = 20;
-        if (bleu > 180)
-          attendB = 10;
-      }
-    }
-  }
-}
-
-
+#include <WiFi.h>
+#include <DNSServer.h>
+#include <WebServer.h>
+#include <WiFiManager.h>
+#include <WiFiMulti.h>
+#include <HTTPClient.h>
+
+// sensors stuff
+#include <OneWire.h>
+#include <DallasTemperature.h>
+#include <DHT.h>
+#include <ESPmDNS.h>
+#define ONE_WIRE_BUS 15
+#define DHTPIN 2
+#define DHTTYPE DHT11
+DHT dht(DHTPIN, DHTTYPE);
+OneWire oneWire(ONE_WIRE_BUS);
+DallasTemperature sensors(&oneWire);
+// end of sensors
+
+// Settings you should check/change
+String resetpass = "YOURresetPASSWORD"; // password to reset wifimanager when allready connected
+const String thingkey = "YourThingSpeakApiWriteKey"; //your thingspeak API key
+const String thingchanel = "000000"; //your thingspeak Chanel #
+// other settings you might like to change
+const long interval = 60000; // interval in ms for sending temperature data to thingspeak
+const String liens = "Acceuil - Température - Version - Reset - Temp stats\n"; // html/links shown at bottom of pages
+String dernadd = "Fraichement booté"; //variable for ip logging (you can put your fresh boot mesage here in text/html)
+// led pins
+uint8_t pinRouge = 12;
+uint8_t pinVerte = 14; // internally pulled up
+uint8_t pinBleu = 13;
+// end of settings you should check/change
+
+// internally used vars
+WebServer server(80);
+String derncoul = "#000000";
+long r = 0;
+long g = 0;
+long b = 0;
+int rouge = 0;
+int vert = 0;
+int bleu = 0;
+unsigned long previousMillis = 0;
+unsigned long previousMillisr = 0;
+unsigned long previousMillisg = 0;
+unsigned long previousMillisb = 0;
+unsigned long previousMillisf = 0;
+int attendR = 70;
+int attendG = 70;
+int attendB = 70;
+int attendF = 700;
+unsigned long flashfois = 0;
+unsigned long flashrendu = 0;
+int roulepastusuite = 0;
+int flashoufade = 0;
+// end of internally used vars
+
+// stylesheet for web pages
+const String css = "\n";
+// end of stylesheet for web pages
+
+// functions used internally
+
+// used to flash leds
+void flashfunk() {
+  if (flashrendu <= flashfois) {
+    flashrendu++;
+    if (rouge == r) {
+      ledcWrite(1, 0);
+      rouge = 0;
+    } else {
+      ledcWrite(1, r);
+      rouge = r;
+    }
+    if (vert == g) {
+      ledcWrite(2, 0);
+      vert = 0;
+    } else {
+      ledcWrite(2, g);
+      vert = g;
+    }
+    if (bleu == b) {
+      ledcWrite(3, 0);
+      bleu = 0;
+    } else {
+      ledcWrite(3, b);
+      bleu = b;
+    }
+  } else {
+    r = rouge;
+    b = bleu;
+    g = vert;
+    flashoufade = 0;
+    flashrendu = 0;
+    Serial.println("Flash fini");
+  }
+}
+
+// used to fade red
+void fadeR() {
+  if (rouge < r) {
+    rouge++;
+    ledcWrite(1, rouge);
+  } else if (rouge > r) {
+    rouge--;
+    ledcWrite(1, rouge);
+  }
+}
+
+// used to fade green
+void fadeG() {
+  if (vert < g) {
+    vert++;
+    ledcWrite(2, vert);
+  } else if (vert > g) {
+    vert--;
+    ledcWrite(2, vert);
+  }
+}
+
+// used to fade blue
+void fadeB() {
+  if (bleu  b) {
+    bleu--;
+    ledcWrite(3, bleu);
+  }
+}
+
+// web page to handle flashing of leds (color/delay/number of flashes)
+void handleFlash() {
+  String addy = server.client().remoteIP().toString();
+  Serial.println("");
+  Serial.println(addy);
+  Serial.println("Flash");
+  String testteu = server.arg("COULEUR");
+  String attend = server.arg("DELAIS");
+  attendF = attend.toInt();
+  String flashnombre = server.arg("FOIS");
+  flashfois = flashnombre.toInt();
+  flashfois = flashfois * 2;
+  Serial.println(testteu);
+  Serial.print("Delais - ");
+  Serial.println(attendF);
+  Serial.print("Fois - ");
+  Serial.println(flashfois / 2);
+  if (testteu != 0) {
+    derncoul = testteu;
+    long number = strtol( &testteu[1], NULL, 16);
+    r = number >> 16;
+    g = number >> 8 & 0xFF;
+    b = number & 0xFF;
+    Serial.print("Rouge = ");
+    Serial.println(r);
+    Serial.print("Vert = ");
+    Serial.println(g);
+    Serial.print("Bleu = ");
+    Serial.println(b);
+    dernadd = addy;
+    flashoufade = 1;
+    flashrendu = 0;
+    ledcWrite(1, 0);
+    ledcWrite(2, 0);
+    ledcWrite(3, 0);
+    rouge = 0;
+    bleu = 0;
+    vert = 0;
+  }
+  String contenu = "<!DOCTYPE html>\n\n\n";
+  contenu += "<meta http-equiv=\"refresh\" content=\"0;url=/\" />\n";
+  contenu += "<meta charset=\"UTF-8\" />\n<title>Que la lumiere soit</title>\n"
+             "<meta name=\"viewport\" content=\"width=device-width, initial-scale=1\">\n";
+  contenu += css;
+  contenu += "\n\n"
+             "Merci\n";
+  server.send(200, "text/html", contenu);
+}
+
+// web page to handle leds fading
+void handleLeds() {
+  String addy = server.client().remoteIP().toString();
+  Serial.println("");
+  Serial.println(addy);
+  String testteu = server.arg("COULEUR");
+  Serial.println(testteu);
+  if (testteu != 0) {
+    derncoul = testteu;
+    long number = strtol( &testteu[1], NULL, 16);
+    r = number >> 16;
+    g = number >> 8 & 0xFF;
+    b = number & 0xFF;
+    if (r != rouge) {
+      Serial.print("Rouge = ");
+      Serial.println(r);
+      dernadd = addy;
+      flashoufade = 0;
+    }
+    if (g != vert) {
+      Serial.print("Vert = ");
+      Serial.println(g);
+      dernadd = addy;
+      flashoufade = 0;
+    }
+    if (b != bleu) {
+      Serial.print("Bleu = ");
+      Serial.println(b);
+      dernadd = addy;
+      flashoufade = 0;
+    }
+  }
+  String contenu = "<!DOCTYPE html>\n\n\n";
+  contenu += "<meta http-equiv=\"refresh\" content=\"0;url=/\" />\n";
+  contenu += "<meta charset=\"UTF-8\" />\n<title>Que la lumiere soit</title>\n"
+             "<meta name=\"viewport\" content=\"width=device-width, initial-scale=1\">\n";
+  contenu += css;
+  contenu += "\n\n"
+             "Merci\n";
+  server.send(200, "text/html", contenu);
+}
+
+// index page
+void handleRoot() {
+  String addy = server.client().remoteIP().toString();
+  Serial.println("");
+  Serial.println(addy);
+  Serial.println("Page acceuil");
+  String contenu = "<!DOCTYPE html>\n\n\n";
+  contenu += "<meta charset=\"UTF-8\" />\n<title>Que la lumiere soit</title>\n"
+             "<meta name=\"viewport\" content=\"width=device-width, initial-scale=1\">\n";
+  contenu += css;
+  contenu += "\n";
+  contenu += "\n\n"
+             "
\n"
+             "<form id=\"laforme\" action=\"/leds\" method=\"post\">\n"
+             "
Change la couleur de mon bureau:
"
+             "<input id=\"colorpad\" type=\"color\" name=\"COULEUR\" class=\"color\" value=\"" + derncoul + "\">
\n"
+             "<input type=\"submit\" class=\"button1\" value=\"Changer\">\n"
+             "</form>\n"
+             "<button onclick=\"disco()\">Hazard</button>
\n"
+             "<button onclick=\"startDisco()\">Auto Disco</button>
\n"
+             "Dernier IP à avoir changé la couleur : ";
+  contenu += dernadd;
+  contenu += "
\n";
+  contenu += liens;
+  contenu += "\n"
+             "
\n";
+  server.send(200, "text/html", contenu);
+}
+
+//reset page
+void handleReset() {
+  int ouireset = 0;
+  String addy = server.client().remoteIP().toString();
+  Serial.println("");
+  Serial.println(addy);
+  Serial.println("!!! RESET PAGE !!!");
+  String testteu = server.arg("RESET");
+  String passme = server.arg("PASSME");
+  if (testteu == "OUI") {
+    if (passme == resetpass) {
+      ouireset = 1;
+    } else {
+      ouireset = 2;
+    }
+  }
+  String contenu = "<!DOCTYPE html>\n\n\n";
+  contenu += "<meta charset=\"UTF-8\" />\n<title>Que la lumiere se RESET</title>\n"
+             "<meta name=\"viewport\" content=\"width=device-width, initial-scale=1\">\n";
+  contenu += css;
+  contenu += "\n\n"
+             "
\n";
+  if (!ouireset) {
+    contenu += "<form action=\"/reset\" method=\"post\">\n"
+               "
Tu veux resetter le wifi network pour reconfigurer ?
"
+               "<input type=\"hidden\" name=\"RESET\" value=\"OUI\">
\n"
+               "<input type=\"password\" name=\"PASSME\" value=\"password\">
\n"
+               "<input type=\"submit\" class=\"button1\" value=\"Reset Wifi Network\">\n"
+               "</form>\n";
+  } else if (ouireset != 1) {
+    contenu += "<form action=\"/reset\" method=\"post\">\n"
+               "
Tu veux resetter le wifi network pour reconfigurer ?
"
+               "<input type=\"hidden\" name=\"RESET\" value=\"OUI\">
\n"
+               "<input type=\"password\" name=\"PASSME\" value=\"password\">
\n"
+               "
!!! MAUVAIS PASSWORD !!!

\n"
+               "<input type=\"submit\" class=\"button1\" value=\"Reset Wifi Network\">\n"
+               "</form>\n";
+    Serial.print("BAD PASSWORD : ");
+    Serial.println(passme);
+  } else if (ouireset == 1) {
+    contenu += "
Reset Dans 10 Secondes
\n";
+  }
+  contenu += "
Dernier IP à avoir changé la couleur :";
+  contenu += dernadd;
+  contenu += "\n
";
+  contenu += liens;
+  contenu += "\n

\n";
+  server.send(200, "text/html", contenu);
+  if (ouireset == 1) {
+    Serial.println("Reset dans 10 secondes");
+    delay(10000);
+    WiFiManager wifiManager;
+    wifiManager.resetSettings();
+    ESP.restart();
+  }
+}
+
+// 404 not found page
+void handleNotFound() {
+  String addy = server.client().remoteIP().toString();
+  Serial.println("");
+  Serial.println(addy);
+  String htmlmessage = "<!DOCTYPE html>\n\n\n";
+  htmlmessage += "<meta charset=\"UTF-8\" />\n<title>404 Not found</title>\n"
+                 "<meta name=\"viewport\" content=\"width=device-width, initial-scale=1\">\n";
+  htmlmessage += css;
+  htmlmessage += "\n\n"
+                 "
\n";
+  htmlmessage += "
404 File Not Found

\n";
+  htmlmessage += "URI: ";
+  htmlmessage += server.uri();
+  htmlmessage += "
\nMethod: ";
+  htmlmessage += (server.method() == HTTP_GET) ? "GET" : "POST";
+  htmlmessage += "
\nArguments: ";
+  htmlmessage += server.args();
+  htmlmessage += "
\n";
+  for (uint8_t i = 0; i < server.args(); i++) {
+    htmlmessage += " " + server.argName(i) + ": " + server.arg(i) + "
\n";
+  }
+  htmlmessage += "
\n";
+  htmlmessage += liens;
+  htmlmessage += "
\n
\n";
+  server.send(404, "text/html", htmlmessage);
+  String message = "404 File Not Found\n";
+  message += "URI: ";
+  message += server.uri();
+  message += "\nMethod: ";
+  message += (server.method() == HTTP_GET) ? "GET" : "POST";
+  message += "\nArguments: ";
+  message += server.args();
+  message += "\n";
+  for (uint8_t i = 0; i < server.args(); i++) {
+    message += " " + server.argName(i) + ": " + server.arg(i) + "\n";
+  }
+  Serial.print(message);
+}
+
+// function executed in main loop every minute to update sensors data to thingspeak.com
+void latemp() {
+  sensors.requestTemperatures();
+  float thetemp = sensors.getTempCByIndex(0);
+  char buffer[10];
+  String tempC = dtostrf(thetemp, 5, 2, buffer);
+  float h = dht.readHumidity();
+  float t = dht.readTemperature();
+  if (tempC != "-127.00") {
+    if (tempC != "85.00") {
+      Serial.print("Envoi de temperature et humidite: ");
+      Serial.print(tempC);
+      Serial.print(" - ");
+      HTTPClient http;
+      String webadd = "http://api.thingspeak.com/update?key=";
+      webadd += thingkey;
+      webadd += "&field1=";
+      webadd += tempC;
+      if (h == h) { // to prevent NaN
+        webadd += "&field2=";
+        webadd += h;
+        Serial.print(h);
+        webadd += "&field3=";
+        webadd += t;
+      }
+      Serial.println("");
+      http.begin(webadd);
+      int httpCode = http.GET();//Send the request
+      http.end();   //Close connection
+    }
+  }
+}
+
+// web page for showing sensors data
+void handleTemp() {
+  sensors.requestTemperatures();
+  float latemp = sensors.getTempCByIndex(0);
+  float h = dht.readHumidity();
+  while (latemp == -127.00) {
+    sensors.requestTemperatures();
+    latemp = sensors.getTempCByIndex(0);
+  }
+  String addy = server.client().remoteIP().toString();
+  Serial.println("");
+  Serial.println(addy);
+  Serial.print("Temperature : ");
+  Serial.println(latemp);
+  String contenu = "<!DOCTYPE html>\n\n\n";
+  contenu += "<meta charset=\"UTF-8\" />\n<title>Quel chaleur</title>\n"
+             "<meta name=\"viewport\" content=\"width=device-width, initial-scale=1\">\n";
+  contenu += css;
+  contenu += "\n\n"
+             "
\n";
+  contenu += "<form action=\"/\" method=\"get\">\n"
+             "
Voici la temperature
"
+             "
";
+  contenu += latemp;
+  contenu += "°C Humidité : ";
+  contenu += h;
+  contenu += "

\n"
+             ""
+             ""
+             "<input type=\"submit\" class=\"button1\" value=\"Acceuil\">\n"
+             "</form>\n"
+             "
Dernier IP à avoir changé la couleur :";
+  contenu += dernadd;
+  contenu += "\n
";
+  contenu += liens;
+  contenu += "\n

\n";
+  server.send(200, "text/html", contenu);
+}
+
+void setup() {
+  Serial.begin(115200);
+  dht.begin();
+  ledcAttachPin(pinRouge, 1); // assign RGB led pins to channels
+  ledcAttachPin(pinVerte, 2);
+  ledcAttachPin(pinBleu, 3);
+  pinMode(pinRouge, OUTPUT);
+  pinMode(pinVerte, OUTPUT);
+  pinMode(pinBleu, OUTPUT);
+  digitalWrite(pinRouge, LOW);
+  digitalWrite(pinBleu, LOW);
+  digitalWrite(pinVerte, LOW);
+  ledcSetup(1, 12000, 8); // 12 kHz PWM, 8-bit resolution
+  ledcSetup(2, 12000, 8);
+  ledcSetup(3, 12000, 8);
+  WiFiManager wifiManager;
+  wifiManager.autoConnect();
+  MDNS.begin("lumiere");
+  server.on("/", handleRoot);
+  server.on("/leds", handleLeds);
+  server.on("/flash", handleFlash);
+  server.on("/reset", handleReset);
+  server.on("/temp", handleTemp);
+  server.on("/version", []() {
+    String addy = server.client().remoteIP().toString();
+    Serial.println("");
+    Serial.println(addy);
+    Serial.println("Version request");
+    server.send(200, "text/html", "V2.0, Steve Olmstead sansillusion@gmail.com\n\n

"
+                "Added fader function\nRemoved connection watchdog (better have good signal)\n
"
+                "Removed mDns (did not work anyway)\n\n

"
+                "Added smoother fading\n\n

"
+                "Added AutoConect WifiManager !\n\n

"
+                "Added basic last IP logging\n
"
+                "Added /reset page to reset wifiManager connection settings\n\n

"
+                "Added /temp (temperature sensor read of ky-001)\n\n

"
+                "Added thingspeak support to send temperature each minute
\n\n
"
+                "Major rewrite for RGB led trip usin mosfet
\n"
+                "Removed serial to free resources for software pwm (still flikers but less than before)
\n\n
"
+                "Seperated LEDs handling page from index\n
"
+                "Added jQuery to load settings without reloading page\n
"
+                "Added random color selection button\n\n

"
+                "Added disco mode script and buttons\n\n

"
+                "Removed mDNS (does not work with esp32)\n
"
+                "        (Re-aded mDNS in 2.0 for esp32 but does not seem to work yet)\n
"
+                "Rewrite of code (removed Ticker and changed a few libraries) for esp32 !!!\n\n

"
+                "Changed fader functions for smoother fade\n
"
+                "Cleaned code\n\n

"
+                "Added Flashing function and page for smart widget usage\n
"
+                "Added var to show your thingspeak channel in /temp iframes\n\n

" + liens);
+  });
+  server.onNotFound(handleNotFound);
+  server.begin();
+  Serial.println("HTTP server started");
+  delay(100);
+  MDNS.addService("http", "tcp", 80);
+  sensors.begin();
+}
+
+void loop() {
+  server.handleClient();
+  unsigned long currentMillis = millis();
+  if (currentMillis - previousMillis >= interval) {
+    previousMillis = currentMillis;
+    latemp();
+  }
+  if (flashoufade == 1) {
+    currentMillis = millis();
+    if (currentMillis - previousMillisf >= attendF) {
+      previousMillisf = currentMillis;
+      flashfunk();
+    }
+  } else {
+    if (r != rouge) {
+      currentMillis = millis();
+      if (currentMillis - previousMillisr >= attendR) {
+        fadeR();
+        previousMillisr = currentMillis;
+        if (rouge > 0)
+          attendR = 70;
+        if (rouge > 40)
+          attendR = 60;
+        if (rouge > 80)
+          attendR = 50;
+        if (rouge > 100)
+          attendR = 40;
+        if (rouge > 120)
+          attendR = 30;
+        if (rouge > 140)
+          attendR = 20;
+        if (rouge > 180)
+          attendR = 10;
+      }
+    }
+    if (g != vert) {
+      currentMillis = millis();
+      if (currentMillis - previousMillisg >= attendG) {
+        fadeG();
+        previousMillisg = currentMillis;
+        if (vert > 0)
+          attendG = 70;
+        if (vert > 40)
+          attendG = 60;
+        if (vert > 80)
+          attendG = 50;
+        if (vert > 100)
+          attendG = 40;
+        if (vert > 120)
+          attendG = 30;
+        if (vert > 140)
+          attendG = 20;
+        if (vert > 180)
+          attendG = 10;
+      }
+    }
+    if (b != bleu) {
+      currentMillis = millis();
+      if (currentMillis - previousMillisb >= attendB) {
+        fadeB();
+        previousMillisb = currentMillis;
+        if (bleu > 0)
+          attendB = 70;
+        if (bleu > 40)
+          attendB = 60;
+        if (bleu > 80)
+          attendB = 50;
+        if (bleu > 100)
+          attendB = 40;
+        if (bleu > 120)
+          attendB = 30;
+        if (bleu > 140)
+          attendB = 20;
+        if (bleu > 180)
+          attendB = 10;
+      }
+    }
+  }
+}
+
+


deep sleep

deep sleep

--- esp8266-temperature.ino
+++ esp8266-temperature.ino
@@ -1,15 +1,9 @@
 #include <ESP8266WiFi.h>
 #include <OneWire.h>
 #include <DallasTemperature.h>
+#include "config.h"

-//AP definitions
-#define AP_SSID "AP-EG"
-#define AP_PASSWORD "ap password"
-
-#define REPORT_INTERVAL 60 // in sec
-
-#define ONE_WIRE_BUS 2  // DS18B20 pin
-OneWire oneWire(ONE_WIRE_BUS);
+OneWire oneWire(2);
 DallasTemperature DS18B20(&oneWire);

 void setup() {
@@ -27,17 +21,19 @@

   sendTeperature(temp);

-  ESP.deepSleep(10000000);
-
+  ESP.deepSleep(DEEP_SLEEP);
+  delay(100);
 }

 void loop() {
+  // nothing to do here
 }

 void wifiConnect() {
-    Serial.print("Connecting to AP");
-    WiFi.begin(AP_SSID, AP_PASSWORD);
-    while (WiFi.status() != WL_CONNECTED) {
+  Serial.println("");
+  Serial.print("Connecting to AP");
+  WiFi.begin(AP_SSID, AP_PASSWORD);
+  while (WiFi.status() != WL_CONNECTED) {
     delay(1000);
     Serial.print(".");
   }
@@ -49,20 +45,24 @@
 void sendTeperature(float temp) {
    WiFiClient client;

-   while(!client.connect("192.168.2.107", 8080)) {
+   while(!client.connect(SERVER_IP, SERVER_PORT)) {
     Serial.println("connection failed");
-    wifiConnect();
+    return;
   }

+  int d1 = temp;
+  float f2 = temp - d1;
+  int d2 = trunc(f2 * 10);
   char postData[8];
-  sprintf((char*)&postData, "%3.2f", temp);
+
+  sprintf(postData, "%3d.%02d", d1, d2);
+  Serial.println(postData);

-  client.println("POST /temperature/esp8266test1 HTTP/1.1");
-  client.println("Host: 192.168.2.107");
+  client.printf("PUT /thermometer/%s HTTP/1.1\n", THERMOMETER_ID);
+  client.printf("Host: %s\n", SERVER_IP);
   client.println("Cache-Control: no-cache");
   client.println("Content-Type: application/x-www-form-urlencoded");
-  client.print("Content-Length: ");
-  client.println(strlen(postData));
+  client.printf("Content-Length: %d\n", strlen(postData));
   client.println();
   client.println(postData);


added Gate output

added Gate output

--- Sequencer/Sequencer.ino
+++ Sequencer/Sequencer.ino
@@ -116,8 +116,9 @@

 /************************************ SEQUENCER FUNCTIONS ***************************************************/
 void runSequence(void){
+  // Sequencer increment
   playhead++;
-  if(playhead > stepTime){
+  if(playhead > stepTime){
     playhead = 0;
     curStep++;
     if(curStep == numSteps) {curStep = 0;}
@@ -125,6 +126,7 @@
   // Gate CV output
   if(playhead < stepTime * dur[curStep] / 100.f){
 //    PORTB |= _BV(PB7); // pin13 HIGH
+    PORTB |= _BV(PB5); // pin11 (Gate) HIGH
     switch(curStep){
       case 0:
          PORTE &= ~_BV(PE4); // pin2 LOW (common anode, so it's a ON)
@@ -150,6 +152,7 @@
   }
   else{
 //    PORTB &= ~_BV(PB7); // pin13 LOW
+    PORTB &= ~_BV(PB5); // pin11 (Gate) LOW
     switch(curStep){
       case 0:
          PORTE |= _BV(PE4); // pin2 LOW (common anode, so it's a ON)


Doug Hilton.  Added ShowAngles to be able to pick and choose multiple angles.  Improved error reporting.

--- XV_Lidar_Controller.ino
+++ XV_Lidar_Controller.ino
@@ -6,7 +6,14 @@
  http://www.getsurreal.com/products/xv-lidar-controller

  Modified to add CRC checking - Doug Hilton, WD0UG November, 2015 mailto: six.speed (at) yahoo (dot) com
-
+ Modified to add ShowErrors / HideErrors - DSH
+ Modified to add ShowAngles - DSH
+ Modified SerialCommand.h to increase # of characters allowed to be input and command length - DSH
+           #define SERIALCOMMAND_BUFFER 100		// ORIGINAL: 32   MODIFIED BY DSH
+           #define SERIALCOMMAND_MAXCOMMANDLENGTH 20	// ORIGINAL: 8
+ ****************************************************************************************
+ NOTE: DON'T FORGET TO COPY THE NEW SerialCommand.h TO YOUR ARDUINO LIBRARY DIRECTORY!!!
+ ****************************************************************************************
  See README for additional information

  The F() macro in the Serial statements tells the compiler to keep your strings in PROGMEM
@@ -85,7 +92,11 @@
 int ixPacket = 0;                          // index into 'Packet' array
 const int VALID_PACKET = 0;
 const int INVALID_PACKET = VALID_PACKET + 1;
-const byte INVALID_DATA_FLAG = (1 << 7);      // Mask for byte 1 of each data quad "Invalid data"
+const byte INVALID_DATA_FLAG = (1 << 7);   // Mask for byte 1 of each data quad "Invalid data"
+
+boolean aryAngles[N_ANGLES];               // true if we're supposed to display the corresponding angle
+boolean bShowAnglesFromArray = false;      // true if we're supposed to display multiple angles
+
 /* REF: https://github.com/Xevel/NXV11/wiki
 The bit 7 of byte 1 seems to indicate that the distance could not be calculated.
 It's interesting to see that when this bit is set, the second byte is always 80, and the values of the first byte seem to be
@@ -108,17 +119,14 @@
 PID rpmPID(&motor_rpm, &pwm_val, &xv_config.rpm_setpoint, xv_config.Kp, xv_config.Ki, xv_config.Kd, DIRECT);

 uint8_t inByte = 0;  // incoming serial byte
-//uint16_t data_status = 0;
-//uint16_t data_4deg_index = 0;
-//uint16_t data_loop_index = 0;
 uint8_t motor_rph_high_byte = 0;
 uint8_t motor_rph_low_byte = 0;
-//uint8_t data0, data2;
 uint16_t aryDist[N_DATA_QUADS] = {0,0,0,0};      // thre are (4) distances, one for each data quad
 // so the maximum distance is 16383 mm (0x3FFF)
 uint16_t aryQuality[N_DATA_QUADS] = {0,0,0,0};   // same with 'quality'
 uint16_t motor_rph = 0;
-uint16_t startingAngle = 0;                   // the first scan angle (of group of 4, based on 'index'), in degrees (0..359)
+uint16_t startingAngle = 0;                      // the first scan angle (of group of 4, based on 'index'), in degrees (0..359)
+boolean bShowErrors = false;                     // true = show 3 kinds of errors

 SerialCommand sCmd;

@@ -149,9 +157,8 @@
   for (ixPacket = 0; ixPacket < PACKET_LENGTH; ixPacket++)  // Initialize
     Packet[ixPacket] = 0;
   ixPacket = 0;
-
-  //hideRaw();      // DSH ONLY!!!!!!!!!!!!
-
+  setLowRPM(xv_config.rpm_min);                      // Make the motor go as slow as possible
+  //hideRaw();     // DSH ONLY!!!!!!!!!!!!
 }
 // Main loop (forever)
 void loop() {
@@ -186,51 +193,87 @@
             if (aryInvalidDataFlag[ix] == 0)
               processSignalStrength(ix);
           }
-          if (xv_config.show_dist) {                       // the 'ShowDistance' command is active
-            if (xv_config.show_angle == SHOW_ALL_ANGLES    // Are we showing all angles or just 1 angle?
-            || ((xv_config.show_angle >= startingAngle) && (xv_config.show_angle < startingAngle + N_DATA_QUADS))) {
-              for (int ix = 0; ix < N_DATA_QUADS; ix++) {  // process each of the (4) angles
-                if ((xv_config.show_angle == SHOW_ALL_ANGLES) || (xv_config.show_angle == startingAngle + ix)) {
-                  if (aryInvalidDataFlag[ix] == 0) {       // make sure that the 'Invalid Data' flag is clear
+          if (xv_config.show_dist) {                         // the 'ShowDistance' command is active
+            if (bShowAnglesFromArray) {                      // we're going to display only angles that are in 'aryAngles'
+              for (int ix = 0; ix < N_DATA_QUADS; ix++) {
+                if (aryAngles[startingAngle + ix]) {         // if we're supposed to display that angle
+                  if (aryInvalidDataFlag[ix] == 0) {         // make sure that the 'Invalid Data' flag is clear
+                    Serial.print(startingAngle + ix);
+                    Serial.print(F(","));
+                    Serial.println(int(aryDist[ix]));
+                    //Serial.print(F(" ("));
+                    //Serial.print(aryQuality[ix]);
+                    //Serial.println(F(")"));
+                  }
+                  else if (bShowErrors) {
+                    /*
                     Serial.print(startingAngle + ix);
                     Serial.print(F(": "));
-                    Serial.print(int(aryDist[ix]));
-                    Serial.print(F(" ("));
-                    Serial.print(aryQuality[ix]);
-                    Serial.println(F(")"));
-                  }
-                  else {
-                    /* // UNCOMMENT BELOW TO PRINT 'INVALID' and 'SIGNAL' ERROR MESSAGES IN REAL-TIME
-                    Serial.print(startingAngle + ix);
-                    Serial.print(F(": "));
-                    for (int ix = 0; ix < PACKET_LENGTH; ix++) {
-                      if (Packet[ix] < 0x10)
-                        Serial.print("0");
-                      Serial.print(Packet[ix], HEX);
-                      Serial.print(" ");
+                    for (int jx = 0; jx < PACKET_LENGTH; jx++) {
+                      if (Packet[jx] < 0x10)
+                        Serial.print(F("0"));
+                      Serial.print(Packet[jx], HEX);
+                      Serial.print(F(" "));
                     }
-                    for (int ix = 0; ix < N_DATA_QUADS; ix++) {
+                    */
+                    if (aryInvalidDataFlag[ix] & INVALID_DATA_FLAG)
+                      Serial.print(F("{I}"));
+                    if (aryInvalidDataFlag[ix] & STRENGTH_WARNING_FLAG)
+                      Serial.print(F("{S}"));
+                    if (aryInvalidDataFlag[ix])
+                      Serial.println(F(""));
+                  }  // else if (bShowErrors)
+                }  // if (aryAngles[startingAngle + ix])
+              }  // for (int ix = 0; ix < N_DATA_QUADS; ix++)
+            }  // if (bShowAnglesFromArray)
+            else {
+              if (xv_config.show_angle == SHOW_ALL_ANGLES    // Are we showing all angles or just 1 angle?
+              || ((xv_config.show_angle >= startingAngle) && (xv_config.show_angle < startingAngle + N_DATA_QUADS))) {
+                for (int ix = 0; ix < N_DATA_QUADS; ix++) {  // process each of the (4) angles
+                  if ((xv_config.show_angle == SHOW_ALL_ANGLES) || (xv_config.show_angle == startingAngle + ix)) {
+                    if (aryInvalidDataFlag[ix] == 0) {       // make sure that the 'Invalid Data' flag is clear
+                      Serial.print(startingAngle + ix);
+                      Serial.print(F(","));
+                      Serial.println(int(aryDist[ix]));
+                      //Serial.print(F(" ("));
+                      //Serial.print(aryQuality[ix]);
+                      //Serial.println(F(")"));
+                    }
+                    else if (bShowErrors) {
+                      /*
+                      Serial.print(startingAngle + ix);
+                      Serial.print(F(": "));
+                      for (int jx = 0; jx < PACKET_LENGTH; jx++) {
+                        if (Packet[jx] < 0x10)
+                          Serial.print(F("0"));
+                        Serial.print(Packet[jx], HEX);
+                        Serial.print(F(" "));
+                      }
+                      */
                       if (aryInvalidDataFlag[ix] & INVALID_DATA_FLAG)
-                        Serial.print("{I}");
-                      else
-                        Serial.print("{_}");
-                    }
-                    for (int ix = 0; ix < N_DATA_QUADS; ix++) {
+                        Serial.print(F("{I}"));
                       if (aryInvalidDataFlag[ix] & STRENGTH_WARNING_FLAG)
-                        Serial.print("{S}");
-                      else
-                        Serial.print("{_}");
-                    }
-                    Serial.println("");
-                    */ // UNCOMMENT ABOVE
-                  }  // else
-                }  // if ((xv_config.show_angle == SHOW_ALL_ANGLES) ...
-              }  // or (int ix = 0; ix < N_DATA_QUADS; ix++)
-            }  // if (xv_config.show_angle == SHOW_ALL_ANGLES ...
+                        Serial.print(F("{S}"));
+                      if (aryInvalidDataFlag[ix])
+                        Serial.println(F(""));
+                    }  // else if (bShowErrors)
+                  }  // if ((xv_config.show_angle == SHOW_ALL_ANGLES) ...
+                }  // or (int ix = 0; ix < N_DATA_QUADS; ix++)
+              }  // if (xv_config.show_angle == SHOW_ALL_ANGLES ...
+            }  // if (bShowAngles)
           }  // if (xv_config.show_dist)
         }  // if (eValidatePacket() == 0
-        else {
-          //Serial.println("Skipping packet with bad CRC");
+        else if (bShowErrors) {
+          /*
+          for (int ix = 0; ix < PACKET_LENGTH; ix++) {
+            if (Packet[ix] < 0x10)
+              Serial.print(F("0"));
+            Serial.print(Packet[ix], HEX);
+            Serial.print(F(" "));
+          }
+          Serial.println(F(" Bad CRC"));
+          */
+          Serial.println(F("C"));
         }
         // initialize a bunch of stuff before we switch back to State 1
         for (int ix = 0; ix < N_DATA_QUADS; ix++) {
@@ -412,8 +455,8 @@
   xv_config.motor_pwm_pin = 9;  // pin connected N-Channel Mosfet

   xv_config.rpm_setpoint = 300;  // desired RPM
-  xv_config.rpm_min = 200;
-  xv_config.rpm_max = 300;
+  xv_config.rpm_min = 180;
+  xv_config.rpm_max = 349;
   xv_config.pwm_min = 100;
   xv_config.pwm_max = 1023;
   xv_config.sample_time = 20;
@@ -449,12 +492,34 @@
   sCmd.addCommand("HideRPM",  hideRPM);
   sCmd.addCommand("ShowDist",  showDist);
   sCmd.addCommand("HideDist",  hideDist);
+  sCmd.addCommand("ShowAngles",  showAngles);      // this must be before "ShowAngle" to ensure correct match
+  sCmd.addCommand("HideAngles",  hideDist);
   sCmd.addCommand("ShowAngle",  showAngle);
   sCmd.addCommand("HideAngle",  hideDist);
   sCmd.addCommand("MotorOff", motorOff);
   sCmd.addCommand("MotorOn",  motorOn);
   sCmd.addCommand("HideRaw", hideRaw);
   sCmd.addCommand("ShowRaw",  showRaw);
+  sCmd.addCommand("ShowErrors", showErrors);
+  sCmd.addCommand("HideErrors", hideErrors);
+}
+/*
+ * showErrors
+ */
+void showErrors() {
+  bShowErrors = true;                                  // enable error display
+  Serial.println(F(" "));
+  Serial.print(F("Showing errors"));
+  Serial.println(F(" "));
+}
+/*
+ * hideErrors
+ */
+void hideErrors() {                                    // disable error display
+  bShowErrors = false;
+  Serial.println(F(" "));
+  Serial.print(F("Hiding errors"));
+  Serial.println(F(" "));
 }
 /*
  * showRPM
@@ -485,7 +550,7 @@
   }
   xv_config.show_angle = SHOW_ALL_ANGLES;
   Serial.println(F(" "));
-  Serial.print(F("Showing Distance data <Angle>: <dist.mm> (quality)}"));
+  Serial.print(F("Showing Distance data <Angle>: <dist mm> (quality)}"));
   Serial.println(F(" "));
 }

@@ -498,6 +563,7 @@
 }

 void showAngle() {
+  bShowAnglesFromArray = false;                        // disable multi-angle display
   showDist();
   double sVal = 0.0;
   char *arg;
@@ -536,6 +602,116 @@
     Serial.println(F(" "));
   }  // if (syntax_error)
 }
+/*
+ * doShowAngles - Multi-angle range(s) implementation - DSH
+ * Command: ShowAngles ddd, ddd-ddd, etc.
+ * Command: HideAngles (remember to clear out aryAngles)
+ * Enter with: N/A
+ * Uses:       aryAngles (an array of 360 booleans) is set to appropriate values
+ * Calls:      showDist
+ * Exits with: N/A
+ * TEST THIS STRING:  ShowAngles 16-20, 300-305, 123-124, 10
+ */
+void showAngles() {
+  double sVal = 0.0;
+  char c, *arg;
+  boolean syntax_error = false;
+  int doing_from_to, from, to, ix, lToken, n_groups = 0;
+
+  for (ix = 0; ix < N_ANGLES; ix++)                      // initialize
+    aryAngles[ix] = false;
+  doing_from_to = 0;                                     // state = doing 'from'
+  // Make sure that there is at least 1 angle or group of angles present
+  do {
+    arg = sCmd.next();                                   // get the next token
+    if (arg == NULL) {                                   // it's empty -- just exit
+      sCmd.readSerial();
+      arg = sCmd.next();
+      break;
+    }
+    // see if the token has an embedded "-", meaning from - to
+    lToken = strlen(arg);                                // get the length of the current token
+    for (ix = 0; ix < lToken; ix++) {
+      c = arg[ix];
+      if (c == ',') {                                     // optional trailing comma
+        doing_from_to = 0;
+        break;
+      }
+      else if (c == '-') {                               // optional '-' means "from - to"
+        to = 0;
+        doing_from_to = 1;                               // from now on, we're doing 'to'
+      }
+      else if (c == ' ') {                               // ignore blanks
+        Serial.println(F("{ }"));
+      }
+      else if ((c >= '0') && (c <= '9')) {
+        if (doing_from_to == 0) {
+          from *= 10;
+          from += c - '0';
+          to = from;                                      // default to = from
+          n_groups++;                                     // count the number of active groups (s/b >= 1)
+        }
+        else {
+          to *= 10;
+          to += c - '0';
+        }
+      }
+      else {
+        syntax_error = true;
+        n_groups = 0;
+        break;
+      }
+    }  // for (ix = 0; ix < lToken; ix++)
+    // validate 'from' and 'to' and set 'aryAngles' with correct values
+    if ((from >= 0) && (from < N_ANGLES) && (to >= 0) && (to < N_ANGLES)) {
+      if (to >= from) {
+        for (ix = from; ix <= to; ix++) {
+          aryAngles[ix] = true;
+        }
+      }
+      else {
+        syntax_error = true;
+        break;
+      }
+    }
+    else {
+      syntax_error = true;
+      break;
+    }
+    from = 0;
+    to = 0;
+    doing_from_to = 0;
+  }  // do
+  while (arg != NULL);
+  if (n_groups == 0)
+    syntax_error = true;
+
+  // Handle syntax errors
+  if (syntax_error) {
+    bShowAnglesFromArray = false;                      // syntax error: disable multi-angle display
+    Serial.println(F(" "));
+    Serial.print(F("Incorrect syntax.  Example: ShowAngles 0, 15-30, 45-50, 10"));
+    Serial.println(F(" "));
+    Serial.print(F("Use a space after each comma. No particular order is required."));
+    Serial.println(F(" "));
+    Serial.print(F("In a from-to pair, the 1st value must be lowest."));
+    Serial.println(F(" "));
+  }
+  else {                                                  // no errors detected, display the angles and start
+    // We're ready to process multiple angles
+    Serial.println(F(""));
+    Serial.print(F("Angles:"));
+    for (int ix = 0; ix < N_ANGLES; ix++) {               // display the angle array
+      if(aryAngles[ix]) {
+        Serial.print(ix, DEC);
+        Serial.print(F(","));
+      }
+    }
+    Serial.println(F(""));
+    bShowAnglesFromArray = true;                          // show multiple angles is enabled
+    showDist();
+  }  // if (syntax_error)
+}

 void motorOff() {
   xv_config.motor_enable = false;
@@ -588,6 +764,9 @@
   Serial.println(F(" "));
 }

+void setLowRPM(double sVal) {
+  xv_config.rpm_setpoint = sVal;
+}
 void setRPM() {
   double sVal = 0.0;
   char *arg;
@@ -786,7 +965,7 @@
   Serial.println(F("  ShowConfig    - Show the running configuration"));
   Serial.println(F("  SaveConfig    - Save the running configuration to EEPROM"));
   Serial.println(F("  ResetConfig   - Restore the original configuration"));
-  Serial.println(F("  SetRPM        - Set the desired rotation speed (min: 200, max: 300)"));
+  Serial.println(F("  SetRPM        - Set the desired rotation speed (min: 180, max: 349)"));
   Serial.println(F("  SetKp         - Set the proportional gain"));
   Serial.println(F("  SetKi         - Set the integral gain"));
   Serial.println(F("  SetKd         - Set the derivative gain"));
@@ -797,6 +976,10 @@
   Serial.println(F("  HideDist      - Hide the distance data"));
   Serial.println(F("  ShowAngle     - Show distance data for a specific angle (0 - 359 or 360 for all)"));
   Serial.println(F("  HideAngle     - Hide distance data for all angles"));
+  Serial.println(F("  ShowAngles    - Show distance data for a multiple angles (ShowAngles 0, 15-30, 45-50, 10)"));
+  Serial.println(F("  HideAngles    - Hide distance data for all angles"));
+  Serial.println(F("  ShowErrors    - Show all error messages"));
+  Serial.println(F("  HideErrors    - Hide error messages"));
   Serial.println(F("  MotorOff      - Stop spinning the lidar"));
   Serial.println(F("  MotorOn       - Enable spinning of the lidar"));
   Serial.println(F("  HideRaw       - Stop outputting the raw data from the lidar"));