Analyze request, animations and patterns are differents, more stable

--- stripNeopixel/stripNeopixel.ino
+++ stripNeopixel/stripNeopixel.ino
@@ -35,15 +35,13 @@

   Code adapté par et pour Au Fil Elec pour les besoins de l'entreprise
  ****************************************************/
-
+
 #include <Adafruit_CC3000.h>
 #include <SPI.h>
 #include <Adafruit_NeoPixel.h>
-#include <avr/wdt.h>
 #include "utility/debug.h"
 #include "utility/socket.h"

-#define debug

 // These are the interrupt and control pins
 #define ADAFRUIT_CC3000_IRQ   2  // MUST be an interrupt pin!
@@ -52,12 +50,12 @@
 #define ADAFRUIT_CC3000_CS    10
 // Use hardware SPI for the remaining pins
 // On an MEGA 2560, SCK = 20, MISO = 22, and MOSI = 21
-
-Adafruit_CC3000 cc3000 = Adafruit_CC3000(ADAFRUIT_CC3000_CS, ADAFRUIT_CC3000_IRQ, ADAFRUIT_CC3000_VBAT,
-                                         SPI_CLOCK_DIVIDER); // you can change this clock speed
-
-#define WLAN_SSID       "your-network-SSID"   // cannot be longer than 32 characters!
-#define WLAN_PASS       "your-network-KEY-PASS"
+#define DEBUG
+
+Adafruit_CC3000 cc3000 = Adafruit_CC3000(ADAFRUIT_CC3000_CS, ADAFRUIT_CC3000_IRQ, ADAFRUIT_CC3000_VBAT); // , SPI_CLOCK_DIVIDER, &Serial
+
+#define WLAN_SSID       "your_SSID"   // cannot be longer than 32 characters!
+#define WLAN_PASS       "your_KEY_PASS"
 // Security can be WLAN_SEC_UNSEC, WLAN_SEC_WEP, WLAN_SEC_WPA or WLAN_SEC_WPA2
 #define WLAN_SECURITY   WLAN_SEC_WPA2

@@ -139,7 +137,10 @@
 ColorScheme schemes[7] = { incandescent, rgb, christmas, hanukkah, kwanzaa, rainbow, fire };

 // Enumeration of possible pattern types.
-enum Pattern { BARS = 0, GRADIENT, RAINBOWS, RAINBOW_CYCLE, COLOR_WIPE, THEATER_CHASE, THEATER_CHASE_RAINBOW };
+enum Pattern { BARS = 0, GRADIENT };
+
+// Enumeration of possible animation types.
+enum Animation { RAINBOWS = 2, RAINBOW_CYCLE, COLOR_WIPE, THEATER_CHASE, THEATER_CHASE_RAINBOW };

 // Bar width values (in number of pixels/lights) for different size options.
 int barWidthValues[3] = { 1,      // Small
@@ -159,9 +160,11 @@

 // Variables to hold current state.
 int currentScheme = 0;
-Pattern currentPattern = RAINBOW_CYCLE;
+Pattern currentPattern = GRADIENT;
+Animation currentAnimation = RAINBOW_CYCLE;
 int currentWidth = 0;
-int currentSpeed = 0;
+int currentSpeed = 20;
+bool isAnimation = true;

 uint8_t buffer[BUFFER_SIZE+1];
 int bufindex = 0;
@@ -170,7 +173,7 @@
 char type[MAX_TYPE+1];
 char value[5];
 char callback[MAX_CALLBACK+1];
-char response[64];
+char response[100];

 void setup() {
   Serial.begin(115200);
@@ -257,14 +260,16 @@
   unsigned long time = millis();
   int offset = speedMS > 0 ? time / speedMS : 0;

-  Color oldColor = gradientColor(scheme, range, gradRange, PIXEL_COUNT-1+offset);
+  Color oldColor = gradientColor(scheme, range, gradRange, PIXEL_COUNT-1+offset);
+  Color currentColor;
+  int rapport = time % speedMS;
   for (int i = 0; i < PIXEL_COUNT; ++i) {
-    Color currentColor = gradientColor(scheme, range, gradRange, i+offset);
+    currentColor = gradientColor(scheme, range, gradRange, i+offset);
     if (speedMS > 0) {
       // Blend old and current color based on time for smooth movement.
-      strip.setPixelColor(i, map(time % speedMS, 0, speedMS, oldColor.red,   currentColor.red),
-                             map(time % speedMS, 0, speedMS, oldColor.green, currentColor.green),
-                             map(time % speedMS, 0, speedMS, oldColor.blue,  currentColor.blue));
+      strip.setPixelColor(i, map(rapport, 0, speedMS, oldColor.red,   currentColor.red),
+                             map(rapport, 0, speedMS, oldColor.green, currentColor.green),
+                             map(rapport, 0, speedMS, oldColor.blue,  currentColor.blue));
     }
     else {
       // No animation, just use the current color.
@@ -284,30 +289,46 @@
   if (width > maxSize) return;

   int offset = speedMS > 0 ? millis() / speedMS : 0;
-
-  for (int i = 0; i < PIXEL_COUNT; ++i) {
-    int colorIndex = ((i + offset) % (scheme.count * width)) / width;
+  int colorIndex = 0;
+
+  for (uint8_t i = 0; i < PIXEL_COUNT; ++i) {
+    colorIndex = ((i + offset) % (scheme.count * width)) / width;
     strip.setPixelColor(i, scheme.colors[colorIndex].red, scheme.colors[colorIndex].green, scheme.colors[colorIndex].blue);
   }
   strip.show();
 }
+
 // Fill the dots one after the other with a color
 void colorWipe(uint32_t c, uint8_t wait) {
-  for(uint16_t i=0; i<strip.numPixels(); i++) {
+  #ifdef debug
+    Serial.print(F("colorWipe wait: ")); Serial.println(wait);
+  #endif
+
+  for(uint8_t i=0; i < PIXEL_COUNT; i++) {
     strip.setPixelColor(i, c);
     strip.show();
+    if (checkServer()) {
+      return;
+    }
     delay(wait);
   }
 }

 void rainbows(uint8_t wait) {
   uint16_t i, j;
-
+
+  #ifdef debug
+    Serial.print(F("rainbow wait: ")); Serial.println(wait);
+  #endif
+
   for(j=0; j<256; j++) {
     for(i=0; i<PIXEL_COUNT; i++) {
       strip.setPixelColor(i, Wheel((i+j) & 255));
     }
     strip.show();
+    if (checkServer()) {
+      return;
+    }
     delay(wait);
   }
 }
@@ -316,18 +337,28 @@
 void rainbowCycle(uint8_t wait) {
   uint16_t i, j, numbers;
   numbers = 256 * 5;
+
+  #ifdef debug
+    Serial.print(F("rainbowCycle wait: ")); Serial.println(wait);
+  #endif

   for(j=0; j < numbers; j++) { // 5 cycles of all colors on wheel
     for(i=0; i < PIXEL_COUNT; i++) {
       strip.setPixelColor(i, Wheel(((i * 256 / PIXEL_COUNT) + j) & 255));
     }
     strip.show();
+    if (checkServer()) {
+      return;
+    }
     delay(wait);
   }
 }

 //Theatre-style crawling lights.
 void theaterChase(uint32_t c, uint8_t wait) {
+  #ifdef debug
+    Serial.print(F("theaterChase wait: ")); Serial.println(wait);
+  #endif
   for (int j=0; j<10; j++) {  //do 10 cycles of chasing
     for (int q=0; q < 3; q++) {
       for (int i=0; i < PIXEL_COUNT; i=i+3) {
@@ -335,7 +366,10 @@
       }
       strip.show();

-      delay(wait);
+      if (checkServer()) {
+        return;
+      }
+      delay(wait*2.5);

       for (int i=0; i < PIXEL_COUNT; i=i+3) {
         strip.setPixelColor(i+q, 0);        //turn every third pixel off
@@ -346,14 +380,21 @@

 //Theatre-style crawling lights with rainbow effect
 void theaterChaseRainbow(uint8_t wait) {
+  #ifdef debug
+    Serial.print(F("theaterChaseRainbow wait: ")); Serial.println(wait);
+  #endif
+
   for (int j=0; j < 256; j++) {     // cycle all 256 colors in the wheel
     for (int q=0; q < 3; q++) {
       for (int i=0; i < PIXEL_COUNT; i=i+3) {
         strip.setPixelColor(i+q, Wheel( (i+j) % 255));    //turn every third pixel on
       }
       strip.show();
-
-      delay(wait);
+
+      if (checkServer()) {
+        return;
+      }
+      delay(wait*2.5);

       for (int i=0; i < PIXEL_COUNT; i=i+3) {
         strip.setPixelColor(i+q, 0);        //turn every third pixel off
@@ -377,7 +418,28 @@
   return strip.Color(WheelPos * 3, 255 - WheelPos * 3, 0);
 }

+void set_speed(uint8_t wait) {
+  if (!isAnimation) {
+    if (wait > 3) {
+      wait = uint8_t(wait / 33.33);
+    }
+    currentSpeed = speedValues[constrain(wait, 0, 3)];
+  } else {
+    currentSpeed = constrain(wait, 0, 1023);
+  }
+  #ifdef debug
+    Serial.print(F("CurrentSpeed: ")); Serial.println(currentSpeed);
+  #endif
+}
+
+bool checkServer() {
+  return httpServer.available().available();
+}
+
 void loop() {
+  #ifdef debug
+    Serial.println(F("loop"));
+  #endif
   //wdt_enable(WDTO_2S);
   // Try to get a client which is connected.
   Adafruit_CC3000_ClientRef client = httpServer.available();
@@ -412,7 +474,7 @@

     // Handle the request if it was parsed.
     if (parsed) {
-      #ifdef debug
+      #ifdef DEBUG
         Serial.println(F("Processing request"));
         Serial.print(F("Action: ")); Serial.println(action);
         Serial.print(F("Path: ")); Serial.println(path);
@@ -428,29 +490,60 @@
         // Update appropriate state for the associated command and value.
         if (strcmp(type, "scheme") == 0) {
           currentScheme = constrain(val, 0, 6);
-          #ifdef debug
-            Serial.print(F("currentScheme: ")); Serial.println(currentScheme);
+          currentPattern = GRADIENT;
+          isAnimation = false;
+          set_speed(currentSpeed);
+          #ifdef DEBUG
+            PRINT_DEBUG("currentScheme: ", value);
           #endif
         }
         else if (strcmp(type, "pattern") == 0) {
-          currentPattern = (Pattern)constrain(val, 0, 6);
-          #ifdef debug
-            Serial.print(F("currentPattern: ")); Serial.println(currentPattern);
+          currentPattern = (Pattern)constrain(val, 0, 1);
+          isAnimation = false;
+          set_speed(currentSpeed);
+          #ifdef DEBUG
+            PRINT_DEBUG("currentPattern: ", value);
+          #endif
+        }
+        else if (strcmp(type, "animation") == 0) {
+          currentAnimation = (Animation)constrain(val, 2, 6);
+          isAnimation = true;
+          #ifdef DEBUG
+            PRINT_DEBUG("Animation: ", value);
           #endif
         }
         else if (strcmp(type, "width") == 0) {
           currentWidth = constrain(val, 0, 2);
-          #ifdef debug
-            Serial.print(F("currentWidth: ")); Serial.println(currentWidth);
+          #ifdef DEBUG
+            PRINT_DEBUG("currentWidth: ", value);
           #endif
         }
         else if (strcmp(type, "speed") == 0) {
-          currentSpeed = speedValues[constrain(val, 0, 3)];
-          #ifdef debug
-            Serial.print(F("currentSpeed: ")); Serial.println(currentSpeed);
+          set_speed(val);
+          #ifdef DEBUG
+            PRINT_DEBUG("currentSpeed: ", value);
           #endif
         }

+        if (callback != NULL) {
+          if (!isAnimation) {
+            sprintf(response, "%s({\"scheme\":%d,\"pattern\":%d,\"width\":%d,\"speed\":%d})",
+                    callback, currentScheme, currentPattern, currentWidth, currentSpeed);
+          } else {
+            sprintf(response, "%s({\"animation\":%d,\"speed\":%d})",
+                    callback, currentAnimation, currentSpeed);
+          }
+        } else {
+          if (!isAnimation) {
+            sprintf(response, "{\"scheme\":%d,\"pattern\":%d,\"width\":%d,\"speed\":%d}",
+                    currentScheme, currentPattern, currentWidth, currentSpeed);
+          } else {
+            sprintf(response, "{\"animation\":%d,\"speed\":%d}",
+                    currentAnimation, currentSpeed);
+          }
+        }
+        char resLength[15];
+        sprintf(resLength, "%d", strlen(response));

         // Respond with the path that was accessed.
         // First send the success response code.
@@ -460,34 +553,15 @@
         client.fastrprintln(F("Content-Type: application/json"));
         client.fastrprintln(F("Connection: close"));
         client.fastrprintln(F("Server: Adafruit CC3000"));
+        client.fastrprint(F("Content-Length: ")); client.fastrprintln(resLength);
         // Send an empty line to signal start of body.
         client.fastrprintln(F(""));
         // Now send the response data.
-        if (callback != NULL) {
-          sprintf(response, "%s({\"type\":\"%s\",\"value\":%s})", callback, type, value);
-        } else {
-          sprintf(response, "{\"type\":%s,\"value\":%s}", type, value);
-        }
         client.fastrprintln(response);
-        #ifdef debug
-          Serial.print(F("Response: "));
-          Serial.println(response);
+
+        #ifdef DEBUG
+          PRINT_DEBUG("Response: ", response);
         #endif
-        /*
-        if (callback != NULL) {
-          client.fastrprint(callback);
-          client.fastrprint(F("("));
-        }
-        client.fastrprint(F("{\"type\": \""));
-        client.fastrprint(type);
-        client.fastrprint(F("\", \"value\": "));
-        client.fastrprint(value);
-        client.fastrprint(F("}"));
-        if (callback != NULL) {
-          client.fastrprint(F(");"));
-        }
-        client.fastrprintln(F(""));
-        */
       }
       else {
         // Unsupported action, respond with an HTTP 405 method not allowed error.
@@ -512,44 +586,31 @@
     Serial.println(F("Client disconnected"));
     client.close();
   }
-  /*
-  // Some example procedures showing how to display to the pixels:
-    colorWipe(strip.Color(255, 0, 0), 50); // Red
-    colorWipe(strip.Color(0, 255, 0), 50); // Green
-    colorWipe(strip.Color(0, 0, 255), 50); // Blue
-    // Send a theater pixel chase in...
-    theaterChase(strip.Color(127, 127, 127), 50); // White
-    theaterChase(strip.Color(127, 0, 0), 50); // Red
-    theaterChase(strip.Color(0, 0, 127), 50); // Blue
-
-    rainbow(20);
-    rainbowCycle(20);
-    theaterChaseRainbow(50);
-  */
-  // BARS = 0, GRADIENT, RAINBOW, RAINBOW_CYCLE, COLOR_WIPE, THEATER_CHASE, THEATER_CHASE_RAINBOW
   // Update pixels based on current state.
-  switch(currentPattern) {
-    case BARS:
+  if (!isAnimation) {
+    if (currentPattern == BARS) {
       bars(schemes[currentScheme], barWidthValues[currentWidth], currentSpeed);
-      break;
-    case GRADIENT:
+    } else if (currentPattern == GRADIENT) {
       gradient(schemes[currentScheme], gradientWidthValues[currentWidth], currentSpeed);
-      break;
-    case RAINBOWS:
-      rainbows(20);
-      break;
-    case RAINBOW_CYCLE:
-      rainbowCycle(20);
-      break;
-    case COLOR_WIPE:
-      colorWipe(Wheel(random(0, 255)), 50);
-      break;
-    case THEATER_CHASE:
-      theaterChase(Wheel(random(0, 255)), 50); // Blue
-      break;
-    case THEATER_CHASE_RAINBOW:
-      theaterChaseRainbow(50);
-      break;
+    }
+  } else {
+    switch(currentAnimation) {
+      case RAINBOWS:
+        rainbows(currentSpeed);
+        break;
+      case RAINBOW_CYCLE:
+        rainbowCycle(currentSpeed);
+        break;
+      case COLOR_WIPE:
+        colorWipe(Wheel(random(0, 255)), currentSpeed);
+        break;
+      case THEATER_CHASE:
+        theaterChase(Wheel(random(0, 255)), currentSpeed); // Blue
+        break;
+      case THEATER_CHASE_RAINBOW:
+        theaterChaseRainbow(currentSpeed);
+        break;
+    }
   }
 }

@@ -576,73 +637,88 @@

 // Parse the action and path from the first line of an HTTP request.
 bool parseFirstLine(char* line, char* action, char* path, char* type, char* value, char* callback) {
-  #ifdef debug
-    Serial.print(F("line: ")); Serial.println(line);
-  #endif
+  PRINT_DEBUG("Line; ", line);
   // Parse first word up to whitespace as action.
   char* lineaction = strtok(line, " ");
   if (lineaction == NULL) {
+    PRINT_DEBUG("Action not found", "");
     return false;
   }
   strncpy(action, lineaction, MAX_ACTION);
+
   // Parse second word up to whitespace as path.
   char* linepath = strtok(NULL, " ");
-  if (linepath == NULL) {
-    #ifdef debug
-      Serial.println(F("linepath NULL"));
-    #endif
+  if (linepath != NULL) {
+    strncpy(path, linepath, MAX_PATH);
+    parsePath(path, type, value, callback);
+  } else {
+    PRINT_DEBUG("Path not found", "");
     return false;
   }
-
-  char* tempPath = strncpy(path, linepath, MAX_PATH);
-  #ifdef debug
-    Serial.print(F("tempPath: ")); Serial.println(tempPath);
-    Serial.print(F("path: ")); Serial.println(path);
+}
+
+bool parsePath(const char* line, char* type, char* value, char* callback) {
+  PRINT_DEBUG("Path; ", (char*)line);
+  char tmp[MAX_PATH];
+  strcpy(tmp, line);
+  char* keyword = strtok(tmp, "/");
+  if (keyword == NULL || strncmp(keyword, "arduino", 7) != 0) {
+    PRINT_DEBUG("Keyword not found or invalid", keyword);
+    return false;
+  }
+  char* linetype = strtok(NULL, "/");
+  if (linetype == NULL) {
+    PRINT_DEBUG("Type is NULL", "");
+    return false;
+  }
+  strncpy(type, linetype, MAX_TYPE);
+
+  char* linevalue = strtok(NULL, "/");
+  PRINT_DEBUG("LineValue1: ", linevalue);
+  if (linevalue == NULL) {
+    PRINT_DEBUG("Value is NULL", "");
+    return false;
+  }
+  linevalue = strtok(linevalue, "?");
+  PRINT_DEBUG("LineValue1: ", linevalue);
+  if (linevalue == NULL) {
+    PRINT_DEBUG("Value is NULL", "");
+    strcpy(value, "0");
+  } else {
+    strncpy(value, linevalue, 5);
+  }
+
+  char* lineParams = strtok(NULL, "?");
+  if (lineParams != NULL)
+    parseParameters(lineParams, callback);
+
+  return true;
+}
+
+void parseParameters(const char* lineParams, char* callback) {
+  PRINT_DEBUG("Parameters: ", (char*)lineParams);
+  char tmp[MAX_PATH];
+  strcpy(tmp, lineParams);
+
+  char* param = strtok(tmp, "&=");
+
+  while (param != NULL) {
+    if (param != NULL && strncmp(param, "callback", 8) == 0) {
+      strcpy(callback, strtok(NULL, "&="));
+      PRINT_DEBUG("Callback found: ", callback);
+      break;
+    }
+    param = strtok(NULL, "&=");
+  }
+}
+
+void PRINT_DEBUG(const char* key, char* fstr)
+{
+  #ifdef DEBUG
+    if(!key) return;
+    Serial.print(key);
+    Serial.println(fstr);
   #endif
-  char* linetype = strtok(tempPath, "/");
-  if (linetype == NULL || strncmp(linetype, "arduino", 7) != 0) {
-    #ifdef debug
-      Serial.println(F("linetype1 NULL"));
-    #endif
-    return false;
-  }
-  linetype = strtok(NULL, "/");
-  if (linetype == NULL) {
-    #ifdef debug
-      Serial.println(F("linetype2 NULL"));
-    #endif
-    return false;
-  }
-  strncpy(type, linetype, MAX_TYPE);
-  char* linevalue = strtok(NULL, "/");
-  if (linevalue == NULL) {
-    #ifdef debug
-      Serial.println(F("linevalue NULL"));
-    #endif
-    value = "0";
-  } else {
-    int i = 0;
-    int j = 0;
-    while(linevalue[i] != '?' && linevalue[i] != '\0' && linevalue[i] != ' ') {
-      value[j++] = linevalue[i++];
-    }
-  }
-  char* linecallback = strtok(tempPath, "?");
-  if (linecallback != NULL) {
-    Serial.print(F("lineCallback: ")); Serial.println(linecallback);
-    int i = -1;
-    int j = 0;
-    while(linecallback[++i] != '=') {}
-    i++;
-    while(linecallback[i] != '&' && linecallback[i] != '\r') {
-      callback[j++] = linecallback[i++];
-    }
-  } else {
-    #ifdef debug
-      Serial.println(F("linecallback NULL"));
-    #endif
-  }
-  return true;
 }

 // Tries to read the IP address and other connection details


Added sensor interogation.

Added sensor interogation.

--- freezer_monitor_v0_7/freezer_monitor_v0_7.ino
+++ freezer_monitor_v0_7/freezer_monitor_v0_7.ino
@@ -1,25 +1,65 @@
-// Test sketch that is loaded on slave Moteinos
-// It will send an encrypted message to the master/gateway every TRANSMITPERIOD
-// It will respond to any ACKed messages from the master
-// Every 3rd message will also be ACKed (request ACK from master).
+/* -----------------------------------------------------------------------------
+   Freezer Monitor
+
+   Accepts item numbers from PS/2 connection and submits initiates an Item
+   process via a RESTful web service.
+
+   Circuit:
+   * RFM12B attached to digital pins 10, 11, 12, 13
+   * LDR sensor attached to analog pin 0
+   * OneWire bus attached to digital pin 3
+   * Hall Effect sensor attached to digital pin 7
+   * Sensor Status LED attached to digital pin 8
+   * RF Status LED attached to digital pin 9
+
+   Created 19-JAN-2014 by Jon Brule
+----------------------------------------------------------------------------- */
+
 #include <RFM12B.h>
+#include <OneWire.h>
+#include <DallasTemperature.h>
+#include <TimerOne.h>

 #define VERSION "v0.7"

-#define MYID         2       // node ID used for this unit
-#define NETWORKID   99
-#define GATEWAYID    1
+#define MYID       2       // node ID used for this unit
+#define NETWORKID  99
+#define GATEWAYID  1
 #define FREQUENCY  RF12_915MHZ //Match this with the version of your Moteino! (others: RF12_433MHZ, RF12_915MHZ)
-#define KEY  "ABCDABCDABCDABCD"
+#define KEY        "ABCDABCDABCDABCD"
+#define ACK_TIME   50  // # of ms to wait for an ack
 #define TRANSMITPERIOD 600 //transmit a packet to gateway so often (in ms)

 #define SERIAL_BAUD      115200
-#define ACK_TIME             50  // # of ms to wait for an ack

 #define BUFFER_SIZE  50
 #define CMD_BOOT     0x10
 #define CMD_READING  0x11

+#define APIN_LDR        0  // data connection for photocell
+#define DPIN_ONEWIRE    3  // data connection for the Dallas OneWire bus
+#define DPIN_HALL       7  // data connection for hall effect
+#define DPIN_SENSOR_LED 8
+#define DPIN_RF_LED     9
+
+struct SensorData {
+  boolean available;
+  unsigned int ldr;
+  unsigned int hall;
+  float tempInsideC;
+  float tempOutsideC;
+};
+
+struct SensorThresholds {
+  unsigned int light;
+  unsigned int door;
+  float minTempInsideC;
+  float maxTempInsideC;
+  float minTempOutsideC;
+  float maxTempOutsideC;
+};
+
+// rfm12b radio
 int interPacketDelay = 1000; //wait this many ms between sending packets
 char input = 0;
 RFM12B radio;
@@ -30,6 +70,16 @@
 char buffer[BUFFER_SIZE];

 long lastPeriod = -1;
+
+// dallas onewire configuration
+OneWire oneWire(DPIN_ONEWIRE);
+DallasTemperature oneWireSensors(&oneWire);
+DeviceAddress thermometerInside  = { 0x10, 0x9B, 0x96, 0x53, 0x02, 0x08, 0x00, 0xF0 };
+DeviceAddress thermometerOutside  = { 0x10, 0x74, 0x6C, 0x53, 0x02, 0x08, 0x00, 0xE6 };
+
+// container for sensor data
+SensorData sensorData;
+SensorThresholds sensorThresholds;

 /******************************************************************************
@@ -48,10 +98,10 @@
   Serial.println(VERSION);

   // radio initialization
-  radio.Initialize(MYID, FREQUENCY, NETWORKID, 0);
-  radio.Encrypt((byte*)KEY);
-  sprintf(buffer, "Transmitting at %d Mhz...", FREQUENCY == RF12_433MHZ ? 433 : FREQUENCY== RF12_868MHZ ? 868 : 915);
-  Serial.println(buffer);
+  setup_radio();
+
+  // sensor initialization
+  setup_sensors();

   // define default sensor thresholds
   setup_sensor_thresholds();
@@ -77,7 +127,7 @@
         radio.SendACK();
         Serial.print(" - ACK sent.");
       }
-      Blink(9,5);
+      blink_led(DPIN_RF_LED, 5);
     }
   }

@@ -102,8 +152,102 @@

     sendSize = (sendSize + 1) % 31;
     Serial.println();
-    Blink(9,5);
-  }
+    blink_led(DPIN_RF_LED, 5);
+    log();
+  }
+
+}
+
+//------------------------------------------------------------------------------
+void blink_led(byte pin, int delay_ms) {
+  digitalWrite(pin, HIGH);
+  delay(delay_ms);
+  digitalWrite(pin, LOW);
+}
+
+//------------------------------------------------------------------------------
+// Compares each sensor's value against its expectation, returning true if the
+// values are acceptable or false if they fall outside the expectations.
+int check_status() {
+  int status = LOW;
+  if (sensorData.ldr > sensorThresholds.light) {
+    status = HIGH;
+  }
+  if (sensorData.hall == sensorThresholds.door) {
+    status = HIGH;
+  }
+  if (sensorData.tempInsideC < sensorThresholds.minTempInsideC) {
+    status = HIGH;
+  }
+  if (sensorData.tempInsideC > sensorThresholds.maxTempInsideC) {
+    status = HIGH;
+  }
+  return status;
+}
+
+//------------------------------------------------------------------------------
+// Logs the current sensor values.
+void log() {
+  Serial.print("Light: ");
+  Serial.print(sensorData.ldr);
+  Serial.print("\t Hall: ");
+  Serial.print(sensorData.hall);
+  Serial.print("\t Temp: ");
+  Serial.print(sensorData.tempInsideC);
+  Serial.print("C, ");
+  Serial.print(sensorData.tempOutsideC);
+  Serial.println("C");
+}
+
+//------------------------------------------------------------------------------
+// Retrieves the new sensor values.
+void interogate_sensors() {
+
+  // block access to sensor data
+  sensorData.available = false;
+
+  // read light level
+  sensorData.ldr = map(analogRead(APIN_LDR), 0, 1023, 0, 255);
+
+  // read door status
+  sensorData.hall = digitalRead(DPIN_HALL);
+
+  // read one-wire sensors
+  oneWireSensors.requestTemperatures();
+  sensorData.tempInsideC = oneWireSensors.getTempC(thermometerInside);
+  sensorData.tempOutsideC = oneWireSensors.getTempC(thermometerOutside);
+
+  // enable access to sensor data
+  sensorData.available = true;
+
+  // update status led
+  digitalWrite(DPIN_SENSOR_LED, check_status());
+
+}
+
+//------------------------------------------------------------------------------
+// Initializes the RFM12B radio.
+void setup_radio() {
+  radio.Initialize(MYID, FREQUENCY, NETWORKID, 0);
+  radio.Encrypt((byte*)KEY);
+  sprintf(buffer, "Transmitting at %d Mhz...", FREQUENCY == RF12_433MHZ ? 433 : FREQUENCY== RF12_868MHZ ? 868 : 915);
+  Serial.println(buffer);
+}
+
+//------------------------------------------------------------------------------
+// Initializes the sensors.
+void setup_sensors() {
+
+  // initialize sensor connections
+  pinMode(APIN_LDR, INPUT);
+  pinMode(DPIN_HALL, INPUT);
+  pinMode(DPIN_SENSOR_LED, OUTPUT);
+  pinMode(DPIN_RF_LED, OUTPUT);
+  oneWireSensors.begin();
+
+  // setup background timer to interogate sensors
+  Timer1.initialize(1000000); // set a timer of length 100000 microseconds (or 0.1 sec - or 10Hz => the led will blink 5 times, 5 cycles of on-and-off, per second)
+  Timer1.attachInterrupt(interogate_sensors); // attach the service routine here
 }

 //------------------------------------------------------------------------------
@@ -130,11 +274,3 @@
   return false;
 }

-//------------------------------------------------------------------------------
-void Blink(byte PIN, int DELAY_MS)
-{
-  pinMode(PIN, OUTPUT);
-  digitalWrite(PIN,HIGH);
-  delay(DELAY_MS);
-  digitalWrite(PIN,LOW);
-}


Add the exponential backoff wait if fail attemps on the arduino end (#55)

--- go/iot/protocol/examples/arduino/protocol.ino
+++ go/iot/protocol/examples/arduino/protocol.ino
@@ -25,8 +25,11 @@
 #define OK 200
 #define FAIL 404
 #define MEASUREUNREG 501
+#define TAGUNREG 502
 #define BUFFER_SIZE 256
 #define JSON_BUFFER_SIZE 200
+// The maximum backoff waiting time is 32 seconds
+#define MAX_BACKOFF_TIME 32000
 #include <Wire.h>
 #include "SparkFunHTU21D.h"
 #include "DHT.h"
@@ -40,6 +43,7 @@
   Serial.begin(9600);
   myHumidity.begin();
   while (!Serial) continue;
+  pinMode(LED_BUILTIN, OUTPUT);
 }

 /*
@@ -55,8 +59,13 @@
  */
 void request(void (*func)()) {
   int code;
+  // For Arduino UNO, it only supports 4-byte integer.
+  unsigned int failcounts = 0;
+  unsigned int delaytime;
+  // The outer loop is to keep sending requests to the slave until receiving a positive response
   do {
     JsonObject* response;
+    // The inner loop is to receive the response from the slave end after sending the request
     do {
       // TODO: Currently we hard-code the argument in the code. Would handle the problem that how to solve
       // multiple arguments.
@@ -75,11 +84,29 @@
     //Serial.println(info);
     switch (code){
       case FAIL:
-        delay(1000);
+        delaytime = (1 << failcounts) + random(1000);
+        if (delaytime > MAX_BACKOFF_TIME){
+          delaytime = MAX_BACKOFF_TIME;
+          // When there are too many fail attempts, turn on the light to notify
+          // Meanwhile stop increasing the fail attempts counter
+          digitalWrite(LED_BUILTIN, HIGH);
+        }
+        Serial.println(delaytime);
+        delay(delaytime);
+        // In case of the overflow
+        if (failcounts < 15)
+          failcounts = failcounts + 1;
         break;
       case MEASUREUNREG:
         exit(-1);
+        break;
       case OK:
+        failcounts = 0;
+        digitalWrite(LED_BUILTIN, LOW);
+        break;
+      case TAGUNREG:
+        failcounts = 0;
+        digitalWrite(LED_BUILTIN, LOW);
         break;
       default:
         exit(-1);
@@ -164,3 +191,4 @@

   Serial.flush();
 }
+


use random

use random

--- MASTER_crusher/MASTER_crusher.ino
+++ MASTER_crusher/MASTER_crusher.ino
@@ -37,8 +37,11 @@
   Serial.begin(9600);
   btSerial.begin(9600);
   reflectanceSensors.init();
+  randomSeed(analogRead(0));
+  Serial.println("Starting master crusher");
   setBluetoothProgram();
   button.waitForButton();
+
   if (useRightProgram) {
     superStartRight();
   } else {
@@ -66,15 +69,23 @@

 void setBluetoothProgram() {
   if (!useBt) {
-    if (random(0, 2) == 0) {
+    Serial.println("We are not using bluetooth");
+    random(2, 500);
+    random(1, 4000);
+    int nr = random(1, 399);
+    Serial.println(nr);
+    if (nr < 200) {
       useRightProgram = true;
+      Serial.println("Using right prog, setting led high");
       digitalWrite(yellowLedPin, HIGH);
     } else {
+      Serial.println("Using left prog, setting led low");
       useRightProgram = false;
       digitalWrite(yellowLedPin, LOW);
     }
     return;
   }
+  Serial.println("We ARE using bluetooth");
   while (true) {
     Serial.println("Venter BT");
     while (btSerial.available()) {


Delete Otto_MarioBros.ino

Delete Otto_MarioBros.ino

--- Otto_MarioBros/Otto_MarioBros.ino
+++ Otto_MarioBros/Otto_MarioBros.ino
@@ -1,283 +0,0 @@
-/*Arduino Mario Bros Tunes
-  With Piezo Buzzer and PWM
- Connect the positive side of the Buzzer to pin 13,
-  by: Dipto Pratyaksa
-  adapted to ottodiy.com
-*/
-
-/*************************************************
- * Public Constants
- *************************************************/
-
-#define NOTE_B0  31
-#define NOTE_C1  33
-#define NOTE_CS1 35
-#define NOTE_D1  37
-#define NOTE_DS1 39
-#define NOTE_E1  41
-#define NOTE_F1  44
-#define NOTE_FS1 46
-#define NOTE_G1  49
-#define NOTE_GS1 52
-#define NOTE_A1  55
-#define NOTE_AS1 58
-#define NOTE_B1  62
-#define NOTE_C2  65
-#define NOTE_CS2 69
-#define NOTE_D2  73
-#define NOTE_DS2 78
-#define NOTE_E2  82
-#define NOTE_F2  87
-#define NOTE_FS2 93
-#define NOTE_G2  98
-#define NOTE_GS2 104
-#define NOTE_A2  110
-#define NOTE_AS2 117
-#define NOTE_B2  123
-#define NOTE_C3  131
-#define NOTE_CS3 139
-#define NOTE_D3  147
-#define NOTE_DS3 156
-#define NOTE_E3  165
-#define NOTE_F3  175
-#define NOTE_FS3 185
-#define NOTE_G3  196
-#define NOTE_GS3 208
-#define NOTE_A3  220
-#define NOTE_AS3 233
-#define NOTE_B3  247
-#define NOTE_C4  262
-#define NOTE_CS4 277
-#define NOTE_D4  294
-#define NOTE_DS4 311
-#define NOTE_E4  330
-#define NOTE_F4  349
-#define NOTE_FS4 370
-#define NOTE_G4  392
-#define NOTE_GS4 415
-#define NOTE_A4  440
-#define NOTE_AS4 466
-#define NOTE_B4  494
-#define NOTE_C5  523
-#define NOTE_CS5 554
-#define NOTE_D5  587
-#define NOTE_DS5 622
-#define NOTE_E5  659
-#define NOTE_F5  698
-#define NOTE_FS5 740
-#define NOTE_G5  784
-#define NOTE_GS5 831
-#define NOTE_A5  880
-#define NOTE_AS5 932
-#define NOTE_B5  988
-#define NOTE_C6  1047
-#define NOTE_CS6 1109
-#define NOTE_D6  1175
-#define NOTE_DS6 1245
-#define NOTE_E6  1319
-#define NOTE_F6  1397
-#define NOTE_FS6 1480
-#define NOTE_G6  1568
-#define NOTE_GS6 1661
-#define NOTE_A6  1760
-#define NOTE_AS6 1865
-#define NOTE_B6  1976
-#define NOTE_C7  2093
-#define NOTE_CS7 2217
-#define NOTE_D7  2349
-#define NOTE_DS7 2489
-#define NOTE_E7  2637
-#define NOTE_F7  2794
-#define NOTE_FS7 2960
-#define NOTE_G7  3136
-#define NOTE_GS7 3322
-#define NOTE_A7  3520
-#define NOTE_AS7 3729
-#define NOTE_B7  3951
-#define NOTE_C8  4186
-#define NOTE_CS8 4435
-#define NOTE_D8  4699
-#define NOTE_DS8 4978
-
-#define melodyPin 13
-//Mario main theme melody
-int melody[] = {
-  NOTE_E7, NOTE_E7, 0, NOTE_E7,
-  0, NOTE_C7, NOTE_E7, 0,
-  NOTE_G7, 0, 0,  0,
-  NOTE_G6, 0, 0, 0,
-
-  NOTE_C7, 0, 0, NOTE_G6,
-  0, 0, NOTE_E6, 0,
-  0, NOTE_A6, 0, NOTE_B6,
-  0, NOTE_AS6, NOTE_A6, 0,
-
-  NOTE_G6, NOTE_E7, NOTE_G7,
-  NOTE_A7, 0, NOTE_F7, NOTE_G7,
-  0, NOTE_E7, 0, NOTE_C7,
-  NOTE_D7, NOTE_B6, 0, 0,
-
-  NOTE_C7, 0, 0, NOTE_G6,
-  0, 0, NOTE_E6, 0,
-  0, NOTE_A6, 0, NOTE_B6,
-  0, NOTE_AS6, NOTE_A6, 0,
-
-  NOTE_G6, NOTE_E7, NOTE_G7,
-  NOTE_A7, 0, NOTE_F7, NOTE_G7,
-  0, NOTE_E7, 0, NOTE_C7,
-  NOTE_D7, NOTE_B6, 0, 0
-};
-//Mario main them tempo
-int tempo[] = {
-  12, 12, 12, 12,
-  12, 12, 12, 12,
-  12, 12, 12, 12,
-  12, 12, 12, 12,
-
-  12, 12, 12, 12,
-  12, 12, 12, 12,
-  12, 12, 12, 12,
-  12, 12, 12, 12,
-
-  9, 9, 9,
-  12, 12, 12, 12,
-  12, 12, 12, 12,
-  12, 12, 12, 12,
-
-  12, 12, 12, 12,
-  12, 12, 12, 12,
-  12, 12, 12, 12,
-  12, 12, 12, 12,
-
-  9, 9, 9,
-  12, 12, 12, 12,
-  12, 12, 12, 12,
-  12, 12, 12, 12,
-};
-//Underworld melody
-int underworld_melody[] = {
-  NOTE_C4, NOTE_C5, NOTE_A3, NOTE_A4,
-  NOTE_AS3, NOTE_AS4, 0,
-  0,
-  NOTE_C4, NOTE_C5, NOTE_A3, NOTE_A4,
-  NOTE_AS3, NOTE_AS4, 0,
-  0,
-  NOTE_F3, NOTE_F4, NOTE_D3, NOTE_D4,
-  NOTE_DS3, NOTE_DS4, 0,
-  0,
-  NOTE_F3, NOTE_F4, NOTE_D3, NOTE_D4,
-  NOTE_DS3, NOTE_DS4, 0,
-  0, NOTE_DS4, NOTE_CS4, NOTE_D4,
-  NOTE_CS4, NOTE_DS4,
-  NOTE_DS4, NOTE_GS3,
-  NOTE_G3, NOTE_CS4,
-  NOTE_C4, NOTE_FS4, NOTE_F4, NOTE_E3, NOTE_AS4, NOTE_A4,
-  NOTE_GS4, NOTE_DS4, NOTE_B3,
-  NOTE_AS3, NOTE_A3, NOTE_GS3,
-  0, 0, 0
-};
-//Underwolrd tempo
-int underworld_tempo[] = {
-  12, 12, 12, 12,
-  12, 12, 6,
-  3,
-  12, 12, 12, 12,
-  12, 12, 6,
-  3,
-  12, 12, 12, 12,
-  12, 12, 6,
-  3,
-  12, 12, 12, 12,
-  12, 12, 6,
-  6, 18, 18, 18,
-  6, 6,
-  6, 6,
-  6, 6,
-  18, 18, 18, 18, 18, 18,
-  10, 10, 10,
-  10, 10, 10,
-  3, 3, 3
-};
-
-void setup(void)
-{
-  pinMode(13, OUTPUT);//buzzer
-  pinMode(10, OUTPUT);//led indicator when singing a note
-
-}
-void loop()
-{
-  //sing the tunes
-  sing(1);
-  sing(1);
-  sing(2);
-}
-int song = 0;
-
-void sing(int s) {
-  // iterate over the notes of the melody:
-  song = s;
-  if (song == 2) {
-    Serial.println(" 'Underworld Theme'");
-    int size = sizeof(underworld_melody) / sizeof(int);
-    for (int thisNote = 0; thisNote < size; thisNote++) {
-
-      // to calculate the note duration, take one second
-      // divided by the note type.
-      //e.g. quarter note = 1000 / 4, eighth note = 1000/8, etc.
-      int noteDuration = 1000 / underworld_tempo[thisNote];
-
-      buzz(melodyPin, underworld_melody[thisNote], noteDuration);
-
-      // to distinguish the notes, set a minimum time between them.
-      // the note's duration + 30% seems to work well:
-      int pauseBetweenNotes = noteDuration * 1.30;
-      delay(pauseBetweenNotes);
-
-      // stop the tone playing:
-      buzz(melodyPin, 0, noteDuration);
-
-    }
-
-  } else {
-
-    Serial.println(" 'Mario Theme'");
-    int size = sizeof(melody) / sizeof(int);
-    for (int thisNote = 0; thisNote < size; thisNote++) {
-
-      // to calculate the note duration, take one second
-      // divided by the note type.
-      //e.g. quarter note = 1000 / 4, eighth note = 1000/8, etc.
-      int noteDuration = 1000 / tempo[thisNote];
-
-      buzz(melodyPin, melody[thisNote], noteDuration);
-
-      // to distinguish the notes, set a minimum time between them.
-      // the note's duration + 30% seems to work well:
-      int pauseBetweenNotes = noteDuration * 1.30;
-      delay(pauseBetweenNotes);
-
-      // stop the tone playing:
-      buzz(melodyPin, 0, noteDuration);
-
-    }
-  }
-}
-
-void buzz(int targetPin, long frequency, long length) {
-  digitalWrite(10, HIGH);
-  long delayValue = 1000000 / frequency / 2; // calculate the delay value between transitions
-  //// 1 second's worth of microseconds, divided by the frequency, then split in half since
-  //// there are two phases to each cycle
-  long numCycles = frequency * length / 1000; // calculate the number of cycles for proper timing
-  //// multiply frequency, which is really cycles per second, by the number of seconds to
-  //// get the total number of cycles to produce
-  for (long i = 0; i < numCycles; i++) { // for the calculated length of time...
-    digitalWrite(targetPin, HIGH); // write the buzzer pin high to push out the diaphram
-    delayMicroseconds(delayValue); // wait for the calculated delay value
-    digitalWrite(targetPin, LOW); // write the buzzer pin low to pull back the diaphram
-    delayMicroseconds(delayValue); // wait again or the calculated delay value
-  }
-  digitalWrite(10, LOW);
-
-}


Tweaks

Tweaks

--- Pan_Tilt_laser/Pan_Tilt_laser.ino
+++ Pan_Tilt_laser/Pan_Tilt_laser.ino
@@ -182,7 +182,7 @@

 void loop() {
-  schedule.run();/*
+  schedule.run();
   if(!mSwitch.switchState()){
     laser.fire(0);
     mSwitch.ledState(0);
@@ -203,7 +203,7 @@
     laser.fire(1);
     schedule.restart();
   }
-*/
+
   static unsigned long timePassed;
   static int changeVal;
   static int markovShakeState;
@@ -248,6 +248,7 @@
     }
     timePassed = millis();
 */
+
   laser.fire(1);

 }


Bumped version

Bumped version

--- Pan_Tilt_laser/Pan_Tilt_laser.ino
+++ Pan_Tilt_laser/Pan_Tilt_laser.ino
@@ -17,6 +17,7 @@
     v1.2.1 - Added Heartbeat during pause
     v1.3.0 - Added laser shake to enhance cat enjoyment
     v1.3.1 - Changed probability polling frequency to once a second
+    v1.4.0 - Added ON/OFF Missile Switch from Sparkfun
 */
 /**************************************************************************/


Serial Tweaks

Serial Tweaks

--- Pan_Tilt_laser/Pan_Tilt_laser.ino
+++ Pan_Tilt_laser/Pan_Tilt_laser.ino
@@ -93,7 +93,7 @@

 void setup() {
-  Serial.begin(BAUD_RATE);
+  //Serial.begin(BAUD_RATE);

   mSwitch.begin();

@@ -134,7 +134,7 @@

   panTilt.begin();

-  Serial.println(F("setup starting..."));
+  //Serial.println(F("setup starting..."));
   mSwitch.ledState(1);

@@ -158,7 +158,7 @@
   delay(1000);
   laser.fire(1);

-  Serial.println(F("setup complete"));
+  //Serial.println(F("setup complete"));

   setNextPauseTime();
   setNextRestTime();
@@ -182,7 +182,7 @@
     panTiltY.angle = 90;
     panTilt.updateAngles();

-    delay(50);
+    delay(20);

     panTilt.detach();
     while(!mSwitch.switchState()){


ISR changed to only invert toggle

ISR changed to only invert toggle

--- SevenSegI2C/examples/SevenSegI2CTest/SevenSegI2CTest.ino
+++ SevenSegI2C/examples/SevenSegI2CTest/SevenSegI2CTest.ino
@@ -1,11 +1,13 @@
+#include <TimerOne.h>
+
 #include <SevenSegI2C.h>
 #include <Wire.h>

 int DIG1 = 2;
 int DIG2 = 7;
 int timer1_counter;
-boolean toggle = 0;
-
+boolean toggle = false;
+int i = 0;
 SevenSeg *redSeg;

 //SevenSeg seg(0x20, DIG1, DIG2);
@@ -13,7 +15,12 @@
 void setup()
 {
   Serial.begin(9600);
-  redSeg = new SevenSeg(0x20, DIG1, DIG2);
+  redSeg = new SevenSeg(0x20, DIG1, DIG2);
+  redSeg->setNumber(13);
+
+  Timer1.initialize(10000);
+  Timer1.attachInterrupt(callback);
+
 //  // initialize timer1
 //  noInterrupts();           // disable all interrupts
 //  //set timer0 interrupt at 2kHz
@@ -33,7 +40,7 @@

 void callback()
 {
-  Serial.println("HI");
+  toggle = !toggle;
 }

 ISR(TIMER0_COMPA_vect)        // interrupt service routine
@@ -53,13 +60,18 @@

 void loop()
 {
-//  for (int i = 0; i < 100; i++) {
-//    redSeg->setNumber(i);
-//    //delay(500);
-//  }
-
-  redSeg->setNumber(13);
-  redSeg->writeDigit(DIG2);
-
+  redSeg->setNumber(i++);
+  if (i>99){
+    i = 0;
+  }
+  if (toggle)
+  {
+    redSeg->writeDigit(DIG1);
+  }
+  else
+  {
+    redSeg->writeDigit(DIG2);
+  }
+  delay(50);
 }


Add Global Clock, fix steerAngle error

Add Global Clock, fix steerAngle error

--- code/TestMule/TestMule.ino
+++ code/TestMule/TestMule.ino
@@ -26,11 +26,13 @@

 IntervalTimer loopTimer;
 uint32_t timer = 0;
+uint32_t globalClock = 0;

 // Runs in an interrupt and sets the flags for our multi-rate main loop
 void multiRateISR(){

     timer++;
+    globalClock++;

     if (timer % THROTTLE_RATE == 0) { throttle_flag = true; }
     if (timer % STEERING_RATE == 0) { steering_flag = true; }
@@ -61,7 +63,7 @@
 uint32_t rightRPM = 0;
 float omega_vehicle;

-float steerAngle;
+float steerAngle = 0.0;

 void setup()
 {
@@ -150,7 +152,7 @@
     else if (logging_flag)
     {
         // Add an entry to the logging buffer
-        sdLogger.addEntry(micros(), requestedThrottle, leftThrottle, rightThrottle, steerAngle, rightRPM);
+        sdLogger.addEntry(globalClock, requestedThrottle, leftThrottle, rightThrottle, steerAngle, rightRPM);
         sdLogger.fastLog();
         logging_flag = false;
     }
@@ -199,7 +201,6 @@
 * ---------------------------------------------------------------------------- */
 void steeringTask(){
     uint16_t steeringPot0;
-    float steerAngle;

     steeringPot0 = analogRead(STEERING0_PIN);
     steerAngle = (steeringPot0 - STEERING_CENTER) * RAD_PER_VAL;


Trying to use events

Trying to use events

no success so far with local sparkcore

--- sketch/teatime.ino
+++ sketch/teatime.ino
@@ -69,7 +69,10 @@
     if (isTeaReady()) {
         teaUp("");
         tmInterval=0;
-		Spark.publish("teaisready", "1", NULL, PRIVATE);
+
+// 		trying to use events, but it doesn't work with private sparkcloud on rpi
+//		Spark.publish("teaisready", "1", NULL, PRIVATE);
+//
     }
     delay(500);


add IR, broadband light metrics

add IR, broadband light metrics

--- WeatherStation/WeatherStation.ino
+++ WeatherStation/WeatherStation.ino
@@ -81,7 +81,6 @@
     blink(10);
     digitalWrite(LEDPIN, LOW);
     digitalWrite(XBEESLEEPPIN, LOW);  //Wake UP XBEE
-
     sleep(60000);
     return;
   }
@@ -90,45 +89,26 @@
   Serial.print(sample);
   Serial.print(", ");

-  float h = dht.getHumidity();
-  float t = dht.getTemperature();
-
-  // check if returns are valid, if they are NaN (not a number) then something went wrong!
-  if (!isnan(t) && !isnan(h)) {
-   if (!isnan(t)){
-    Serial.print("'Temp':");
-    Serial.print(t);
-    Serial.print(", ");
-   }
-   if (!isnan(h)){
-    Serial.print("'RH':");
-    Serial.print(h);
-    Serial.print(", ");
-   }
-  }
+  Serial.print("'Temp':"); printValue(dht.getTemperature());
+  Serial.print("'RH':"); printValue(dht.getHumidity());

   sensors_event_t event;
   bmp.getEvent(&event);
-  Serial.print("'AtmoPressure':");
-  if (event.pressure)
-  {
-     Serial.print(event.pressure); Serial.print(", ");
-  }
-  else
-  {
-    Serial.print("'NaN', ");
-  }
-
+  Serial.print("'AtmoPressure':"); printValue(event.pressure);
+
+  uint16_t broadband = 0;
+  uint16_t infrared = 0;
+
   tsl.getEvent(&event);
-  Serial.print("'AmbientLight':");
-  if (event.light)
-  {
-    Serial.print(event.light); Serial.print(", ");
-  }
-  else
-  {
-    Serial.print("'NaN' ");
-  }
+  long lx = event.light;
+  tsl.getLuminosity (&broadband, &infrared);
+  if (lx == 0 && broadband > 65000){ //Sensor appears to be in direct sunlight outside it's resolution limits. Set lx value to max to simplify downstream logic
+      lx = 0xFFFF;
+  }
+  Serial.print("'AmbientLight':"); printValue(lx);
+  Serial.print("'BroadbandLight':"); printValue(broadband);
+  Serial.print("'Infrared':"); printValue(infrared);
+
   Serial.println("}}");

   delay(2000);   //Delay at the end to allow xbee to flush its send buffer
@@ -139,6 +119,16 @@
   sleep(60000);
 }

+void printValue(long value){
+  if (!isnan(value))
+  {
+    Serial.print(value); Serial.print(", ");
+  }
+  else
+  {
+    Serial.print("'NaN', ");
+  }
+}

 int pingCoordinator(void){


Fix variable in TwoSensorsDefault (#31)

Fix variable in TwoSensorsDefault (#31)

dht2.read() used temperature and humidity. Not temperature2 and humidity2


Fix for super-fast printing.

Fix for super-fast printing.

git-svn-id: d8bfcd070c2c81762cca1b3912331324182919ba@19303 0d6f1817-ed0e-0410-87c9-987e46238f29

--- zimodem/zcommand.ino
+++ zimodem/zcommand.ino
@@ -1601,7 +1601,8 @@
 bool ZCommand::readSerialStream()
 {
   bool crReceived=false;
-  while(HWSerial.available()>0)
+  while((HWSerial.available()>0)
+        &&(!crReceived))
   {
     uint8_t c=HWSerial.read();
     logSerialIn(c);


Added DHTxx support

Added DHTxx support

--- arduino/arduino.ino
+++ arduino/arduino.ino
@@ -1,28 +1,36 @@
-// temps entre actualitzacions de els elements
-// [lm35_1, lm35_2, ldr_1]
 #include <Wire.h>
 #include <SFE_BMP180.h>
+#include "DHT.h"

 #define count(x) sizeof(x)/sizeof(unsigned long)
 #define groundPin A0
-#define ALTITUDE 570
+
+
+#define ALTITUDE 570 // We need it for the barometric pressure calculus

 #define BMP180T 0   // Temperature
 #define BMP180P 1   // Pressure
+#define DHT22T  2   // Temperature
+#define DHT22H  3   // Humidity
+#define DHT22HI 4   // Heat Index

-#define NOTUSED -1  // For BMP180 sensor.
+#define NOTUSED -1  // For BMP180/DHT22 sensor.
+
+#define DHTTYPE DHT22
+#define DHTPIN  4

 SFE_BMP180 pressure;
+DHT dht(DHTPIN, DHTTYPE);

-int types[] = {BMP180T,BMP180P};
-unsigned long lastUpdate[] = {0,0};
-unsigned long updateTimes[] = {30000,60000};
-int pins[] = {NOTUSED,NOTUSED};
+int types[] = {BMP180T,BMP180P,DHT22T,DHT22H,DHT22HI};
+unsigned long lastUpdate[] = {0,0,0,0,0};
+unsigned long updateTimes[] = {30000,60000,30000,30000,60000};
+int pins[] = {NOTUSED,NOTUSED,NOTUSED,NOTUSED,NOTUSED};

 int secureAnalogRead(int pin) {
-  delay(0.01);
-  analogRead(groundPin);
-  delay(0.01);
+  //delay(0.01);
+  //analogRead(groundPin);
+  //delay(0.01);
   return analogRead(pin);

 }
@@ -43,7 +51,6 @@
   char status;
   if(bmp180Temperature(T)) {
     Serial.println(T);
-    delay(500);
     status = pressure.startPressure(3);
     if (status != 0) {
         delay(status);
@@ -74,17 +81,48 @@
   String c, v;
   switch (type) {
     case BMP180T:
-        double T;
-        c = "BMP180T";
-        if (bmp180Temperature(T)) v = String(T);
-        else v = c + " Error";
-        break;
+      {
+      double t;
+      c = "BMP180T";
+      if (bmp180Temperature(t)) v = String(t);
+      else v = c + " Error";
+      break;
+      }
+
     case BMP180P:
-        double P;
-        c = "BMP180P";
-        if (bmp180Pressure(P)) v = String(P);
-        else v = c + " Error";
-        break;
+      {
+      double p;
+      c = "BMP180P";
+      if (bmp180Pressure(p)) v = String(p);
+      else v = c + " Error";
+      break;
+      }
+
+    case DHT22T:
+      {
+      float t = dht.readTemperature();    // Default temperature unit is ºC.
+      c = "DHT22T";
+      v = String(t);
+      break;
+      }
+
+    case DHT22H:
+      {
+      float h = dht.readHumidity();
+      c = "DHT22H";
+      v = String(h);
+      break;
+      }
+    case DHT22HI:
+      {
+      float h, t, hi;
+      h = dht.readHumidity();
+      t = dht.readTemperature(true);    // We need value in farenheit.
+      hi = dht.computeHeatIndex(t,h);
+      c = "DHT22HI";
+      v = String(dht.convertFtoC(hi));
+      break;
+      }
   }
   sendCommand(c, v);
 }
@@ -138,6 +176,7 @@
   Serial.begin(9600); // set the baud rate
   if (pressure.begin()) Serial.println("BMP180 init success");
   else Serial.println("BMP180 init fail\n\n");
+  dht.begin();

   for (int i = 0; i < count(updateTimes); i++) {
     pinMode(pins[i], INPUT);


changed channel and volume changes

changed channel and volume changes

--- arduino_signal/arduino_signal.ino
+++ arduino_signal/arduino_signal.ino
@@ -160,323 +160,316 @@
 }
 void SendChannelUpCode() {
 //Change Channel Up
-delayMicroseconds(47780);
-pulseIR(8780);
+delayMicroseconds(23880);
+pulseIR(8760);
 delayMicroseconds(4400);
-pulseIR(640);
-delayMicroseconds(460);
-pulseIR(620);
-delayMicroseconds(460);
-pulseIR(640);
-delayMicroseconds(1560);
-pulseIR(620);
-delayMicroseconds(460);
-pulseIR(640);
-delayMicroseconds(460);
-pulseIR(640);
-delayMicroseconds(460);
-pulseIR(620);
-delayMicroseconds(460);
-pulseIR(640);
-delayMicroseconds(460);
-pulseIR(620);
-delayMicroseconds(1560);
-pulseIR(640);
-delayMicroseconds(1560);
-pulseIR(620);
-delayMicroseconds(460);
-pulseIR(640);
-delayMicroseconds(1560);
-pulseIR(640);
-delayMicroseconds(1540);
-pulseIR(640);
-delayMicroseconds(1560);
-pulseIR(640);
-delayMicroseconds(1560);
-pulseIR(620);
-delayMicroseconds(1560);
-pulseIR(640);
-delayMicroseconds(1560);
+pulseIR(540);
+delayMicroseconds(580);
+pulseIR(580);
+delayMicroseconds(500);
+pulseIR(600);
+delayMicroseconds(1600);
+pulseIR(580);
+delayMicroseconds(500);
+pulseIR(600);
+delayMicroseconds(500);
+pulseIR(540);
+delayMicroseconds(560);
+pulseIR(580);
+delayMicroseconds(500);
+pulseIR(600);
+delayMicroseconds(500);
+pulseIR(540);
+delayMicroseconds(1640);
+pulseIR(580);
+delayMicroseconds(1620);
+pulseIR(560);
+delayMicroseconds(520);
+pulseIR(580);
+delayMicroseconds(1620);
+pulseIR(580);
+delayMicroseconds(1600);
+pulseIR(540);
+delayMicroseconds(1660);
+pulseIR(580);
+delayMicroseconds(1620);
+pulseIR(560);
+delayMicroseconds(1620);
+pulseIR(540);
+delayMicroseconds(1660);
+pulseIR(600);
+delayMicroseconds(480);
+pulseIR(560);
+delayMicroseconds(540);
+pulseIR(600);
+delayMicroseconds(480);
+pulseIR(620);
+delayMicroseconds(480);
+pulseIR(540);
+delayMicroseconds(560);
+pulseIR(600);
+delayMicroseconds(520);
+pulseIR(580);
+delayMicroseconds(480);
+pulseIR(540);
+delayMicroseconds(560);
+pulseIR(580);
+delayMicroseconds(1600);
+pulseIR(540);
+delayMicroseconds(1660);
+pulseIR(600);
+delayMicroseconds(1600);
+pulseIR(580);
+delayMicroseconds(1600);
+pulseIR(540);
+delayMicroseconds(1640);
+pulseIR(620);
+delayMicroseconds(1580);
+pulseIR(600);
+delayMicroseconds(1600);
+pulseIR(520);
+delayMicroseconds(39000);
+pulseIR(8800);
+delayMicroseconds(2180);
+pulseIR(640);
+delayMicroseconds(28264);
+pulseIR(8800);
+delayMicroseconds(2200);
+pulseIR(620);
+
+}
+void SendChannelDownCode() {
+
+//Change Channel Down
+delayMicroseconds(872);
+pulseIR(8820);
+delayMicroseconds(4340);
 pulseIR(640);
 delayMicroseconds(440);
-pulseIR(640);
-delayMicroseconds(460);
-pulseIR(640);
-delayMicroseconds(460);
-pulseIR(620);
-delayMicroseconds(460);
-pulseIR(640);
-delayMicroseconds(460);
-pulseIR(620);
-delayMicroseconds(480);
-pulseIR(620);
-delayMicroseconds(460);
-pulseIR(640);
-delayMicroseconds(460);
-pulseIR(620);
-delayMicroseconds(1560);
-pulseIR(640);
-delayMicroseconds(1560);
-pulseIR(640);
-delayMicroseconds(1560);
-pulseIR(620);
-delayMicroseconds(1560);
-pulseIR(640);
+pulseIR(660);
+delayMicroseconds(440);
+pulseIR(620);
+delayMicroseconds(1580);
+pulseIR(620);
+delayMicroseconds(460);
+pulseIR(620);
+delayMicroseconds(500);
+pulseIR(620);
+delayMicroseconds(460);
+pulseIR(640);
+delayMicroseconds(440);
+pulseIR(640);
+delayMicroseconds(480);
+pulseIR(620);
 delayMicroseconds(1540);
 pulseIR(660);
-delayMicroseconds(1560);
-pulseIR(620);
-delayMicroseconds(1560);
-pulseIR(640);
-delayMicroseconds(38880);
-pulseIR(8800);
-delayMicroseconds(2200);
-pulseIR(620);
-delayMicroseconds(28284);
-pulseIR(8780);
-delayMicroseconds(2200);
-pulseIR(620);
-
-
-}
-void SendChannelDownCode() {
-
-//Change Channel Down
-delayMicroseconds(9564);
-pulseIR(8820);
-delayMicroseconds(4360);
-pulseIR(620);
-delayMicroseconds(460);
-pulseIR(640);
-delayMicroseconds(460);
-pulseIR(620);
-delayMicroseconds(1560);
-pulseIR(640);
-delayMicroseconds(460);
-pulseIR(640);
-delayMicroseconds(460);
-pulseIR(620);
-delayMicroseconds(460);
-pulseIR(640);
-delayMicroseconds(460);
-pulseIR(640);
-delayMicroseconds(460);
-pulseIR(620);
-delayMicroseconds(1560);
-pulseIR(640);
 delayMicroseconds(1540);
 pulseIR(640);
 delayMicroseconds(460);
-pulseIR(620);
-delayMicroseconds(1560);
-pulseIR(660);
-delayMicroseconds(1560);
-pulseIR(620);
-delayMicroseconds(1560);
-pulseIR(520);
-delayMicroseconds(1660);
-pulseIR(620);
-delayMicroseconds(1580);
-pulseIR(560);
-delayMicroseconds(1640);
-pulseIR(520);
-delayMicroseconds(580);
-pulseIR(540);
-delayMicroseconds(540);
-pulseIR(600);
-delayMicroseconds(1600);
-pulseIR(560);
-delayMicroseconds(520);
-pulseIR(600);
-delayMicroseconds(500);
-pulseIR(520);
-delayMicroseconds(580);
-pulseIR(560);
-delayMicroseconds(520);
-pulseIR(600);
-delayMicroseconds(500);
-pulseIR(540);
-delayMicroseconds(1640);
-pulseIR(580);
-delayMicroseconds(1620);
-pulseIR(580);
-delayMicroseconds(500);
-pulseIR(580);
-delayMicroseconds(1620);
-pulseIR(600);
-delayMicroseconds(1580);
-pulseIR(560);
-delayMicroseconds(1640);
-pulseIR(580);
-delayMicroseconds(1620);
-pulseIR(580);
-delayMicroseconds(38940);
+pulseIR(640);
+delayMicroseconds(1540);
+pulseIR(640);
+delayMicroseconds(1560);
+pulseIR(620);
+delayMicroseconds(1560);
+pulseIR(640);
+delayMicroseconds(1560);
+pulseIR(640);
+delayMicroseconds(1560);
+pulseIR(620);
+delayMicroseconds(1560);
+pulseIR(640);
+delayMicroseconds(460);
+pulseIR(620);
+delayMicroseconds(460);
+pulseIR(640);
+delayMicroseconds(1560);
+pulseIR(620);
+delayMicroseconds(460);
+pulseIR(640);
+delayMicroseconds(460);
+pulseIR(640);
+delayMicroseconds(460);
+pulseIR(620);
+delayMicroseconds(460);
+pulseIR(640);
+delayMicroseconds(460);
+pulseIR(640);
+delayMicroseconds(1540);
+pulseIR(640);
+delayMicroseconds(1580);
+pulseIR(620);
+delayMicroseconds(460);
+pulseIR(640);
+delayMicroseconds(1560);
+pulseIR(620);
+delayMicroseconds(1560);
+pulseIR(640);
+delayMicroseconds(1540);
+pulseIR(640);
+delayMicroseconds(1560);
+pulseIR(620);
+delayMicroseconds(38920);
 pulseIR(8820);
 delayMicroseconds(2160);
-pulseIR(640);
-delayMicroseconds(28284);
-pulseIR(8820);
-delayMicroseconds(2140);
-pulseIR(640);
-
-}
-
-void SendVolUpCode() {
-
-//Vol Up
-delayMicroseconds(41216);
-pulseIR(8840);
-delayMicroseconds(4340);
-pulseIR(620);
-delayMicroseconds(460);
-pulseIR(640);
-delayMicroseconds(460);
-pulseIR(600);
-delayMicroseconds(1580);
-pulseIR(640);
-delayMicroseconds(460);
-pulseIR(600);
-delayMicroseconds(500);
-pulseIR(640);
-delayMicroseconds(440);
-pulseIR(640);
-delayMicroseconds(460);
-pulseIR(600);
-delayMicroseconds(500);
-pulseIR(620);
-delayMicroseconds(1560);
-pulseIR(640);
-delayMicroseconds(1540);
-pulseIR(640);
-delayMicroseconds(460);
-pulseIR(620);
-delayMicroseconds(1580);
-pulseIR(640);
-delayMicroseconds(1560);
-pulseIR(620);
-delayMicroseconds(1560);
-pulseIR(600);
-delayMicroseconds(1580);
-pulseIR(640);
-delayMicroseconds(1580);
-pulseIR(600);
-delayMicroseconds(480);
-pulseIR(620);
-delayMicroseconds(460);
-pulseIR(620);
-delayMicroseconds(500);
-pulseIR(640);
-delayMicroseconds(1540);
-pulseIR(600);
-delayMicroseconds(480);
-pulseIR(620);
-delayMicroseconds(480);
-pulseIR(640);
-delayMicroseconds(440);
-pulseIR(620);
-delayMicroseconds(480);
-pulseIR(640);
-delayMicroseconds(1560);
-pulseIR(600);
-delayMicroseconds(1580);
-pulseIR(640);
-delayMicroseconds(1560);
-pulseIR(640);
-delayMicroseconds(440);
-pulseIR(640);
-delayMicroseconds(1560);
-pulseIR(620);
-delayMicroseconds(1560);
-pulseIR(640);
-delayMicroseconds(1560);
-pulseIR(640);
-delayMicroseconds(1560);
-pulseIR(620);
-delayMicroseconds(38920);
-pulseIR(8800);
-delayMicroseconds(2160);
-pulseIR(640);
-
-}
-void SendVolDownCode() {
-
-//Vol Down
-delayMicroseconds(62900);
-pulseIR(8820);
-delayMicroseconds(4360);
-pulseIR(620);
-delayMicroseconds(460);
-pulseIR(640);
-delayMicroseconds(460);
-pulseIR(600);
-delayMicroseconds(1580);
-pulseIR(620);
-delayMicroseconds(480);
-pulseIR(640);
-delayMicroseconds(460);
-pulseIR(620);
-delayMicroseconds(460);
-pulseIR(640);
-delayMicroseconds(460);
-pulseIR(640);
-delayMicroseconds(460);
-pulseIR(620);
-delayMicroseconds(1560);
-pulseIR(640);
-delayMicroseconds(1560);
-pulseIR(620);
-delayMicroseconds(480);
-pulseIR(600);
-delayMicroseconds(1580);
-pulseIR(640);
-delayMicroseconds(1560);
-pulseIR(620);
-delayMicroseconds(1560);
-pulseIR(640);
-delayMicroseconds(1540);
-pulseIR(640);
-delayMicroseconds(1580);
-pulseIR(600);
-delayMicroseconds(480);
-pulseIR(620);
-delayMicroseconds(1580);
-pulseIR(620);
-delayMicroseconds(460);
-pulseIR(640);
-delayMicroseconds(1560);
-pulseIR(620);
-delayMicroseconds(460);
-pulseIR(660);
-delayMicroseconds(440);
-pulseIR(600);
-delayMicroseconds(500);
-pulseIR(620);
-delayMicroseconds(460);
-pulseIR(640);
-delayMicroseconds(1560);
-pulseIR(620);
-delayMicroseconds(460);
-pulseIR(640);
-delayMicroseconds(1560);
-pulseIR(620);
-delayMicroseconds(460);
-pulseIR(640);
-delayMicroseconds(1560);
-pulseIR(620);
-delayMicroseconds(1580);
-pulseIR(600);
-delayMicroseconds(1580);
-pulseIR(640);
-delayMicroseconds(1560);
-pulseIR(620);
-delayMicroseconds(38920);
-pulseIR(8800);
-delayMicroseconds(2160);
-pulseIR(640);
+pulseIR(620);
 delayMicroseconds(28284);
 pulseIR(8840);
 delayMicroseconds(2140);
-pulseIR(640);
+pulseIR(600);
+
+}
+
+void SendVolUpCode() {
+//Vol Up
+delayMicroseconds(44280);
+pulseIR(8860);
+delayMicroseconds(4320);
+pulseIR(620);
+delayMicroseconds(480);
+pulseIR(600);
+delayMicroseconds(480);
+pulseIR(620);
+delayMicroseconds(1580);
+pulseIR(600);
+delayMicroseconds(500);
+pulseIR(600);
+delayMicroseconds(480);
+pulseIR(620);
+delayMicroseconds(480);
+pulseIR(600);
+delayMicroseconds(480);
+pulseIR(620);
+delayMicroseconds(480);
+pulseIR(620);
+delayMicroseconds(1580);
+pulseIR(600);
+delayMicroseconds(1600);
+pulseIR(580);
+delayMicroseconds(500);
+pulseIR(620);
+delayMicroseconds(1580);
+pulseIR(600);
+delayMicroseconds(1580);
+pulseIR(580);
+delayMicroseconds(1600);
+pulseIR(620);
+delayMicroseconds(1600);
+pulseIR(580);
+delayMicroseconds(1600);
+pulseIR(600);
+delayMicroseconds(500);
+pulseIR(600);
+delayMicroseconds(480);
+pulseIR(600);
+delayMicroseconds(500);
+pulseIR(600);
+delayMicroseconds(1580);
+pulseIR(620);
+delayMicroseconds(480);
+pulseIR(600);
+delayMicroseconds(500);
+pulseIR(580);
+delayMicroseconds(500);
+pulseIR(600);
+delayMicroseconds(500);
+pulseIR(600);
+delayMicroseconds(1580);
+pulseIR(620);
+delayMicroseconds(1580);
+pulseIR(600);
+delayMicroseconds(1580);
+pulseIR(600);
+delayMicroseconds(500);
+pulseIR(600);
+delayMicroseconds(1600);
+pulseIR(600);
+delayMicroseconds(1580);
+pulseIR(620);
+delayMicroseconds(1580);
+pulseIR(600);
+delayMicroseconds(1580);
+pulseIR(620);
+delayMicroseconds(38920);
+pulseIR(8840);
+delayMicroseconds(2140);
+pulseIR(600);
+}
+void SendVolDownCode() {
+
+//Vol Down
+delayMicroseconds(272);
+pulseIR(8820);
+delayMicroseconds(4360);
+pulseIR(580);
+delayMicroseconds(520);
+pulseIR(580);
+delayMicroseconds(500);
+pulseIR(600);
+delayMicroseconds(1600);
+pulseIR(580);
+delayMicroseconds(500);
+pulseIR(600);
+delayMicroseconds(500);
+pulseIR(580);
+delayMicroseconds(520);
+pulseIR(580);
+delayMicroseconds(500);
+pulseIR(600);
+delayMicroseconds(500);
+pulseIR(560);
+delayMicroseconds(1620);
+pulseIR(600);
+delayMicroseconds(1600);
+pulseIR(580);
+delayMicroseconds(500);
+pulseIR(620);
+delayMicroseconds(1580);
+pulseIR(600);
+delayMicroseconds(1600);
+pulseIR(560);
+delayMicroseconds(1620);
+pulseIR(600);
+delayMicroseconds(1600);
+pulseIR(580);
+delayMicroseconds(1600);
+pulseIR(580);
+delayMicroseconds(520);
+pulseIR(600);
+delayMicroseconds(1580);
+pulseIR(580);
+delayMicroseconds(520);
+pulseIR(600);
+delayMicroseconds(1580);
+pulseIR(580);
+delayMicroseconds(540);
+pulseIR(580);
+delayMicroseconds(480);
+pulseIR(620);
+delayMicroseconds(500);
+pulseIR(560);
+delayMicroseconds(520);
+pulseIR(600);
+delayMicroseconds(1580);
+pulseIR(600);
+delayMicroseconds(520);
+pulseIR(580);
+delayMicroseconds(1600);
+pulseIR(560);
+delayMicroseconds(540);
+pulseIR(580);
+delayMicroseconds(1600);
+pulseIR(580);
+delayMicroseconds(1600);
+pulseIR(620);
+delayMicroseconds(1580);
+pulseIR(600);
+delayMicroseconds(1580);
+pulseIR(600);
+delayMicroseconds(38940);
+pulseIR(8820);
+delayMicroseconds(2180);
+pulseIR(580);

 }
 void SendChannel59Code() {


commence debugging

commence debugging

--- colors_arduino/colors_arduino.ino
+++ colors_arduino/colors_arduino.ino
@@ -57,6 +57,18 @@

 /* Checks for user input. */
 void loop() {
+    /* BEGIN DEBUGGING */
+    for (int i = 0; i < 8; i++) {
+      board[0][0] = i;
+      board[0][1] = i;
+      board[0][2] = i;
+      board[0][3] = i;
+      renderBoard();
+      delay(500);
+    }
+    return;
+    /* END DEBUGGING */
+
     // Make sure we have a game going on
     if (!gameInProgress) {
         gameResult ? wonGame() : lostGame();
@@ -64,27 +76,31 @@
     }

     // Read inputs
-    int upVal = analogRead(UP_PIN);
-    int rightVal = analogRead(RIGHT_PIN);
-    int downVal = analogRead(DOWN_PIN);
-    int leftVal = analogRead(LEFT_PIN);
+    int upVal = digitalRead(UP_PIN);
+    int rightVal = digitalRead(RIGHT_PIN);
+    int downVal = digitalRead(DOWN_PIN);
+    int leftVal = digitalRead(LEFT_PIN);

     // Confirm that there was no previous button press (so we don't respond too many times)
     if (!buttonPressed) {
         // Make a move
         if (upVal) {
-            buttonPressed = true;
+            Serial.println("UP");
+            buttonPressed = true;
             makeMove(UP);
         }
         else if (rightVal) {
+            Serial.println("RIGHT");
             buttonPressed = true;
             makeMove(RIGHT);
         }
         else if (downVal) {
+            Serial.println("DOWN");
             buttonPressed = true;
             makeMove(DOWN);
         }
         else if (leftVal) {
+            Serial.println("LEFT");
             buttonPressed = true;
             makeMove(LEFT);
         }
@@ -94,6 +110,8 @@
     else if (!upVal && !rightVal && !downVal && !leftVal) {
         buttonPressed = false;
     }
+
+    delay(100);
 }

 /****************************************
@@ -101,9 +119,14 @@
  ****************************************/

 /* Resets internal game state and display. */
-void newGame() {
+void newGame() {
     // Clear board
     memcpy(board, blankBoard, sizeof(board));
+
+    /* BEGIN DEBUGGING */
+    renderBoard();
+    return;
+    /* END DEBUGGING */

     // Add |initialTiles| new tiles to the board
     int initialTiles = 2;
@@ -293,7 +316,7 @@
     return colors[value];
 }

-void renderBoard() {
+void renderBoard() {
     byte A = color(15) % 2     << 0
            + color( 1)         << 1
            + color( 2)         << 4
@@ -372,4 +395,4 @@
 /* Randomly returns the index of a row or column. */
 int randomIndex() {
     return random(0, 4);
-}+}


last day and its done finally !

last day and its done finally !

--- zippy_the_fox.ino
+++ zippy_the_fox.ino
@@ -179,6 +179,8 @@
 	motorLeft.initialise();
 	motorRight.initialise();

+	delay(500);
+
 	ENABLE_STANDBY;

 	initialiseBot();


Update Launchpad_Data_Processor.ino

Update Launchpad_Data_Processor.ino

--- Launchpad_Data_Processor/Launchpad_Data_Processor.ino
+++ Launchpad_Data_Processor/Launchpad_Data_Processor.ino
@@ -1,4 +1,4 @@
-/*                                                                   25th SEPTEMBER 2014
+/*                                                                    14th NOVEMBER 2014
 ========================================================================================
 ========================= Engineering Design 3A - FSAE TEAM 52 =========================
 ========================================================================================
@@ -57,12 +57,12 @@
                                            //  sets the maximum time elapsed before
                                            //  program should send an config update.

-boolean xbeeMode = false;                  //  This condition determines whether Xbees
+boolean xbeeMode = true;                  //  This condition determines whether Xbees
                                            //  are being used. Usually this would be
                                            //  true, except for testing without the
                                            //  Xbee.

-boolean SDMode = false;                    //  Condition to execute optional SD
+boolean SDMode = true;                    //  Condition to execute optional SD
                                            //  functionality. This is provided for
                                            //  testing purposes where the SD might
                                            //  not be used.
@@ -72,10 +72,12 @@
                                            //  which helps with testing transmission
                                            //  capacity.

+int dataRateDelay = 10;                  //  Sets the delay between each transmission
+
 //================================Setup Global Variables=================================
 float bdata = 0.00;   //set start point on 'B' data stream
 float binc = 0.20;    //set increment on 'B' data stream
-
+File myFile;
                                             //  These are default names for data sets.
                                             //  They may be changed freely by user, or
                                             //  program functions.
@@ -95,8 +97,9 @@
                                             //  9600, 14400, 19200, 38400, 57600,
                                             //  115200, 230400, 460800, 921600
   Serial2.begin(115200);
-
+
   //~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~Xbee Configuration~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+  Serial.println("----------Configuring Transmitting Xbee Module----------");
   if(xbeeMode)
   {
     int ok_count = 0;
@@ -176,7 +179,44 @@
       //Serial.println(" OK found");
     }  while(ok_count < 4);

-    Serial.println("OK received. Configuration complete");
+    Serial.println("OK received. Xbee Configuration complete\n");
+
+
+  //~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~SD Card Implementation~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+  if(SDMode)                              //  SD only needs to be initialized if SD is being
+  {                                       //  used. Otherwise, initialization will fail.
+    Serial.println("----------Configuring SD Card Backup----------");
+    pinMode(10, OUTPUT);                  //  Setup pin configuration
+
+    if (!SD.begin(4)) {                   //  Check if SD card is present
+      Serial.println("Initialization failed: Card may not be present");
+      return;
+    }
+                                          //  Delete existing data on SD card
+    Serial.println("Erasing existing data on card...");
+    boolean fileFlag = true;
+    int m=0;
+    while(fileFlag)
+    {
+       char fileName[15];
+       sprintf(fileName, "data%d.txt", m);
+       if(SD.exists(fileName))
+       {
+         Serial.print("Removing ");
+         Serial.println(fileName);
+         SD.remove(fileName);
+       }
+       else fileFlag = false;
+       m++;
+    }
+    Serial.println("All files removed");
+
+                                        //  Create new file
+    Serial.println("Creating file: data0.txt\n");
+    myFile = SD.open("data0.txt", FILE_WRITE);
+    Serial.println("SD configuration complete.");
+
+  }

   }

@@ -188,144 +228,170 @@
 void loop() {
   float timeElapsed = 0;
   float addedTime = 0;
-  int n = 0;
-  File myFile;
-
-  //~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~SD Card Implementation~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
-  if(SDMode)                              //  SD only needs to be initialized if SD is being
-  {                                       //  used. Otherwise, initialization will fail.
-    pinMode(10, OUTPUT);
-
-    if (!SD.begin(4)) {
-      Serial.println("initialization failed!");
-      return;
-    }
-
-    if(SD.exists("data.txt")){
-      SD.remove("data.txt");
-    }
+  float execTime = 0;
+  float initRead = 0;
+  float resetTime = 0;
+  int n=0;                                // Count loops around print routine
+  int i=0;
+  int transStat = 0;
+  int prevStat = 0;
+  boolean downloadBegin = false;
+  boolean transBegin = false;
+  float batteryLevel = 100;                 //  100% battery by default
+  float vehicleSpeed = 0;                   //  Speed starts at 0ms
+  float vehicleAccel = 0;                   //  Acceleration starts at 0ms^2
+  float engineTemp = 20;                    //  Engine temperature starts at 20 degrees
+  int vehicleIndicators = 0;
+
+  for(;;)
+  {
+    //~~~~~~~~~~~~~~~~~~~~~~~Create simulation data for now~~~~~~~~~~~~~~~~~~~~~~~~~~~
+    execTime = float(millis())/1000;     //  millis command is a long int that
+
+    timeElapsed = execTime - addedTime;     //  Checks how much time has elapsed,
+                                            //  if it has been more than 5 seconds
+    if((timeElapsed > configUpdateLimit) && sendConfigInfo)
+    {                                       //  since last config update, sends a
+       sendConfigString();                  //  config string.
+       addedTime = execTime;
+    }
+
+    //~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~SD Download Routine~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+                                  //  If a download is requested, no further data needs
+                                  //  to be read/generated/logged to SD. If information
+                                  //  was still being logged/transmitted, data will be
+                                  //  jumbled and SD writing happening simultaneously to
+                                  //  reading.
+
+    if(downloadBegin && myFile)
+    {
+      downloadSD();
+      downloadBegin = false;
+      Serial2.print("#\r");
+    }
+
+
+    //~~~~~~~~~~~~~~~~~~~~~~~~~Check for signals from plotter~~~~~~~~~~~~~~~~~~~~~~~~~
+    if(xbeeMode)
+    {
+      if(Serial2.available() > 2)
+      {
+        char start_buf[10] = "";
+        Serial2.readBytes(start_buf, Serial2.available());
+        Serial.print("Received string was: ");
+        Serial.println(String(start_buf));

-    myFile = SD.open("data.txt", FILE_WRITE);
-  }
-
-  //~~~~~~~~~~~~~~~~~~~~~~~~~~~Generate and Transmit Mock Data~~~~~~~~~~~~~~~~~~~~~~~~~~~
-  if(mockMode)                              //  Enters mock data transmission mode
-  {
-    int ramp = 0;
-    for(;;)                                 //  Loops in this mode forever
-    {
-           //~~~~~~~~~~~~~~~Print mock data string to serial port~~~~~~~~~~~~~~~~~~~~~~~~
-           float exectime = float(millis())/1000; //  millis command is a long int that
-                                                  //  contains program execute time in ms.
-
-           Serial2.print(exectime);                // 'T' data stream
+        if(String(start_buf) == "!!!")
+        {
+          Serial.println("----------Start Transmission Signal Received----------");
+          transBegin = true;
+        }
+        if(String(start_buf) == "~~~")
+        {
+          Serial.println("----------Stop Transmission Signal Received----------");
+          transBegin = false;
+        }
+        if(String(start_buf) == "---")
+        {
+          Serial.println("----------Timer Reset Signal Received----------");
+          Serial2.println("$");
+          Serial.println("Returned reset acknowledgement.");
+          while(Serial2.available() < 2);
+          memset(&start_buf, 0, sizeof(start_buf));
+          Serial2.readBytes(start_buf, Serial2.available());
+          Serial.print("Confirmation received: ");;
+          Serial.println(start_buf);
+
+          n=0;
+          initRead = 0;
+          resetTime = execTime;
+          createNewSDFile();
+        }
+        if(String(start_buf) == "===")
+        {
+          Serial.println("Initiating SD Download");
+          downloadBegin = true;
+          Serial.println(downloadBegin);
+        }
+        char error_buf[1] = "";
+        while(Serial2.available() > 0)
+        {
+          Serial.print(".");
+          Serial2.readBytes(error_buf, 1);
+        }
+        Serial.println("Buffer Flushed.\n");
+
+      }
+      if(!transBegin) continue;
+    }
+    else
+    {
+      if(Serial.available() > 2)
+      {
+        char start_buf[10] = "";
+        Serial.readBytes(start_buf, Serial.available());
+
+
+        Serial.print("Plotter string received was: ");
+        Serial.println(String(start_buf));
+        if(String(start_buf) == "!!!")
+        {
+          transBegin = true;
+        }
+        if(String(start_buf) == "~~~")  transBegin = false;
+        if(String(start_buf) == "---")
+        {
+          n=0;
+          initRead = 0;
+          resetTime = execTime;
+        }
+        if(String(start_buf) == "===")
+        {
+          Serial.println("Initiating SD Download");
+          downloadBegin = true;
+          Serial.println(downloadBegin);
+        }
+
+      }
+      if(!transBegin) continue;
+    }
+
+    if(mockMode)
+    {
+      if(n >= 500) continue;
+      //~~~~~~~~~~~~~~~Print mock data string to serial port~~~~~~~~~~~~~~~~~~~~~~~~
+         Serial2.print(execTime);                // 'T' data stream
+         Serial2.print(" ");
+         if(myFile) {
+          myFile.print(execTime);           // Print dataset to SD Card
+          myFile.print(" ");                         // Formatting
+         }
+         int i=1;
+         for(i; i < sigNum; i++)
+         {
+           float mockSig = random(0,1000);
+           Serial2.print(mockSig);               // 'A' data stream
            Serial2.print(" ");
-           Serial2.print(ramp);
-           Serial2.print(" ");
-           ramp += 1;

-           int i=2;
-           for(i; i < sigNum; i++)
-           {
-             Serial2.print(random(0,1000));          // 'A' data stream
-             Serial2.print(" ");
+                                                 //  SD Card Implementation
+          if(myFile) {
+            myFile.print(mockSig);           // Print dataset to SD Card
+            myFile.print(" ");                         // Formatting
            }
-           Serial2.print(" \r");
-
-           delay(25);//delay in ms 250 = 4 times a second
-
-           timeElapsed = exectime - addedTime;     //  Checks how much time has elapsed,
-                                                   //  if it has been more than 5 seconds
-                                                   /*
-           if((timeElapsed > configUpdateLimit) && sendConfigInfo)
-           {                                       //  since last config update, sends a
-             sendConfigString();                   //  config string.
-             addedTime = exectime;
-           }
-           */
-
-
-      }
-  }
-  else                                      //  Enters data acquisition mode
-  {
-                                            //  Creates realistic string of variables as
-                                            //  to those that would be expected.
-    float execTime = 0;
-    float batteryLevel = 100;               //  100% battery by default
-    float vehicleSpeed = 0;                 //  Speed starts at 0ms
-    float vehicleAccel = 0;                 //  Acceleration starts at 0ms^2
-    float engineTemp = 20;                   //  Engine temperature starts at 20 degrees
-    int vehicleIndicators = 0;
-    float initRead = 0;
-    float resetTime = 0;
-    int n=0;                                // Count loops around print routine
-    int i=0;
-    boolean transBegin = false;
-    boolean downloadBegin = false;
-
-    for(;;)
-    {
-      //~~~~~~~~~~~~~~~~~~~~~~~Create simulation data for now~~~~~~~~~~~~~~~~~~~~~~~~~~~
-      execTime = float(millis())/1000;     //  millis command is a long int that
-
-      timeElapsed = execTime - addedTime;     //  Checks how much time has elapsed,
-                                              //  if it has been more than 5 seconds
-      if((timeElapsed > configUpdateLimit) && sendConfigInfo)
-      {                                       //  since last config update, sends a
-         sendConfigString();                  //  config string.
-         addedTime = execTime;
-      }
-
-      //~~~~~~~~~~~~~~~~~~~~~~~~~Check for signals from plotter~~~~~~~~~~~~~~~~~~~~~~~~~
-     if(xbeeMode)
-      {
-        if(Serial2.available() > 2)
-        {
-          char start_buf[10] = "";
-          Serial2.readBytes(start_buf, Serial2.available());
-          Serial.print("Plotter string received was: ");
-          Serial.println(String(start_buf));
-          if(String(start_buf) == "!!!")
-          {
-            transBegin = true;
-          }
-          if(String(start_buf) == "~~~")  transBegin = false;
-          if(String(start_buf) == "---")
-          {
-            n=0;
-            initRead = 0;
-            resetTime = execTime;
-          }
-        }
-        if(!transBegin) continue;
-      }
-      else
-      {
-        if(Serial.available() > 2)
-        {
-          char start_buf[10] = "";
-          Serial.readBytes(start_buf, Serial.available());
-
-
-          Serial.print("Plotter string received was: ");
-          Serial.println(String(start_buf));
-          if(String(start_buf) == "!!!")
-          {
-            transBegin = true;
-          }
-          if(String(start_buf) == "~~~")  transBegin = false;
-          if(String(start_buf) == "---")
-          {
-            n=0;
-            initRead = 0;
-            resetTime = execTime;
-          }
-        }
-        if(!transBegin) continue;
-      }
-
+         }
+         myFile.print("\r");
+         Serial2.print(" \r");
+         delay(dataRateDelay);
+         n++;
+
+    }
+    else
+    {
       //~~~~~~~~~~~~~~~~~~~~~~~~~Generate Data for transmission~~~~~~~~~~~~~~~~~~~~~~~~~~
+                                                //  Creates realistic string of variables as
+                                                //  to those that would be expected.
+
+
       execTime = execTime - resetTime;

       i++;
@@ -355,12 +421,19 @@
         {
           if(SDMode)
           {
-            //SD with Xbee yet to be added, but should be much the same as below
-            Serial.println("SD with Xbee yet to be added, but should be much the same");
+                                              //  Transmit each data set
+            Serial2.print(currentDataSet[i]);
+            Serial2.print(" ");
+            if(i == (sizeof(currentDataSet)/sizeof(float) - 1)) Serial2.print("\r");
+                                              //  SD Card Implementation
+            if(myFile) {
+              myFile.print(currentDataSet[i]);           // Print dataset to SD Card
+              myFile.print(" ");                         // Formatting
+              if(i == (sizeof(currentDataSet)/sizeof(float) - 1)) myFile.print("\r");
+            }
           }
           else
           {
-            Serial.println("Sending data...");
             Serial2.print(currentDataSet[i]);
             Serial2.print(" ");
             if(i == (sizeof(currentDataSet)/sizeof(float) - 1)) Serial2.print("\r");
@@ -398,10 +471,11 @@
           }
         }
       }
-      delay(100);
+      delay(dataRateDelay);
       n++;                                   //  Increment loop counter
-    }
-  }
+    }
+  }
+

   // each while loop has a wait 1000 milliseconds before the loop
   // repeats for the output to be constant and not
@@ -439,3 +513,114 @@
     }
     return;
 }
+
+void downloadSD()
+{
+  String dataSet;
+  int bytesStored = 0;
+  int byteCount = 0;
+
+                      //  Close and save current SD file
+  Serial.println("SD File Saved.");
+  myFile.close();
+
+                      //  Determine how many files exist on SD card
+  boolean fileFlag = true;
+  int m=0;
+  char fileName[15];
+  while(fileFlag)
+  {
+     sprintf(fileName, "data%d.txt", m);
+     if(SD.exists(fileName))
+     {
+       Serial.print(fileName);
+       Serial.println(" exists.");
+     }
+     else
+     {
+       Serial.print(fileName);
+       Serial.println(" does not exist.");
+       fileFlag = false;
+     }
+     m++;
+  }
+
+                    //  Issue prompt to GUI on which file should be read
+  Serial.println("Prompting user to select file");
+  Serial2.print("%");
+  for(int u=0; u<(m-1); u++)  Serial2.print(u);
+  Serial2.print("\r");
+                    //  Wait for response from GUI
+  while(Serial2.available() < 3);
+                    //  Read in response
+  char start_buf[10] = "";
+  Serial2.readBytes(start_buf, Serial2.available());
+  Serial.println(start_buf);
+  sprintf(fileName, "data%c.txt", start_buf[2]);
+  Serial.println(fileName);
+
+                    //  Open selected file
+  if(SD.exists(fileName))  myFile = SD.open(fileName, FILE_READ);
+  else
+  {
+    Serial.println("File selected does not exist. Download cancelled");
+    return;
+  }
+
+  bytesStored = myFile.available();
+  Serial.print(bytesStored);
+  Serial.println(" bytes available on SD card.");
+  while(byteCount <= bytesStored)
+  {
+    dataSet = "";
+    for(int r=0; r<sigNum; r++)
+    {
+      String sampBuffer = "";
+      int s=0;
+      char sampChar;
+      do
+      {
+        sampChar = myFile.read();
+        byteCount++;
+        sampBuffer += String(sampChar);
+        s++;
+      }  while((!String(sampChar).equals(" ")) && (byteCount <= bytesStored));
+      dataSet += sampBuffer;
+      if(byteCount > bytesStored) break;
+    }
+    if(byteCount >  bytesStored) break;
+
+    Serial.print("Data Set was: ");
+    Serial.println(dataSet);
+    Serial2.print(dataSet);
+    delay(100);
+  }
+  Serial2.print("\r\n");
+  Serial2.print("#\r");
+  Serial.println("Download complete.");
+
+  createNewSDFile();
+  return;
+}
+
+void createNewSDFile()
+{
+                            //  Close current SD file and create a new one
+    Serial.println("Creating new SD File...");
+    myFile.close();
+                            //  Check existing files to determine next file name
+    boolean fileFlag = true;
+    int m=0;
+    char fileName[15];
+    while(fileFlag)
+    {
+       sprintf(fileName, "data%d.txt", m);
+       if(SD.exists(fileName))   m++;
+       else                      fileFlag = false;
+    }
+    Serial.print("New file name is: ");
+    Serial.println(fileName);
+    myFile = SD.open(fileName, FILE_WRITE);
+
+    return;
+}


feat: Sleep in between cycles

feat: Sleep in between cycles

--- kiln.ino
+++ kiln.ino
@@ -75,7 +75,7 @@
 		// go to sleep for a while to save battery life.  this will reset the
 		// entire program so we start up from the beginning
 		delay(PRE_SLEEP_DELAY);
-		/*sleep(MEASUREMENT_INTERVAL);*/
+		sleep(MEASUREMENT_INTERVAL);
 	} else {
 		Serial.println("Oh noes!  Couldn't read from our sensors!");

@@ -101,8 +101,7 @@

 void sleep(int seconds) {
 	digitalWrite(POWER_PIN, LOW);
-	digitalWrite(POWER_PIN, LOW);
-	//System.sleep(SLEEP_MODE_DEEP, seconds);
+	System.sleep(SLEEP_MODE_DEEP, seconds);
 }

 bool publishEvent() {


Fixed the bug introduced in 3f5698e4bd4a8cd0590b72b008c49a3ce1a96958.

--- webservertask.ino
+++ webservertask.ino
@@ -116,14 +116,10 @@
     AsyncResponseStream *response;
     if ( request->hasArg( "boottime" ) )
     {
-      time_t rawtime;
-      struct tm * timeinfo;
-      char buffer [25];
-
-      time (&rawtime);
-      timeinfo = localtime ( &rawtime );
-      strftime ( buffer, sizeof(buffer), "%c", timeinfo );
-      return request->send( 200, HTML_HEADER, buffer );
+      char response[25];
+
+      strftime ( response, sizeof( response ), "%c", localtime ( &systemStart.tv_sec ) );
+      return request->send( 200, HTML_HEADER, response );
     }

     else if ( request->hasArg( "channelcolors" ) )


ESP32 Improvements - add comments on configuration, leave RAM for SD Library even though matrix.begin() is called first, add placeholders for adjusting frameRate

--- AnimatedGIFs.ino
+++ AnimatedGIFs.ino
@@ -38,6 +38,8 @@
  * DIN          |  12
  * CLK          |  13
  * CS (default) |  15
+ *
+ * Wiring for ESP32 follows the default for the ESP32 SD Library, see: https://github.com/espressif/arduino-esp32/tree/master/libraries/SDis is on the default Teensy 3.1 SPI pins, and chip select can be on any GPIO,
  *
  * This code first looks for .gif files in the /gifs/ directory
  * (customize below with the GIF_DIRECTORY definition) then plays random GIFs in the directory,
@@ -62,6 +64,9 @@
  *    set kRefreshDepth=24 and kDmaBufferRows=2 or set USB Type: "None" in Arduino,
  *    decrease refreshRate in setup() to 90 or lower to get good an accurate GIF frame rate
  *  - Set the chip select pin for your board.  On Teensy 3.5/3.6, the onboard microSD CS pin is "BUILTIN_SDCARD"
+ *  - For ESP32 and large panels, you don't need to lower the refreshRate, but you can lower the frameRate (number of times the refresh buffer
+ *    is updaed with new data per second), giving more time for the CPU to decode the GIF.
+ *    Use matrix.setMaxCalculationCpuPercentage() or matrix.setCalcRefreshRateDivider()
  */

 #if defined (ARDUINO)
@@ -169,14 +174,23 @@

     matrix.setBrightness(defaultBrightness);

-    // for large panels, set the refresh rate lower to leave more CPU time to decoding GIFs (needed if GIFs are playing back slowly)
+
+    // for large panels, may want to set the refresh rate lower to leave more CPU time to decoding GIFs (needed if GIFs are playing back slowly)
     //matrix.setRefreshRate(90);
-
-    // for large panels on ESP32, set the calculation refresh rate divider lower to leave more CPU time to decoding GIFs (needed if GIFs are playing back slowly)
-    //matrix.setCalcRefreshRateDivider(4);

 #if !defined(ESP32)
     matrix.begin();
+#endif
+
+#if defined(ESP32)
+    // for large panels on ESP32, may want to set the max percentage time dedicated to updating the refresh frames lower, to leave more CPU time to decoding GIFs (needed if GIFs are playing back slowly)
+    //matrix.setMaxCalculationCpuPercentage(50);
+
+    // alternatively, for large panels on ESP32, may want to set the calculation refresh rate divider lower to leave more CPU time to decoding GIFs (needed if GIFs are playing back slowly) - this has the same effect as matrix.setMaxCalculationCpuPercentage() but is set with a different parameter
+    //matrix.setCalcRefreshRateDivider(4);
+
+    // The ESP32 SD Card library is going to want to malloc about 28000 bytes of DMA-capable RAM, make sure at least that much is left free
+    matrix.begin(28000);
 #endif

     // Clear screen
@@ -188,19 +202,10 @@
         scrollingLayer.start("No SD card", -1);
 #endif
         Serial.println("No SD card");
-        // for ESP32 we need to allocate SmartMatrix DMA buffers after we (in this case fail to) initialize the SD card to avoid using up too much memory
-#if defined(ESP32)
-        matrix.begin();
-#endif
         while(1);
     }

     // for ESP32 we need to allocate SmartMatrix DMA buffers after initializing the SD card to avoid using up too much memory
-#if defined(ESP32)
-    matrix.begin();
-    // If you don't see this message, SmartMatrix Library is likely using up too much CPU, lower the refresh rate or increase the calc refresh rate divider
-    Serial.println("matrix.begin() returned");
-#endif

     // Determine how many animated GIF files exist
     num_files = enumerateGIFFiles(GIF_DIRECTORY, false);


Re-add the all important mqtt publish line

--- Arilux_AL-LC0X.ino
+++ Arilux_AL-LC0X.ino
@@ -253,6 +253,7 @@
           root["payload_on"] = ARILUX_MQTT_STATE_ON_PAYLOAD;
           root["payload_off"] = ARILUX_MQTT_STATE_OFF_PAYLOAD;
           root.printTo(configBuf, sizeof(configBuf));
+          mqttClient.publish(HOME_ASSISTANT_MQTT_DISCOVERY_TOPIC, configBuf, true)
         #endif
       } else {
         DEBUG_PRINTLN(F("ERROR: The connection to the MQTT broker failed"));


updated. THIS VERSION IS CORRECT

updated. THIS VERSION IS CORRECT

--- BucketWheelActuationDriver/BucketWheelActuationDriver.ino
+++ BucketWheelActuationDriver/BucketWheelActuationDriver.ino
@@ -78,11 +78,11 @@
   //select which direction to go
   if (steps > 0) {
     digitalWrite(DIRECTION_PIN, LOW);
-    dir = -1;
+    dir = 1;
   }
   else {
     digitalWrite(DIRECTION_PIN, HIGH);
-    dir = 1;
+    dir = -1;
   }

   for(int i = 0; i < abs(steps); i++) {
@@ -138,7 +138,7 @@
   if (percent > 100 || percent < 0) return ERROR_OUT_OF_RANGE;

   //calculate number of steps and move.
-  int stepsToMove = int((toPercent(currentSteps) - percent)/100.0 * FULL_STEPS);
+  int stepsToMove = int(-(toPercent(currentSteps) - percent)/100.0 * FULL_STEPS);
   Serial.print("Moving to ");
   Serial.print(percent, DEC);
   Serial.print("% from ");


Delete K_Nearest_Neighbors_Sounds.ino

Delete K_Nearest_Neighbors_Sounds.ino

--- K_Nearest_Neighbors_Sounds/K_Nearest_Neighbors_Sounds.ino
+++ K_Nearest_Neighbors_Sounds/K_Nearest_Neighbors_Sounds.ino
@@ -1,384 +0,0 @@
-// Distance Sensor
-// Feature is height
-// Pre-known object of different heights
-// Pattern is see what the object is closest to.
-#include <Arduino.h>
-//#include <NewPing.h>
-#include <HX711.h>
-#include <Wire.h>
-#include <ToneDetector.h>
-#include "Adafruit_TCS34725.h"
-
-#include "Object.h"
-#include "CompareObject.h"
-
-// #define IR_SENSOR_PIN_1 6
-
-bool wait = false;
-
-// K Nearest Neighbors
-const int K = 3;
-
-void outputFrequencyAsBar(uint16_t aFrequency);
-
-const size_t NUM_OF_KNOWN_OBJECTS = 9;
-const size_t NUM_OF_OBJECT_TYPES = 3;
-// FIXME: Change to sound types
-String Object_Types[NUM_OF_OBJECT_TYPES] = {"Dog Barking", "Car Alarm", "Door Bell"};
-
-Object knownObjects[NUM_OF_KNOWN_OBJECTS];
-
-// Takes the features from the current object and converts them to strings and integers
-// **
-void ObjectFeatureExtraction(Object &currObject) {
-  // Get the various sound features
-  // Call the sound functions and stuff
-}
-
-float RescaleValue(float value, const float min, const float max) {
-  return (value-min)/(max-min);
-}
-
-// Rescale object features to 1-0 range
-void RescaleObject(Object *object) {
-  object->weight = RescaleValue(object->weight, WEIGHT_MIN, WEIGHT_MAX);
-  object->r = RescaleValue(object->r, COLOR_MIN, COLOR_MAX);
-  object->g = RescaleValue(object->g, COLOR_MIN, COLOR_MAX);
-  object->b = RescaleValue(object->b, COLOR_MIN, COLOR_MAX);
-}
-
-//  Computes the euclidean distance between the known and the current object's rgb values
-float ComputeDistanceofColors(Object currObject, Object knownObject) {
-  float red = currObject.r - knownObject.r;
-  float green = currObject.g - knownObject.g;
-  float blue = currObject.b - knownObject.b;
-  float dist = pow(red, 2) + pow(green, 2) + pow(blue, 2);
-  dist = roundf(dist* 100.0) / 100.0;
-  return dist;
-}
-
-// Computes the euclidean distance between the known and the current object's features
-float ComputeDistanceofObjects(Object currObject, Object knownObject) {
-  float weight = (currObject.weight - knownObject.weight);
-  float color_dist = ComputeDistanceofColors(currObject, knownObject);
-  float dist = weight*weight + color_dist*color_dist;
-
-  return dist;
-}
-
-// FIXME: Not the most accurate form of comparison.
-// May be good for now.
-// Compares the frequency arrays from the currObject and the knownObject
-// Returns the average difference between the arrays
-float CompareFrequencyArray(Object currObject, Object knownObject, CompareObject &compObject) {
-  int array_size = min(currObject.freq_size, knownObject.freq_size);
-  // The compObject takes the difference between the currObject and the knownObject
-  float avg_dist;
-  float sum = 0;
-  for(int i = 0; i < array_size; ++i) {
-    compObject.freq[i] = abs(currObject[i] - knownObject[i]);
-    sum += compObject.freq[i];
-  }
-  avg_dist = sum / array_size;
-  return avg_dist;
-}
-
-// Finds the patterns from the current object and compares them to patterns from the given objects
-// **
-String ObjectPatternRecognition(Object currObject, Object knownObjects[]) {
-  int count = 0;
-  int max_count = 0;
-  String most_frequent_type;
-
-  Object kNearestObjects[K];
-
-  CompareObject compObj;
-
-  Serial.print("Object frequency: ");
-
-  for(int i = 0; i < currObject.freq_size; ++i) {
-    Serial.println(currObject.freq[i]);
-  }
-
-  // First K known objects are the closest K, obviously, so just fill array
-  for(int i = 0; i < K; ++i) {
-    kNearestObjects[i].type = knownObjects[i].type;
-    // Fill the frequency array for the closest K objects.
-    for(int j = 0; j < freq_size; ++j) {
-      kNearestObjects[i].freq[j] = knownObjects[i].freq[j];
-    }
-  }
-
-  // TODO: Use Min Heap Data Structure to Optimize this part
-  // Now, determine if each remaining object is among the K closest, and if so insert into array (thus dropping one obj)
-  for(int i = K; i < NUM_OF_KNOWN_OBJECTS; ++i) { // For each remaining known object
-    int j;
-
-    // FIXME: Figure out comparison from compare frequency array and average
-    // Find the current max difference in the K nearest objects
-    float max_diff_of_K_nearest = 0;
-    int max_index = 0;
-    float temp_dist = 0;
-
-    for(j = 0; j < K; ++j) {
-      // kNearest Objects is the difference between the currObject and the knownObjects
-      // ComputeDistanceofObjects should compute the total distance for kNearestObjects[j]
-      // May just add this to the above
-      temp_dist = CompareFrequencyArray(currObject, kNearestObjects[j], compObj);
-
-      if(temp_dist > max_diff_of_K_nearest) { // Update max
-        max_diff_of_K_nearest = temp_dist;
-        max_index = j;
-      }
-    }
-
-    // If the current known object's difference < the max difference in the current K nearest neighbors
-    temp_dist = ComputeDistanceofObjects(currObject, knownObjects[i]);
-
-    if(temp_dist < max_diff_of_K_nearest) {
-      // Replace the existing neighbor having max_diff_of_K_nearest, by the current known object, in the K nearest neighbors array
-      kNearestObjects[max_index].type = knownObjects[i].type;
-      // Replace the frequency array as well
-      for(int j = 0; j < kNearestObjects[max_type].freq_size; ++j) {
-        kNearestObjects[max_index].freq[j] = knownObjects[i].freq[j];
-      }
-
-    }
-    // End FIXME
-  }
-
-  // For testing purposes
-  for(int i = 0; i < K; ++i) {
-    for(int j = 0; j < currObject.freq_size; ++j) {
-      Serial.println(currObject[i].freq[j]);
-    }
-  }
-
-  // Find out which object type occurs most frequently
-  for(int i = 0; i < NUM_OF_OBJECT_TYPES; ++i) {
-    int j;
-    count = 0;
-    for(j = 0; j < K; ++j) {
-      if(kNearestObjects[j].type == Object_Types[i]) {
-        count++;
-      }
-    }
-    if(count > max_count) {
-      max_count = count;
-      most_frequent_type = Object_Types[i];
-    }
-  }
-
-  return most_frequent_type;
-}
-
-// Prints the type of object that is being passed through the project
-// **
-void Actuation(String object) {
-  if(object != "") {
-    Serial.print("\t");
-    Serial.println(object);
-  }
-}
-
-void PopulateKnownObjects() {
-  // Change values and measure
-  knownObjects[0].type = "Orange";
-  knownObjects[0].weight = 270.0;
-  knownObjects[0].r = 255;
-  knownObjects[0].g = 139;
-  knownObjects[0].b = 85;
-
-  knownObjects[1].type = "Orange";
-  knownObjects[1].weight = 257.0;
-  knownObjects[1].r = 255;
-  knownObjects[1].g = 140;
-  knownObjects[1].b = 88;
-
-  knownObjects[2].type = "Orange";
-  knownObjects[2].weight = 250.0;
-  knownObjects[2].r = 255;
-  knownObjects[2].g = 128;
-  knownObjects[2].b = 85;
-
-  knownObjects[3].type = "Apple";
-  knownObjects[3].weight = 228.0;
-  knownObjects[3].r = 118;
-  knownObjects[3].g = 76;
-  knownObjects[3].b = 62;
-
-  knownObjects[4].type = "Apple";
-  knownObjects[4].weight = 216.0;
-  knownObjects[4].r = 111;
-  knownObjects[4].g = 80;
-  knownObjects[4].b = 63;
-
-  knownObjects[5].type = "Apple";
-  knownObjects[5].weight = 224.0;
-  knownObjects[5].r = 124;
-  knownObjects[5].g = 80;
-  knownObjects[5].b = 65;
-
-  knownObjects[6].type = "Lemon";
-  knownObjects[6].weight = 154.0;
-  knownObjects[6].r = 255;
-  knownObjects[6].g = 229;
-  knownObjects[6].b = 127;
-
-  knownObjects[7].type = "Lemon";
-  knownObjects[7].weight = 148.0;
-  knownObjects[7].r = 255;
-  knownObjects[7].g = 242;
-  knownObjects[7].b = 139;
-
-  knownObjects[8].type = "Lemon";
-  knownObjects[8].weight = 141.0;
-  knownObjects[8].r = 255;
-  knownObjects[8].g = 255;
-  knownObjects[8].b = 141;
-
-  knownObjects[9].type = "Pear";
-  knownObjects[9].weight = 217.0;
-  knownObjects[9].r = 198;
-  knownObjects[9].g = 183;
-  knownObjects[9].b = 110;
-
-  knownObjects[10].type = "Pear";
-  knownObjects[10].weight = 230.0;
-  knownObjects[10].r = 172;
-  knownObjects[10].g = 150;
-  knownObjects[10].b = 90;
-
-  knownObjects[11].type = "Pear";
-  knownObjects[11].weight = 222.0;
-  knownObjects[11].r = 207;
-  knownObjects[11].g = 190;
-  knownObjects[11].b = 109;
-}
-
-
-void setup() {
-  Serial.begin(9600);
-  // May need to use the below for this case
-  //Serial.begin(115200);
-
-  // Microphone function
-  setToneDetectorControlDefaults();
-  // Tone range
-  setToneDetectorMatchValues(1000, 2500);
-
-  PopulateKnownObjects();
-
-  String closestObject;
-}
-
-// Remove later, just for testing purposes
-void outputFrequencyAsBar(uint16_t aFrequency) {
-  if (aFrequency > 800) {
-    aFrequency -= 800;
-    uint8_t tNumberOfStarsToPrint = (aFrequency / 50) + 1;
-    for (int i = 0; i < tNumberOfStarsToPrint; ++i) {
-      Serial.print("*");
-    }
-  }
-  Serial.println();
-}
-
-void loop() {
-  String closestObject;
-
-  uint16_t tFrequency = readSignal();
-
-  digitalWrite(LED_BUILTIN, LOW);
-
-
-  if (tFrequency > SIGNAL_MAX_ERROR_CODE) {
-    Serial.print(tFrequency);
-    Serial.print("Hz ");
-    outputFrequencyAsBar(tFrequency);
-
-    // Plausability check, don't output anything if error
-    tFrequency = doPlausi();
-    if (tFrequency == SIGNAL_FIRST_LAST_PLAUSI_FAILED) {
-      /*
-       * You get this error code if no trigger occurs in the first or last 128 samples because signal is noisy or or only a burst
-      */
-      wait = false;
-    }
-    else if (tFrequency == SIGNAL_DISTRIBUTION_PLAUSI_FAILED) {
-      /*
-       * You get this error code if more than 1/8 of the samples are greater than 1.5 or less than 0.75 of the average period
-      */
-      wait = false;
-    }
-    else {
-
-      // FIXME: This should be in feature extraction
-      computeDirectAndFilteredMatch(tFrequency);
-      if (ToneDetectorControl.ToneMatchDirect == TONE_MATCH && !wait) {
-        // signal match
-        digitalWrite(LED_BUILTIN, HIGH);
-
-        // Do sound detection thing
-        Serial.println("Sound Detected");
-
-        delay(1000);
-
-        digitalWrite(LED_BUILTIN, HIGH);
-
-        Object currObject;
-
-        ObjectFeatureExtraction(currObject);
-
-        closestObject = ObjectPatternRecognition(currObject, knownObjects);
-
-        Actuation(closestObject);
-
-        wait = true;
-
-        delay(1000);
-      }
-      else if(ToneDetectorControl.ToneMatchDirect == TONE_MATCH && wait) {
-        digitalWrite(LED_BUILTIN, LOW);
-      }
-    }
-  }
-  else {
-    digitalWrite(LED_BUILTIN, LOW);
-    wait = false;
-  }
-
-  /*
-
-  // Sensor was tripped and wasn't right before.
-  if(IR_Sensor1 == LOW && !wait) {
-    Serial.println("Fruit Detected");
-
-    delay(1000);
-
-    digitalWrite(LED_BUILTIN, HIGH);
-    Object currObject;
-
-    ObjectFeatureExtraction(currObject);
-
-    closestObject = ObjectPatternRecognition(currObject, knownObjects);
-
-    Actuation(closestObject);
-
-    wait = true;
-
-    delay(1000);
-  }
-  // Sensor was tripped and was right before.
-  else if(IR_Sensor1 == LOW && wait) {
-    digitalWrite(LED_BUILTIN, LOW);
-  }
-  // Sensor was not tripped.
-  else if(IR_Sensor1 == HIGH){
-    digitalWrite(LED_BUILTIN, LOW);
-    wait = false;
-  }
-
-  */
-
-}