Remove Particle Photon references, change SD pinout defaults (Assuming more people are using Teensy 3.5/3.6/4.1 than SmartMatrix Shield V3)

--- AnimatedGIFs.ino
+++ AnimatedGIFs.ino
@@ -35,7 +35,7 @@
  * This code has been tested with many size GIFs including 128x32, 64x64, 32x32, and 16x16 pixel GIFs, but is optimized for 32x32 pixel GIFs.
  *
  * Wiring is on the default Teensy 3.2 SPI pins, and chip select can be on any GPIO,
- * set by defining SD_CS in the code below.  For Teensy 3.5/3.6 with the onboard SDIO, change SD_CS to BUILTIN_SDCARD
+ * set by defining SD_CS in the code below.  For Teensy 3.5/3.6/4.1 with the onboard SDIO, SD_CS should be the default BUILTIN_SDCARD
  * Function     | Pin
  * DOUT         |  11
  * DIN          |  12
@@ -72,13 +72,8 @@
  *    Use matrix.setMaxCalculationCpuPercentage() or matrix.setCalcRefreshRateDivider()
  */

-#if defined (ARDUINO)
 #include <SmartLEDShieldV4.h>  // comment out this line for if you're not using SmartLED Shield V4 hardware (this line needs to be before #include <SmartMatrix3.h>)
 #include <SmartMatrix3.h>
-#elif defined (SPARK)
-#include "application.h"
-#include "SmartMatrix3_Photon_Apa102/SmartMatrix3_Photon_Apa102.h"
-#endif

 #include <SD.h>
 #include "GifDecoder.h"
@@ -123,14 +118,12 @@
  */
 GifDecoder<kMatrixWidth, kMatrixHeight, 12> decoder;

-// Chip select for SD card on the SmartMatrix Shield or Photon
+// Chip select for SD card
 #if defined(ESP32)
     #define SD_CS 5
 #elif defined (ARDUINO)
-    #define SD_CS 15
-    //#define SD_CS BUILTIN_SDCARD
-#elif defined (SPARK)
-    #define SD_CS SS
+    #define SD_CS BUILTIN_SDCARD
+    //#define SD_CS 15
 #endif

 #if defined(ESP32)


got the OO valve and flow control working; revised MCP pin mapping; removed valveStateChange imperative version; danced a short jig and drank 3 glasses of wine. Now where was I?

--- ardesp/waterelf/waterelf.ino
+++ ardesp/waterelf/waterelf.ino
@@ -3,7 +3,7 @@
 #include <ESP8266WiFi.h>
 #include <WiFiClient.h>
 #include <ESP8266WebServer.h>
-#include "./DNSServer.h"      // Patched lib
+#include "./DNSServer.h"      // patched lib
 #include <FS.h>
 #include <OneWire.h>
 #include <DallasTemperature.h>
@@ -45,36 +45,36 @@
   "<meta name=\"viewport\" content=\"width=device-width, initial-scale=1.0\">"
   ""
   "\n";
-const char* pageDefault =
+const char* pageDefault = // TODO build the growbeds according to their num
   "
Welcome to WaterElf
\n"
   "
Control
\n"
   "

\n"
   "
Join a wifi network
\n"
   "
Configure data sharing
\n"
-  "
\n"
-    "<form method='POST' action='actuate'>\n"
-    "External power: "
-    "on <input type='radio' name='state' value='on'>\n"
-    "off <input type='radio' name='state' value='off'>\n"
-    "<input type='submit' value='Submit'></form>\n"
-  "
"
   "
"
     "<form method='POST' action='valve1'>\n"
-    "Growbed valve pump 1: "
-    "on <input type='radio' name='state' value='on'>\n"
-    "off <input type='radio' name='state' value='off'>\n"
+    "Growbed 1: "
+    "fill <input type='radio' name='state' value='on'>\n"
+    "drain <input type='radio' name='state' value='off'>\n"
     "<input type='submit' value='Submit'></form>\n"
   "
"
   "
"
     "<form method='POST' action='valve2'>\n"
-    "Growbed valve pump 2: "
-    "on <input type='radio' name='state' value='on'>\n"
-    "off <input type='radio' name='state' value='off'>\n"
+    "Growbed 2: "
+    "fill <input type='radio' name='state' value='on'>\n"
+    "drain <input type='radio' name='state' value='off'>\n"
     "<input type='submit' value='Submit'></form>\n"
   "
"
   "
"
     "<form method='POST' action='valve3'>\n"
-    "Growbed valve pump 3: "
+    "Growbed 3: "
+    "fill <input type='radio' name='state' value='on'>\n"
+    "drain <input type='radio' name='state' value='off'>\n"
+    "<input type='submit' value='Submit'></form>\n"
+  "
"
+  "
\n"
+    "<form method='POST' action='actuate'>\n"
+    "Power: "
     "on <input type='radio' name='state' value='on'>\n"
     "off <input type='radio' name='state' value='off'>\n"
     "<input type='submit' value='Submit'></form>\n"
@@ -103,6 +103,8 @@
   long waterLevel1;
   long waterLevel2;
   long waterLevel3;
+  // TODO add last reboot
+  // TODO add free memory?
 } monitor_t;
 monitor_t monitorData[MONITOR_POINTS];
 int monitorCursor = 0;
@@ -150,13 +152,15 @@

 /////////////////////////////////////////////////////////////////////////////
 // MCP23008 stuff ///////////////////////////////////////////////////////////
-Adafruit_MCP23008 mcp; // Create object for MCP23008
-const int P1_MCP_PIN = 0;
-const int P2_MCP_PIN = 3;
-const int P3_MCP_PIN = 7;
-const int S1_MCP_PIN = 2;
-const int S2_MCP_PIN = 6;
-const int S3_MCP_PIN = 1;
+Adafruit_MCP23008 mcp; // create object for MCP23008
+const int mcpPins[] = { 0, 1, 2, 3, 6, 7, }; // pins to init in setup
+const int mcpPinsUsed = 6; // length of mcpPins array
+const int valvePinMap[][2] = {
+  { -1, -1 }, // there's no valve numbered 0...
+  { 0, 2 },   // valve 1: pump on pin 0, solenoid on pin 2
+  { 3, 6 },   // valve 2: ...
+  { 7, 1 },   // valve 3: ...
+};

 /////////////////////////////////////////////////////////////////////////////
 // level sensing stuff //////////////////////////////////////////////////////
@@ -188,6 +192,9 @@
 // differences are absorbed into the dry time?

 class Valve { // each valve /////////////////////////////////////////////////
+  public:
+  static int counter;               // counter for setting valve number
+  int number;                       // id of this valve, counting from 1
   char dryMins = 45;                // mins to leave bed drained per cycle
                                     // in beds with overflows can be 0; else
                                     // will be cycle time minus fill time
@@ -195,11 +202,41 @@
   bool gotOverflow = false;         // does the growbed have an overflow?
   char fillLevel = 5;               // cms below the level sensor: drain point

+  Valve() { number = counter++; }
+  void stateChange(bool newState) { // turn on or off
+    Serial.print("Growbed Valve Air Pump ");
+    Serial.print(number);
+    int pumpMcpPin = valvePinMap[number][0];
+    int solenoidMcpPin = valvePinMap[number][1];
+
+    // trigger MOSFETs via the MCP
+    if(newState == true){
+      mcp.digitalWrite(pumpMcpPin, HIGH);
+      mcp.digitalWrite(solenoidMcpPin, HIGH);
+      Serial.println(" on");
+    } else {
+      mcp.digitalWrite(pumpMcpPin, LOW);
+      mcp.digitalWrite(solenoidMcpPin, LOW);
+      Serial.println(" off");
+    }
+  }
+  void on()  { stateChange(true); } // fill time
+  void off() { stateChange(false); }// drain time
+  void step(monitor_t* now) {       // check conditions and adjust state
+    /* TODO
+    if(! running) {
+      if(startTime >= millis()) {
+        running = true;
+        ...
+      }
+    }
+    */
+  }
+};
+int Valve::counter = 1;             // definition (the above only declares)
+
+class FlowController { // the set of valves and their config ////////////////
   public:
-  void step(monitor_t* now) {       // check conditions and adjust state
-  }
-};
-class FlowController { // the set of valves and their config ////////////////
   int numValves = 3;                // WARNING! call init if resetting!
   char cycleMinutes = 60;           // how long is a flood/drain cycle?
   char maxSimultaneousDrainers = 1; // how many beds can drain simultaneously
@@ -208,10 +245,10 @@
   char staggerMins = 10;            // gap to leave between valve startups
   Valve* valves = 0;                // the valves and their states

-  public:
   FlowController() { init(); }
   int getStaggerMillis() { return staggerMins * 60 * 1000; }
   void init() {
+    Valve::counter = 1;
     if(valves != 0) delete(valves);
     valves = new Valve[numValves];

@@ -262,12 +299,8 @@
   startWebServer();

   mcp.begin();      // use default address 0 for mcp23008
-  mcp.pinMode(P1_MCP_PIN, OUTPUT);
-  mcp.pinMode(P2_MCP_PIN, OUTPUT);
-  mcp.pinMode(P3_MCP_PIN, OUTPUT);
-  mcp.pinMode(S1_MCP_PIN, OUTPUT);
-  mcp.pinMode(S2_MCP_PIN, OUTPUT);
-  mcp.pinMode(S3_MCP_PIN, OUTPUT);
+  for(int i = 0; i < mcpPinsUsed; i++)
+    mcp.pinMode(mcpPins[i], OUTPUT);

   if(WiFi.hostname("waterelf"))
     Serial.println("set hostname succeeded");
@@ -285,9 +318,9 @@

   // valve demo mode TODO remove?
   if (GOT_TEMP_SENSOR==FALSE) {
-    valveStateChange(1, TRUE, P1_MCP_PIN, S1_MCP_PIN);
+    flowController.valves[0].on();
     delay(15000);
-    valveStateChange(1, FALSE, P1_MCP_PIN, S1_MCP_PIN);
+    flowController.valves[0].off();
     delay(5000);
   }

@@ -621,15 +654,15 @@
   toSend += pageFooter;
   webServer.send(200, "text/html", toSend);
 }
-void handle_valve1() { handle_valve(1, P1_MCP_PIN, S1_MCP_PIN); }
-void handle_valve2() { handle_valve(2, P2_MCP_PIN, S2_MCP_PIN); }
-void handle_valve3() { handle_valve(3, P3_MCP_PIN, S3_MCP_PIN); }
-void handle_valve(int valveNum, int pumpMcpPin, int solenoidMcpPin) {
+void handle_valve1() { handle_valve(0); } // valves in the UI are...
+void handle_valve2() { handle_valve(1); } // ...numbered from 1, but...
+void handle_valve3() { handle_valve(2); } // ...from 0 in the FlowController
+void handle_valve(int valveNum) {
   Serial.print("serving page at /valve");
-  Serial.println(valveNum);
+  Serial.println(valveNum + 1);
   String toSend = pageTop;
   toSend += ": Setting Water Valve ";
-  toSend += valveNum;
+  toSend += valveNum + 1;
   toSend += pageTop2;

   boolean newState = false;
@@ -639,34 +672,16 @@
         newState = true;
     }
   }
-
-  // now we trigger MOSFETs off or on
-  valveStateChange(valveNum, newState, pumpMcpPin, solenoidMcpPin);
+  flowController.valves[valveNum].stateChange(newState);

   toSend += "
Water Valve ";
-  toSend += valveNum;
+  toSend += valveNum + 1;
   toSend += " triggered
\n";
   toSend += "
(New state should be ";
   toSend += (newState) ? "on" : "off";
   toSend += ".)
\n";
   toSend += pageFooter;
   webServer.send(200, "text/html", toSend);
-}
-void valveStateChange(
-  int valveNum, boolean newState, int pumpMcpPin, int solenoidMcpPin
-) {
-  Serial.print("Growbed Valve Air Pump ");
-  Serial.print(valveNum);
-
-  if(newState == true){
-    mcp.digitalWrite(pumpMcpPin, HIGH);
-    mcp.digitalWrite(solenoidMcpPin, HIGH);
-    Serial.println(" on");
-  } else {
-    mcp.digitalWrite(pumpMcpPin, LOW);
-    mcp.digitalWrite(solenoidMcpPin, LOW);
-    Serial.println(" off");
-  }
 }

 /////////////////////////////////////////////////////////////////////////////


some simple loop control to avoid doing everything on each tick; added link to actuator form (but yet to handle submission of it); tested with 1.6.6 from head of repo (ok but no longer reconnects automatically); cleaned up debug messages and tidied up some var names


Update example to include rotated text.

Update example to include rotated text.

--- examples/pcdtest/pcdtest.ino
+++ examples/pcdtest/pcdtest.ino
@@ -150,6 +150,21 @@
   display.display();
   delay(2000);

+  // rotation example
+  display.clearDisplay();
+  display.setRotation(1);  // rotate 90 degrees counter clockwise, can also use values of 2 and 3 to go further.
+  display.setTextSize(1);
+  display.setTextColor(BLACK);
+  display.setCursor(0,0);
+  display.println("Rotation");
+  display.setTextSize(2);
+  display.println("Example!");
+  display.display();
+  delay(2000);
+
+  // revert back to no rotation
+  display.setRotation(0);
+
   // miniature bitmap display
   display.clearDisplay();
   display.drawBitmap(30, 16,  logo16_glcd_bmp, 16, 16, 1);


v3.0 Add select switches

v3.0 Add select switches

--- GPSLCD.ino
+++ GPSLCD.ino
@@ -15,17 +15,17 @@
         LCDs available.

    The MIT License (MIT)
-
+
    Permission is hereby granted, free of charge, to any person obtaining a copy
    of this software and associated documentation files (the "Software"), to deal
    in the Software without restriction, including without limitation the rights
    to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
    copies of the Software, and to permit persons to whom the Software is
    furnished to do so, subject to the following conditions:
-
+
    The above copyright notice and this permission notice shall be included in all
    copies or substantial portions of the Software.
-
+
    THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
    IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
    FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
@@ -54,6 +54,12 @@
 #else
   // Selects either altitude or the date/time to be displayed
   pinMode(ALTITUDE_DATE_TIME_SW, INPUT);
+  // Select switches
+  pinMode(DISPLAY_12_HOUR_SW, INPUT);
+  pinMode(CONVERT_TO_LOCAL_SW, INPUT);
+  pinMode(DISPLAY_HDOP_SW, INPUT);
+  pinMode(CARDINAL_SW, INPUT);
+  pinMode(NOT_USED_YET_SW, INPUT);
 #endif
   pinMode (ON_BOARD_LED, OUTPUT); // Turn off on-board LED
   digitalWrite (ON_BOARD_LED, LOW); //       "
@@ -88,6 +94,11 @@
   static bool dateTimeToggle = true;
   static bool headingToggle = true;
   static bool hdopToggle = true;
+  bool display12_24_Hour = !digitalRead(DISPLAY_12_HOUR_SW);
+  bool localUTCTimeDate = !digitalRead(CONVERT_TO_LOCAL_SW);
+  bool displayHdop = !digitalRead(DISPLAY_HDOP_SW);
+  bool cardinal8_16 = !digitalRead(CARDINAL_SW);
+  bool notUsedYet = !digitalRead(NOT_USED_YET_SW);
 #endif
 #ifdef DATA_VALID_OVERRIDE
   const bool dataValidOverride = true; // Set true to override data valid for debugging
@@ -261,79 +272,81 @@
     lcd.setCursor (0, 1); // Go to 2nd line
     lcd.print("Lon: ");
     lcd.print(GPSData.lon);
-#ifndef CONVERT_TO_LOCAL
-    // Only display if time/date is selected
-    if (!(digitalRead(ALTITUDE_DATE_TIME_SW))) {
-      lcd.print("      "); // Clear the extra chars
-      uint8_t DOW = dayOfWeek(GPSData.year, GPSData.month, GPSData.day);
-      if (IsDST(GPSData.day, GPSData.month, DOW)) {
-        lcd.print("DST");
+    if ((digitalRead(ALTITUDE_DATE_TIME_SW))) {
+      // Only display if time/date is selected
+      if (!localUTCTimeDate) {
+        lcd.print("      "); // Clear the extra chars
+        uint8_t DOW = dayOfWeek(GPSData.year, GPSData.month, GPSData.day);
+        if (IsDST(GPSData.day, GPSData.month, DOW)) {
+          lcd.print("DST");
+        }
+        else {
+          lcd.print(" ST");
+        }
       }
       else {
-        lcd.print(" ST");
-      }
-    }
+        lcd.print("         "); // Clear the extra chars
+      }
+    } // if ((digitalRead(ALTITUDE_DATE_TIME_SW)))
     else {
-      lcd.print("         "); // Clear the extra chars
-    }
-#else // #ifndef CONVERT_TO_LOCAL
-#ifdef DISPLAY_HDOP
-    // Display Horizontal Dilution of Precision (Hdop) with the format X.X
-    // It comes in from the GPS module as XXX
-    // If you care how Hdop is computed (I don't :-(), see the following:
-    // http://www2.unb.ca/gge/Resources/gpsworld.may99.pdf
-    float Hdop = (float)GPSData.hdop / 100.0f; // Hdop in X.X format
-    lcd.print(" Hdop:");
-    if (Hdop < 10.0f) {
-      lcd.print(Hdop);
-    }
-    else {
-      // Hdop value too large for my LCD, so cross it out
-      // Toggle Hdop indicator every TOGGLETIME_INTERVAL seconds
-      if (now - prevHdopTime > TOGGLETIME_INTERVAL / 3) {
-        prevHdopTime = now;
-        if (hdopToggle) {
-          hdopToggle = false;
-          lcd.print("XXX");
+      if (!displayHdop) {
+        // Display Horizontal Dilution of Precision (Hdop) with the format X.X
+        // It comes in from the GPS module as XXX
+        // If you care how Hdop is computed (I don't :-(), see the following:
+        // http://www2.unb.ca/gge/Resources/gpsworld.may99.pdf
+        float Hdop = (float)GPSData.hdop / 100.0f; // Hdop in X.X format
+        lcd.print(" Hdop:");
+        if (Hdop < 10.0f) {
+          lcd.print(Hdop);
         }
         else {
-          hdopToggle = true;
-          lcd.print("   ");
-        } // if (hdopToggle)
-      } // if (now - prevHdopTime > TOGGLETIME_INTERVAL)
-    } // if (Hdop < 10.0f)
-#else // #ifdef DISPLAY_HDOP
-    // Display horizontal position error in feet
-    float hError = (float)GPSData.hdop / 100.0f; // Error in X.X format
-    hError *= GPS_RECEIVER_ERROR; // Error in meters
-    hError *= _GPS_FEET_PER_METER; // Error in feet
-    lcd.print(" Err: ");
-    if (hError < 100.0f) {
-      lcd.print((uint8_t)hError);
-      if (hError < 10.0f) {
-        lcd.print("f "); // feet
-      }
-      else {
-        lcd.print("f"); // feet
-      }
-    }
-    else { // if (hError < 100.0f)
-      // horizontal position error value too large for my LCD, so cross it out
-      // Toggle Hdop indicator every TOGGLETIME_INTERVAL seconds
-      if (now - prevHdopTime > TOGGLETIME_INTERVAL / 3) {
-        prevHdopTime = now;
-        if (hdopToggle) {
-          hdopToggle = false;
-          lcd.print("XXX");
-        }
-        else {
-          hdopToggle = true;
-          lcd.print("   ");
-        } // if (hdopToggle)
-      } // if (now - prevHdopTime > TOGGLETIME_INTERVAL)
-    } // if (hError < 100.0f)
-#endif // #ifdef DISPLAY_HDOP
-#endif // #ifndef CONVERT_TO_LOCAL
+          // Hdop value too large for my LCD, so cross it out
+          // Toggle Hdop indicator every TOGGLETIME_INTERVAL seconds
+          if (now - prevHdopTime > TOGGLETIME_INTERVAL / 3) {
+            prevHdopTime = now;
+            if (hdopToggle) {
+              hdopToggle = false;
+              lcd.print("XXX");
+            }
+            else {
+              hdopToggle = true;
+              lcd.print("   ");
+            } // if (hdopToggle)
+          } // if (now - prevHdopTime > TOGGLETIME_INTERVAL)
+        } // if (Hdop < 10.0f)
+      }
+      else { // if (!displayHdop)
+        // Display horizontal position error in feet
+        float hError = (float)GPSData.hdop / 100.0f; // Error in X.X format
+        hError *= GPS_RECEIVER_ERROR; // Error in meters
+        hError *= _GPS_FEET_PER_METER; // Error in feet
+        lcd.print(" Err: ");
+        if (hError < 100.0f) {
+          lcd.print((uint8_t)hError);
+          if (hError < 10.0f) {
+            lcd.print("f "); // feet
+          }
+          else {
+            lcd.print("f"); // feet
+          }
+        }
+        else { // if (hError < 100.0f)
+          // horizontal position error value too large for my LCD, so cross it out
+          // Toggle Hdop indicator every TOGGLETIME_INTERVAL seconds
+          if (now - prevHdopTime > TOGGLETIME_INTERVAL / 3) {
+            prevHdopTime = now;
+            if (hdopToggle) {
+              hdopToggle = false;
+              lcd.print("XXX");
+            }
+            else {
+              hdopToggle = true;
+              lcd.print("   ");
+            } // if (hdopToggle)
+          } // if (now - prevHdopTime > TOGGLETIME_INTERVAL)
+        } // if (hError < 100.0f)
+      } // if (displayHdop)
+    } // if ((digitalRead(ALTITUDE_DATE_TIME_SW)))
     lcd.setCursor (0, 2); // Go to 3rd line
     lcd.print("Spd: ");
     if (GPSData.speed < SPEED_CUTOUT) {
@@ -354,7 +367,7 @@
         prevHeadingTime = now;
         if (headingToggle) { // Display cardinal heading
           headingToggle = false;
-          lcd.print(cardinal(GPSData.heading));
+          lcd.print(cardinal(GPSData.heading, cardinal8_16));
         }
         else { // Display degrees heading
           headingToggle = true;
@@ -393,24 +406,26 @@
           uint8_t day  = GPSData.day;
           uint8_t month = GPSData.month;
           uint16_t year = GPSData.year;
-#ifdef CONVERT_TO_LOCAL
-          // Convert UTC time to local time (no need to convert the date)
-          bool DST = convertToLocal (&hour, &year, &month,
-                                     &day, GPSData.lon, false); // false means no date conversion
-#else // #ifdef CONVERT_TO_LOCAL
-#ifdef DISPLAY_12_HOUR
-          if (hour == 0) { // 12 hour clocks don't display 0
-            hour = 12;
+          bool DST = false;
+          if (localUTCTimeDate) {
+            // Convert UTC time to local time (no need to convert the date)
+            DST = convertToLocal (&hour, &year, &month,
+                                  &day, GPSData.lon, false); // false means no date conversion
           }
-#endif // #ifdef DISPLAY_12_HOUR
-#endif // #ifdef CONVERT_TO_LOCAL
-#ifdef DISPLAY_12_HOUR
+          else { // if (localUTCTimeDate)
+            if (display12_24_Hour) {
+              if (hour == 0) { // 12 hour clocks don't display 0
+                hour = 12;
+              }
+            } // if (display12_24_Hour)
+          } // if (localUTCTimeDate)
           char AMPM[] = "am";
-          if (hour >= 12) { // Convert to 12 hour format
-            if (hour > 12) hour -= 12;
-            strcpy (AMPM, "pm");
-          }
-#endif
+          if (display12_24_Hour) {
+            if (hour >= 12) { // Convert to 12 hour format
+              if (hour > 12) hour -= 12;
+              strcpy (AMPM, "pm");
+            }
+          } // if (display12_24_Hour)
           if (hour < 10) lcd.print("0");
           lcd.print(hour);
           lcd.print(":");
@@ -419,23 +434,25 @@
           lcd.print(":");
           if (GPSData.second < 10) lcd.print("0");
           lcd.print(GPSData.second);
-#ifdef DISPLAY_12_HOUR
-          lcd.print(AMPM);
-#endif // #ifdef DISPLAY_12_HOUR
-#ifdef CONVERT_TO_LOCAL
-#ifdef DISPLAY_12_HOUR
-          (DST) ? lcd.print(" DST") : lcd.print("  ST");
-#else // #ifdef DISPLAY_12_HOUR
-          (DST) ? lcd.print("   DST") : lcd.print("    ST");
-#endif // #ifdef DISPLAY_12_HOUR
-#endif // #ifndef CONVERT_TO_LOCAL
-#ifndef CONVERT_TO_LOCAL
-#ifdef DISPLAY_12_HOUR
-          lcd.print(" UTC");
-#else // #ifdef DISPLAY_12_HOUR
-          lcd.print("   UTC");
-#endif // #ifdef DISPLAY_12_HOUR
-#endif // #ifndef CONVERT_TO_LOCAL
+          if (display12_24_Hour) {
+            lcd.print(AMPM);
+          }
+          if (localUTCTimeDate) {
+            if (display12_24_Hour) {
+              (DST) ? lcd.print(" DST") : lcd.print("  ST");
+            }
+            else {
+              (DST) ? lcd.print("   DST") : lcd.print("    ST");
+            } // if (display12_24_Hour)
+          } // if (localUTCTimeDate)
+          if (!localUTCTimeDate) {
+            if (display12_24_Hour) {
+              lcd.print(" UTC");
+            }
+            else {
+              lcd.print("   UTC");
+            } // if (display12_24_Hour)
+          } // if (!localUTCTimeDate)
         } // if (dateTimeToggle)
         else {
           // Display date
@@ -445,11 +462,12 @@
           uint8_t day  = GPSData.day;
           uint8_t month = GPSData.month;
           uint16_t year = GPSData.year;
-#ifdef CONVERT_TO_LOCAL
-          // Convert UTC date to local date
-          bool DST = convertToLocal (&hour, &year, &month,
-                                     &day, GPSData.lon, true); // true means date conversion
-#endif // #ifdef CONVERT_TO_LOCAL
+          bool DST = false;
+          if (localUTCTimeDate) {
+            // Convert UTC date to local date
+            DST = convertToLocal (&hour, &year, &month,
+                                  &day, GPSData.lon, true); // true means date conversion
+          } // if (localUTCTimeDate)
           if (month < 10) lcd.print("0");
           lcd.print(month);
           lcd.print("/");
@@ -558,19 +576,22 @@
 }

 // Compute the cardinal points of the compass
-const char* cardinal(double course)
-{
-#ifdef _16CARDINAL
-  const char* directions[] = {"N  ", "NNE", "NE ", "ENE", "E  ", "ESE", "SE ", "SSE",
-                              "S  ", "SSW", "SW ", "WSW", "W  ", "WNW", "NW ", "NNW"
-                             };
-#else
-  const char* directions[] = {"N  ", "N  ", "NE ", "NE ", "E  ", "E  ", "SE ", "SE ",
-                              "S  ", "S  ", "SW ", "SW ", "W  ", "W  ", "NW ", "NW "
-                             };
-#endif // #ifdef _16CARDINAL
-  uint8_t direction = (uint8_t)((course + 11.25d) / 22.5d);
-  return directions[direction % 16];
+const char* cardinal(double course, bool cardinalSelect)
+{
+  if (!cardinalSelect) {
+    const char* directions[] = {"N  ", "NNE", "NE ", "ENE", "E  ", "ESE", "SE ", "SSE",
+                                "S  ", "SSW", "SW ", "WSW", "W  ", "WNW", "NW ", "NNW"
+                               };
+    uint8_t direction = (uint8_t)((course + 11.25d) / 22.5d);
+    return directions[direction % 16];
+  }
+  else {
+    const char* directions[] = {"N  ", "N  ", "NE ", "NE ", "E  ", "E  ", "SE ", "SE ",
+                                "S  ", "S  ", "SW ", "SW ", "W  ", "W  ", "NW ", "NW "
+                               };
+    uint8_t direction = (uint8_t)((course + 11.25d) / 22.5d);
+    return directions[direction % 16];
+  } // if (!cardinalSelect)
 }

 /* Ripped off from Stackoverflow
@@ -611,7 +632,6 @@
   return previousSunday <= 0;
 }

-#ifdef CONVERT_TO_LOCAL
 /* Convert UTC time and date to local time and date
    Difference between UTC time/date (at Greenwich) and local time/date is 15 minutes
    per 1 degree of longitude. See the following:
@@ -672,5 +692,4 @@
   } // if (convertDate)
   return (DST);
 }
-#endif // #ifdef CONVERT_TO_LOCAL
 #endif // #ifndef _16x2


New modes added

New modes added

--- Master.ino
+++ Master.ino
@@ -446,6 +446,10 @@

     if(inputHOLD == sync)
       synchronization();
+    else if(inputHOLD == crdM)
+    {
+      Serial.println("In alphabetic order:\nOnur Calik\nMusab Cevik\nBaran Dereli\nOzgun Sensoy\nYigit Suoglu");
+    }
     else if(inputHOLD == recal) //start recalabration seq. wait for synchronization seq.
     {
       Serial.print("Getting enviroment values"); //get env


Added 'emit' function, phase II

Added 'emit' function, phase II

--- chromis-particle/chromis.ino
+++ chromis-particle/chromis.ino
@@ -44,12 +44,6 @@
     irrecv.enableIRIn(); // Start the receiver

     pinMode(PIN_OUTPUT, OUTPUT);
-    Particle.function("tvOff", tvOff);
-    Particle.function("tvOn", tvOn);
-    Particle.function("hdmi1", hdmi1);
-    Particle.function("hdmi2", hdmi2);
-    Particle.function("hdmi3", hdmi3);
-    Particle.function("hdmi4", hdmi4);
     Particle.function("emit", emit);
 }

@@ -68,85 +62,60 @@
 // Power Off: "NEC,20DFA35C,32"

 int emit(String command) {
-	if (command != "") {
-        char inputStr[64];
-        command.toCharArray(inputStr, 64);
-        char *scheme = strtok(inputStr, ",");
-        char *p = strtok(NULL, ",");
-        int data = strtol(p, NULL, 16);
-        p = strtok(NULL, ",");
-        int bits = atoi(p);
-        //TODO: use scheme, data, bits here
-        //TODO: to emit IR signals
-        return 1;
-    }
-    else {
+	if (command == "") {
         return 0;
     }

-    /*
-    int p = 0;
-    int i = command.indexOf(',', p);
-    String scheme = command.substring(p, i).toUpperCase();
-    p = i+1;
-    i = command.indexOf(',', p);
-    String data = command.substring(p, i).toUpperCase();
-    p = i+1;
-    String bits = command.substring(p);
+    char inputStr[64];
+    command.toCharArray(inputStr, 64);
+    char *scheme = strtok(inputStr, ",");
+    char *p = strtok(NULL, ",");
+    int data = strtol(p, NULL, 16);
+    p = strtok(NULL, ",");
+    int bits = atoi(p);

-    if (scheme == "NEC") {
-        irsend.sendNEC(0x20DFA35C, 32);
-        irsend.sendNEC(REPEAT, 32);
-        irsend.sendNEC(REPEAT, 32);
+    if (strcmp(scheme, "NEC")==0) {
+        irsend.sendNEC(data, bits);
+        irsend.sendNEC(REPEAT, bits);
+        irsend.sendNEC(REPEAT, bits);
     }
-    return 0;
-    */
-}
+    else if (strcmp(scheme, "SONY")==0) {
+        irsend.sendSony(data, bits);
+        irsend.sendSony(REPEAT, bits);
+        irsend.sendSony(REPEAT, bits);
+    }
+    else if (strcmp(scheme, "RC5")==0) {
+        irsend.sendRC5(data, bits);
+        irsend.sendRC5(REPEAT, bits);
+        irsend.sendRC5(REPEAT, bits);
+    }
+    else if (strcmp(scheme, "RC6")==0) {
+        irsend.sendRC6(data, bits);
+        irsend.sendRC6(REPEAT, bits);
+        irsend.sendRC6(REPEAT, bits);
+    }
+    else if (strcmp(scheme, "DISH")==0) {
+        irsend.sendDISH(data, bits);
+        irsend.sendDISH(REPEAT, bits);
+        irsend.sendDISH(REPEAT, bits);
+    }
+    else if (strcmp(scheme, "SHARP")==0) {
+        irsend.sendSharp(data, bits);
+        irsend.sendSharp(REPEAT, bits);
+        irsend.sendSharp(REPEAT, bits);
+    }
+    else if (strcmp(scheme, "PANASONIC")==0) {
+        irsend.sendPanasonic(data, bits);
+        irsend.sendPanasonic(REPEAT, bits);
+        irsend.sendPanasonic(REPEAT, bits);
+    }
+    else if (strcmp(scheme, "JVC")==0) {
+        irsend.sendJVC(data, bits, 0);
+        irsend.sendJVC(data, bits, 1);
+        irsend.sendJVC(data, bits, 1);
+    }
+    // Neither Sanyo nor Mitsubishi is implemented yet

-int tvOff(String extra) {
-    irsend.sendNEC(0x20DFA35C, 32);
-    irsend.sendNEC(REPEAT, 32);
-    irsend.sendNEC(REPEAT, 32);
-    irrecv.enableIRIn();
-    return 1;
-}
-
-int tvOn(String extra) {
-    irsend.sendNEC(0x20DF23DC, 32);
-    irsend.sendNEC(REPEAT, 32);
-    irsend.sendNEC(REPEAT, 32);
-    irrecv.enableIRIn();
-    return 1;
-}
-
-int hdmi1(String extra) {
-    irsend.sendNEC(0xFF10EF, 32);
-    irsend.sendNEC(REPEAT, 32);
-    irsend.sendNEC(REPEAT, 32);
-    irrecv.enableIRIn();
-    return 1;
-}
-
-int hdmi2(String extra) {
-    irsend.sendNEC(0xFF50AF, 32);
-    irsend.sendNEC(REPEAT, 32);
-    irsend.sendNEC(REPEAT, 32);
-    irrecv.enableIRIn();
-    return 1;
-}
-
-int hdmi3(String extra) {
-    irsend.sendNEC(0xFF30CF, 32);
-    irsend.sendNEC(REPEAT, 32);
-    irsend.sendNEC(REPEAT, 32);
-    irrecv.enableIRIn();
-    return 1;
-}
-
-int hdmi4(String extra) {
-    irsend.sendNEC(0xFF708F, 32);
-    irsend.sendNEC(REPEAT, 32);
-    irsend.sendNEC(REPEAT, 32);
     irrecv.enableIRIn();
     return 1;
 }


Updated version_info

Updated version_info

--- Arduino/McLighting/version_info.ino
+++ Arduino/McLighting/version_info.ino
@@ -10,4 +10,5 @@
  * 17 Jun 2018 v 2.1.2
  * - Upgrade to ArduinoJSON 6.xx from ArduinoJSON 5.xx
  * - Added example for static IP
-  */
+ * - Added more internal variables to /esp_status
+ */


style: closing paren lint

style: closing paren lint

--- examples/profiles/ANCS.ino
+++ examples/profiles/ANCS.ino
@@ -54,8 +54,7 @@
         notifications[i].notiUID,
         39,
         (uint8_t *)data,
-        5000
-      );
+        5000);

       Serial.print("l: ");
       Serial.print(len);


#include Bridge.h in HttpClient

#include Bridge.h in HttpClient

--- hardware/arduino/avr/libraries/Bridge/examples/HttpClient/HttpClient.ino
+++ hardware/arduino/avr/libraries/Bridge/examples/HttpClient/HttpClient.ino
@@ -1,4 +1,5 @@

+#include <Bridge.h>
 #include <HttpClient.h>

 void setup() {


Changed invalid bonding value to 0xFF in ble_proximity_template

--- libraries/BLE/examples/ble_proximity_template/ble_proximity_template.ino
+++ libraries/BLE/examples/ble_proximity_template/ble_proximity_template.ino
@@ -276,7 +276,7 @@
       {
         //We failed the read dymanic data
         //Set the flag in the EEPROM that the contents of the EEPROM is invalid
-        EEPROM.write(0, 0x00);
+        EEPROM.write(0, 0xFF);

         status = false;
         break;
@@ -337,7 +337,7 @@
               {
                 uint8_t eeprom_status = 0;
                 eeprom_status = EEPROM.read(0);
-                if (eeprom_status != 0x00)
+                if (eeprom_status != 0xFF)
                 {
                   Serial.println(F("Previous Bond present. Restoring"));
                   Serial.println(F("Using existing bond stored in EEPROM."));
@@ -529,7 +529,7 @@
         {
           uint8_t eeprom_status = 0;
           eeprom_status = EEPROM.read(0);
-          if (eeprom_status != 0x00)
+          if (eeprom_status != 0xFF)
           {
             Serial.println(F("Previous Bond present. Restoring"));
             Serial.println(F("Using existing bond stored in EEPROM."));
@@ -684,7 +684,7 @@
     Serial.println(F("Pairing/Bonding info cleared from EEPROM."));
     Serial.println(F("Remove the wire on Pin 6 and reset the board for normal operation."));
     //Address. Value
-    EEPROM.write(0, 0);
+    EEPROM.write(0, 0xFF);
     while(1) {};
   }
 }


Added F() in Serial.print(\string\)

Added F() in Serial.print(\string\)

--- mwsLCD/mwsLCD.ino
+++ mwsLCD/mwsLCD.ino
@@ -470,16 +470,14 @@
   //--------------------------

   //lcd.clear();
-  //lcd.print("Longitude (dd.d)");
+  //lcd.print(F("Lon:"));
+  //lcd.print(gps.location.lng(), 6);
+  //lcd.print(F(" (dd.d)"));
   //lcd.setCursor(0, 2);
-  //lcd.print(gps.location.lng(), 6);
-  //delay(2000);
-
-  //lcd.clear();
-  //lcd.print("Latitude (dd.d)");
-  //lcd.setCursor(0, 2);
+  //lcd.print(F("Lat:"));
   //lcd.print(gps.location.lat(), 6);
-  //delay(2000);
+  //lcd.print(F(" (dd.d)"));
+  //delay(5000);

   lcd.clear();
   sprintf(sz, "%02d-%02d-%02d", gps.date.year(), gps.date.month(), gps.date.day());
@@ -487,27 +485,27 @@
   lcd.setCursor(0, 2);
   sprintf(sz, "%02d:%02d:%02d", gps.time.hour(), gps.time.minute(), gps.time.second());
   lcd.print(sz);
-  lcd.print(" GMT");
+  lcd.print(F(" GMT"));
   delay(5000);

   lcd.clear();
-  lcd.print("WD: ");
+  lcd.print(F("WD: "));
   lcd.print(get_wind_direction());
-  lcd.print(" N=0 CW");
+  lcd.print(F(" N=0 CW"));
   lcd.setCursor(0, 2);
-  lcd.print("WS:");
+  lcd.print(F("WS:"));
   lcd.print(get_wind_speed(), 1);
-  lcd.print(" m/s");
+  lcd.print(F(" m/s"));
   delay(5000);

   lcd.clear();
-  lcd.print("H:");
+  lcd.print(F("H:"));
   lcd.print(myHumidity.readHumidity());
-  lcd.print(" %");
+  lcd.print(F(" %"));
   lcd.setCursor(0, 2);
-  lcd.print("T:");
+  lcd.print(F("T:"));
   lcd.print(myPressure.readTemp());
-  lcd.print(" C");
+  lcd.print(F(" C"));
   delay(5000);

   //Not enough dynamic memory in UNO
@@ -518,18 +516,18 @@
   //delay(2000);

   lcd.clear();
-  lcd.print("R:");
+  lcd.print(F("R:"));
   lcd.print(rainin);
-  lcd.print(" mm/h");
+  lcd.print(F(" mm/h"));
   lcd.setCursor(0, 2);
-  lcd.print("P:");
+  lcd.print(F("P:"));
   lcd.print(myPressure.readPressure()/100.0);
-  lcd.print(" hPa");
+  lcd.print(F(" hPa"));
   delay(5000);

   //Not enough dynamic memory in UNO
   //lcd.clear();
-  //lcd.print("Rain 5min (mm)");
+  //lcd.print(F("Rain 5min (mm)"));
   //lcd.setCursor(0, 2);
   //lcd.print(rainin_5m);
   //delay(2000);
@@ -537,14 +535,14 @@

   //Not enough dynamic memory in UNO
   //lcd.clear();
-  //lcd.print("Battery Level");
+  //lcd.print(F("Battery Level"));
   //lcd.setCursor(0, 2);
   //lcd.print(get_battery_level());
   //delay(2000);

   //Not enough dynamic memory in UNO
   //lcd.clear();
-  //lcd.print("Sunlight");
+  //lcd.print(F("Sunlight"));
   //lcd.setCursor(0, 2);
   //lcd.print(get_light_level());
   //delay(2000);


More floats

More floats

--- seven-segment-float/src/seven-segment-float.ino
+++ seven-segment-float/src/seven-segment-float.ino
@@ -96,7 +96,7 @@
   }

   //testCaseAllNum();
-  splitNumber(.1234);
+  splitNumber(.1111);
 }

 void clearLEDs() {
@@ -154,15 +154,17 @@

   //split whole number portion first (left of decimal)
   //if integral is 0-9
-  if (whole < 10) {
+  if (whole < 1)
+    digitsLeft = 4;
+  else if (whole < 10) {
     splitLeft[0] = whole;
-    digitsLeft = 4;
+    digitsLeft = 3;
   }
   //else if whole is 10-99
   else if (whole < 100) {
     splitLeft[1] = whole / 10;
     splitLeft[0] = whole % 10;
-    digitsLeft = 3;
+    digitsLeft = 2;
   }
   //else if whole is 100-999
   else if (whole < 1000) {
@@ -170,7 +172,7 @@
     whole = whole % 100;
     splitLeft[1] = whole / 10;
     splitLeft[0] = whole % 10;
-    digitsLeft = 2;
+    digitsLeft = 1;
   }
   //else if whole is 1000-9999
   else if (whole < 10000) {
@@ -180,15 +182,15 @@
     whole = whole % 100;
     splitLeft[1] = whole / 10;
     splitLeft[0] = whole % 10;
-    digitsLeft = 1;
-  }
-
-  double decimal = fractional * (pow(10,digitsLeft));
-
+    digitsLeft = 0;
+  }
+
+  int decimal = int(fractional * (pow(10,digitsLeft)));
   Serial.print(whole);
   Serial.print("\t");
-  Serial.print(decimal,4);
+  Serial.print(decimal);
   Serial.print("\n");
+
 /*
   //split decimal number portion next (right of decimal)
   //if decimalToWhole is 0-9


Changed last changed date

Changed last changed date

--- rp6control/rp6control.ino
+++ rp6control/rp6control.ino
@@ -8,7 +8,7 @@

    Made by: Rick van Schijndel
    Creation date: 8-4-2016
-   Last modified: 1-6-2016
+   Last modified: 13-6-2016
 */

 //For the people that downloaded this from github, use the shareddata header.


Added variable turning angle

Added variable turning angle

--- rp6control/rp6control.ino
+++ rp6control/rp6control.ino
@@ -19,12 +19,15 @@
 #include <SoftwareSerial.h>
 #include <Rp6.h>

+#define DEBUG 1
+
 enum class State { Forward, Backward, Left, Right, Startup };
 State state = State::Startup;
 SoftwareSerial Comport(D7, D8);

 int robotSpeed = 0;
-float invertedRotateSpeed = 0; // can be 0 through 1, the higher it is, the slower the robot rotates
+float invertedRotateSpeed = 0; // can be 0 to 1, the higher it is, the slower the robot rotates
+
 // Create an instance of the server
 // specify the port to listen on as an argument
 WiFiServer server(80);
@@ -54,24 +57,24 @@

   Comport.begin(9600);
   // Connect to WiFi network
-  Serial.println();
-  Serial.println();
-  Serial.print("Connecting to ");
-  Serial.println(ssid);
+  DebugPrintln("");
+  DebugPrintln("");
+  DebugPrint("Connecting to ");
+  DebugPrintln(ssid);

   WiFi.begin(ssid, password);

   while (WiFi.status() != WL_CONNECTED)
   {
     delay(500);
-    Serial.print(".");
-  }
-  Serial.println("");
-  Serial.println("WiFi connected");
+    DebugPrint(".");
+  }
+  DebugPrintln("");
+  DebugPrintln("WiFi connected");

   // Start the server
   server.begin();
-  Serial.println("Server started");
+  DebugPrintln("Server started");

   // Print the IP address
   Serial.println(WiFi.localIP());
@@ -83,24 +86,24 @@
 }

 void robotAction() {
-  int leftSpeed = robotSpeed;
-  int rightSpeed = robotSpeed;
   switch (state) {
     case State::Forward:
     case State::Backward:
       // keep it at robotSpeed
+      Rp6.moveAtSpeed(robotSpeed, robotSpeed);
       break;
     case State::Left:
-      leftSpeed *= invertedRotateSpeed;
+      //Rp6.rotate(robotSpeed, RP6_LEFT, 10); // 10 degrees, will this work right?
+      Rp6.moveAtSpeed(robotSpeed * invertedRotateSpeed, robotSpeed);
       break;
     case State::Right:
-      rightSpeed *= invertedRotateSpeed;
+      //Rp6.rotate(robotSpeed, RP6_RIGHT, 10); // same as above
+      Rp6.moveAtSpeed(robotSpeed, robotSpeed * invertedRotateSpeed);
       break;
     default:
-      rightSpeed *= 0;
-      leftSpeed *= 0;
-  }
-  Rp6.moveAtSpeed(leftSpeed, rightSpeed);
+      Rp6.moveAtSpeed(0, 0);
+      break;
+  }
 }

 void connection() {
@@ -111,13 +114,19 @@
         !client[clientCounter].connected())
     {
       client[clientCounter] = server.available();
-      Serial.printf("Client(%d) has connected.\n", clientCounter);
+      //Serial.printf("Client(%d) has connected.\n", clientCounter);
+      DebugPrint("Client(");
+      DebugPrint(String(clientCounter));
+      DebugPrintln(") has connected.");
       connectionlist[clientCounter] = true;
     }
     else
     {
-      Serial.printf("ERROR: Client(%d) still connected.\n", clientCounter);
-      Serial.println("Trying next client.");
+      //Serial.printf("ERROR: Client(%d) still connected.\n", clientCounter);
+      DebugPrint("ERROR: Client(");
+      DebugPrint(String(clientCounter));
+      DebugPrintln(") still connected.");
+      DebugPrintln("Trying next client.");
     }
     clientCounter++;
     clientCounter = clientCounter % clientsize;
@@ -137,7 +146,10 @@
       connectionlist[j] = client[j].connected();
       if (!connectionlist[j])
       {
-        Serial.printf("Client(%d) has disconnected.\n", j);
+        //Serial.printf("Client(%d) has disconnected.\n", j);
+        DebugPrint("Client(");
+        DebugPrint(String(j));
+        DebugPrint(") has disconnected.");
       }
     }
     useCommand(commandline);
@@ -151,7 +163,7 @@
     if (paramcheck > 0) {
       useCommandWithParams(command);
     } else {
-      Serial.println("NACK");
+      DebugPrintln("NACK");
     }
   }
 }
@@ -160,13 +172,15 @@
   int endCommand = command.indexOf(":");
   String beginCommand = command.substring(0, endCommand);
   String parameter = command.substring(endCommand + 1);
-  Serial.println("begincommand:" + beginCommand + ", parameter:" + parameter);
+  DebugPrintln("begincommand:" + beginCommand + ", parameter:" + parameter);

   if (beginCommand == "SPEED") {
     setRobotSpeed(parameter.toInt());
   }
-
-  if (beginCommand == "DIRECTION") {
+  else if (beginCommand == "ANGLE") {
+    setTurningAngle(parameter.toInt());
+  }
+  else if (beginCommand == "DIRECTION") {
     if (parameter == "RIGHT")
     {
       state = State::Right;
@@ -186,8 +200,11 @@
     }
     else
     {
-      Serial.println("NACK");
-    }
+      DebugPrintln("NACK");
+    }
+  }
+  else {
+    DebugPrintln("NACK");
   }
 }

@@ -200,6 +217,32 @@
   } else {
     robotSpeed = 0;
   }
-  Serial.printf("Speed set to %d\n", robotSpeed);
-}
-
+  //Serial.printf("Speed set to %d\n", robotSpeed);
+  DebugPrint("Speed set to ");
+  DebugPrintln(String(robotSpeed));
+}
+
+void setTurningAngle(int angle) {
+  if (angle < 0 || angle > 100) {
+    DebugPrintln("An error occured");
+    return;
+  }
+  double angleDouble = angle;
+  double rotateSpeed = angleDouble / 100;
+  invertedRotateSpeed = 1.0 - rotateSpeed;
+  DebugPrint("InvSpeed:");
+  DebugPrintln(String(invertedRotateSpeed));
+}
+
+void DebugPrint(String message) {
+#if DEBUG
+  Serial.print(message);
+#endif
+}
+
+void DebugPrintln(String message) {
+#if DEBUG
+  Serial.println(message);
+#endif
+}
+


Fix wrong constants

Fix wrong constants

--- examples/esp8266/esp8266.ino
+++ examples/esp8266/esp8266.ino
@@ -78,7 +78,7 @@
   device.connectSecure(wifiClient, LOSANT_ACCESS_KEY, LOSANT_ACCESS_SECRET);

   // For an unsecure connection.
-  // device.connect(wifiClient, ACCESS_KEY, ACCESS_SECRET);
+  // device.connect(wifiClient, LOSANT_ACCESS_KEY, LOSANT_ACCESS_SECRET);

   while(!device.connected()) {
     delay(500);


Bumped version to 0.7 for s/w contrast/brightness control

--- DigitalVFO.ino
+++ DigitalVFO.ino
@@ -20,7 +20,7 @@

 // Digital VFO program name & version
 const char *ProgramName = "DigitalVFO";
-const char *Version = "0.6";
+const char *Version = "0.7";
 const char *Callsign = "vk4fawr";
 const char *Callsign16 = "vk4fawr         ";

@@ -43,6 +43,9 @@
 const int re_pinA = 2;     // encoder A pin
 const int re_pinB = 3;     // encoder B pin
 const int re_pinPush = 4;  // encoder pushbutton pin
+
+// define Teensy pin controlling contrast
+const byte mc_Contrast = 6;

 // max and min frequency showable
 #define MAX_FREQ        30000000L
@@ -749,6 +752,10 @@
   lcd.noCursor();
   lcd.createChar(SPACE_CHAR, sel_digits[SPACE_INDEX]);

+  // initialize contrast control
+  pinMode(mc_Contrast, OUTPUT);
+  analogWrite(mc_Contrast, 75);
+
   // get state back from EEPROM
   restore_from_eeprom();

@@ -784,7 +791,7 @@
 // Define the menus to be used, plus handler code
 //-----

-const char *menu_items[] = {"Save slot", "Restore slot", "Delete slot"};
+const char *menu_items[] = {"Save slot", "Restore slot", "Delete slot", "Settings"};
 #define NumMainMenuItems (sizeof(menu_items)/sizeof(const char *))

 Menu main_menu = {"Menu", menu_display, menu_select,
@@ -798,6 +805,12 @@

 Menu delete_menu = {menu_items[2], savresdel_display, delete_select,
                     NumSaveSlots, NULL};
+
+//const char *settings_items[] = {"Contrast"};
+//#define NumSettingsMenuItems (sizeof(settings_items)/sizeof(const char *))
+//
+//Menu settings_menu = {menu_items[3], settings_display, settings_select,
+//                      NumSettingsMenuItems, settings_items};

 void menu_display(Menu *menu, int slot_num)


Still fiddling with menu code

Still fiddling with menu code

--- DigitalVFO.ino
+++ DigitalVFO.ino
@@ -15,18 +15,25 @@
 #include <EEPROM.h>

-#define DEBUG   // define if debugging
+//#define DEBUG   // define if debugging

 // Digital VFO program name & version
 const char *ProgramName = "Digital VFO";
-const char *Version = "0.2";
+const char *Version = "0.3";
 const char *Callsign = "vk4fawr";
 const char *Callsign16 = "vk4fawr         ";

 // display constants - below is for ubiquitous small HD44780 16x2 display
 #define NUM_ROWS        2
 #define NUM_COLS        16
+
+// define one row of blanks
+const char *BlankRow = "                ";
+// check it has the right length
+//#if sizeof(BlankRow) <> NUM_COLS
+//  #error "BlankRow not defined correctly?"
+//#endif

 // define data pins we connect to the LCD
 const byte lcd_RS = 7;
@@ -137,7 +144,6 @@
   }
 }

-#ifdef DEBUG
 //----------------------------------------------------------
 // Convert an event number to a display string
 //----------------------------------------------------------
@@ -156,7 +162,6 @@
     default:            return "UNKNOWN!";
   }
 }
-#endif

 // display a simple banner
 void banner(void)
@@ -186,6 +191,89 @@

   delay(500);
 }
+
+
+////////////////////////////////////////////////////////////////////////////////
+// Code to handle the menus.
+////////////////////////////////////////////////////////////////////////////////
+
+typedef void (*MenuDisplay)(Menu *menu, int slot_num);
+typedef void (*MenuAction)(Menu *menu, int slot_num);
+
+struct Menu
+{
+  const char *title;
+  MenuDisplay display;
+  MenuAction action;
+  int num_items;
+  const char **items;
+};
+
+void show_menu(struct Menu *menu)
+{
+  int item_index = 0;
+
+  Serial.print("show_menu("); Serial.print(menu->title); Serial.println(")");
+
+  lcd.clear();
+  lcd.setCursor(0, 0);
+  lcd.write(menu->title);
+  menu->display(menu, item_index);
+
+  while (true)
+  {
+    if (queue_len() > 0)
+    {
+      // get next event and handle it
+      byte event = pop_event();
+      Serial.print("show_menu: popped event "); Serial.println(event2display(event));
+
+      switch (event)
+      {
+        case vfo_RLeft:
+          Serial.println("Menu: vfo_RLeft");
+          --item_index;
+          if (item_index < 0)
+            item_index = 0;
+          break;
+        case vfo_RRight:
+          Serial.print("Menu: vfo_RRight, menu->num_items="); Serial.println(menu->num_items);
+          ++item_index;
+          if (item_index >= menu->num_items)
+            item_index = menu->num_items - 1;
+          Serial.print("Menu: vfo_RRight, new item_index="); Serial.println(item_index);
+          break;
+        case vfo_DnRLeft:
+          Serial.println("Menu: vfo_DnRLeft");
+          break;
+        case vfo_DnRRight:
+          Serial.println("Menu: vfo_DnRRight");
+          break;
+        case vfo_Click:
+          Serial.println("Menu: vfo_Click");
+          if (menu->action)
+            (*menu->action)(menu, item_index);
+          break;
+        case vfo_HoldClick:
+          Serial.println("Menu: vfo_HoldClick, exit menu");
+          flush_queue();
+          return;
+        default:
+          Serial.print("Menu: unrecognized event "); Serial.println(event);
+          break;
+      }
+
+      // update the item display
+      Serial.print("Calling menu->display: menu->title=");
+      Serial.print(menu->title);
+      Serial.print(", item_index=");
+      Serial.println(item_index);
+      menu->display(menu, item_index);
+    }
+  }
+}
+
+
 ////////////////////////////////////////////////////////////////////////////////
 // The system event queue.
 // Implemented as a circular buffer.
@@ -359,7 +447,7 @@
 ////////////////////////////////////////////////////////////////////////////////

 // time when click becomes a "hold click" (milliseconds)
-#define HoldClickTime 1000
+#define HoldClickTime 700

 // internal variables
 bool re_rotation = false;       // true if rotation occurred while knob down
@@ -378,13 +466,9 @@

 void re_setup(int position)
 {
-  // set pinA as an input, pulled HIGH to the logic voltage (5V or 3.3V for most cases)
+  // set RE data pins as pullup inputs
   pinMode(re_pinA, INPUT_PULLUP);
-
-  // set pinB as an input, pulled HIGH to the logic voltage (5V or 3.3V for most cases)
   pinMode(re_pinB, INPUT_PULLUP);
-
-  // set pinPush as an input, pulled HIGH to the logic voltage (5V or 3.3V for most cases)
   pinMode(re_pinPush, INPUT_PULLUP);

   // attach pins to IST on rising edge only
@@ -489,6 +573,10 @@
 // address for int 'selected digit'
 const int AddressSelDigit = AddressFreq + sizeof(AddressFreq);

+// number of frequency save slots in EEPROM
+const int NumSaveSlots = 10;
+const int SaveSlotBase = AddressSelDigit + sizeof(AddressSelDigit);
+

 // save VFO state to EEPROM
 void save_to_eeprom(void)
@@ -506,69 +594,6 @@

 ////////////////////////////////////////////////////////////////////////////////
-// Code to handle the menus.
-////////////////////////////////////////////////////////////////////////////////
-
-typedef void (*MenuDisplay)(int slot_num);
-typedef void (*MenuAction)(int slot_num);
-
-struct Menu
-{
-  const char *title;
-  int num_items;
-  MenuDisplay display;
-  MenuAction action;
-  const char **items;
-};
-
-void show_menu(struct Menu *menu)
-{
-  Serial.print("show_menu("); Serial.print(menu->title); Serial.println(")");
-
-  lcd.clear();
-  lcd.setCursor(0, 0);
-  lcd.write(menu->title);
-  menu->display(0);
-
-  while (true)
-  {
-    if (queue_len() > 0)
-    {
-      // get next event and handle it
-      byte event = pop_event();
-      Serial.print("show_menu: popped event "); Serial.println(event2display(event));
-
-      switch (event)
-      {
-        case vfo_RLeft:
-          Serial.println("Menu: vfo_RLeft");
-          continue;
-        case vfo_RRight:
-          Serial.println("Menu: vfo_RRight");
-          continue;
-        case vfo_DnRLeft:
-          Serial.println("Menu: vfo_DnRLeft");
-          continue;
-        case vfo_DnRRight:
-          Serial.println("Menu: vfo_DnRRight");
-          continue;
-        case vfo_Click:
-          Serial.println("Menu: vfo_Click");
-          continue;
-        case vfo_HoldClick:
-          Serial.println("Menu: vfo_HoldClick, exit menu");
-          flush_queue();
-          return;
-        default:
-          Serial.print("Menu: unrecognized event "); Serial.println(event);
-          continue;
-      }
-    }
-  }
-}
-
-
-////////////////////////////////////////////////////////////////////////////////
 // Code to handle the DDS-60
 ////////////////////////////////////////////////////////////////////////////////

@@ -585,6 +610,17 @@
 //----------------------------------------------------------
 // The standard Arduino setup() function.
 //----------------------------------------------------------
+
+void zero_save_slots(void)
+{
+  for (int i = 0; i < NumSaveSlots; ++i)
+  {
+    int address = SaveSlotBase + i * sizeof(unsigned long);
+    EEPROM.put(address, 0L);
+    Serial.print("Zeroing address "); Serial.println(address);
+  }
+  Serial.println("End of zero_save_slots()");
+}

 void setup(void)
 {
@@ -597,12 +633,16 @@
   lcd.createChar(SPACE_CHAR, sel_digits[SPACE_INDEX]);

   restore_from_eeprom();
+//  zero_save_slots();
+//  Serial.println("After zero_save_slots()");

   // set up the rotary encoder
   re_setup(VfoSelectDigit);

   // show program name and version number
+#ifndef DEBUG
   banner();
+#endif

   // get going
   show_main_screen();
@@ -614,22 +654,116 @@
   print_freq(VfoFrequency, VfoSelectDigit, 0);
 }

+//-----
+// Define the menus to be used, plus handler code
+//-----
+
+const char *main_menu_items[2] = {"Save", "Restore"};
+#define NumMainMenuItems (sizeof(main_menu_items)/sizeof(const char *))
+
+Menu main_menu = {"Menu", menu_item_display, menu_item_action,
+                  NumMainMenuItems, main_menu_items};
+
+Menu save_menu = {"Save", save_restore_item_display, save_item_action,
+                  NumSaveSlots, NULL};
+
+Menu restore_menu = {"Restore", save_restore_item_display, restore_item_action,
+                     NumSaveSlots, NULL};
+
+
+void menu_item_display(Menu *menu, int slot_num)
+{
+  Serial.print("menu_item_display: menu="); Serial.println(menu->title);
+  Serial.print("menu_item_display: slot_num="); Serial.println(slot_num);
+
+  // figure out max length of item strings
+  int max_len = 0;
+  Serial.print("menu->num_items="); Serial.println(menu->num_items);
+  for (int i = 0; i < menu->num_items; ++ i)
+  {
+    int new_len = strlen(menu->items[i]);
+
+    if (new_len > max_len)
+        max_len = new_len;
+    Serial.print("i="); Serial.print(i);
+    Serial.print(", new_len="); Serial.print(new_len);
+    Serial.print(", max_len="); Serial.println(max_len);
+  }
+  Serial.print("Max item len="); Serial.println(max_len);
+
+  // write indexed item on lower row, right-justified
+  lcd.setCursor(0, 1);
+  lcd.write(BlankRow);
+  Serial.print("Setting cursor to column "); Serial.println(NUM_COLS - max_len);
+  Serial.print("item text="); Serial.println(menu->items[slot_num]);
+  lcd.setCursor(NUM_COLS - max_len, 1);
+  lcd.write(menu->items[slot_num]);
+}
+
+void menu_item_action(Menu *menu, int slot_num)
+{
+  Serial.print("menu_item_action: slot_num="); Serial.println(slot_num);
+  const char *action_text = menu->items[slot_num];
+
+  if (strcmp(action_text, "Save") == 0)
+  {
+      show_menu(&save_menu);
+  }
+  else if (strcmp(action_text, "Restore") == 0)
+  {
+      show_menu(&restore_menu);
+  }
+}
+
+void save_restore_item_display(Menu *menu, int slot_num)
+{
+  // display data for save frequency slot
+  Serial.print("save_restore_item_display: menu="); Serial.println(menu->title);
+  Serial.print("save_restore_item_display: slot_num="); Serial.println(slot_num);
+
+  // max length of item strings is "0: xxxxxxxxHz"
+  const int max_len = 13;
+  char buf[MAX_FREQ_CHARS + 1];
+  int address = SaveSlotBase + slot_num * sizeof(unsigned long);
+  unsigned long freq;
+
+  // get saved frequency, convert to a display buffer
+  EEPROM.get(address, freq);
+  Serial.print("save_restore_item_display: freq="); Serial.println(freq);
+  ltobbuff(buf, MAX_FREQ_CHARS, freq);
+  buf[MAX_FREQ_CHARS] = 0;
+  Serial.print("save_restore_item_display: buf="); Serial.write(buf, MAX_FREQ_CHARS);
+  Serial.println("");
+
+  // write indexed item on lower row, right-justified
+  lcd.setCursor(0, 1);
+  lcd.write(BlankRow);
+  lcd.setCursor(NUM_COLS - max_len, 1);
+  lcd.write(slot_num + '0');
+  lcd.write(": ");
+  lcd.write(buf);
+  lcd.write("Hz");
+}
+
+void save_item_action(Menu *menu, int slot_num)
+{
+  int address = SaveSlotBase + slot_num * sizeof(unsigned long);
+
+  Serial.print("save_item_action: saving Frequency "); Serial.print(VfoFrequency);
+  Serial.print(" to slot "); Serial.print(slot_num);
+  Serial.print("="); Serial.println(address);
+
+  EEPROM.put(address, VfoFrequency);
+}
+
+void restore_item_action(Menu *menu, int slot_num)
+{
+  Serial.print("restore_item_action: slot_num="); Serial.println(slot_num);
+}
+
 //----------------------------------------------------------
 // Standard Arduino loop() function.
 //----------------------------------------------------------
-
-void item_display(int slot_num)
-{
-  Serial.print("item_display: slot_num="); Serial.println(slot_num);
-}
-
-void item_action(int slot_num)
-{
-  Serial.print("item_action: slot_num="); Serial.println(slot_num);
-}
-
-const char *main_menu_items[2] = {"Save", "Restore"};
-Menu main_menu = {"Menu", 2, item_display, item_action, main_menu_items};

 void loop(void)
 {


Adding motion sensor

Adding motion sensor

--- wellnessmirror/wellnessmirror.ino
+++ wellnessmirror/wellnessmirror.ino
@@ -4,7 +4,8 @@
 #include <Bridge.h>
 #include <HttpClient.h>
 #include <math.h>
-
+#define PIN 6
+int pirState = LOW;
 #define TIMECTL_MAXTICKS  4294967295L
 #define TIMECTL_INIT      0
 long time;
@@ -27,6 +28,8 @@
 int r = 0;
 int g = 0;
 int b = 255;
+int hasMotion = LOW;
+int wasEnabled = false;
 Adafruit_NeoPixel strip = Adafruit_NeoPixel(102, 6, NEO_GRB + NEO_KHZ800);

 void setup() {
@@ -59,10 +62,16 @@
   r = atoi(rChar);
   g = atoi(gChar);
   b = atoi(bChar);
-
-  if(atoi(mode) == 1) activities();
-  else setColorAndPattern(r, g, b, atoi(pattern));
-
+  if(checkMotionDetection()){
+    if(atoi(mode) == 1) activities();
+    else setColorAndPattern(r, g, b, atoi(pattern));
+  }
+  if(waitTime(&flashTimeMark2, 60000)){
+    hasMotion = digitalRead(10);
+    if(hasMotion == LOW){
+       wasEnabled = false;
+    }
+  }
 }

 void setColorAndPattern(int r, int g, int b, int pattern){
@@ -115,6 +124,16 @@
   }
 }

+int checkMotionDetection(){
+   if(waitTime(&flashTimeMark, 1000)){
+     hasMotion = digitalRead(10);
+     if (hasMotion == HIGH) {
+        wasEnabled = true;
+        return wasEnabled;
+     }
+   }
+   return wasEnabled;
+}
 void off(int r, int g, int b){
   tintPixels(r, g, b, 0);
 }
@@ -168,6 +187,7 @@
     }
   }
 }
+
 void ideal(int r, int g, int b){
   tintPixels(r,g,b,100);
   if(waitTime(&flashTimeMark, 3000)){
@@ -192,7 +212,6 @@
   }
   strip.show();
 }
-

 float linearTween (float t, float b, float c, float d) {
   return c*t/d + b;


- moved config to top (except accel profile) - defined statusLED - debug & cleanup

--- GeheimTuer.ino
+++ GeheimTuer.ino
@@ -1,11 +1,38 @@
 #include <WS2812.h>
+
+/* config */

 // MAXPIX+EXTRAPIX must fit into uint8_t
 #define MAXPIX 20  // LED stripe length
 #define EXTRAPIX 3 // animation buffer, read window moves back and forth EXTRAPIX pixels

-// WS2812 output
+// on-board status LED
+const int statusLED = 13;
+
+// WS2812 data
 const int ledPin = 11;
+
+// I/O connections to bridge driver module
+// https://www.olimex.com/Products/RobotParts/MotorDrivers/BB-VNH3SP30/
+// https://www.olimex.com/Products/RobotParts/MotorDrivers/BB-VNH3SP30/resources/BB-VNH3SP30_schematic.pdf
+const int motorDiagAPin = 5;
+const int motorDiagBPin = 6;
+const int motorInAPin = 7;
+const int motorInBPin = 8;
+const int motorPWMPin = 9;
+
+// switch inputs, active-low
+const int switchFront = 3; // front is at the closed position
+const int switchFrontIRQ = 1; // TODO: maybe use interrupts & sleep
+
+const int switchBack = 4;
+
+// wire-ORed buttons, active-low
+const int switchTrigger = 2;
+const int switchTriggerIRQ = 0;
+
+
+/* WS2812 LEDs */

 cRGB leds[MAXPIX+EXTRAPIX];
 cRGB tmp_leds[MAXPIX]; // temp array for fading and blinking
@@ -29,6 +56,7 @@
 const cRGB white = {g: 0x1F, r: 0x1F, b: 0x1F};
 const cRGB red = {g: 0x00, r: 0x1F, b: 0x00};
 const cRGB green = {g: 0x1F, r: 0x00, b: 0x00};
+const cRGB yellow = {g: 0x1F, r: 0x1F, b: 0x00};
 const cRGB blue = {g: 0x00, r: 0x00, b: 0x1F};

 // macro instead of inline function. TODO: compare generated code again
@@ -52,18 +80,11 @@
 }

+/* motor driver */
+
 // global motor direction variable, required for PWM-brake & coasting
 // TODO: PWM-brake is never used, maybe refactor & remove
 enum motorDir { forward, backward } motorDir;
-
-// I/O connections to bridge driver module
-// https://www.olimex.com/Products/RobotParts/MotorDrivers/BB-VNH3SP30/
-// https://www.olimex.com/Products/RobotParts/MotorDrivers/BB-VNH3SP30/resources/BB-VNH3SP30_schematic.pdf
-const int motorDiagAPin = 5;
-const int motorDiagBPin = 6;
-const int motorInAPin = 7;
-const int motorInBPin = 8;
-const int motorPWMPin = 9;

 // ad-hoc acceleration profile
 // TODO: self-calibration by means of driveTotalMillis
@@ -178,18 +199,8 @@
 const struct accelProfile *accelProfile; // pointer to current profile
 int accelProfileIdx = 0;

-// switch inputs, active-low
-const int switchFront = 3; // front is at the closed position
-const int switchFrontIRQ = 1; // TODO: maybe use interrupts & sleep
-
-const int switchBack = 4;
-
-// wire-ORed buttons, active-low
-const int switchTrigger = 2;
-const int switchTriggerIRQ = 0;
-
-
-// unsorted variables below. TODO: refactor & cleanup
+
+/* unsorted variables below. TODO: refactor & cleanup */

 // buttons & switches do different things in different states
 enum doorStates { doorClosed, doorOpening, doorOpen, doorClosing, doorBlocked, doorError } doorState;
@@ -225,6 +236,9 @@

 void setup() {
+  pinMode(statusLED, OUTPUT);
+  digitalWrite(statusLED, HIGH);
+
   Serial.begin(115200);
   Serial.print(F("\r\nDoor control init\r\n"));

@@ -294,12 +308,10 @@
     setLeds1(red, ledBlink);
   }

-// TODO: on-board status LEDs, independent of ws2812
-digitalWrite(13, LOW);
-pinMode(13, OUTPUT);
-
 //  attachInterrupt(switchFrontIRQ, switchFrontInterrupt, CHANGE);
 //  attachInterrupt(switchTriggerIRQ, switchTriggerInterrupt, FALLING);
+
+  digitalWrite(statusLED, LOW);
 }

 void loop() {
@@ -373,6 +385,13 @@
       motorEnable();
       doorState = doorBlocked;
       break;
+    case 'k': {
+      const cRGB white255 = {g: 0xFF, r: 0xFF, b: 0xFF};
+      setLeds1(white255, ledSolid);
+      break; }
+    case 'K':
+      setLeds1(black, ledSolid);
+      break;
   }
 }

@@ -391,7 +410,7 @@
           initDrive(backward, accelProfileHigh);
           swTrigger = HIGH; // re-arm swTrigger
         }
-        setLeds2(white, black, 3, ledBackward);
+        setLeds2(white, black, EXTRAPIX, ledBackward);
         doorState = doorOpening;
       }
       break;
@@ -418,7 +437,7 @@
           debug(currentMillis, F("openInterval timeout - closing door\r\n"));
           initDrive(forward, accelProfileHigh);
         }
-        setLeds2(white, black, 3, ledForward);
+        setLeds2(white, black, EXTRAPIX, ledForward);
         doorState = doorClosing;
       }
       break;
@@ -533,7 +552,7 @@
           ledMode = ledBackward;
           doorState = doorOpening;
         }
-        setLeds2(white, black, 3, ledMode);
+        setLeds2(white, black, EXTRAPIX, ledMode);
         swTrigger = HIGH;
       }
       break;
@@ -546,9 +565,9 @@
 if (motorDiagA == HIGH && motorDiagB == HIGH) {
   setLeds1(red, ledSolid);
   doorState = doorBlocked;
-  digitalWrite(13, LOW);
+  digitalWrite(statusLED, LOW);
 } else {
-  digitalWrite(13, HIGH);
+  digitalWrite(statusLED, HIGH);
 }
       break;
   }
@@ -778,7 +797,7 @@
  * PWM frequency divisors. His post can be viewed at:
  *   http://forum.arduino.cc/index.php?topic=16612#msg121031
  */
-void setPwmFrequency(int pin, int divisor) {
+void setPwmFrequency(const int pin, const int divisor) {
   byte mode;
   if(pin == 5 || pin == 6 || pin == 9 || pin == 10) {
     switch(divisor) {


Update Solar-Weather-Station-V2.0-wifi_mgr.ino

--- Weather_Station/Solar-Weather-Station-V2.0-wifi_mgr.ino
+++ Weather_Station/Solar-Weather-Station-V2.0-wifi_mgr.ino
@@ -25,6 +25,7 @@
 8. v2.3 Add Double Reset Detector - to detect double press on reset button and wipe the wifi settings
 9. v2.4 Define wake up interval - to save battery, default 10 mins, during wifi setup
 10. v2.5 replace DoubleResetDetector with ESP_DoubleResetDetector (bug randomly caused wifi settings disappeared)
+11. v.2.51 remove doubleresetdetector, caused unknown problem

 Todo
 * Option to specify option to enable (Y/N) DHT22, UV sensor during wifi setup
@@ -42,9 +43,9 @@
 #include <BlynkSimpleEsp8266.h>

 //#include <DoubleResetDetector.h>   //<<-- got bug, auto wipe of wifi manager settings happened
-#define ESP_DRD_USE_LITTLEFS    true    //false
-#define DOUBLERESETDETECTOR_DEBUG       true  //false
-#include <ESP_DoubleResetDetector.h>
+//#define ESP_DRD_USE_LITTLEFS    true    //false
+//#define DOUBLERESETDETECTOR_DEBUG       true  //false
+//#include <ESP_DoubleResetDetector.h>

 // configuration constants
 const bool bme280Debug = 0; // controls serial printing
@@ -108,12 +109,12 @@

 // Number of seconds after reset during which a
 // subseqent reset will be considered a double reset.
-#define DRD_TIMEOUT 10
+//#define DRD_TIMEOUT 10

 // RTC Memory Address for the DoubleResetDetector to use
-#define DRD_ADDRESS 0
-
-DoubleResetDetector* drd;
+//#define DRD_ADDRESS 0
+
+//DoubleResetDetector* drd;

 //callback notifying us of the need to save config
 void saveConfigCallback () {
@@ -148,8 +149,11 @@
   //  saveCounter(eventCounter);         // this also puts bme0 to sleep
   bme0.updateF4Control16xSleep(); // use instead of saveCounter if counter is not required

+  // Call the double reset detector loop method every so often,
+  // so that it can recognise when the timeout expires.
   // You can also call drd.stop() when you wish to no longer
-  drd->loop();
+  // consider the next reset as a double reset.
+//  drd->loop();

   goToSleep();
 } // end of void setup()
@@ -217,18 +221,18 @@
   //Local intialization. Once its business is done, there is no need to keep it around
   WiFiManager wifiManager;

-  drd = new DoubleResetDetector(DRD_TIMEOUT, DRD_ADDRESS);
-  if (drd->detectDoubleReset())
-  {
-    Serial.println("Double Reset Detected");
-    wifiManager.resetSettings();
-    ESP.reset();
-    delay(1000);
-  }
-  else
-  {
-    Serial.println("No Double Reset Detected");
-  }
+//  drd = new DoubleResetDetector(DRD_TIMEOUT, DRD_ADDRESS);
+//  if (drd->detectDoubleReset())
+//  {
+//    Serial.println("Double Reset Detected");
+//    wifiManager.resetSettings();
+//    ESP.reset();
+//    delay(1000);
+//  }
+//  else
+//  {
+//    Serial.println("No Double Reset Detected");
+//  }

   //set config save notify callback
   wifiManager.setSaveConfigCallback(saveConfigCallback);
@@ -245,9 +249,9 @@
   wifiManager.setConfigPortalTimeout(60);

   if (!wifiManager.autoConnect("Weather Station", "configme")) {
-    Serial.println("failed to connect and hit timeout");
-    ESP.deepSleep(Sleep_Time * 60 * 1000000); //deepSleep is microseconds 1 sec = 1000000
-    delay(100);
+    Serial.println("failed to connect to Wifi, AP mode started");
+//    drd->loop(); //don't trigger double press reset
+    goToSleep();
 //    ESP.reset();
 //    delay(1000);
   }
@@ -309,6 +313,7 @@
         Serial.println("Blynk Connection Fail");
         //needs testing on whether this line should be commented out:
         //wifiManager.resetSettings();
+//        drd->loop(); //don't trigger double press reset
         ESP.reset();
         delay (100);
       }
@@ -319,6 +324,7 @@
       //Connect to blynk using an already-open internet connection and preset configuration
       if(!Blynk.connect()) {
         Serial.println("Blynk connection timed out.");
+//        drd->loop(); //don't trigger double press reset
         ESP.reset();
         delay (100);
       }


Updated

Updated

Updated but it isn't deployed.

--- learning_mode/Proyecto.ino
+++ learning_mode/Proyecto.ino
@@ -8,6 +8,8 @@

 int nobodyGotIt = 999;
 int steps[8] = {8,4,2,1,5,3,7,6};
+int stepNumber;
+boolean finished = false;

 void setup() {

@@ -19,14 +21,21 @@
   for(int i = 0 ; i < sizeof(LEDS) ; i++){
     pinMode(LEDS[i], OUTPUT);
   }
+
+  stepNumber = 0;

 }

 void loop() {

+  digitalWrite(LEDS[stepNumber], 1);
   uint8_t whoGotTheP = getPressedButtonID();
+
   letTheLEDWakeUp(whoGotTheP);
+  if(finished){
+    learnFinishedAnimation();
+  }

 }

@@ -40,19 +49,46 @@
       return i;
     }
   }
-
   return nobodyGotIt;
-

 }

 void letTheLEDWakeUp(int pint){

-  if(pint != nobodyGotIt){
-    digitalWrite(LEDS[pint], !digitalRead(LEDS[pint]));
+  if(LEDS[pint] == steps[stepNumber]){
+
+    digitalWrite(LEDS[stepNumber], 0);
+    if(stepNumber == sizeof(steps)){
+      finished = true
+
+    }else{
+      stepNumber++;
+      digitalWrite(LEDS[stepNumber], 1);
+
+    }
+
+
+  }else{
+
+    digitalWrite(LEDS[stepNumber], 0);
+    delay(250);
+    digitalWrite(LEDS[stepNumber], 1);
+    delay(250);
+    digitalWrite(LEDS[stepNumber], 0);
+    delay(250);
+    digitalWrite(LEDS[stepNumber], 1);
+    delay(100);
   }

 }

+void learnFinishedAnimation(){
+  for(int i = 0 ; i < (sizeof(LEDS) - 1) ; i++){
+    digitalWrite(LEDS[i], 1);
+    delay(200);
+    digitalWrite(LEDS[i], 0);
+  }
+}

+


TimeAlarms example refined

TimeAlarms example refined

--- b_TimeAlarms.ino
+++ b_TimeAlarms.ino
@@ -4,31 +4,16 @@

 boolean setupTimeAlarmsIsCalled = false; // to avoid setupTimeAlarms() to be called twice.

-void AddMinutes(int *h, int *m, int x)
-{
-  *m += x;
-  if (*m >= 60) {
-    *h += *m / 60; *m %= 60;
-    *h %= 24;
-  }
-}
-
 void exampleAlarm()
 {
-  int h, m;
-  queueIn(F("@")); // power on
-  h = hour(); m = minute();
-  AddMinutes(&h, &m, 1);
-  Alarm.alarmOnce(h, m, 0, alarmStart);
+  queueIn(F("@"));
+  Alarm.timerOnce(30, alarmStart); // 30 seconds delay for start up
 }

 void alarmStart()
 {
-  int h, m;
   startRecording();
-  h = hour(); m = minute();
-  AddMinutes(&h, &m, 1);
-  Alarm.alarmOnce(h, m, 0, alarmStop);
+  Alarm.timerOnce(60, alarmStop); // take video for 1 minutes
 }

 void alarmStop()
@@ -48,24 +33,18 @@

 void setupTimeAlarms()
 {
-  if (!setupTimeAlarmsIsCalled) {
-    int h, m;
+  if (!setupTimeAlarmsIsCalled) {
+    time_t t;
     setupTimeAlarmsIsCalled = true;
     __debug(F("Time alarms set"));
-    // current time := hh:mm:xx
-    // 1. power on hh:mm+1:30; start hh:mm+2:00; stop hh:mm+3:00; off hh:mm+3:05;
-    // 2. power on hh:mm+3:30; start hh:mm+4:00; stop hh:mm+5:00; off hh:mm+5:05;
-    // 3. power on hh:mm+5:30; start hh:mm+6:00; stop hh:mm+7:00; off hh:mm+7:05;
-    // 4. power on hh:mm+7:30; start hh:mm+8:00; stop hh:mm+9:00; off hh:mm+9:05;
-    h = hour(); m = minute();
-    AddMinutes(&h, &m, 1);
-    Alarm.alarmRepeat(h, m, 30, exampleAlarm);
-    AddMinutes(&h, &m, 2);
-    Alarm.alarmRepeat(h, m, 30, exampleAlarm);
-    AddMinutes(&h, &m, 2);
-    Alarm.alarmRepeat(h, m, 30, exampleAlarm);
-    AddMinutes(&h, &m, 2);
-    Alarm.alarmRepeat(h, m, 30, exampleAlarm);
+    // X = current time
+    //   1. power on X + 60s; start X + 90s; stop X + 150s; off X + 155s;
+    //   2. power on X + 180s; start X + 210s; stop X + 270s; off X + 275s;
+    // and repeat 1, 2 everyday.
+    t = now() + 60;
+    Alarm.alarmRepeat(hour(t), minute(t), second(t), exampleAlarm);
+    t += 120;
+    Alarm.alarmRepeat(hour(t), minute(t), second(t), exampleAlarm);
     // suspend for now
     //alarmSuspend();
   }


hotfix

hotfix

--- sketchbook/printer/printer.ino
+++ sketchbook/printer/printer.ino
@@ -133,12 +133,12 @@
                 break;
             case '=': // lazy
             case '+': // head on
-                head.write(90);
+                head.write(100);
                 delay(250);
                 Serial.write("ok.\n");
                 break;
             case '-': // head off
-                head.write(130);
+                head.write(140);
                 delay(250);
                 Serial.write("ok.\n");
                 break;


Forgot predeclaration

Forgot predeclaration

--- firefighter/firefighter.ino
+++ firefighter/firefighter.ino
@@ -60,6 +60,7 @@
 double getPercentError(double actual, double target);
 void turnToAngle(double targetAngle, double speed);
 void naviguessMaze(double swagSpeed);
+void driveToDistance(double targetDistance, double speed);

 // Encoder commands
 void countPulseRight();


Added more verbose comments to ControlLED demo

--- examples/ControlLED/ControlLED.ino
+++ examples/ControlLED/ControlLED.ino
@@ -24,6 +24,8 @@
 const int lineRed = DEFAULT_TIP;
 const int lineWhite = DEFAULT_RING;

+// Specify the number of LEDs to control, and to which
+// digital pin each LED is attached.
 #if defined(__MSP432P401R__)		// MSP432 target
 #define LED_PIN_COUNT 4
 const int ledPins[LED_PIN_COUNT] = {78, 75, 76, 77};
@@ -32,24 +34,39 @@
 const int ledPins[LED_PIN_COUNT] = {8, 9, 10, 13};
 #endif

+// Lists are 2 + (9 * dimension) bytes,
+// so incidentally a 255-byte max data length
+// limits this demo's lists to 28 elements.
 #define MAXDATALEN 255
+
 uint8_t header[16];
 uint8_t data[MAXDATALEN];

+// Run once when the Arduino resets. This first sets
+// the LED pins to OUTPUT, then initializes a new CBL2
+// instance. This is responsible for dealing with the
+// actual calculator<->Arduino message exchange.
 void setup() {
   for(int i = 0; i < LED_PIN_COUNT; i++) {
     pinMode(ledPins[i], OUTPUT);
 	digitalWrite(ledPins[i], LOW);
   }

-  Serial.begin(9600);
+  Serial.begin(9600);                           // Used for debugging
   cbl = new CBL2(lineRed, lineWhite);
   cbl->resetLines();
-  // cbl->setVerbosity(true, &Serial);			// Comment this in for mesage information
+  // cbl->setVerbosity(true, &Serial);			// Comment this in for verbose message information
+
+  // The following registers buffers for exchanging data, the maximum
+  // allowed data length, and functions to call on Get() and Send().
   cbl->setupCallbacks(header, data, MAXDATALEN,
                       onGetAsCBL2, onSendAsCBL2);
 }

+// Repeatedly check to see if the calculator has initiated a Get()
+// or a Send() operation yet. If it has, then onGetAsCBL2() or
+// onSendAsCBL2() will be invoked, since they were registered in
+// setup() above.
 void loop() {
   int rval;
   rval = cbl->eventLoopTick();
@@ -59,20 +76,23 @@
   }
 }

+// Callback when the CBL2 class has successfully received a variable
+// from the attached calculator.
 int onGetAsCBL2(uint8_t type, enum Endpoint model, int datalen) {
   Serial.print("Got variable of type ");
   Serial.print(type);
   Serial.print(" from endpoint of type ");
   Serial.println((int)model);

+  // We only want to handle lists.
   if (type != VarTypes82::VarRList)
     return -1;

   // Turn the LEDs on or off
   uint16_t list_len = sizeWordToInt(&(data[0]));			// Convert 2-byte size word to int
   if (list_len == 1) {
-    // It is a 1-element list now
-	int value = (int)TIVar::realToFloat8x(&data[2], model);	// First list element starts here
+    // It is indeed a 1-element list
+	int value = (int)TIVar::realToFloat8x(&data[2], model);	// First list element starts after 2-byte size word
     Serial.print("Received value ");
     Serial.println(value);
     for(int i = 0; i < LED_PIN_COUNT; i++) {
@@ -84,6 +104,9 @@
   return 0;
 }

+// Callback when the CBL2 class notices the attached calculator
+// wants to start a Get() exchange. The CBL2 class needs to get
+// any data to send before continuing the exchange.
 int onSendAsCBL2(uint8_t type, enum Endpoint model, int* headerlen,
                  int* datalen, data_callback* data_callback)
 {
@@ -91,5 +114,5 @@
   Serial.print(type);
   Serial.print(" from endpoint of type ");
   Serial.println((int)model);
-  return -1;
+  return -1;		// -1 means we have no data to send.
 }


ADD:rest function so that marionette does not jerk back to rest position

--- serialmovements/serialmovements.ino
+++ serialmovements/serialmovements.ino
@@ -35,24 +35,12 @@

   }
   if (command == "walk") {
-
-//    legswalk(legs);
-
-
     startTime = millis();
     Serial.print("wagao");
     while (millis() < startTime + duration*1000) {
-        walk(arm1,arm2,legs);
-
-
-//      Serial.println("walking");
-//      Serial.println("start: ");
-//      Serial.print(startTime);
-//      Serial.println("now: ");
-//      Serial.print(millis());
-
-
+        walk(arm1,arm2,legs);
     }
+    rest(arm1,arm2,legs);
     command = "";
   }

@@ -83,39 +71,31 @@
 }

 void rest(Servo servo1, Servo servo2, Servo servo3) {
-    if (pos<170) {
-      for (pos; pos <= 170; pos++) {
+  int servo1Pos = servo1.read();
+  int servo2Pos = servo2.read();
+
+    if (servo1Pos<170) {
+      for (servo1Pos; servo1Pos <= 170; pos++) {
         servo1.write(pos);
-        servo2.write(pos-170);
+        if (servo2Pos != 0) {
+          servo2Pos--;
+          servo2.write(servo2Pos);
+        }
      }
-    }else {
-      for (pos; pos >= 170; pos--) {
-        servo1.write(pos);
-
+    } else if (servo1Pos>170) {
+        for (servo1Pos; servo1Pos >= 170; pos--) {
+          servo1.write(pos);
+          if (servo2Pos != 0) {
+            servo2Pos--;
+            servo2.write(servo2Pos);
+          }
+        }
+      } else {
+          if (servo2Pos != 0) {
+            servo2Pos--;
+            servo2.write(servo2Pos);
+          }
       }
-    }
-
-
-    for (pos; pos <= 180; pos += 1) {       // goes from 0 degrees to 180 degrees
-
-      servo1.write(pos);
-      servo2.write(pos-90);
-      servo3.write(legPos);
-      legPos -= 1;
-      delay(15);
-  }
-    for (pos = 180; pos >= 90; pos -= 1) { // goes from 180 degrees to 0 degrees
-      servo1.write(pos);              // tell servo to go to position in variable 'pos'
-      servo2.write(pos-90);
-      servo3.write(legPos1);
-      legPos1 += 1;
-      delay(15);                       // waits 15ms for the servo to reach the position
-
-  }
-
-
-
-
 }

 void legswalk(Servo servo) {


Update Firmware.ino

Update Firmware.ino

--- src/piggy_back_loggers/SD_prototype_Firmware/Firmware/Firmware.ino
+++ src/piggy_back_loggers/SD_prototype_Firmware/Firmware/Firmware.ino
@@ -63,7 +63,6 @@
 #include "state.h"
 #include "RTC_PCF8523.h"

-// DANIEL
 /*********************************************************************************\
  * Setup:
  *    System State structure      Complete
@@ -82,7 +81,17 @@
 void setup()
 {
   resetState(&State);             // Setup the System State structure
-                                  // Load Date_t with Date/Time info
+
+  pinMode(2, INPUT);              // Setup the Digital Pins
+  pinMode(3, INPUT);
+  pinMode(4, OUTPUT);
+  pinMode(5, INPUT);
+
+  attachInterrupt(digitalPinToInterrupt(2), INT0_ISR, FALLING);   // Setup Interrupts
+  attachInterrupt(digitalPinToInterrupt(3), INT1_ISR, FALLING);
+
+  loadDateTime(&Date);            // Load Date_t with Date/Time info
+
   disableUnneededPeripherals();   // Disable unneeded peripherals
 }

@@ -95,7 +104,7 @@
   *   Set serialOn flag.
   *   call serialPowerUp()
   \*****************************************/
-  if(/*(digitalRead(5) == 0) && */!State.serialOn)
+  if((digitalRead(5) == 0) && !State.serialOn)
   {
     State.serialOn = true;
     serialPowerUp();
@@ -118,6 +127,8 @@
   *                 putting this in a
   *                 function)
   \*****************************************/
+  if(State.flag4)
+    // Daniel's function

   // JOSH
   /*****************************************\


Refactored the radio_pipe so I think other people can use it

--- firmware/2016/radio_pipe/radio_pipe.ino
+++ firmware/2016/radio_pipe/radio_pipe.ino
@@ -38,7 +38,7 @@
   }
 }

-bool receive_data_from_robot() {
+bool receiveDataFromAnotherRadio() {
   if (radio.available()) {
     while (radio.available()) {
       radio.read(&msg_from_robot, sizeof(msg_from_robot));
@@ -48,32 +48,30 @@
   return false;
 }

-void send_data_to_ROS() {
-  //Serial.println(msg_from_robot[0]); //Serial.write() may be a better choice for this
-  //Serial.println(msg_from_robot[1]); //Serial.write() may be a better choice for this
+void sendDataToSerialPort() {
+  Serial.println(msg_from_robot[0]); //Serial.write() may be a better choice for this
+  Serial.println(msg_from_robot[1]); //Serial.write() may be a better choice for this
 }

-bool receive_data_from_ROS() {
+bool receiveDataFromSerialPort() {
   if (Serial.available()) {
-    send_data_to_robot();
     int i = 0;
     while (i<3) {
-      msg_from_ROS[i++] = Serial.read();
-      //Serial.println(msg_from_ROS[i-1]);
+      msg_from_ROS[i++] = Serial.read() - 48;
     }
-    parseROStoRobot();
+    parseSerialMessageToRobot();
     return true;
   }
   return false;
 }

-void parseROStoRobot() {
+void parseSerialMessageToRobot() {
   robotPipe = msg_from_ROS[0];
   commands[0] = msg_from_ROS[1];
   commands[1] = msg_from_ROS[2];
 }

-void send_data_to_robot() {
+void sendDataToRobot() {
   radio.stopListening();
   radio.openWritingPipe(pipe[robotPipe]);
   robot_online = radio.write(commands, sizeof(commands));
@@ -82,10 +80,10 @@
 }

 void loop() {
-  if (receive_data_from_robot())
-    send_data_to_ROS();
-  if (receive_data_from_ROS())
-    send_data_to_robot();
+  if (receiveDataFromAnotherRadio())
+    sendDataToSerialPort();
+  if (receiveDataFromSerialPort())
+    sendDataToRobot();

   delay(10);
 }


Delete SimpleAudioPlayer.ino

Delete SimpleAudioPlayer.ino

--- firmware/examples/SimpleAudioPlayer.ino
+++ firmware/examples/SimpleAudioPlayer.ino
@@ -1,82 +0,0 @@
-/*
-  Simple Audio Player
-
- Demonstrates the use of the Audio library for the Arduino Due
-
- Hardware required :
- * Arduino shield with a SD card on CS4
- * A sound file named "test.wav" in the root directory of the SD card
- * An audio amplifier to connect to the DAC0 and ground
- * A speaker to connect to the audio amplifier
-
- Original by Massimo Banzi September 20, 2012
- Modified by Scott Fitzgerald October 19, 2012
- Modified by Arturo Guadalupi December 18, 2015
-
- This example code is in the public domain
-
- http://www.arduino.cc/en/Tutorial/SimpleAudioPlayer
-
-*/
-
-#include <SD.h>
-#include <SPI.h>
-#include <Audio.h>
-
-void setup() {
-  // debug output at 9600 baud
-  Serial.begin(9600);
-
-  // setup SD-card
-  Serial.print("Initializing SD card...");
-  if (!SD.begin(4)) {
-    Serial.println(" failed!");
-    while(true);
-  }
-  Serial.println(" done.");
-  // hi-speed SPI transfers
-
-  // 44100kHz stereo => 88200 sample rate
-  // 100 mSec of prebuffering.
-  Audio.begin(88200, 100);
-}
-
-void loop() {
-  int count = 0;
-
-  // open wave file from sdcard
-  File myFile = SD.open("test.wav");
-  if (!myFile) {
-    // if the file didn't open, print an error and stop
-    Serial.println("error opening test.wav");
-    while (true);
-  }
-
-  const int S = 1024; // Number of samples to read in block
-  short buffer[S];
-
-  Serial.print("Playing");
-  // until the file is not finished
-  while (myFile.available()) {
-    // read from the file into buffer
-    myFile.read(buffer, sizeof(buffer));
-
-    // Prepare samples
-    int volume = 1024;
-    Audio.prepare(buffer, S, volume);
-    // Feed samples to audio
-    Audio.write(buffer, S);
-
-    // Every 100 block print a '.'
-    count++;
-    if (count == 100) {
-      Serial.print(".");
-      count = 0;
-    }
-  }
-  myFile.close();
-
-  Serial.println("End of file. Thank you for listening!");
-  while (true) ;
-}
-


modified write function

modified write function

--- module/module.ino
+++ module/module.ino
@@ -191,15 +191,16 @@
 	int i = 0;

 	// prepare data to be written
-	unsigned char timeByte0 = time & MSB;
-	unsigned char timeByte1 = (time >> 8) & MSB;
-	unsigned char timeByte2 = (time >> 16) & MSB;
-	unsigned char timeByte3 = (time >> 24) & MSB;
+	unsigned char timeByte[4];
+	unsigned char timeByte[3] = time & MSB;
+	unsigned char timeByte[2] = (time >> 8) & MSB;
+	unsigned char timeByte[1] = (time >> 16) & MSB;
+	unsigned char timeByte[0] = (time >> 24) & MSB;

 	unsigned char A[] = { 0x00, 0x1A, CMD_WRITE, 0x01, numBlocks, startAddress,
 						0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF,
 						0xDD, 0xA1, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF,
-						timeByte3, timeByte2, timeByte1, timeByte0 };
+						timeByte[0], timeByte[1], timeByte[2], timeByte[3] };
 	unsigned char BCC = checksum( A, sizeof(A)/sizeof(A[0]) );
 	unsigned char CMD[] = { STX, 0x00, 0x1A, CMD_WRITE, 0x01, numBlocks, startAddress,
 						0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF,


button test

button test

--- _20-esp8266-dash-deepsleep-test/_20-esp8266-dash-deepsleep-test.ino
+++ _20-esp8266-dash-deepsleep-test/_20-esp8266-dash-deepsleep-test.ino
@@ -13,7 +13,7 @@
 #include "user_interface.h"
 }

-ADC_MODE(ADC_VCC);
+//ADC_MODE(ADC_VCC);

 #define DEBUG_PRINT 1

@@ -46,7 +46,7 @@
 volatile int topicMsgSent   = LOW;
 volatile int relaystatus    = LOW;

-int vdd;
+int vdd = 0 ;

 //
 unsigned long startMills = 0;
@@ -76,10 +76,10 @@
     Serial.println(receivedpayload);
   }

-  if ( receivedpayload == "{\"LIGHT\":1}") {
+  if ( receivedpayload == "{\"LIGHT\":1,\"READY\":1}") {
     relaystatus = 1 ;
   }
-  else if ( receivedpayload == "{\"LIGHT\":0}") {
+  else if ( receivedpayload == "{\"LIGHT\":0,\"READY\":1}") {
     relaystatus = 0 ;
   }

@@ -118,60 +118,96 @@
 {
   if (WiFi.status() != WL_CONNECTED) {
     // WIFI
-    if (DEBUG_PRINT) {
-      Serial.print("===> WIFI ---> Connecting to ");
+    delay(10);
+    if (DEBUG_PRINT) {
+      Serial.print("===> WIFI 1 ---> Connecting to ");
       Serial.print(millis() - startMills);
       Serial.print(" ");
       Serial.println(ssid);
     }
     delay(10);
-    WiFi.mode(WIFI_STA);
-    // ****************
-    WiFi.begin(ssid, password);
-    //WiFi.begin(ssid, password, channel, bssid);
-    //WiFi.config(IPAddress(ip_static), IPAddress(ip_gateway), IPAddress(ip_subnet));
-    // ****************
-
-    int Attempt = 0;
-    while (WiFi.status() != WL_CONNECTED) {
-      if (DEBUG_PRINT) {
+
+    if ( wifi_get_opmode() != 1 ) {
+      if (DEBUG_PRINT) {
+        Serial.println("===> opmode to STA");
+      }
+      WiFi.mode(WIFI_STA);
+    }
+
+    static struct station_config conf;
+    wifi_station_get_config(&conf);
+    const char* ssidinconf = reinterpret_cast<const char*>(conf.ssid);
+    const char* passphraseinconf = reinterpret_cast<const char*>(conf.password);
+
+    if ( (strcmp(ssidinconf, ssid) != 0) || (strcmp(passphraseinconf, password) != 0) ) {
+      if (DEBUG_PRINT) {
+        Serial.println("===> setup ssid / password");
+      }
+      WiFi.begin(ssid, password);
+    }
+    //system_deep_sleep_set_option(0);
+    system_phy_set_rfoption(1);
+    wifi_set_channel(10);
+    wifi_station_set_hostname("TEST");
+    WiFi.config(IPAddress(ip_static), IPAddress(ip_gateway), IPAddress(ip_subnet), IPAddress(ip_gateway));
+
+    /*
+    Prototype:
+    bool wifi_set_ip_info(
+    uint8 if_index,
+    struct ip_info *info  )
+    Prototype:
+    uint8 if_index : set station IP or soft-AP IP
+    #define STATION_IF 0x00
+    #define SOFTAP_IF 0x01
+    struct ip_info *info : IP information
+    Example:
+    wifi_set_opmode(STATIONAP_MODE); //Set softAP + station mode
+      struct ip_info info;
+      wifi_station_dhcpc_stop();
+      wifi_softap_dhcps_stop();
+
+    IP4_ADDR(&info.ip, 192, 168, 3, 200);  IP4_ADDR(&info.gw, 192, 168, 3, 1);  IP4_ADDR(&info.netmask, 255, 255, 255, 0);  wifi_set_ip_info(STATION_IF, &info);
+
+    IP4_ADDR(&info.ip, 10, 10, 10, 1);  IP4_ADDR(&info.gw, 10, 10, 10, 1);  IP4_ADDR(&info.netmask, 255, 255, 255, 0);  wifi_set_ip_info(SOFTAP_IF, &info);
+      wifi_softap_dhcps_start();
+
+    */
+
+    int timeout = millis() + 10000;
+    while ((WiFi.status() != WL_CONNECTED) && (timeout > millis())) {
+      delay(10);
+      if (DEBUG_PRINT) {
+        Serial.print(millis() - startMills);
         Serial.print(". ");
-        Serial.print(Attempt);
-      }
-      //
-      digitalWrite(blueLED, HIGH);
-      delay(50);
-      digitalWrite(blueLED, LOW);
-      delay(50);
-      //
-      Attempt++;
-      if (Attempt == 150)
-      {
-        if (DEBUG_PRINT) {
-          Serial.println();
-          Serial.println("-----> Could not connect to WIFI");
-        }
-        goingToSleepWithFail();
-      }
-    }
-
-    wifiMills = millis() - startMills;
-    if (DEBUG_PRINT) {
-      Serial.println();
-      Serial.print("===> WiFi connected : ");
-      Serial.println(wifiMills);
-      Serial.print("---> IP address: ");
-      Serial.println(WiFi.localIP());
-
-      Serial.print("===>  Current WIFI : ");
-      Serial.print(WiFi.RSSI());
-      Serial.print("\t");
-      Serial.print(WiFi.BSSIDstr());
-      Serial.print("\t");
-      Serial.print(WiFi.channel());
-      Serial.print("\t");
-      Serial.println(WiFi.SSID());
-
+        yield();
+      }
+    }
+
+    if ((WiFi.status() != WL_CONNECTED)) {
+      if (DEBUG_PRINT) {
+        Serial.println();
+        Serial.println("-----> Could not connect to WIFI");
+      }
+      goingToSleepWithFail();
+    } else {
+      wifiMills = millis() - startMills;
+      if (DEBUG_PRINT) {
+        Serial.println();
+        Serial.print("===> WiFi connected : ");
+        Serial.println(wifiMills);
+        Serial.print("---> IP address: ");
+        Serial.println(WiFi.localIP());
+
+        Serial.print("===>  Current WIFI : ");
+        Serial.print(WiFi.RSSI());
+        Serial.print("\t");
+        Serial.print(WiFi.BSSIDstr());
+        Serial.print("\t");
+        Serial.print(WiFi.channel());
+        Serial.print("\t");
+        Serial.println(WiFi.SSID());
+      }
     }

     //wifi_set_sleep_type(LIGHT_SLEEP_T);
@@ -195,16 +231,18 @@
   //digitalWrite(resetupPin, LOW);
   digitalWrite(redLED, HIGH);

-  vdd = ESP.getVcc() ;
+  //vdd = ESP.getVcc() ;
   WiFiClient::setLocalPortStart(millis() + vdd);

   if (DEBUG_PRINT) {
     Serial.begin(115200);
+    Serial.println("");
   }

   // ****************
-  system_deep_sleep_set_option(2);
-  //
+  //system_deep_sleep_set_option(0);
+  //WiFi.config(IPAddress(ip_static), IPAddress(ip_gateway), IPAddress(ip_subnet));
+  //wifi_set_phy_mode(PHY_MODE_11B);
   //wifi_set_phy_mode(PHY_MODE_11B);
   //wifi_set_phy_mode(PHY_MODE_11G);
   //wifi_set_phy_mode(PHY_MODE_11N);
@@ -250,7 +288,6 @@
     wifi_connect();
   }

-
   if ( subMsgReceived == HIGH ) {
     subMills = (millis() - startMills) - wifiMills ;
     if (DEBUG_PRINT) {
@@ -274,7 +311,7 @@
     goingToSleepWithFail();
   }
   client.loop();
-
+  yield();

 }


turning

turning

--- arduino_motor/mains/Config.ino
+++ arduino_motor/mains/Config.ino
@@ -23,6 +23,6 @@
 //double const Config::TICKS_PER_DEGREE_LEFT = (WHEELS_INTERVAL_LEFT/2)*(PI/180)*(1/DISTANCE_PER_TICK_CM);

 // range from 796 - 810; 803 baseline, -7 to +7; log 14 = 4
-double const Config::TICKS_PER_DEGREE_LEFT = (803+(-6))/90.0; // [-6, ]
+double const Config::TICKS_PER_DEGREE_LEFT = (803+(-6))/90.0; // [-6, -6]
 double const Config::TICKS_PER_DEGREE = (803+(-4))/90.0; // [-5, -4]
 int const Config::VIRTUAL_OFFSET = 5;


Repush ximu codes

Repush ximu codes

--- backend/Ximu/serial/serial.ino
+++ backend/Ximu/serial/serial.ino
@@ -1,41 +0,0 @@
-#include "XimuReceiver.h"
-#include <SoftwareSerial.h>
-
-XimuReceiver receiver;
-// Digital Pin 2 is RX
-SoftwareSerial imuSerial(2, 3);
-
-void setup() {
-  Serial.begin(115200);
-  // According to documentation, Leonardo needs to wait for serial port connect
-  while(!Serial) {;}
-
-  imuSerial.begin(115200);
-}
-
-void loop() {
-  ErrorCode e = ERR_NO_ERROR;
-
-  while(Serial.available() > 0){
-    e = receiver.processNewChar(imuSerial.read());
-  }
-
-  if (e != ERR_NO_ERROR) {
-    Serial.print("ERROR: ");
-    Serial.print(e);
-    Serial.print("\n");
-  }
-
-  if(receiver.isQuaternionGetReady()) {
-    QuaternionStruct quaternion = receiver.getQuaternion();
-    Serial.print("w: ");
-    Serial.print(quaternion.w);
-    Serial.print(" x: ");
-    Serial.print(quaternion.x);
-    Serial.print(" y: ");
-    Serial.print(quaternion.y);
-    Serial.print(" z: ");
-    Serial.print(quaternion.z);
-    Serial.print("\n");
-  }
-}


Programming mode Esp-12F board update - reliability

--- source/supremeDuck/supremeDuck.ino
+++ source/supremeDuck/supremeDuck.ino
@@ -2,11 +2,11 @@
 supremeDuck project - https://github.com/michalmonday/supremeDuck
 Created by Michal Borowski

-Last edited: 05/03/2019
+Last edited: 12/03/2019
 */

-#define APP_Version "1.23"                            // It is used to compare it with the mobile app version.
+#define APP_Version "1.24"                            // It is used to compare it with the mobile app version.
                                                      // For example: 1.08 is compatible with 1.081 or 1.83148,
                                                      // but it's not compatible with 1.09 or 1.091319
                                                      // (in such case notification will be displayed in the app)
@@ -313,7 +313,10 @@

     pinMode(WIFI_DUCKY_GPIO_0_CONTROL_PIN, OUTPUT);
     pinMode(WIFI_DUCKY_ENABLE_CONTROL_PIN, OUTPUT);
-
+
+    digitalWrite(WIFI_DUCKY_ENABLE_CONTROL_PIN,LOW); // set it low first to reset the Esp-12F
+    delay(500);
+
     digitalWrite(WIFI_DUCKY_GPIO_0_CONTROL_PIN,LOW);
     digitalWrite(WIFI_DUCKY_ENABLE_CONTROL_PIN,HIGH);


Add servo

Add servo

--- iot/iot.ino
+++ iot/iot.ino
@@ -1,13 +1,33 @@
+#include <Servo.h>
+
 int led = 13;
+
+Servo servo;
+int servoPos = 0;

 void setup() {
   // Initialize LED output
-  pinMode(led, OUTPUT);
+  pinMode(led, OUTPUT);
+
+  servo.attach(9);
 }

 void loop() {
-  digitalWrite(led, HIGH);   // turn the LED on (HIGH is the voltage level)
-  delay(1000);               // wait for a second
+  digitalWrite(led, HIGH);   // turn the LED on (HIGH is the voltage level)
+
+  for (servoPos = 0; servoPos < 90; servoPos += 1)
+  {
+    servo.write(servoPos);
+    delay(10);
+  }
+
   digitalWrite(led, LOW);    // turn the LED off by making the voltage LOW
-  delay(1000);               // wait for a second
+
+  delay(2500);
+
+  for (servoPos = 90; servoPos >= 1; servoPos -= 1)
+  {
+    servo.write(servoPos);
+    delay(10);
+  }
 }


turning complete

turning complete

--- run/arduino/arduinoActuator/arduinoActuator.ino
+++ run/arduino/arduinoActuator/arduinoActuator.ino
@@ -6,21 +6,15 @@
 #define pwmPin 3
 #define dirPin 2

-int currentVal = -1;
-int changedVal = 0;
-int newVal = 0;
+int stickVal = 50;
+int actuatorVal = 0;

 void setup() {
   // put your setup code here, to run once:
   pinMode(pwmPin, OUTPUT);
   pinMode(dirPin, OUTPUT);

-  currentVal = -1;
   setActuatorValue(50);
-//  digitalWrite(dirPin, HIGH);
-//    analogWrite(pwmPin, 255);
-//    delay((300/100) * 25);
-//    analogWrite(pwmPin, 0);

   Serial.begin(SERIAL_ADDRESS);
   SPI.begin();
@@ -34,73 +28,40 @@
 }

 void setActuatorValue(int value) {
-//  if (value > 0) {
-//    digitalWrite(dirPin, HIGH);
-//    analogWrite(pwmPin, 255);
-////    Serial.println("A");
-//    delay((3000/1000) * (value*10));
-////    Serial.println("B");
-//    analogWrite(pwmPin, 0);
-//  }
-//  else if (value < 0) {
-//    digitalWrite(dirPin, LOW);
-//    analogWrite(pwmPin, 255);
-//    delay((3000/1000) * (value * -10));
-//    analogWrite(pwmPin, 0);
-//  }
   if (value >= 0 && value <= 100) {
-    if (value > 50) {
+    int movement = (value - actuatorVal);
+    if (movement > 0) {
       digitalWrite(dirPin, HIGH);
       analogWrite(pwmPin, 255);
-      delay((300/100) * 50);
+      delay((300/100) * movement/2);
       analogWrite(pwmPin, 0);
-      currentVal = 1;
     }
-    else if (value < 50) {
+    else if (movement < 0) {
       digitalWrite(dirPin, LOW);
       analogWrite(pwmPin, 255);
-      delay((300/100) * 50);
+      delay((300/100) * ((movement * -1)/2));
       analogWrite(pwmPin, 0);
-      currentVal = -1;
     }
-    else {
-      if (currentVal == -1) {
-        digitalWrite(dirPin, HIGH);
-        analogWrite(pwmPin, 255);
-        delay((300/100) * 50);
-        analogWrite(pwmPin, 0);
-      }
-      else if (currentVal == 1) {
-        digitalWrite(dirPin, LOW);
-        analogWrite(pwmPin, 255);
-        delay((300/100) * 50);
-        analogWrite(pwmPin, 0);
-      }
-      currentVal = 0;
-    }
+
+    actuatorVal = value;
     delay(5);
   }
 }

 void loop() {
   // put your main code here, to run repeatedly:
-//  Serial.println(changedVal);
-//  changedVal = newVal - currentVal;
-//  Serial.println("A");
-//  setActuatorValue(changedVal);
-//  Serial.println("B");
-//  currentVal = newVal;
-  setActuatorValue(newVal);
+  setActuatorValue(stickVal);
 }

 // callback for received data
 void receiveData(int byteCount) {
   while(Wire.available()) {
-    newVal = Wire.read();
+    stickVal = Wire.read();
+    delay(5);
   }
 }

 // callback for sending data
 void sendData() {
-  Wire.write(currentVal);
+  Wire.write(actuatorVal);
 }