Temp/Time added

Temp/Time added

Added Bitmap for fire.
Added Time display
Moved screen around

--- Caravan_Thermostat_TX/Caravan_Thermostat_TX.ino
+++ Caravan_Thermostat_TX/Caravan_Thermostat_TX.ino
@@ -7,9 +7,11 @@
 */

 // Setup the includes
+#include <Wire.h>
 #include <SPI.h>
 #include <TFT.h>  // Arduino LCD library
 #include <dht.h> // DHT11 Library
+#include <TimeLib.h>
 #include <DS1307RTC.h> // RTC Library
 //#include <IRremote.h> // IR Library

@@ -29,6 +31,7 @@
 // Create instances
 TFT TFTscreen = TFT(cs, dc, rst);
 dht DHT;
+

 // Define Global Variables
 char PreviousTemperature[4];
@@ -36,31 +39,114 @@
 char CurrentTemperature[4];
 char CurrentHumidity[4];
 bool HeatingOn = false;
-double ReqTemp = 0; // Failsafe to 0 incase of powerloss. This may well be changed.
-int TempStartPointX = 44;
-int TempStartPointY = 40;
+int ReqTemp = 28; // Failsafe to 0 incase of powerloss. This may well be changed.
+int TempStartPointX = 5; //44 Center
+int TempStartPointY = 35;
+int TimeStartPointX = 5;
+int TimeStartPointY = TFTscreen.height() - 20;
+int ReqTempStartPointX = TFTscreen.width() - 75;
+int ReqTempStartPointY = TFTscreen.height() - 32;
+int PreviousHour = 0;
+int PreviousMinute = 0;

 // Color definitions
-#define BLACK    0x0000
-#define BLUE     0x001F
-#define RED      0xF800
-#define GREEN    0x07E0
-#define CYAN     0x07FF
-#define MAGENTA  0xF81F
-#define YELLOW   0xFFE0
-#define WHITE    0xFFFF
+#define Black           0x0000      /*   0,   0,   0 */
+#define Navy            0x000F      /*   0,   0, 128 */
+#define DarkGreen       0x03E0      /*   0, 128,   0 */
+#define DarkCyan        0x03EF      /*   0, 128, 128 */
+#define Maroon          0x7800      /* 128,   0,   0 */
+#define Purple          0x780F      /* 128,   0, 128 */
+#define Olive           0x7BE0      /* 128, 128,   0 */
+#define LightGrey       0xC618      /* 192, 192, 192 */
+#define DarkGrey        0x7BEF      /* 128, 128, 128 */
+#define Blue            0x001F      /*   0,   0, 255 */
+#define Green           0x07E0      /*   0, 255,   0 */
+#define Cyan            0x07FF      /*   0, 255, 255 */
+#define Red             0xF800      /* 255,   0,   0 */
+#define Magenta         0xF81F      /* 255,   0, 255 */
+#define Yellow          0xFFE0      /* 255, 255,   0 */
+#define White           0xFFFF      /* 255, 255, 255 */
+#define Orange          0xFD20      /* 255, 165,   0 */
+#define GreenYellow     0xAFE5      /* 173, 255,  47 */
+#define Pink            0xF81F
+#define Brown           0x8A22
+#define OffBlack        0x3186
+
+const unsigned char PROGMEM CampFireFlames[] =
+{
+  B00000000, B00000010, B00000000, B00000000, B00000000, //               #
+  B00000000, B00000011, B11100000, B00000000, B00000000, //               #####
+  B00000000, B00000011, B00011000, B00000000, B00000000, //               ##   ##
+  B00000000, B00000001, B00000100, B00000000, B00000000, //                #     #
+  B00000000, B00000001, B10000010, B00000000, B00000000, //                ##     #
+  B00000000, B00000000, B10000001, B00000000, B00000000, //                 #      #
+  B00000000, B00000000, B10000001, B00000000, B00000000, //                 #      #
+  B00000000, B00000000, B10000000, B10000000, B00000000, //                 #       #
+  B00000000, B00000000, B10000000, B10000000, B00000000, //                 #       #
+  B00000000, B00000000, B10000000, B10000000, B00000000, //                 #       #
+  B00000000, B00000001, B10000000, B10011000, B00000000, //                ##       #  ##
+  B00000000, B00000001, B00000001, B00011100, B00000000, //                #       #   ###
+  B00000000, B00000001, B00000001, B00001011, B00000000, //                #       #    # ##
+  B00000000, B00000010, B00000001, B00011001, B00000000, //               #        #   ##  #
+  B00000011, B10000110, B00000001, B00010000, B10000000, //       ###    ##        #   #    #
+  B00000001, B11001100, B00000001, B11110000, B10000000, //        ###  ##         #####    #
+  B00000001, B01111000, B00000000, B01000000, B01000000, //        # ####            #       #
+  B00000001, B00110000, B00000000, B00000000, B01000000, //        #  ##                     #
+  B00000001, B00000000, B00000000, B00000000, B10000000, //        #                        #
+  B00000001, B00000000, B00000000, B00000000, B10000000, //        #                        #
+  B00000011, B00000000, B00110000, B00000001, B00000000, //       ##          ##           #
+  B00000010, B00000000, B00110000, B00000001, B00000000, //       #           ##           #
+  B00000100, B00000000, B00111000, B00000001, B00000000, //      #            ###          #
+  B00001000, B00000000, B00111000, B00000001, B00000000, //     #             ###          #
+  B00011000, B00000000, B00101100, B00000000, B10000000, //    ##             # ##          #
+  B00010000, B00000000, B01001100, B00000000, B11000000, //    #             #  ##          ##
+  B00010000, B00000000, B10001000, B00000000, B01100000, //    #            #   #            ##
+  B00110000, B00000001, B10001000, B00000000, B00100000, //   ##           ##   #             #
+  B00010000, B00000011, B00011000, B10000000, B00010000, //    #          ##   ##   #          #
+  B00110000, B00000110, B00010000, B11000000, B00010000, //   ##         ##    #    ##         #
+  B00010000, B00000100, B00110000, B11000000, B00001000, //    #         #    ##    ##          #
+  B00010000, B00001100, B00110000, B11100000, B00001000, //    #        ##    ##    ###         #
+  B00010000, B00001000, B00010001, B11100000, B00001000, //    #        #      #   ####         #
+  B00001000, B00001000, B00001111, B11110000, B00001000, //     #       #       ########        #
+  B00001100, B00001000, B00000000, B01110000, B00001000, //     ##      #            ###        #
+  B00000100, B00001000, B00000000, B01110000, B00001000, //      #      #            ###        #
+  B00000010, B00001000, B00000000, B00010000, B00010000, //       #     #              #       #
+  B00000011, B00001100, B00000000, B00010000, B00010000, //       ##    ##             #       #
+  B00000001, B00000100, B00000000, B00000000, B00100000, //        #     #                    #
+  B00000000, B01000110, B00000000, B00110000, B01000000, //          #   ##           ##     #
+  B00000000, B00110011, B00000000, B00100001, B10000000, //           ##  ##          #    ##
+  B00000000, B00011111, B10000000, B01000111, B00000000, //            ######        #   ###
+  B00000000, B00000111, B11111111, B11110100, B00000000, //              ############### #
+  B00000000, B00000000, B11111111, B11100000, B00000000, //                 ###########
+};
+const unsigned char PROGMEM CampFireLogs[] =
+{
+  B00001100, B00000000, B00000000, B00000000, B00011100, //     ##                             ###
+  B00011001, B11110000, B00000000, B00000111, B11110110, //    ##  #####                 ####### ##
+  B00010000, B00011111, B10000000, B11111100, B00000011, //    #       ######       ######        ##
+  B00010000, B00000011, B11111101, B10000000, B00000010, //    #          ######## ##             #
+  B00011110, B00001111, B11110000, B00000000, B00011110, //    ####     ########               ####
+  B00001111, B11111100, B00000000, B00000011, B11011000, //     ##########                #### ##
+  B00111111, B00000000, B00000000, B11111111, B11110000, //   ######                ############
+  B01000000, B00000000, B00011111, B01000000, B00011000, //  #                 ##### #         ##
+  B11000000, B00000101, B11110110, B11000000, B00001000, // ##           # ##### ## ##          #
+  B11000001, B11111000, B00000000, B01111110, B00001000, // ##     ######            ######     #
+  B01111111, B10000000, B00000000, B00000011, B01111000, //  ########                     ## ####
+  B00000000, B00000000, B00000000, B00000000, B00100000, //                                   #
+};

 void setup() {
   Serial.begin(115200);
+  setSyncProvider(RTC.get);
   SetupDisplayLayout();
+
 }

 void loop() {
   // Read the Temperature
   ReadTemperature();
-
-  // wait for a bit.
   delay(2000);
+  ReadTime();
 }

 // Define Functions.
@@ -70,11 +156,21 @@

   // Draw the relevant static content.
   //oC
-  TFTscreen.stroke(WHITE);
+  TFTscreen.stroke(White);
   TFTscreen.setTextSize(1);
-  TFTscreen.text("o", 120, 25);
+  TFTscreen.text("o", TempStartPointX + 76, TempStartPointY - 8);
+  String TempRequested = "";
+  TempRequested += ReqTemp;
+  TFTscreen.text(TempRequested.c_str(), ReqTempStartPointX, ReqTempStartPointY);
+
   TFTscreen.setTextSize(2);
-  TFTscreen.text("c", 124, 29);
+  TFTscreen.text("c", TempStartPointX + 80, TempStartPointY - 4);
+  TFTscreen.text(":", TimeStartPointX + 23, TimeStartPointY);
+
+  TFTscreen.drawLine(0, TFTscreen.height() - 24, TFTscreen.width(), TFTscreen.height() - 24, OffBlack);
+  TFTscreen.drawLine(0, 24, TFTscreen.width(), 24, OffBlack);
+  TFTscreen.drawLine(TFTscreen.width() - 60, 24, TFTscreen.width() - 60, TFTscreen.height() - 24, OffBlack);
+  DrawFire(HeatingOn);
 }

 void ReadTemperature()
@@ -87,16 +183,93 @@
       //Serial.println("Temp OK");
       double sensorVal = double(DHT.temperature);
       dtostrf(sensorVal, 2, 0, CurrentTemperature);
-      //Serial.println(PreviousTemperature);
-      //Serial.println(CurrentTemperature);
-      sensorVal = double(DHT.humidity);
-      dtostrf(sensorVal, 2, 0, CurrentHumidity);
       if (memcmp(CurrentTemperature, PreviousTemperature, 4) != 0)
       {
         UpdateTemperature();
+        // Do we need to turn the heating on?
+        if (sensorVal < ReqTemp - 1)  {
+          HeatingOn = true;
+        }
+        if (sensorVal > ReqTemp + 1) {
+          HeatingOn = false;
+        }
+        DrawFire(HeatingOn);
       }
-  }
-}
+      sensorVal = double(DHT.humidity);
+      dtostrf(sensorVal, 2, 0, CurrentHumidity);
+  }
+}
+
+void ReadTime()
+{
+  String TimeToDisplay = "";
+  if (PreviousHour != hour())
+  {
+    TimeToDisplay = "";
+    TFTscreen.setTextSize(2);
+    TFTscreen.stroke(Black);
+    TimeToDisplay += Time2Digit(PreviousHour);
+    TFTscreen.text(TimeToDisplay.c_str(), TimeStartPointX, TimeStartPointY);
+
+    TimeToDisplay = "";
+    TimeToDisplay += Time2Digit(hour());
+    TFTscreen.stroke(White);
+    TFTscreen.text(TimeToDisplay.c_str(), TimeStartPointX, TimeStartPointY);
+
+    PreviousHour = hour();
+  }
+  if (PreviousMinute != minute())
+  {
+    TimeToDisplay = "";
+    TFTscreen.setTextSize(2);
+    TFTscreen.stroke(Black);
+    TimeToDisplay += Time2Digit(PreviousMinute);
+    TFTscreen.text(TimeToDisplay.c_str(), TimeStartPointX + 35, TimeStartPointY);
+
+    TimeToDisplay = "";
+    TimeToDisplay += Time2Digit(minute());
+    TFTscreen.stroke(White);
+    TFTscreen.text(TimeToDisplay.c_str(), TimeStartPointX + 35, TimeStartPointY);
+
+    PreviousMinute = minute();
+
+  }
+  TimeToDisplay += Time2Digit(hour());
+  TimeToDisplay += ":";
+  TimeToDisplay += Time2Digit(minute());
+  TimeToDisplay += ":";
+  TimeToDisplay += Time2Digit(second());
+  Serial.println("Time is " + TimeToDisplay);
+
+  // Display the time on the screen.
+
+}
+
+void DrawFire(bool Flame)
+{
+  //Do we need flame?
+  if (Flame)
+  {
+    TFTscreen.drawBitmap(TFTscreen.width() - 45, 36, CampFireFlames, 40, 44, Red);
+  }
+  else
+  {
+    TFTscreen.drawBitmap(TFTscreen.width() - 45, 36, CampFireFlames, 40, 44, Black);
+  }
+
+  TFTscreen.drawBitmap(TFTscreen.width() - 45, 80, CampFireLogs, 40, 12, Brown);
+}
+
+String Time2Digit(int Number)
+{
+  String StringToReturn = "";
+  if (Number >= 0 && Number < 10) {
+    StringToReturn += "0";
+  }
+  StringToReturn += Number;
+  return StringToReturn;
+}
+
 void UpdateTemperature()
 {
   Serial.println("Temp Diff");
@@ -126,71 +299,71 @@
 void Display1(int Pos)
 {
   Display8(Pos);
-  DisplayTop(Pos, 0x0000);
-  DisplayTopLeft(Pos, 0x0000);
-  DisplayCenter(Pos, 0x0000);
-  DisplayBottom(Pos, 0x0000);
-  DisplayBottomLeft(Pos, 0x0000);
+  DisplayTop(Pos, Black);
+  DisplayTopLeft(Pos, Black);
+  DisplayCenter(Pos, Black);
+  DisplayBottom(Pos, Black);
+  DisplayBottomLeft(Pos, Black);
 }
 void Display2(int Pos)
 {
   Display8(Pos);
-  DisplayTopLeft(Pos, 0x0000);
-  DisplayBottomRight(Pos, 0x0000);
+  DisplayTopLeft(Pos, Black);
+  DisplayBottomRight(Pos, Black);
 }

 void Display3(int Pos)
 {
   Display8(Pos);
-  DisplayTopLeft(Pos, 0x0000);
-  DisplayBottomLeft(Pos, 0x0000);
+  DisplayTopLeft(Pos, Black);
+  DisplayBottomLeft(Pos, Black);
 }
 void Display4(int Pos)
 {
   Display8(Pos);
-  DisplayTop(Pos, 0x0000);
-  DisplayBottomLeft(Pos, 0x0000);
-  DisplayBottom(Pos, 0x0000);
+  DisplayTop(Pos, Black);
+  DisplayBottomLeft(Pos, Black);
+  DisplayBottom(Pos, Black);
 }
 void Display5(int Pos)
 {
   Display8(Pos);
-  DisplayTopRight(Pos, 0x0000);
-  DisplayBottomLeft(Pos, 0x0000);
+  DisplayTopRight(Pos, Black);
+  DisplayBottomLeft(Pos, Black);
 }
 void Display6(int Pos)
 {
   Display8(Pos);
-  DisplayTopRight(Pos, 0x0000);
+  DisplayTopRight(Pos, Black);
 }
 void Display7(int Pos)
 {
   Display8(Pos);
-  DisplayTopLeft(Pos, 0x0000);
-  DisplayCenter(Pos, 0x0000);
-  DisplayBottomLeft(Pos, 0x0000);
-  DisplayBottom(Pos, 0x0000);
+  DisplayTopLeft(Pos, Black);
+  DisplayCenter(Pos, Black);
+  DisplayBottomLeft(Pos, Black);
+  DisplayBottom(Pos, Black);
 }

 void Display8(int Pos)
 {
-  DisplayTop(Pos, 0xFFFF);
-  DisplayTopLeft(Pos, 0xFFFF);
-  DisplayTopRight(Pos, 0xFFFF);
-  DisplayCenter(Pos, 0xFFFF);
-  DisplayBottom(Pos, 0xFFFF);
-  DisplayBottomLeft(Pos, 0xFFFF);
-  DisplayBottomRight(Pos, 0xFFFF);
+  DisplayTop(Pos, White);
+  DisplayTopLeft(Pos, White);
+  DisplayTopRight(Pos, White);
+  DisplayCenter(Pos, White);
+  DisplayBottom(Pos, White);
+  DisplayBottomLeft(Pos, White);
+  DisplayBottomRight(Pos, White);
 }
 void Display9(int Pos)
 {
   Display8(Pos);
-  DisplayBottomLeft(Pos, 0x0000);
+  DisplayBottomLeft(Pos, Black);
 }
 void Display0(int Pos)
 {
   Display8(Pos);
-  DisplayCenter(Pos, 0x0000);
+  DisplayCenter(Pos, Black);
 }
 void DisplayTop(int Pos, uint16_t Color)
 {
@@ -242,3 +415,11 @@
   }
 }

+void print2digits(int number) {
+  if (number >= 0 && number < 10) {
+    Serial.write('0');
+  }
+  Serial.print(number);
+}
+
+


signing test

signing test

--- firmware/firmware.ino
+++ firmware/firmware.ino
@@ -91,6 +91,7 @@

     warnGPS();
 #endif
+

     logln("Done. System ready.");


Update espnow-sensorNode.ino

Update espnow-sensorNode.ino

--- ESP-Now/espnow-sensorNode/espnow-sensorNode.ino
+++ ESP-Now/espnow-sensorNode/espnow-sensorNode.ino
@@ -54,7 +54,7 @@
   esp_now_add_peer(remoteMac, ESP_NOW_ROLE_SLAVE, WIFI_CHANNEL, NULL, 0);

   esp_now_register_send_cb([](uint8_t* mac, uint8_t status) {
-    Serial.print("send_cb, status = "); Serial.print(status); // this always shows 1 which should mean fail!? Don't know whats going on there.
+    Serial.print("send_cb, status = "); Serial.print(status);
     Serial.print(", to mac: ");
     char macString[50] = {0};
     sprintf(macString,"%02X:%02X:%02X:%02X:%02X:%02X", mac[0], mac[1], mac[2], mac[3], mac[4], mac[5]);


added config mode callback and color feedback, added initial color retrieval

--- handlers/ESPHandler/ESPHandler.ino
+++ handlers/ESPHandler/ESPHandler.ino
@@ -29,7 +29,7 @@
 }

-#define NUMPIXELS 60
+#define NUMPIXELS 1

 #define DATAPIN    13 // GPIO15 - MISO
 #define CLOCKPIN   9 // GPIO14 - CLK
@@ -37,12 +37,12 @@
 // ========== HANDLER INFO ==========
 const char* AUTOCONFIG_ACCESSPOINT_NAME = "LightHandlerConfigAP";
 const char* GEOMETRY = "Cube";
-const int GEOMETRY_WIDTH = 8;
+const int GEOMETRY_WIDTH = 1;
 const int GEOMETRY_HEIGHT = 1;
-const int GEOMETRY_LENGTH = 12;
+const int GEOMETRY_LENGTH = 1;
 const int LIGHT_SIZE = 1;
-const char* HANDLER_INFO = "ESP8266-based APA102 Handler";
-const char* VERSION = "1.0.1";
+const char* HANDLER_INFO = "ESP8266-based WS2812 Handler";
+const char* VERSION = "1.0.2";
 const char* DNS_POSTFIX = "";
 // ==================================

@@ -97,15 +97,29 @@
   Serial.println("===============================");
 }

+void configModeCallback () {
+  Serial.println("Entered config mode");
+  Serial.println(WiFi.softAPIP());
+
+  for (int i=0; i<NUMPIXELS; i++) {
+    strip.setPixelColor(i), strip.Color(0, 255, 0));
+  }
+  strip.show();
+}
+
 void setup()
 {
   Serial.begin(115200);

+  strip.begin();
+
   WiFiManager wifiManager;

   String apName = String(AUTOCONFIG_ACCESSPOINT_NAME) + String("_") + String(ESP.getChipId());
   char apNameBuffer[apName.length()];
   apName.toCharArray(apNameBuffer, apName.length());
+
+  wifiManager.setAPCallback(configModeCallback);

   if(!wifiManager.autoConnect(apNameBuffer)) {
     Serial.println("failed to connect to WiFi and hit timeout");
@@ -113,6 +127,11 @@
     ESP.reset();
     delay(1000);
   }
+
+  for (int i=0; i<NUMPIXELS; i++) {
+    strip.setPixelColor(i), strip.Color(0, 0, 255));
+  }
+  strip.show();

   Serial.println("Connected to WiFi");
 }
@@ -165,6 +184,51 @@
   client.print("Host: ");
   client.println(serverAddress);
   client.println("Connection: close");
+}
+
+bool handlerIsRegistered() {
+  Serial.println("> handlerIsRegistered()");
+
+  bool result = false;
+
+  Serial.println("trying to determine whether the handler is already registered");
+
+  if (connectToAPI()) {
+    client.print("GET /api/handlers/");
+    client.print(ESP.getFlashChipId());
+    client.println(" HTTP/1.1");
+    sendHTTPHeader();
+    client.println();
+
+    delay(10);
+    String line = client.readStringUntil('\r');
+
+    if (line.startsWith("HTTP/1.1 404 Not Found")) {
+      Serial.println("handler not yet registered");
+      result = false;
+    } else if (line.startsWith("HTTP/1.1 200 OK")) {
+      // TODO check if light count has changed and delete existing and reregister if changed
+
+      Serial.println("handler already registered");
+      result = true;
+    } else {
+      Serial.print(line);
+      while(client.available()) {
+        String line = client.readStringUntil('\r');
+        Serial.print(line);
+      }
+      Serial.println("");
+      Serial.println("unrecognized status code or error");
+    }
+
+    client.stop();
+
+  }
+
+  Serial.print("< ");
+  Serial.println(result);
+
+  return result;
 }

 int registerHandler() {
@@ -219,7 +283,6 @@
     }

     client.stop();
-
   }

   Serial.print("< ");
@@ -228,49 +291,46 @@
   return error;
 }

-bool handlerIsRegistered() {
-  Serial.println("> handlerIsRegistered()");
-
-  bool result = false;
-
-  Serial.println("trying to determine whether the handler is already registered");
+void getCurrentColor() {
+  Serial.println("> getCurrentColor()");

   if (connectToAPI()) {
     client.print("GET /api/handlers/");
     client.print(ESP.getFlashChipId());
-    client.println(" HTTP/1.1");
+    client.println("/control HTTP/1.1");
     sendHTTPHeader();
     client.println();

     delay(10);
     String line = client.readStringUntil('\r');
-    /*Serial.println(line);
-
-    while(client.available()) {
-      String line = client.readStringUntil('\r');
-      Serial.println(line);
-    }*/

     if (line.startsWith("HTTP/1.1 404 Not Found")) {
-      Serial.println("handler not yet registered");
+      Serial.println("light color not found");
       result = false;
     } else if (line.startsWith("HTTP/1.1 200 OK")) {
-      // TODO check if light count has changed and delete existing and reregister if changed
+      String received_data = "";
+      while(client.available()) {
+        received_data = received_data + client.readStringUntil('\r');
+      }
+      StaticJsonBuffer<256> jsonBuffer;
+      JsonObject& root = jsonBuffer.parseObject(receive);

-      Serial.println("handler already registered");
-      result = true;
-    } else {
+      const char* hostname = root["hostname"];
+      const char* ip = root["ip"];
+      const char* port = root["port"];
+      const char* name = root["name"];
+    } else {
+      Serial.print(line);
+      while(client.available()) {
+        String line = client.readStringUntil('\r');
+        Serial.print(line);
+      }
+      Serial.println("");
       Serial.println("unrecognized status code or error");
     }

     client.stop();
-
-  }
-
-  Serial.print("< ");
-  Serial.println(result);
-
-  return result;
+  }
 }

 void listenForServer()
@@ -391,14 +451,13 @@

   server.begin();
   Serial.println("HTTP server started");
-
-  strip.begin();
 }

 void loop()
 {
   if (isInitialized) {
     server.handleClient();
+    //ESP.wdtDisable();
   } else if (serverAddress == "") { // has server data received
     if (!multicastServerIsStarted) {
       startMulticastServer();
@@ -409,10 +468,11 @@
   } else {
     if (!handlerIsRegistered()) {
       registerHandler();
+      getCurrentColor();
       delay(500);
     } else {
       startWebServer();
       isInitialized = true;
     }
   }
-}
+}


updated SD mount point

updated SD mount point

--- software/yun_air/yun_air.ino
+++ software/yun_air/yun_air.ino
@@ -134,7 +134,7 @@
   delay(125000);

   p.begin("python");
-  p.addParameter("/mnt/sd/modbus_tcp_slave.py"); // modbus float holding registers
+  p.addParameter("/mnt/sda1/modbus_tcp_slave.py"); // modbus float holding registers
   p.addParameter(RO_START);                      // read only start address
   p.addParameter(RO_LENGTH);                     // read only number of holding registers
   p.addParameter(RW_START);                      // read/write start address (optional)


added three new scenes

added three new scenes

--- taurus.ino
+++ taurus.ino
@@ -66,13 +66,16 @@
 		SYMBOLS_SNAKE,
 		SCROLL_STARS,
 		EYES,
+		CHANNEL,
+		VHS,
+		SYMBOL_SHIFT,
 		TOTAL
 };

 // TODO:
 // Better scene random order

-Scene currentScene = EYES;
+Scene currentScene = SYMBOL_SHIFT;
 Scene lastScene = -1;
 TVout TV;
 unsigned long startTime = 0;
@@ -538,6 +541,141 @@
 		checkSceneEnded(20);
 }

+void channelScene(bool changed) {
+		if (changed) {
+				char *s = "VIDEO 1";
+				TV.set_cursor(WIDTH - (strlen(s) * FONT_W) - 2, FONT_H + 2);
+				TV.print(s);
+		}
+
+		TV.delay(1);
+
+		checkSceneEnded(8);
+}
+
+int vhsTime = 0;
+void vhsScene(bool changed) {
+		char *stop = "STOP";
+		char *play = "PLAY";
+		const int timerWidth = 5;
+		char *timer = "--:--";
+
+		if (changed) {
+				vhsTime = 0;
+				TV.set_cursor(2, FONT_H + 2);
+				TV.print(stop);
+
+				TV.set_cursor(WIDTH - (timerWidth * FONT_W) - 2, FONT_H + 2);
+				TV.print(timer);
+
+				TV.delay(3500);
+				TV.clear_screen();
+
+				TV.set_cursor(2, FONT_H + 2);
+				TV.print(play);
+
+				return;
+		}
+
+		TV.set_cursor(WIDTH - (timerWidth * FONT_W) - 2, FONT_H + 2);
+		TV.print("00:0");
+		TV.print(vhsTime % 10);
+		vhsTime++;
+
+		TV.delay(1000);
+
+		checkSceneEnded(9);
+}
+
+void shiftLine(int orientation, int direction, int index, int step) {
+		if (orientation == 0) {
+				// Shift column
+				if (direction == 1) {
+						for (int i = HEIGHT - 2; i >= 0; i--) {
+								unsigned char pix = TV.get_pixel(index, i);
+								TV.set_pixel(index, i + step, pix);
+						}
+				} else {
+						for (int i = 1; i <= HEIGHT - 1; i++) {
+								unsigned char pix = TV.get_pixel(index, i);
+								TV.set_pixel(index, i - step, pix);
+						}
+				}
+		} else {
+				// Shift row
+				if (direction == 1) {
+						for (int i = WIDTH - 2; i >= 0; i--) {
+								unsigned char pix = TV.get_pixel(i, index);
+								TV.set_pixel(i + step, index, pix);
+						}
+				} else {
+						for (int i = 1; i <= WIDTH - 1; i++) {
+								unsigned char pix = TV.get_pixel(i, index);
+								TV.set_pixel(i - step, index, pix);
+						}
+				}
+		}
+}
+
+#define STEP_COUNT 500
+unsigned char steps[STEP_COUNT][4] = { 0 };
+bool rewinding = false;
+int stepIdx = 0;
+char *shiftSymbol = NULL;
+void symbolShiftScene(bool changed) {
+		if (changed) {
+				rewinding = false;
+				stepIdx = 0;
+
+				if (random(2) == 0) {
+						shiftSymbol = getSignSymbol(random(SIGN_COUNT));
+				} else {
+						shiftSymbol = getPlanetSymbol(random(PLANET_COUNT));
+				}
+
+				TV.bitmap(BMP_X, BMP_Y, shiftSymbol);
+				TV.delay(1000);
+		}
+
+		int direction, step, col, row, orientation;
+
+		if (!rewinding) {
+				direction = random(2);
+				step = random(1, 6);
+				col = random(WIDTH);
+				row = random(HEIGHT);
+				orientation = random(2);
+
+				steps[stepIdx][0] = orientation;
+				steps[stepIdx][1] = direction;
+				steps[stepIdx][2] = (orientation == 0) ? col : row;
+				steps[stepIdx][3] = step;
+
+				stepIdx++;
+				if (stepIdx == STEP_COUNT) {
+						rewinding = true;
+				}
+		} else if (stepIdx >= 0) {
+				orientation = steps[stepIdx][0];
+				direction = (steps[stepIdx][1] == 0) ? 1 : 0;
+				col = row = steps[stepIdx][2];
+				step = steps[stepIdx][3];
+
+				stepIdx--;
+		} else {
+				TV.bitmap(BMP_X, BMP_Y, shiftSymbol);
+				rewinding = false;
+				stepIdx = 0;
+				TV.delay(200);
+		}
+
+		shiftLine(orientation, direction, (orientation == 0) ? col : row, step);
+
+		if (checkSceneEnded(25)) {
+				TV.delay(1500);
+		}
+}
+
 void loop() {
 		bool changed = false;
 		if (currentScene != lastScene) {
@@ -609,6 +747,15 @@
 				case EYES:
 						eyesScene(changed);
 						break;
+				case CHANNEL:
+						channelScene(changed);
+						break;
+				case VHS:
+						vhsScene(changed);
+						break;
+				case SYMBOL_SHIFT:
+						symbolShiftScene(changed);
+						break;
 				default:
 						TV.print("Invalid scene. ");
 						TV.delay(1000);


FIX

FIX

Robot no longer continuously runs into the same spot
Hugs the wall after first turning away

--- bumperexample.ino
+++ bumperexample.ino
@@ -7,11 +7,11 @@
 #define QTR_THRESHOLD 1000 // microseconds

 // these might need to be tuned for different motor types
-#define REVERSE_SPEED 200 // 0 is stopped, 400 is full speed
-#define TURN_SPEED 200
+#define REVERSE_SPEED 400 // 0 is stopped, 400 is full speed
+#define TURN_SPEED 400
 #define FORWARD_SPEED 400
-#define REVERSE_DURATION 100 // ms
-#define TURN_DURATION 300 // ms
+#define REVERSE_DURATION 400 // ms
+#define TURN_DURATION 400 // ms

 // POKêMON CHAMPION MUSIC
 #define MELODY_LENGTH 95
@@ -84,26 +84,29 @@
  }

   if(currentDir == 'R') {
-    if(currentDelay < REVERSE_DURATION) {
-      motors.setSpeeds(-REVERSE_SPEED, -REVERSE_SPEED);
-    } else if(currentDelay < REVERSE_DURATION + TURN_DURATION) {
-      motors.setSpeeds(TURN_SPEED, -TURN_SPEED);
-    } else {
-      motors.setSpeeds(FORWARD_SPEED, FORWARD_SPEED);
-      currentDir = 'F';
-      currentDelay = 0;
-    }
-    currentDelay++;
-    } else if(currentDir == 'L') {
+    for (int i = 0; currentDelay < REVERSE_DURATION + TURN_DURATION; currentDelay++) {
       if(currentDelay < REVERSE_DURATION) {
         motors.setSpeeds(-REVERSE_SPEED, -REVERSE_SPEED);
-      } else if(currentDelay < REVERSE_DURATION + TURN_DURATION) {
-        motors.setSpeeds(-TURN_SPEED, TURN_SPEED);
+      } else if(currentDelay < REVERSE_DURATION + TURN_DURATION) {
+        motors.setSpeeds(TURN_SPEED, -TURN_SPEED);
       } else {
-        motors.setSpeeds(FORWARD_SPEED, FORWARD_SPEED);
+        motors.setSpeeds(FORWARD_SPEED, FORWARD_SPEED);
         currentDir = 'F';
-        currentDelay = 0;
-      } currentDelay++;
+        currentDelay = 0;
+      }
+    }
+
+    } else if(currentDir == 'L') {
+      for (int i = 0; currentDelay < REVERSE_DURATION + TURN_DURATION; currentDelay++) {
+        if(currentDelay < REVERSE_DURATION) {
+          motors.setSpeeds(-REVERSE_SPEED, -REVERSE_SPEED);
+        } else if(currentDelay < REVERSE_DURATION + TURN_DURATION) {
+          motors.setSpeeds(-TURN_SPEED, TURN_SPEED);
+        } else {
+          motors.setSpeeds(FORWARD_SPEED, FORWARD_SPEED);
+          currentDir = 'F';
+          currentDelay = 0;
+        } currentDelay++;
+      }
     }
 }
-


Fix wrong frequency.

Fix wrong frequency.

--- WizardView.ino
+++ WizardView.ino
@@ -70,7 +70,7 @@

     // Set to race frequencies.
     delay(1000); // Wait for modules to settle.
-    rx1.setFrequency(5805);
+    rx1.setFrequency(5665);
     rx2.setFrequency(5745);
     rx3.setFrequency(5885);
     rx4.setFrequency(5945);


Changing brightness down for testing again. Changing schema for 5 different capacitive touch areas on box. Will keep lamp a steady color (right now blue) while capacitive touch sensor isn’t triggered. Added functions for this steady light and for logo theme.

--- capacitive_touch_lamp/capacitive_touch_lamp.ino
+++ capacitive_touch_lamp/capacitive_touch_lamp.ino
@@ -5,7 +5,7 @@

 #define PIN 6
 #define NUM_LEDS 16
-#define BRIGHTNESS 100
+#define BRIGHTNESS 10
 #define ledPin 13

 Adafruit_NeoPixel strip = Adafruit_NeoPixel(NUM_LEDS, PIN, NEO_GRB + NEO_KHZ800);
@@ -27,20 +27,26 @@
      switch(var)
      {
         case 1:
-          yoda();
+          rebel();
           break;
         case 2:
-          luke();
+          lightSide();
           break;
         case 3:
-          vader();
+          empire();
           break;
         case 4:
-          vaderBreathing();
+          darkSide();
+          break;
+        case 5:
+          logo();
           break;
      }
   }
-  delay(500);
+  else {
+    blueRing();
+  }
+  delay(100);

   //colorWipe(strip.Color(255, 0, 0), 50); // Red
   //colorWipe(strip.Color(0, 255, 0), 50); // Green
@@ -52,7 +58,14 @@
   //rainbowCycle(20);
 }

-void yoda() {
+void blueRing() {
+  for(uint16_t i=0; i<strip.numPixels(); i++) {
+    strip.setPixelColor(i, strip.Color(0, 0, 255));
+  }
+  strip.show();
+}
+
+void rebel() {
   //blink(1);
   colorPulse(0, 255, 0, 100, 100);
   clearRing();
@@ -60,7 +73,7 @@
   delay(100);
 }

-void luke() {
+void lightSide() {
   //blink(2);
   colorPulse(0, 255, 0, 100, 100);
   clearRing();
@@ -68,7 +81,7 @@
   delay(100);
 }

-void vader() {
+void empire() {
   //blink(3);
   colorPulse(255, 0, 0, 100, 100);
   clearRing();
@@ -76,12 +89,20 @@
   delay(100);
 }

-void vaderBreathing() {
+void darkSide() {
   //blink(4);
   colorPulse(255, 0, 0, 100, 100);
   clearRing();
   strip.show();
   delay(100);
+}
+
+void logo() {
+  //blink(5);
+  colorPulse(255, 255, 5, 100, 1100);
+  clearRing();
+  strip.show();
+  delay(100);
 }

 // Fill the dots one after the other with a color
@@ -133,7 +154,7 @@
   return strip.Color(WheelPos * 3, 255 - WheelPos * 3, 0);
 }

-void colorPulse(int r, int g, int b, uint8_t wait, uint8_t waitExtra) {
+void colorPulse(int r, int g, int b, uint16_t wait, uint16_t waitExtra) {
   clearRing();
   strip.show();
   delay(wait);


Check for change of state before altering led pin state.

--- base2clock.ino
+++ base2clock.ino
@@ -40,6 +40,7 @@
 int interval_time = INTERVAL_TIME;
 boolean time_set, increment_flg = false;
 unsigned long mils, prev_mils = 0;
+boolean hasP1changed, hasP2changed, hasP3changed ,  hasP4changed, hasP5changed, hasP6changed, hasP7changed, hasP8changed =  false;

 // function prototypes
 void setTimeSlow();
@@ -96,6 +97,8 @@
       p8 = p7 = p6 = p5 = p4 = p3 = p2 = p1 = 1;
     else
       p8 = p7 = p6 = p5 = p4 = p3 = p2 = p1 = 0;
+
+    hasP1changed = hasP2changed = hasP3changed  =  hasP4changed = hasP5changed = hasP6changed = hasP7changed = hasP8changed =  true;
     lightLights();
     delay(1000 * BLINK_DELAY);
  }
@@ -138,37 +141,46 @@

   if(p8 == 0){
     p8 = 1;
+    hasP8changed =  true;
   }
   else if (p7 == 0){
     p7 = 1;
     p8 = 0;
+    hasP7changed = hasP8changed =  true;
   }
   else if (p6 == 0){
     p6 = 1;
     p8 = p7 = 0;
+    hasP6changed = hasP7changed = hasP8changed =  true;
   }
   else if (p5 == 0){
     p5 = 1;
     p8 = p7 = p6 = 0;
+    hasP5changed = hasP6changed = hasP7changed = hasP8changed =  true;
   }
   else if (p4 == 0){
     p4 = 1;
     p8 = p7 = p6 = p5 = 0;
+    hasP4changed = hasP5changed = hasP6changed = hasP7changed = hasP8changed =  true;
   }
   else if (p3 == 0){
     p3 = 1;
     p8 = p7 = p6 = p5 = p4 = 0;
+    hasP3changed  =  hasP4changed = hasP5changed = hasP6changed = hasP7changed = hasP8changed =  true;
   }
   else if (p2 == 0){
     p2 = 1;
     p8 = p7 = p6 = p5 = p4 = p3 = 0;
+    hasP2changed = hasP3changed  =  hasP4changed = hasP5changed = hasP6changed = hasP7changed = hasP8changed =  true;
   }
   else if (p1 == 0){
     p1 = 1;
     p8 = p7 = p6 = p5 = p4 = p3 = p2 = 0;
+    hasP1changed = hasP2changed = hasP3changed  =  hasP4changed = hasP5changed = hasP6changed = hasP7changed = hasP8changed =  true;
   }
   else { // all lights were lit, so this increment resets them to all off
     p8 = p7 = p6 = p5 = p4 = p3 = p2 = p1 = 0;
+    hasP1changed = hasP2changed = hasP3changed  =  hasP4changed = hasP5changed = hasP6changed = hasP7changed = hasP8changed =  true;
   }

   lightLights();
@@ -176,36 +188,54 @@

 void lightLights() {
-  if(p1 == 1)
-    digitalWrite(13, HIGH);
-  else
-    digitalWrite(13, LOW);
-  if(p2 == 1)
-    digitalWrite(12, HIGH);
-  else
-    digitalWrite(12, LOW);
-  if(p3 == 1)
-    digitalWrite(11, HIGH);
-  else
-    digitalWrite(11, LOW);
-  if(p4 == 1)
-    digitalWrite(10, HIGH);
-  else
-    digitalWrite(10, LOW);
-  if(p5 == 1)
-    digitalWrite(9, HIGH);
-  else
-    digitalWrite(9, LOW);
-  if(p6 == 1)
-    digitalWrite(8, HIGH);
-  else
-    digitalWrite(8, LOW);
-  if(p7 == 1)
-    digitalWrite(7, HIGH);
-  else
-    digitalWrite(7, LOW);
-  if(p8 == 1)
-    digitalWrite(6, HIGH);
-  else
-    digitalWrite(6, LOW);
+  if(hasP1changed){
+    if(p1 == 1)
+      digitalWrite(13, HIGH);
+    else
+      digitalWrite(13, LOW);
+  }
+  if(hasP2changed){
+    if(p2 == 1)
+      digitalWrite(12, HIGH);
+    else
+      digitalWrite(12, LOW);
+  }
+  if(hasP3changed){
+    if(p3 == 1)
+      digitalWrite(11, HIGH);
+    else
+      digitalWrite(11, LOW);
+  }
+  if(hasP4changed){
+    if(p4 == 1)
+      digitalWrite(10, HIGH);
+    else
+      digitalWrite(10, LOW);
+  }
+  if(hasP5changed){
+    if(p5 == 1)
+      digitalWrite(9, HIGH);
+    else
+      digitalWrite(9, LOW);
+  }
+  if(hasP6changed){
+    if(p6 == 1)
+      digitalWrite(8, HIGH);
+    else
+      digitalWrite(8, LOW);
+  }
+  if(hasP7changed){
+    if(p7 == 1)
+      digitalWrite(7, HIGH);
+    else
+      digitalWrite(7, LOW);
+  }
+  if(hasP8changed){
+    if(p8 == 1)
+      digitalWrite(6, HIGH);
+    else
+      digitalWrite(6, LOW);
+  }
+
+  hasP1changed = hasP2changed = hasP3changed  =  hasP4changed = hasP5changed = hasP6changed = hasP7changed = hasP8changed =  false;
 } // end lightLights()


oops forgot something here

oops forgot something here

--- Examples/BasicSetup/BasicSetup.ino
+++ Examples/BasicSetup/BasicSetup.ino
@@ -6,6 +6,7 @@

 void setup() {
   Serial.begin(115200);
+  comms.messageCallback = messageReceive;
   comms.setup();
 }


Open FLB for flush...

Open FLB for flush...

--- pump_speed_byte_and_pi_calculation.ino
+++ pump_speed_byte_and_pi_calculation.ino
@@ -119,9 +119,23 @@
 void flushCycle()
 {
 	detachInterrupt(digitalPinToInterrupt(GROUP_SOLENOID));
+#ifdef INVERT_FLB_OUTPUT
+	digitalWrite(FLOW_LIMIT_BYPASS, LOW);
+#else
+	digitalWrite(FLOW_LIMIT_BYPASS, HIGH);
+#endif
+	digitalWrite(GREEN_LED, HIGH);
+	digitalWrite(RED_LED, LOW);
 	g_newPull = false;
 	while (digitalRead(GROUP_SOLENOID) == LOW)
 		md.setM1Speed(constrain((int)(cleanPWM * 4.0), pumpMinPWM, pumpMaxPWM));
-	md.setM1Speed(0);	 //Shut down pump motor
+	md.setM1Speed(0);	 //Shut down pump motor
+#ifdef INVERT_FLB_OUTPUT
+	digitalWrite(FLOW_LIMIT_BYPASS, HIGH);
+#else
+	digitalWrite(FLOW_LIMIT_BYPASS, LOW);
+#endif
 	g_flushCycle = false;
+	digitalWrite(GREEN_LED, LOW);
+	digitalWrite(RED_LED, HIGH);
 }


remove comment

remove comment

--- OpenDeck_MCU/OpenDeck_MCU.ino
+++ OpenDeck_MCU/OpenDeck_MCU.ino
@@ -5,9 +5,6 @@
 Author: Igor Petrovic

 */
-
-//disable default serial object
-

 #include "OpenDeck.h"


No need for large message ids, pattern is enough

--- attiny85/transmitter/transmitter.ino
+++ attiny85/transmitter/transmitter.ino
@@ -7,8 +7,8 @@
 #define PIN_TX 3

-byte ledState = LOW;             // ledState used to set the LED
-unsigned long msgId = 0;
+byte ledState = HIGH;             // ledState used to set the LED
+byte msgId = 0;

 volatile byte wd_check = 0; // A number for the watchdog timerer to check
@@ -55,11 +55,12 @@
 {
   pinMode(LED_DEBUG, OUTPUT);
   pinMode(PIN_TX, OUTPUT);
-  watchdog_setup();
-
+
   vw_set_ptt_inverted(true); // Required for DR3100
   vw_setup(2000);      // Bits per sec
   vw_set_tx_pin(PIN_TX);
+
+  watchdog_setup();
 }

 void loop()
@@ -73,21 +74,22 @@
   }
   digitalWrite(LED_DEBUG, ledState);

-  ++msgId;
+
   char msg[16];
-  sprintf(msg, "%lu,wd=%d,mv=%u", msgId, wd_check, readVcc());
+  sprintf(msg, "%d,wd=%d,mv=%u", msgId, wd_check, readVcc());
   vw_send((uint8_t *)msg, strlen(msg));
   vw_wait_tx(); // Wait until the whole message is gone
   // Cannot use millis() as timer 0 is used by virtualwire on Attiny85
   _delay_ms(1000);

   // Detect cpu freeze.
-  // Watchdog checks tha about 4 seconds have run since last check.
+  // Watchdog checks that about 4 seconds have run since last check.
   // So make sure to record every "second" encountered.
   // If the power is unstable then these seconds will not match with
   // watchdog's timer, and force a reset.
   ++wd_check;

+  ++msgId;
 }

 void watchdog_setup()


support Mega2560

support Mega2560

--- PM2.5/PlanTower/PlanTower.ino
+++ PM2.5/PlanTower/PlanTower.ino
@@ -1,21 +1,21 @@
+unsigned char ide_workaround = 0;
+
 #include <SoftwareSerial.h>

 #define SET_PIN 12
 #define SENSOR_BAUD_RATE 9600
 #define DEBUG_BARUD_RATE 115200

+#if defined(__AVR_ATmega1280__) || defined(__AVR_ATmega2560__)
+#define mySerial Serial3
+#define DebugSerial Serial
+#else
 #define _DBG_RXPIN_ 2
 #define _DBG_TXPIN_ 3
-
-#define SOFTSERIAL
-
-#ifdef SOFTSERIAL
 SoftwareSerial mySerial(_DBG_RXPIN_,_DBG_TXPIN_);
 #define DebugSerial	Serial
-#else
-#define mySerial Serial
-SoftwareSerial DebugSerial(_DBG_RXPIN_,_DBG_TXPIN_);
 #endif
+

 boolean findHeader()
 {
@@ -29,6 +29,7 @@
 void setup() {
     mySerial.begin(SENSOR_BAUD_RATE);     // opens serial port, sets data rate to 9600 bps
     DebugSerial.begin(DEBUG_BARUD_RATE);
+    delay(1000);
     pinMode(SET_PIN, OUTPUT);
     digitalWrite(SET_PIN, LOW);
     delay(100);
@@ -38,7 +39,8 @@
 void loop() {
     static unsigned int data[15]={0};
     int i;
-
+
+    DebugSerial.println("reading..");
     while (!( mySerial.available() > 0 && findHeader() )) { };

     //DebugSerial.println(mySerial.available());


ccitt CRC

ccitt CRC

--- gatherer/gatherer.ino
+++ gatherer/gatherer.ino
@@ -6,17 +6,28 @@
 #include <SFE_LSM9DS0.h>
 #include <TinyGPS++.h>

+#define lo8(x) ((x)&0xff)
+#define hi8(x) ((x)>>8)

 #define LSM9DS0_XM  0x1D // Would be 0x1E if SDO_XM is LOW
 #define LSM9DS0_G   0x6B // Would be 0x6A if SDO_G is LOW
 LSM9DS0 dof(MODE_I2C, LSM9DS0_G, LSM9DS0_XM);

-inline uint16_t softcrcXMODEM(uint16_t seed, uint8_t *data, uint16_t datalen) {
+
+uint16_t crc_ccitt_update (uint16_t crc, uint8_t data) {
+  data ^= lo8 (crc);
+  data ^= data << 4;
+  return ((((uint16_t)data << 8) | hi8 (crc)) ^ (uint8_t)(data >> 4)
+    ^ ((uint16_t)data << 3));
+}
+
+inline uint16_t softcrc(uint16_t seed, uint8_t *data, uint16_t datalen) {
     for (uint16_t i=0; i<datalen; i++) {
-        seed = _crc_xmodem_update(seed,  data[i]);
+        seed = crc_ccitt_update(seed,  data[i]);
     }
     return seed;
 }
+

 SFE_BMP180 pressure;
 TinyGPSPlus gps;
@@ -26,9 +37,6 @@
 boolean cameraState = 0;

 int communicationPin = 15;
-<<<<<<< Updated upstream
-<<<<<<< Updated upstream
-<<<<<<< Updated upstream

 const byte magic = 0xFF;

@@ -71,7 +79,7 @@
     Serial1.write((byte) to_send[k]);
   }

-  crc = softcrcXMODEM(0, to_send, to_send_next_pos);
+  crc = softcrc(0, to_send, to_send_next_pos);

   byte hi = crc >> 8;
   byte lo = crc & 0xFF;
@@ -118,13 +126,6 @@
     to_send_next_pos++;
   }
 }
-
-=======
->>>>>>> Stashed changes
-=======
->>>>>>> Stashed changes
-=======
->>>>>>> Stashed changes

 void setup() {
   Serial1.begin(19200);


make "if" statement instead of just ifdef

--- arduino/ws2812_controller/ws2812_controller.ino
+++ arduino/ws2812_controller/ws2812_controller.ino
@@ -48,10 +48,11 @@
 }

 uint8_t N = 0;
-#ifdef PRINT_FPS
-int fpsCounter = 0;
-int secondTimer = 0;
-#endif
+if(PRINT_FPS == 1)
+{
+    int fpsCounter = 0;
+    int secondTimer = 0;
+}
 void loop() {
     // Read data over socket
     int packetSize = port.parsePacket();
@@ -66,12 +67,14 @@
             pixels[N].B = (uint8_t)packetBuffer[i+3];
         }
       ledstrip.show(pixels);
-      Serial.print("*");
-      #ifdef PRINT_FPS
+
+      if(PRINT_FPS == 1)
+      {
+        Serial.print("*");
         fpsCounter++;
-      #endif
+      }
   }
-  #ifdef PRINT_FPS
+ if(PRINT_FPS == 1){
   if(millis() - secondTimer >= 1000)
   {
     secondTimer = millis();
@@ -79,5 +82,5 @@
     Serial.printf("FPS: %d\n", fpsCounter);
     fpsCounter = 0;
   }
-  #endif
+ }
 }


More work on notification/display handling

--- Sakuya_TiLDA/Sakuya_TiLDA.ino
+++ Sakuya_TiLDA/Sakuya_TiLDA.ino
@@ -16,6 +16,7 @@
 display_t display = DISPLAY_IDLE;

 nlist_t *notif_list_head;
+nlist_t *current_display_notif;

 void setup(void)
 {
@@ -45,9 +46,11 @@
       case 'N':
         process_notification_message(data);
         break;
+
       case 'L':
         process_led_message(data);
         break;
+
       default:
         break;
     }
@@ -59,13 +62,14 @@
   // Poll backlight timeout
   backlight_timeout(BACKLIGHT_IDLE_TIMEOUT_MS);

+  if((display == DISPLAY_NOTIFICATIONS) && (!current_display_notif))
+    display = DISPLAY_IDLE;
+
   // Display some text on the GLCD
   tilda.glcd.firstPage();
   do
   {
-    //TODO
-
-    tilda.glcd.drawBitmapP(0, 0, 8, 64, sakuya_1_bitmap);
+    draw();
   }
   while(tilda.glcd.nextPage());
 }
@@ -75,6 +79,10 @@
  */
 void button_handler(buttonid_t id, uint32_t time)
 {
+  // Ignore short presses
+  if(time < 100)
+    return;
+
   // Toggle backlight on pressing Light button
   if(id == BUTTON_LIGHT)
   {
@@ -92,10 +100,12 @@
       if(handle_idle_buttons(id))
         enable_backlight();
       break;
+
     case DISPLAY_NOTIFICATIONS:
       if(handle_notification_buttons(id))
         enable_backlight();
       break;
+
     default:
       return;
   }
@@ -113,8 +123,11 @@
     case BUTTON_DOWN:
     case BUTTON_UP:
     case BUTTON_A:
-      //TODO: Go to notification display
-      break;
+      display = DISPLAY_NOTIFICATIONS;
+      if(!current_display_notif)
+        current_display_notif = notif_list_tail();
+      break;
+
     default:
       return false;
   }
@@ -129,20 +142,38 @@
  */
 bool handle_notification_buttons(buttonid_t id)
 {
+  notification_t *current_notif = current_display_notif->notification;
+
   switch(id)
   {
     case BUTTON_DOWN:
-      //TODO: Go to previous notification
-      break;
+      // Go to previous notification
+      if(current_display_notif->prev)
+        current_display_notif = current_display_notif->prev;
+      break;
+
     case BUTTON_UP:
-      //TODO: Go to next notification
-      break;
+      // Go to next notification
+      if(current_display_notif->next)
+        current_display_notif = current_display_notif->next;
+      break;
+
     case BUTTON_A:
-      //TODO: Dismiss notification
-      break;
+      // Try to find a new notification to display
+      if(current_display_notif->next)
+        current_display_notif = current_display_notif->next;
+      else if(current_display_notif->prev)
+        current_display_notif = current_display_notif->prev;
+      else
+        display = DISPLAY_IDLE;
+
+      notif_list_remove(current_notif);
+      break;
+
     case BUTTON_B:
-      //TODO: Go to idle display
-      break;
+      display = DISPLAY_IDLE;
+      break;
+
     default:
       return false;
   }
@@ -307,7 +338,10 @@
 {
   nlist_t *current = notif_list_head;

-  while(current->next != NULL)
+  if(!current)
+    return NULL;
+
+  while(current->next)
     current = current->next;

   return current;
@@ -347,7 +381,7 @@
 {
   nlist_t *current = notif_list_head;

-  while(current != NULL)
+  while(current)
   {
     if(current->notification == notif)
       break;
@@ -376,3 +410,37 @@

   return true;
 }
+
+void draw()
+{
+  switch(display)
+  {
+    case DISPLAY_IDLE:
+      draw_idle();
+      break;
+
+    case DISPLAY_NOTIFICATIONS:
+      draw_notification(current_display_notif->notification);
+      break;
+  }
+}
+
+/**
+ * Draws the idle/no notifications display.
+ */
+void draw_idle()
+{
+  //TODO
+  tilda.glcd.drawBitmapP(0, 0, 8, 64, sakuya_1_bitmap);
+}
+
+/**
+ * Draws infor for a given notification.
+ *
+ * @param notif Notification to draw
+ */
+void draw_notification(notification_t *notif)
+{
+  //TODO
+  tilda.glcd.drawBitmapP(0, 0, 8, 64, flan_bitmap);
+}


Delete InkyBoard_06_color.ino

Delete InkyBoard_06_color.ino

--- examples/InkyBoard_06_color/InkyBoard_06_color.ino
+++ examples/InkyBoard_06_color/InkyBoard_06_color.ino
@@ -1,31 +0,0 @@
-/**
- * color
- *
- */
-
-#include <Servo.h>
-#include <InkyBoard.h>
-#include <Display.h>
-
-InkyBoard B; // definieer B als InkyBoard
-void setup() {
-  B.DEBUG = true; // laat debug zien (via seriele poort)
-  B.init(); // initieer het bord
-
-  B.calibrateColor(B.CALIBRATE_BLACK); // zwart kalibreren, als debug aanstaat wordt er eerst 3 sec gewacht zodat je tijd hebt om papier voor de sensor te doen
-  delay(1000);
-  B.calibrateColor(B.CALIBRATE_WHITE); // ook wit kalibreren
-}
-
-void loop() {
-    B.getColor(); // waardes worden weggeschreven naar seriele poort als debug aan staat
-
-    /**
-     * de waardes van de kleuren bevinden zich in:
-     * B.colorR -> rood
-     * B.colorG -> groen
-     * B.colorB -> blauw
-     */
-
-    delay(500);
-}


Change timing for pumping

Change timing for pumping

--- prevyuduino/prevyuduino.ino
+++ prevyuduino/prevyuduino.ino
@@ -77,7 +77,9 @@
   sensorValue = analogRead(analogInPin);
   Serial.print("Sensor: ");
   Serial.println(sensorValue);
-  levelIsDown = sensorValue>250;
+  levelIsDown = sensorValue>512;
+  Serial.print("dropCounter: ");
+  Serial.println(dropCounter);

   if (dropCounter>150) //This should normaly never happen
   {
@@ -100,8 +102,10 @@
       if (!freeze)
       {
         digitalWrite(pumpPin, HIGH);
-        Serial.println("High");
-        delay(5000);
+        Serial.println("Pump");
+        delay(1000);
+        digitalWrite(pumpPin, LOW);
+        delay(2000);
         dropCounter = 0; //Reset the drop counter
       }
     }
@@ -120,7 +124,7 @@
     }
     digitalWrite(pumpPin, LOW);
   }
-  levelWasDown = (sensorValue>250);
+  levelWasDown = (sensorValue>512);

   // change the analog out value:
   analogWrite(analogOutPin, int(receivedValue));
@@ -168,7 +172,7 @@
          digitalWrite(analogOutPin, HIGH);   // turn the flow on (HIGH is the voltage level)
          dropCounter++;
        }
-       delay(900);               // wait for a second
+       delay(1100);               // wait for a second

    }
 }


Also turn lights on in Arduino experimentation code

--- experiments/NewPing4Sensors/NewPing4Sensors.ino
+++ experiments/NewPing4Sensors/NewPing4Sensors.ino
@@ -10,10 +10,10 @@
 uint8_t currentSensor = 0;          // Keeps track of which sensor is active.

 NewPing sonar[SONAR_NUM] = {     // Sensor object array.
-  NewPing(11, 12, MAX_DISTANCE), // Each sensor's trigger pin, echo pin, and max distance to ping.
-  NewPing(9, 10, MAX_DISTANCE),
-  NewPing(2, 3, MAX_DISTANCE),
-  NewPing(5, 6, MAX_DISTANCE)
+  NewPing(13+2, 13+1, MAX_DISTANCE), // Each sensor's trigger pin, echo pin, and max distance to ping.
+  NewPing(13+4, 13+3, MAX_DISTANCE),
+  NewPing(13+6, 13+5, MAX_DISTANCE),
+  NewPing(8, 7, MAX_DISTANCE)
 };

 void setup() {
@@ -21,6 +21,28 @@
   pingTimer[0] = millis() + 75;           // First ping starts at 75ms, gives time for the Arduino to chill before starting.
   for (uint8_t i = 1; i < SONAR_NUM; i++) // Set the starting time for each sensor.
     pingTimer[i] = pingTimer[i - 1] + PING_INTERVAL;
+
+
+  pinMode(3, OUTPUT);
+  pinMode(5, OUTPUT);
+  pinMode(6, OUTPUT);
+  pinMode(9, OUTPUT);
+  pinMode(10, OUTPUT);
+  pinMode(11, OUTPUT);
+  /*
+  digitalWrite(3, HIGH);
+  digitalWrite(5, HIGH);
+  digitalWrite(6, HIGH);
+  digitalWrite(9, HIGH);
+  digitalWrite(10, HIGH);
+  digitalWrite(11, HIGH);
+  */
+//  analogWrite(3, 100);
+  analogWrite(5, 100);
+  analogWrite(6, 100);
+  analogWrite(9, 100);
+  analogWrite(10, 100);
+  analogWrite(11, 100);
 }

 void loop() {


communication tests

communication tests

--- serialracoon.ino
+++ serialracoon.ino
@@ -25,7 +25,7 @@
 #define HC_05_SETUPKEY        4
 #define HC_05_PWR1            5  // Connect in parallel to HC-05 VCC
 #define HC_05_PWR2            6  // Connect in parallel to HC-05 VCC
-#define CMD_W                 500 // msec
+#define CMD_W                 1100 // msec

 #define msg(x) Serial.println(x)

@@ -138,6 +138,7 @@

 }

+long int cnt = 0;
 void loop()
 {
   int btIn = -1;
@@ -165,6 +166,14 @@
     //Serial.print(fromSerialStr);
   }

+
+  char out[80];
+
+  sprintf(out, "test data sequince %d\r\n", cnt++);
+//  BTSerial.write("test data sequince\r\n");
+  BTSerial.write(out);
+  delay(100);
+
 }


add more comments describing the fucntionality of the code.

--- firmware/PCB_V02/PCB_V02.ino
+++ firmware/PCB_V02/PCB_V02.ino
@@ -106,13 +106,21 @@

 void loop() {

-  //handle motor control
+  // Is the motor on? If so, has it been on for more time than motorOn?
+  // Is the motorCommand still ON or has it been turned off by other logic?
+  // If all true, then turn off the motor and record the time.
   if (motorState == HIGH && (millis() - time) >= motorOn && motorCommand) {
     motorState = LOW;
     digitalWrite(motorPin, motorState);
     time = millis();
   }

+  // Is the motor off? Is so, has it been off for more time than motorOff?
+  // Is there a pulse count remaining in motorPulse?
+  // Is the motorCommand still ON or has it been turned off by other logic?
+  // If all true, then turn on the motor, decrease the pulse count by 1
+  // and record the time. If the pulse count goes to 0 then turn off the
+  // motorCommand. The last haptic pulse has been sent.
   if (motorState == LOW && (millis() - time) >= motorOff
                           && motorPulse > 0 && motorCommand) {
     motorState = HIGH;
@@ -125,6 +133,9 @@
     }
   }

+  // If the motor has been on for time = motorOn and the motorCommand
+  // has been switched to false, then turn off the motor, stop the haptic
+  // feedback and reset the motorPulse to the original motorCount.
   if ((millis()-time) >= motorOn && !motorCommand) {
     motorState = LOW;
     digitalWrite(motorPin, motorState);
@@ -142,6 +153,8 @@
     aJson.deleteItem(msg);
   }

+  // Until USB has been connected, display a spinning wheel on
+  // the 7 segment display.
   if (!usbConnected) {
     for (int c = 0; c < 6; c++) {
       sendDigit(circle[c]);


clock/2

clock/2

Signed-off-by: Robert Nelson <d6c41255011d14bfa93d8562b946ca186cfa0c7b@gmail.com>

--- ws_bm_rtc.ino
+++ ws_bm_rtc.ino
@@ -1,4 +1,5 @@
 #include <Wire.h>
+#include <avr/power.h>
 #include "Adafruit_INA219.h"
 #include "RTClib.h"
 /* https://www.digikey.com/product-detail/en/sparkfun-electronics/SEN-11050/1568-1228-ND/5721423 */
@@ -10,11 +11,20 @@

 char daysOfTheWeek[7][12] = {"Sunday", "Monday", "Tuesday", "Wednesday", "Thursday", "Friday", "Saturday"};

+/* 16Mhz */
+//#define ws_baud 57600
+//#define ws_one_second 1000
+//#define ws_short_delay 200
+
+/* 8Mhz */
+#define ws_baud 115200
+#define ws_one_second 2000
+#define ws_short_delay 400
+
 void setup () {
-	//while (!Serial1);     // will pause Zero, Leonardo, etc until serial console opens
-	uint32_t currentFrequency;
+	clock_prescale_set(clock_div_2);

-	Serial1.begin(57600);
+	Serial1.begin(ws_baud);
 	Serial1.println("Hello!");

 	if (! rtc.begin()) {
@@ -82,50 +92,51 @@
 	current_mA_B = ina219_B.getCurrent_mA();
 	loadvoltage_B = busvoltage_B + (shuntvoltage_B / 1000);

-	delay(1000);
+	delay(ws_short_delay);

 	Serial1.print("$LOAD:"); Serial1.print(now.unixtime());
 	Serial1.print(":BusVolt:"); Serial1.print(busvoltage_A); Serial1.println("V*");

-	delay(200);
+	delay(ws_short_delay);

 	Serial1.print("$LOAD:"); Serial1.print(now.unixtime());
 	Serial1.print(":ShuntVolt:"); Serial1.print(shuntvoltage_A); Serial1.println("mV*");

-	delay(200);
+	delay(ws_short_delay);

 	Serial1.print("$LOAD:"); Serial1.print(now.unixtime());
 	Serial1.print(":LoadVolt:"); Serial1.print(loadvoltage_A); Serial1.println("V*");

-	delay(200);
+	delay(ws_short_delay);

 	Serial1.print("$LOAD:"); Serial1.print(now.unixtime());
 	Serial1.print(":Current:"); Serial1.print(current_mA_A); Serial1.println("mA*");

-	delay(200);
-
-	//delay(1000);
+	delay(ws_short_delay);

 	Serial1.print("$SOLAR:"); Serial1.print(now.unixtime());
 	Serial1.print(":BusVolt:"); Serial1.print(busvoltage_B); Serial1.println("V*");

-	delay(200);
+	delay(ws_short_delay);

 	Serial1.print("$SOLAR:"); Serial1.print(now.unixtime());
 	Serial1.print(":ShuntVolt:"); Serial1.print(shuntvoltage_B); Serial1.println("mV*");

-	delay(200);
+	delay(ws_short_delay);

 	Serial1.print("$SOLAR:"); Serial1.print(now.unixtime());
 	Serial1.print(":LoadVolt:"); Serial1.print(loadvoltage_B); Serial1.println("V*");

-	delay(200);
+	delay(ws_short_delay);

 	Serial1.print("$SOLAR:"); Serial1.print(now.unixtime());
 	Serial1.print(":Current:"); Serial1.print(current_mA_B); Serial1.println("mA*");
 	Serial1.println("");

-	//delay(1000);
-	//delay(3000);
-	delay(3200);
+	delay(ws_short_delay);
+	delay(ws_short_delay);
+	delay(ws_one_second);
+	delay(ws_one_second);
+	delay(ws_one_second);
 }
+


updated parallel out 2

updated parallel out 2

--- proj/parallel_out_test_2/parallel_out_test_2.ino
+++ proj/parallel_out_test_2/parallel_out_test_2.ino
@@ -6,9 +6,6 @@

 CRGB leds[NUM_STRIPS * NUM_LED];
-
-CRGB led_inter[NUM_STRIPS][NUM_LED];
-

 // READ ME!!! //
 // These are the pins on the arduion we're using. Attach a 5ft strip to each of the pins, then just tell me
@@ -35,8 +32,6 @@
   CRGB::Black,
 };

-CRGBPalette16 gPalette;
-uint8_t gHue;

 void setup() {
   // LEDS.addLeds<WS2811_PORTA,NUM_STRIPS>(leds, NUM_LEDS_PER_STRIP);
@@ -51,48 +46,13 @@
 void loop() {

-  //  for (uint8_t ss = 0; ss < NUM_STRIPS; ss++) {
-  //    fill_solid(&(leds[ss*NUM_LED]), NUM_LED, CHSV(2*ss*16, 192, 255));
-  //  }
-
-  EVERY_N_MILLISECONDS(10) {
-    gHue++;
-  }
-
-  update_RainbowBlack_p();
-  theater_chase();
-
-  for(uint8_t strip = 0; strip < NUM_STRIPS; strip++) {
-    for(uint8_t ll = 0; ll < NUM_LED; ll++) {
-      leds[strip*NUM_LED + ll] = led_inter[strip][ll];
+  for (uint8_t strip = 0; strip < NUM_STRIPS; strip++) {
+    for (uint8_t ll = 0; ll < NUM_LED; ll++) {
+      leds[strip * NUM_LED + ll] = CHSV(strip*2*16, 192, 255);
     }
   }

   LEDS.show();
-  LEDS.delay(100);
+  LEDS.delay(10);
 }

-void theater_chase() {
-  static uint8_t pal_index = 0;
-  EVERY_N_MILLISECONDS(100) {
-    pal_index++;
-  }
-
-  for (uint8_t ss = 0; ss < NUM_STRIPS; ss++) {
-    fill_palette(led_inter[ss], NUM_LED, pal_index, 6, gPalette, 60, LINEARBLEND);
-  }
-
-}
-
-// RB|B|B|B repeating
-void update_RainbowBlack_p() {
-  // Instead of blacking out, fill backgroud with rainbow, then
-  // fill every thing with black except
-  fill_rainbow(gPalette, 16, gHue, 10);
-  for (uint8_t i = 0 ; i < 16; i++) {
-    if ( i % 4 == 0) {
-      continue;
-    }
-    gPalette[i] = CRGB::Black;
-  }
-}


Support transition velocity and multiple sensors

--- projects/musicbox/firmware/MusicBox/MusicBox.ino
+++ projects/musicbox/firmware/MusicBox/MusicBox.ino
@@ -24,12 +24,12 @@

   void sendNoteOn(byte channel, byte key, byte velocity)
   {
-    sendCommand(0x80, channel, key, velocity);
+    sendCommand(0x90, channel, key, velocity);
   }

   void sendNoteOff(byte channel, byte key, byte velocity)
   {
-    sendCommand(0x90, channel, key, velocity);
+    sendCommand(0x80, channel, key, velocity);
   }

 private:
@@ -43,6 +43,89 @@
   Stream& mStream;
 };

+class MusicBoxPip
+{
+public:
+  static const int kMaxTime = 1000;
+  static const int kMinVelocity = 1;
+  static const int kMaxVelocity = 128;
+
+  enum Transition
+  {
+    eTransitioned_None,
+    eTransitioned_On,
+    eTransitioned_Off
+  };
+
+public:
+  MusicBoxPip() :
+    mPin(0),
+    mVelocity(0),
+    mWasOn(false),
+    mStartTime(0)
+  {
+  }
+
+  void begin(int pin)
+  {
+    mPin = pin;
+    pinMode(mPin, INPUT);
+    mWasOn = isOnNow();
+    mStartTime = millis();
+  }
+
+  Transition checkTransition()
+  {
+    bool isOn = isOnNow();
+    Transition transition = eTransitioned_None;
+
+    if (!mWasOn && isOn)
+    {
+      calculateTransitionVelocity();
+      transition = eTransitioned_On;
+    }
+    else if(mWasOn && !isOn)
+    {
+      calculateTransitionVelocity();
+      transition = eTransitioned_Off;
+    }
+
+    mWasOn = isOn;
+    return transition;
+  }
+
+  int transitionVelocity()
+  {
+    return mVelocity;
+  }
+
+private:
+
+  bool isOnNow()
+  {
+    return digitalRead(mPin) <= 0;
+  }
+
+  void calculateTransitionVelocity()
+  {
+    unsigned long now = millis();
+    unsigned long elapsed = now - mStartTime;
+    mStartTime = now;
+
+    if (elapsed > kMaxTime)
+    {
+      elapsed = kMaxTime;
+    }
+
+    mVelocity = map(kMaxTime - elapsed, 0, kMaxTime, kMinVelocity, kMaxVelocity);
+  }
+
+  int mPin;
+  bool mWasOn;
+  unsigned long mStartTime;
+  int mVelocity;
+};
+
 //
 // Serial MIDI device:
 //  Baud: 9600
@@ -52,21 +135,23 @@

 static const int kMidiBaud = 9600;
 static const int kMidiChannel = 0;
-static const int kDotCount = 13;
-static byte sPitchMap[kDotCount];

-static const int kMidiBegin = 30;
-static const int kMidiEnd = 85;
-static const int kVelocity = 64;
+static const int kMidiNoteBegin = 52;
+static const int kMidiNoteEnd = 58;

-static int sDot = 0;
+static const int kPipCount = 6;
+static MusicBoxPip sMusicBoxPips[kPipCount];
+static byte sPitchMap[kPipCount];
+static int sPinMap[] = {13, 12, 11, 10, 9, 8};

 void setup()
 {
+
   // Seed pitch map table with something...
-  for (int dot = 0; dot < kDotCount; dot++)
+  for (int pip = 0; pip < kPipCount; pip++)
   {
-    sPitchMap[dot] = map(dot, 0, kDotCount - 1, kMidiBegin, kMidiEnd);
+    sMusicBoxPips[pip].begin(sPinMap[pip]);
+    sPitchMap[pip] = map(pip, 0, kPipCount - 1, kMidiNoteBegin, kMidiNoteEnd);
   }

   Serial.begin(kMidiBaud);
@@ -75,11 +160,19 @@

 void loop()
 {
-  sMidiStream.sendNoteOn(kMidiChannel, sPitchMap[sDot], kVelocity);
-  delay(100);
-  sMidiStream.sendNoteOff(kMidiChannel, sPitchMap[sDot], kVelocity);
-  delay(1000);
-
-  sDot = (sDot + 1) % kDotCount;
+  for (int pip = 0; pip < kPipCount; pip++)
+  {
+    MusicBoxPip::Transition transition = sMusicBoxPips[pip].checkTransition();
+
+    if (transition == MusicBoxPip::eTransitioned_On)
+    {
+      sMidiStream.sendNoteOn(kMidiChannel, sPitchMap[pip], sMusicBoxPips[pip].transitionVelocity());
+    }
+    else if (transition == MusicBoxPip::eTransitioned_Off)
+    {
+      sMidiStream.sendNoteOff(kMidiChannel, sPitchMap[pip], sMusicBoxPips[pip].transitionVelocity());
+    }
+  }
 }
+


victory song

victory song

--- pingpong/pingpong.ino
+++ pingpong/pingpong.ino
@@ -6,8 +6,10 @@

 #define P1PIN           8
 #define P2PIN           9
+#define SPEAKERPIN      6
 #define LONGPRESS_TIME 25

+// Button handling
 enum { BUTTON_NONE=0, BUTTON_SHORT, BUTTON_LONG};

 class Button {
@@ -59,8 +61,65 @@
   return event;
 }

-
-
+// Victory Song
+class VictorySong {
+  public:
+    VictorySong(int pin);
+    void init();
+    void play();
+
+  protected:
+    const int pin;
+    int songLength;
+    char *notes;
+    int tempo;
+    int frequency(char note);
+};
+
+VictorySong::VictorySong(int p) : pin(p)
+{
+}
+
+void VictorySong::init()
+{
+  pinMode(pin, OUTPUT);
+  songLength = 17;
+  notes = "efg dab bbbbbaagg";
+  tempo = 94;
+}
+
+void VictorySong::play()
+{
+  int i, duration;
+  int beats[] = {1,2,5,3,2,4,2,5,2,2,2,2,3,3,3,3,2};
+  for (i = 0; i < songLength; i++) {
+    duration = beats[i] * tempo;
+
+    if (notes[i] == ' ') {
+      delay(duration);
+    } else {
+      tone(pin, frequency(notes[i]), duration);
+      delay(duration);
+    }
+    delay(tempo/10);
+  }
+}
+
+int VictorySong::frequency(char note)
+{
+  int i;
+  const int numNotes = 8;
+  char names[] = {'c', 'd', 'e', 'f', 'g', 'a', 'b', 'C'};
+  int frequencies[] = {262, 294, 330, 349, 392, 440, 494, 523};
+  for (i = 0; i < numNotes; i++) {
+    if (names[i] == note) {
+      return(frequencies[i]);
+    }
+  }
+  return 0;
+}
+
+// Game Logics
 int p1Score = 0;
 int p2Score = 0;

@@ -68,6 +127,7 @@

 Button p1Button(P1PIN);
 Button p2Button(P2PIN);
+VictorySong victorySong(SPEAKERPIN);

 void setup()
 {
@@ -80,6 +140,7 @@

   p1Button.init();
   p2Button.init();
+  victorySong.init();
 }

 void loop()
@@ -148,6 +209,7 @@
       lcd.print("WINNER");
     }
     Serial.println("   *** WINNER ***");
+    victorySong.play();

     gameOver = 1;
   }


examples-ltc: basicthreads: trim trailing whitespace

Remove trailing whitespace from BasicThreads.ino.

Signed-off-by: Sean Cross <d7e19930cc1f42c2d0781f4d9e6f1fe5891bf9cf@xobs.io>

--- examples-ltc/B.Threads/BasicThreads/BasicThreads.ino
+++ examples-ltc/B.Threads/BasicThreads/BasicThreads.ino
@@ -28,7 +28,7 @@
 #define THREAD_MEMORY 64
 // higher numbers will get run first if there's a scheduling conflict
 // The highest number is 127
-#define THREAD_PRIORITY 20
+#define THREAD_PRIORITY 20

 // You can make more threads if you want, to control more pins!
 #define NUMBER_OF_THREADS 2
@@ -43,7 +43,7 @@
 };
 static fade_thread_config thread_config[NUMBER_OF_THREADS];

-static thread_t *fade_threads[NUMBER_OF_THREADS];
+static thread_t *fade_threads[NUMBER_OF_THREADS];

 // this magic function creates a Thread from heap
 static thread_t *runThread(tfunc_t pf, void *arg) {
@@ -60,22 +60,22 @@
 // You'll recognize this code from the "fade" demo!
 void fade_code(void *config) {
   struct fade_thread_config *cfg = (struct fade_thread_config *)config;
-
-  int led = cfg->pin;
+
+  int led = cfg->pin;
   int fadeAmount = cfg->speed;
-
+
   int brightness = 0;
   while(1) {
     analogWrite(led, brightness);    // update the led's brightness

     // move the brightness by fadeAmount toward a brightness limit
     brightness = brightness + fadeAmount;
-
+
     // check if the brightness is at the bottom or top of the 0-255 scale
     // if it is, invert the amount we fade by
     if (brightness <= 0 || brightness >= 255) {
-      fadeAmount = -fadeAmount ;
-    }
+      fadeAmount = -fadeAmount;
+    }
     // pause for 30 milliseconds, or else the effect is too fast
     delay(30);
   }
@@ -86,19 +86,19 @@
   thread_config[0].pin = 3; // pin number can be set to any number 0-5
   thread_config[1].pin = 4;
   //            ^ this is the thread number, has to be less than NUMBER_OF_THREADS
-
+
   // configure the speed of fading
   thread_config[0].speed = 5;
   thread_config[1].speed = 8;

   // start each of the threads. We do this in setup, not loop, because
   // we don't want to keep on starting threads over and over again!
-
-  // The first thread starts running after this line of code.
+
+  // The first thread starts running after this line of code.
   fade_threads[0] = runThread(fade_code, &thread_config[0]);
-
+
   delay(1000); // this will delay the start of the second thread by 1 second
-
+
   // The second thread starts running after this line of code.
   fade_threads[1] = runThread(fade_code, &thread_config[1]);
 }


Update comment in IRRemoteControlDemo.ino

--- examples/IRRemoteControlDemo/IRRemoteControlDemo.ino
+++ examples/IRRemoteControlDemo/IRRemoteControlDemo.ino
@@ -1,5 +1,5 @@
 /*
- * IRRemoteControle: IRRemoteControlDemo - demonstrates receiving/sending IR codes.
+ * IRRemoteControl: IRRemoteControlDemo - demonstrates receiving/sending IR codes.
  * Created by Cristiano Borges - STI - Fatesg
  * August, 2017
  */


update

update

--- src/Firmware.ino
+++ src/Firmware.ino
@@ -7,7 +7,7 @@
 #ifdef MAKEBLOCK
 #define PULSES_PER_MM 80
 #else
-#define PULSES_PER_MM 100
+#define PULSES_PER_MM 60
 #endif
 #define CURVE_SECTION 0.5
 #define NUM_STEPS 10
@@ -36,6 +36,7 @@
 } PlannerPoint;
 typedef struct
 {
+    volatile bool prevDir[NUM_AXIS] = {0, 0};
     volatile long currentPosition[NUM_AXIS] = {0, 0};
     volatile long targetPosition[NUM_AXIS];
     volatile long startPosition[NUM_AXIS];
@@ -82,7 +83,7 @@
 {
     Serial.begin(115200);
     Serial.println("start");
-    delay(3000);
+    delay(300);
     initTimer();
 #ifdef MAKEBLOCK
     pinMode(47, OUTPUT);
@@ -96,12 +97,16 @@
         steppers[i].setMicroStep(16);
         steppers[i].disableOutputs();
     }
-#endif
-    // setPower(0);
-    // setSpeed(1000);
+#else
+    steppers[0].setBack(0);
+    steppers[1].setBack(0);
+#endif
+    setPower(0);
+    setSpeed(100);
+    setAccel(100);
     // firePower(80);
-    // moveTo(0, 0);
-
+    moveTo(-100, -100);
+    lineTo(0, 0);
     Serial.println("opened");
     // testRun();
 }
@@ -351,8 +356,6 @@
                 {
                     lineTo(x, y);
                 }
-                _sys.targetPosition[0] = x;
-                _sys.targetPosition[1] = y;
             }
             break;
             case 4:
@@ -368,6 +371,8 @@
                 waitingForFinish();
                 _sys.currentPosition[0] = 0;
                 _sys.currentPosition[1] = 0;
+                _sys.targetPosition[0] = 0;
+                _sys.targetPosition[1] = 0;
             }
             break;
             case 90:
@@ -423,6 +428,31 @@
                 }
                 break;
             }
+            case 5:
+            {
+                if (hasCommand('x') && hasCommand('y'))
+                {
+                    long x = getCommand('x');
+                    long y = getCommand('y');
+                    steppers[0].setBack(x);
+                    steppers[1].setBack(y);
+                }
+                break;
+            }
+            case 6:
+            {
+                if (hasCommand('x') && hasCommand('y'))
+                {
+                    long x = getCommand('x') / 2;
+                    long y = getCommand('y') / 2;
+                    for (int i = 0; i < 5; i++)
+                    {
+                        moveTo(-x + _sys.targetPosition[0], -y + _sys.targetPosition[1]);
+                        moveTo(x + _sys.targetPosition[0], y + _sys.targetPosition[1]);
+                    }
+                }
+                break;
+            }
             }
         }
         finishCommand();
@@ -430,6 +460,8 @@
 }
 void addMotion(long x, long y, uint8_t power, uint16_t speed, uint16_t acceleration)
 {
+    _sys.targetPosition[0] = x;
+    _sys.targetPosition[1] = y;
     _points[_sys.plannedIndex].targetPosition[0] = x;
     _points[_sys.plannedIndex].targetPosition[1] = y;
     _points[_sys.plannedIndex].dir[0] = _prevPoint.targetPosition[0] < _points[_sys.plannedIndex].targetPosition[0];
@@ -497,6 +529,8 @@
 {
     if (_sys.plannedLength > 0)
     {
+        _sys.prevDir[0] = _points[0].dir[0];
+        _sys.prevDir[1] = _points[0].dir[1];
         for (int i = 0; i < _sys.plannedLength - 1; i++)
         {
             _points[i] = _points[i + 1];
@@ -516,6 +550,14 @@
         shiftPlanned();
         if (_sys.plannedLength > 0)
         {
+            if (_sys.prevDir[0] != _points[0].dir[0])
+            {
+                _sys.currentPosition[0] -= steppers[0].getBack() * (_points[0].dir[0] ? 1 : -1);
+            }
+            if (_sys.prevDir[1] != _points[0].dir[1])
+            {
+                _sys.currentPosition[1] -= steppers[1].getBack() * (_points[0].dir[1] ? 1 : -1);
+            }
             firePower(_points[0].power);
         }
 #ifdef DEBUG


Installed tail servos and added support to trigger them.

--- arduino/motion/src/drive/drive.ino
+++ arduino/motion/src/drive/drive.ino
@@ -1,3 +1,5 @@
+#include <Servo.h>
+
 /*
  * K9OS drive motor sketch
  * Controls Scooter Motors,
@@ -274,16 +276,16 @@
     } if(rotate>0){
       // Left
       //Serial.println("lf");
-      analogWrite(PWMPin, 50);
+      analogWrite(PWMPin, 70);
       analogWrite(PWMPinA, 0);
       analogWrite(PWMPin2, 0);
-      analogWrite(PWMPinA2,50);
+      analogWrite(PWMPinA2,70);
       digitalWrite(EnablePin, HIGH);
     } if(rotate<0) {
       // Backward
       analogWrite(PWMPin, 0);
-      analogWrite(PWMPinA,50 );
-      analogWrite(PWMPin2,50);
+      analogWrite(PWMPinA,70 );
+      analogWrite(PWMPin2,70);
       analogWrite(PWMPinA2,0);
       digitalWrite(EnablePin, HIGH);
     }


max speed to player in playback

max speed to player in playback

--- saymon_says/saymon_says.ino
+++ saymon_says/saymon_says.ino
@@ -27,9 +27,9 @@
 const int maxLength = 100; //max level
 const int statePrepare = 0;
 const int statePlay = 1;
-const int stateEnd = 2;
+const int stateGameOver = 2;
 const int stateNewLevel = 3;
-const int statePressedOk = 4;
+const int stateEnd = 4;

 const int buttonUnknow = 0;
 const int buttonDown = 1;
@@ -40,14 +40,14 @@
 int state;
 int sequence[maxLength];
 int currentPlayingSeqIndex;
-int stateRedButton;
-int buttonStates[4] = { buttonUnknow, buttonUnknow, buttonUnknow, buttonUnknow };
+int buttonStates[4];
+unsigned long buttonFeedBackStartMillis;

 void setup() {
   Serial.begin(9600);

   display.begin(SSD1306_SWITCHCAPVCC);
-
+
   pinMode(redLed, OUTPUT);
   pinMode(greenLed, OUTPUT);
   pinMode(yellowLed, OUTPUT);
@@ -63,32 +63,22 @@
     sequence[i] = redButton;
   }

-  stateRedButton = 0;
-
+  for (int i = 0; i < 4; i++ ) {
+    buttonStates[i] = buttonUnknow;
+  }
+
+  buttonFeedBackStartMillis = 0;
 }

 void loop() {
-
-    computeButtonStates(0, redButton, redLed);
-    computeButtonStates(1, greenButton, greenLed);
-    computeButtonStates(2, yellowButton, yello);
-    computeButtonStates(3, blueButton);
-
+
   if (state == stateNewLevel) {
     level ++;
-    String a = "livello ";
-     a += level;
-    displayWrite(a);
+    displayStringInt("livello ", level);
     delay(2000);
     state = statePrepare;
   }

-  if (state == stateEnd) {
-    String a = "punti ";
-    a += level;
-    displayWrite(a);
-  }
-
   if (state == statePrepare) {
     //set
     for (int i = level - 1 ; i < level; i++) {
@@ -98,9 +88,9 @@
       if (button == 2) sequence[i] = yellowButton;
       if (button == 3) sequence[i] = blueButton;
     }
-
+
     //play
-    displayWrite("memorizza");
+    displayString("memorizza");
     for (int i = 0; i < level; i++) {
       int button = sequence[i];
       if (button == redButton) { tone(tonePin, NOTE_C4); digitalWrite(redLed, HIGH); }
@@ -114,9 +104,7 @@
         mapLevel = maxMapLevel;
       }
       int delayMemorization = 500 + map(mapLevel, 1, maxMapLevel, 800, 0);
-
-      //Serial.println(delayMemorization);
-
+
       delay(delayMemorization);
       noTone(tonePin);
       allLedOff();
@@ -124,80 +112,79 @@

     }
     state = statePlay;
-    displayWrite("ripeti");
+    displayString("ripeti");
     currentPlayingSeqIndex = 0;

   }

-  if (state == statePlay) {
-
-
-
+   if (state == statePlay) {
+   //if (state == 100) {
+
+      if (buttonStates[0] == buttonPressed) {
+        checkPressing(redButton);
+        buttonStates[0] = buttonUnknow;
+      } else if (buttonStates[1] == buttonPressed) {
+        checkPressing(greenButton);
+        buttonStates[1] = buttonUnknow;
+      } else if (buttonStates[2] == buttonPressed) {
+        checkPressing(yellowButton);
+        buttonStates[2] = buttonUnknow;
+      } else if (buttonStates[3] == buttonPressed) {
+        checkPressing(blueButton);
+        buttonStates[3] = buttonUnknow;
+      }
+  }
+
+  if (state == stateGameOver) {
+    displayString("sbagliato");
+    delay(1000);
+    displayStringInt("punti ", level);
+    state = stateEnd;
+  }
+
+       //manage pressing
+      computeButtonState(0, redButton, redLed, NOTE_C4);
+      computeButtonState(1, greenButton, greenLed, NOTE_D4);
+      computeButtonState(2, yellowButton, yellowLed, NOTE_E4);
+      computeButtonState(3, blueButton, blueLed, NOTE_F4);
+
+      pressingFeedback(false);

-  //    stateRedButton = analogRead(A0);
-//      stateRedButton = analogRead(A0);
-  //    stateRedButton = analogRead(A0);
-    //  stateRedButton = analogRead(A0);
-  }
-
-//  Serial.println(analogRead(A0));
-  /*
-  if (pressed(redButton) && (state == statePlay)) {
-    checkPressing(redLed, NOTE_C4, redButton);
-  } else if (pressed(greenButton) && (state == statePlay)) {
-    checkPressing(greenLed, NOTE_D4, greenButton);
-  } else if (pressed(yellowButton) && (state == statePlay)) {
-    checkPressing(yellowLed, NOTE_E4, yellowButton);
-  } else if (pressed(blueButton) && (state == statePlay)) {
-    checkPressing(blueLed, NOTE_F4, blueButton);
-  }
-  */
-
-}
-
-void computeButtonStates(int index, int button, int led) {
-      int tmpVal = analogRead(button);
-      delay(20);
-      if (tmpVal > 900) {
-        buttonStates[index] = buttonDown;
-        digitalWrite(led, HIGH);
-      } else {
-        if (buttonStates[index] == buttonDown) {
-          //Serial.print(index);
-          //Serial.println("pressed");
-          buttonStates[index] = buttonPressed;
-          digitalWrite(led, LOW);
-        }
+}
+
+void pressingFeedback(boolean waitForButtonEnd) {
+    if (waitForButtonEnd && buttonFeedBackStartMillis > 0 && millis() - buttonFeedBackStartMillis < 1000) {
+      delay(1000 - (millis() - buttonFeedBackStartMillis));
+      noTone(tonePin);
+        buttonFeedBackStartMillis = 0;
+        //allLedOff();
+    } else {
+      if (buttonFeedBackStartMillis > 0 && millis() > 1000 + buttonFeedBackStartMillis) {
+        noTone(tonePin);
+        buttonFeedBackStartMillis = 0;
+        //allLedOff();
       }
-
-
-}
-
-void checkPressing(int led, unsigned int note, int button) {
-        digitalWrite(led, HIGH);
-         tone(tonePin, note);
-
-       if (sequence[currentPlayingSeqIndex] == button) {
-
-         displayWrite("OK !");
-         currentPlayingSeqIndex ++;
-         if (currentPlayingSeqIndex >= level) {
-           state = stateNewLevel;
-         }
-       } else {
-         displayWrite("sbagliato");
-         state = stateEnd;
-       }
-          delay(1000);
-          noTone(tonePin);
-          allLedOff();
-
-}
-
-boolean pressed(int button) {
-  return analogRead(button) > 900;
-}
-
+    }
+}
+
+void displayStringInt(char * str, int i) {
+    display.setTextSize(2);
+    display.setTextColor(WHITE);
+    display.setCursor(0,0);
+    display.clearDisplay();
+    display.print(str);
+    display.print(i);
+    display.display();
+}
+
+void displayString(char * str) {
+  display.setTextSize(2);
+  display.setTextColor(WHITE);
+  display.setCursor(0,0);
+  display.clearDisplay();
+  display.println(str);
+  display.display();
+}

 void allLedOff() {
   digitalWrite(redLed, LOW);
@@ -207,12 +194,34 @@
 }

-void displayWrite(String text) {
-  display.clearDisplay();
-  display.setTextSize(2);
-  display.setTextColor(WHITE);
-  display.setCursor(0,0);
-  display.print(text);
-  display.display();
-}
-
+void computeButtonState(int index, int button, int led, int note) {
+      int tmpVal = analogRead(button);
+      delay(20);
+      if (tmpVal > 900) {
+        allLedOff();
+        buttonStates[index] = buttonDown;
+        digitalWrite(led, HIGH);
+        tone(tonePin, note);
+        buttonFeedBackStartMillis = millis();
+      } else {
+        if (buttonStates[index] == buttonDown) {
+          buttonStates[index] = buttonPressed;
+          allLedOff();
+        }
+      }
+}
+
+
+void checkPressing(int button) {
+  if (sequence[currentPlayingSeqIndex] == button) {
+    currentPlayingSeqIndex ++;
+    if (currentPlayingSeqIndex >= level) {
+      state = stateNewLevel;
+      pressingFeedback(true);
+    }
+  } else {
+    state = stateGameOver;
+    pressingFeedback(true);
+  }
+
+}