D21FM: moving stuff down to lib

D21FM: moving stuff down to lib

--- V0p2_Main/V0p2_Main.ino
+++ V0p2_Main/V0p2_Main.ino
@@ -94,7 +94,7 @@
   {
   OTV0P2BASE::serialPrintlnAndFlush(); // Start new line to highlight error.  // May fail.
   OTV0P2BASE::serialPrintAndFlush('!'); // Indicate error with leading '!' // May fail.
-  OTV0P2BASE::serialPrintlnAndFlush(s); // May fail.
+  OTV0P2BASE::serialPrintlnAndFlush(s); // Print supplied detail text. // May fail.
   panic();
   }

@@ -508,79 +508,8 @@
   DEBUG_SERIAL_PRINT(intTempC16);
   DEBUG_SERIAL_PRINTLN();
 #endif
-
 #if !defined(ENABLE_MIN_ENERGY_BOOT)
-  // Seed PRNG(s) with available environmental values and clock time/jitter for some entropy.
-  // Also sweeps over SRAM and EEPROM (see RAMEND and E2END), especially for non-volatile state and uninitialised areas of SRAM.
-  // TODO: add better PRNG with entropy pool (eg for crypto).
-  // TODO: add RFM22B WUT clock jitter, RSSI, temperature and battery voltage measures.
-  const uint16_t srseed = OTV0P2BASE::sramCRC();
-  const uint16_t eeseed = OTV0P2BASE::eeCRC();
-  // DHD20130430: maybe as much as 16 bits of entropy on each reset in seed1, concentrated in the least-significant bits.
-  const uint16_t s16 = (__DATE__[5]) ^
-                       Vcc ^
-                       (intTempC16 << 1) ^
-#if !defined(ALT_MAIN_LOOP)
-                       (heat << 2) ^
-#if defined(TEMP_POT_AVAILABLE)
-                       ((((uint16_t)tempPot) << 3) + tempPot) ^
-#endif
-                       (AmbLight.get() << 4) ^
-#if defined(HUMIDITY_SENSOR_SUPPORT)
-                       ((((uint16_t)rh) << 8) - rh) ^
-#endif
-#endif
-                       (OTV0P2BASE::getMinutesSinceMidnightLT() << 5) ^
-                       (((uint16_t)OTV0P2BASE::getSubCycleTime()) << 6);
-  //const long seed1 = ((((long) clockJitterRTC()) << 13) ^ (((long)clockJitterWDT()) << 21) ^ (((long)(srseed^eeseed)) << 16)) + s16;
-  // Seed simple/fast/small built-in PRNG.  (Smaller and faster than srandom()/random().)
-  const uint8_t nar1 = OTV0P2BASE::noisyADCRead();
-  OTV0P2BASE::seedRNG8(nar1 ^ (uint8_t) s16, oldResetCount - (uint8_t)((s16+eeseed) >> 8), ::OTV0P2BASE::clockJitterWDT() ^ (uint8_t)srseed);
-#if 0 && defined(DEBUG)
-  DEBUG_SERIAL_PRINT_FLASHSTRING("nar ");
-  DEBUG_SERIAL_PRINTFMT(nar1, BIN);
-  DEBUG_SERIAL_PRINTLN();
-#endif
-  // TODO: seed other/better PRNGs.
-  // Feed in mainly persistent/nonvolatile state explicitly.
-  OTV0P2BASE::addEntropyToPool((uint8_t)(eeseed >> 8) + nar1, 0);
-  OTV0P2BASE::addEntropyToPool((uint8_t)s16 ^ (uint8_t)(s16 >> 8), 0);
-  for(uint8_t i = 0; i < V0P2BASE_EE_LEN_SEED; ++i)
-    { OTV0P2BASE::addEntropyToPool(eeprom_read_byte((uint8_t *)(V0P2BASE_EE_START_SEED + i)), 0); }
-  OTV0P2BASE::addEntropyToPool(OTV0P2BASE::noisyADCRead(), 1); // Conservative first push of noise into pool.
-  // Carry a few bits of entropy over a reset by picking one of the four designated EEPROM bytes at random;
-  // if zero, erase to 0xff, else AND in part of the seed including some of the previous EEPROM hash (and write).
-  // This amounts to about a quarter of an erase/write cycle per reset/restart per byte, or 400k restarts endurance!
-  // These 4 bytes should be picked up as part of the hash/CRC of EEPROM above, next time,
-  // essentially forming a longish-cycle (poor) PRNG even with little new real entropy each time.
-  OTV0P2BASE::seedRNG8(nar1 ^ (uint8_t) s16, oldResetCount - (uint8_t)((s16+eeseed) >> 8), ::OTV0P2BASE::clockJitterWDT() ^ (uint8_t)srseed);
-  uint8_t *const erp = (uint8_t *)(V0P2BASE_EE_START_SEED + (3&((s16)^((eeseed>>8)+(__TIME__[7]))))); // Use some new and some eeseed bits to choose which byte to updated.
-  const uint8_t erv = eeprom_read_byte(erp);
-  if(0 == erv) { OTV0P2BASE::eeprom_smart_erase_byte(erp); }
-  else
-    {
-    OTV0P2BASE::eeprom_smart_clear_bits(erp,
-#if !defined(NO_clockJitterEntropyByte)
-      ::OTV0P2BASE::clockJitterEntropyByte()
-#else
-      (::OTV0P2BASE::clockJitterWDT() ^ nar1) // Less good fall-back when clockJitterEntropyByte() not available with more actual entropy.
-#endif
-      + ((uint8_t)eeseed)); // Nominally include disjoint set of eeseed bits in choice of which to clear.
-    }
-#if 0 && defined(DEBUG)
-  DEBUG_SERIAL_PRINT_FLASHSTRING("srseed ");
-  DEBUG_SERIAL_PRINTFMT(srseed, BIN);
-  DEBUG_SERIAL_PRINTLN();
-  DEBUG_SERIAL_PRINT_FLASHSTRING("eeseed ");
-  DEBUG_SERIAL_PRINTFMT(eeseed, BIN);
-  DEBUG_SERIAL_PRINTLN();
-  DEBUG_SERIAL_PRINT_FLASHSTRING("RNG8 ");
-  DEBUG_SERIAL_PRINTFMT(randRNG8(), BIN);
-  DEBUG_SERIAL_PRINTLN();
-  DEBUG_SERIAL_PRINT_FLASHSTRING("erv ");
-  DEBUG_SERIAL_PRINTFMT(erv, BIN);
-  DEBUG_SERIAL_PRINTLN();
-#endif
+  OTV0P2BASE::seedPRNGs();
 #endif
 #endif


Sistemato SMD-01

Sistemato SMD-01

--- GizWits/SMD-01/SMD-01.ino
+++ GizWits/SMD-01/SMD-01.ino
@@ -18,11 +18,10 @@
   Serial.begin(115200);
   delay(10);

-  // We start by connecting to a WiFi network
-  Serial.println();
-  Serial.println();
+  // Si parte!
   Serial.print("Connecting to ");
   Serial.println(ssid);
+
   WiFi.begin(ssid, password);
   while (WiFi.status() != WL_CONNECTED) {
     delay(500);
@@ -37,10 +36,7 @@

 void loop() {

-  //Serial.print("Connecting to ");
-  //Serial.println(host);
-
-  // Use WiFiClient class to create TCP connections
+  // Usiamo WiFiClient per la connessione al web
   WiFiClient client;
   const int httpPort = 80;
   if (!client.connect(host, httpPort)) {
@@ -48,25 +44,26 @@
     return;
   }

-  // Reading temperature and humidity
+  // Leggiamo il valore analogico della LDR
   int lux = analogRead(A0);

-  // This will send the request to the server
-  client.print(String("GET /dweet/for/SchoolMakerDay?lux=") + String(lux) + " HTTP/1.1\r\n" +
+  // Costruisco l'url per dweet.io
+  String url = String("GET /dweet/for/SchoolMakerDayLDR?lux=") +
+               String(lux) + " HTTP/1.1\r\n" +
                "Host: " + host + "\r\n" +
-               "Connection: close\r\n\r\n");
+               "Connection: close\r\n\r\n";
+
+  // il Log qui...
+  // https://dweet.io/follow/SchoolMakerDayLDR
+  client.print(url);
   delay(10);

-  // Read all the lines of the reply from server and print them to Serial
+  // Leggo tutto quello che mi arriva come risposta...
   while(client.available()){
     String line = client.readStringUntil('\r');
-    //Serial.print(line);
+    Serial.print(line);
   }
-
-  //Serial.println();
-  //Serial.println("closing connection");
-
-  // Repeat every 5 seconds
-  delay(10000);
-
+
+  // Ogni 5 secondi rifaciamo il giro.
+  delay(5000);
 }


Added white led to TemperatureSensor

Added white led to TemperatureSensor

--- TemperatureSensor/TemperatureSensor.ino
+++ TemperatureSensor/TemperatureSensor.ino
@@ -6,6 +6,7 @@
  + LM35DT - OUTPUT on A6
  + LM35DT - GND on A7 (bridged to common GND)
  + LM35DT - INPUT on +5V
+ + White LED (+) on D08
  + Blue LED (+) on D09
  + Green LED (+) on D10
  + Yellow LED (+) on D11
@@ -27,6 +28,7 @@
 int Y = 11;         // Yellow LED
 int G = 10;         // Green LED
 int B =  9;         // Blue LED
+int W =  8;         // White LED
 int ledGND = 7;

 float mv = 0.0;     // milliVolts read
@@ -43,6 +45,7 @@
   pinMode(Y, OUTPUT);
   pinMode(G, OUTPUT);
   pinMode(B, OUTPUT);
+  pinMode(W, OUTPUT);
   pinMode(ledGND, OUTPUT);
 }

@@ -67,7 +70,12 @@
   delay(1000-mv);

   // Display output on the leds
-  if (C > 0.0) // Cool
+  if (C > 0.0) // Cold
+    digitalWrite(W, HIGH);
+  else
+    digitalWrite(W, LOW);
+
+  if (C > 15.0) // Cool
     digitalWrite(B, HIGH);
   else
     digitalWrite(B, LOW);
@@ -87,3 +95,4 @@
   else
     digitalWrite(R, LOW);
 }
+


Clean up animation code

Clean up animation code

--- MagnusCore/MagnusCore.ino
+++ MagnusCore/MagnusCore.ino
@@ -13,27 +13,16 @@
 const uint16_t LEDS_PER_STRAND = 50;
 const bool RGBW_SUPPORT = false;

-// Mask to clear 'upper case' ASCII bit
-const char CASE_MASK = ~0x20;
-
 enum Direction { NORTH = 0, NORTHEAST, EAST, SOUTHEAST, SOUTH, SOUTHWEST, WEST, NORTHWEST };
 enum Ownership {  neutral = 0, enlightened, resistance };
-
-struct pixel_string {
-  uint16_t phase;
-  uint32_t timing;
-};

 // Static animation implementations singleton
 Animations animations;

 AnimationState states[NUM_STRINGS];

-//Animation *pCurrAnimation;
-
-CircularBuffer<Animation *> animationQueue;
-
-pixel_string strings[NUM_STRINGS];
+typedef CircularBuffer<Animation *> QueueType;
+QueueType animationQueues[NUM_STRINGS];

 // Parameter 1 = number of pixels in strip
 // Parameter 2 = Arduino pin number (most are valid)
@@ -94,10 +83,9 @@
   return uint8_t( constrain(inVal, 0, 100) );
 }

-
 uint8_t dir;
 uint8_t percent;
-uint8_t owner;    // 0=neutral, 1=enl, 2=res
+Ownership owner;    // 0=neutral, 1=enl, 2=res

 // the setup function runs once when you press reset or power the board
@@ -110,12 +98,9 @@
   {
     strip.setPin(i + BASE_PIN);
     strip.show(); // Initialize all pixels to 'off'
-
-    strings[i].phase = 0;
-    strings[i].timing = 0;
   }

-  dir = NORTH; // begin on the north resonator
+  dir = 0;
   owner = neutral;
   percent = 0;
 }
@@ -123,109 +108,75 @@
 // the loop function runs over and over again forever
 void loop()
 {
-  uint16_t i, val;
+    uint16_t i, val;

-  if( collect_serial() )
-  {
-      // we have valid buffer of serial input
-      char cmd = command[0] & CASE_MASK;
-      switch (cmd) {
-          case '*':
-            Serial.println("Magnus Core Node");
-            break;
-          case 'E':
-          case 'R':
-              owner = cmd == 'E' ? enlightened : resistance;
-              percent = getPercent(&command[1]);
-              uint8_t red, green, blue, white;
-              Color c;
-              c = ToColor(0x00,
-                  owner == enlightened ? 0xff : 0x00,
-                  owner == resistance ? 0xff : 0x00,
-                  0x00);
-              animations.pulse.init(states[0], strip, c);
-//              pCurrAnimation = &animations.pulse;
-              animationQueue.setTo(&animations.pulse);
-              break;
+    if( collect_serial() )
+    {
+        // we have valid buffer of serial input
+        char cmd = command[0];
+        switch (cmd) {
+            case '*':
+                Serial.println("Magnus Core Node");
+                break;
+            case 'E':
+            case 'e':
+            case 'R':
+            case 'r':
+                owner = cmd == 'E' ? enlightened : resistance;
+                percent = getPercent(&command[1]);
+                uint8_t red, green, blue, white;
+                Color c;
+                c = ToColor(0x00,
+                        owner == enlightened ? 0xff : 0x00,
+                        owner == resistance ? 0xff : 0x00,
+                        0x00);
+                for (int i = 0; i < NUM_STRINGS; i++) {
+                    QueueType& animationQueue = animationQueues[i];
+                    animations.pulse.init(states[i], strip, c);
+                    animationQueue.setTo(&animations.pulse);
+                }
+                break;

-          case 'N':
-              owner = neutral;
-              animations.redFlash.init(states[0], strip, RGBW_SUPPORT);
-              animationQueue.setTo(&animations.redFlash);
-              animationQueue.add(&animations.solid);
-              percent = 20;
-              break;
+            case 'N':
+            case 'n':
+                owner = neutral;
+                percent = 20;
+                for (int i = 0; i < NUM_STRINGS; i++) {
+                    QueueType& animationQueue = animationQueues[i];
+                    animations.redFlash.init(states[i], strip, RGBW_SUPPORT);
+                    animationQueue.setTo(&animations.redFlash);
+                    animationQueue.add(&animations.solid);
+                }
+                break;

-          default:
-              Serial.print("Unkwown command "); Serial.println(cmd);
-              break;
-      }
-      Serial.print((char *)command); Serial.print(" - ");Serial.print(command[0],DEC);Serial.print(": ");
-      Serial.print("owner "); Serial.print(owner,DEC); Serial.print(", percent "); Serial.println(percent,DEC);
-  }
+            default:
+                Serial.print("Unkwown command "); Serial.println(cmd);
+                break;
+        }
+        Serial.print((char *)command); Serial.print(" - ");Serial.print(command[0],DEC);Serial.print(": ");
+        Serial.print("owner "); Serial.print(owner,DEC); Serial.print(", percent "); Serial.println(percent,DEC);
+    }

-  if(strings[dir].timing < millis() )
-  {
-      strings[dir].timing += 10; // every 100 milliseconds we will check this direction
+    strip.setPin(dir + BASE_PIN);  // pick the string

-      strip.setPin(dir+BASE_PIN);  // pick the string
+    QueueType& animationQueue = animationQueues[dir];
+    unsigned int queueSize = animationQueue.size();
+    if (queueSize > 1) {
+        if (animationQueue.peek()->done(states[dir])) {
+            animationQueue.remove();
+            queueSize--;
+            animationQueue.peek()->start(states[dir]);
+        }
+    }
+    if (queueSize > 0) {
+        //strip.setBrightness(255);
+        strip.setBrightness((uint8_t)((uint16_t)(255*(percent/100.0))));
+        //pCurrAnimation->doFrame(states[0], strip);
+        animationQueue.peek()->doFrame(states[dir], strip);
+    }

-      uint8_t red, green, blue, white;
-      red = 0x20; green = 0; blue = 0x20; white = 0x20;
-      bool useAnimations = false;
-      if( owner == neutral )
-      {
-          red = 0x40; green = 0x40; blue = 0x40; white = 0x40;
-          //      red = 0; green = 0; blue = 0; white = 0x40;
-          useAnimations = true;
-      }
-      else if( owner == resistance )
-      {
-          red = 0; green = 0x1f; blue = 0xff;; white = 0;
-          useAnimations = true;
-      }
-      else if( owner == enlightened )
-      {
-          red = 0x1f; green = 0xff; blue = 0; white = 0;
-          useAnimations = true;
-      }
-
-      if (useAnimations) {
-          unsigned int queueSize = animationQueue.size();
-          if (queueSize > 1) {
-              if (animationQueue.peek()->done(states[0])) {
-                  animationQueue.remove();
-                  queueSize--;
-                  animationQueue.peek()->start(states[0]);
-              }
-          }
-          if (queueSize > 0) {
-              //strip.setBrightness(255);
-              strip.setBrightness((uint8_t)((uint16_t)(255*(percent/100.0))));
-              //pCurrAnimation->doFrame(states[0], strip);
-              animationQueue.peek()->doFrame(states[0], strip);
-          }
-      } else {
-          for(i=0; i < strip.numPixels(); i++)
-          {
-              //strip.setPixelColor(i, green,blue,red); // for RGB order is funny?
-              //        strip.setPixelColor(i, green, red, blue,white);
-              strip.setPixelColor(i, red, green, blue);
-              //        float scale = ((millis()/100)%100)/200.0 + 0.5;
-              float scale = 1.0f;
-              float pct = percent * scale;
-              //        Serial.print("Percent: "); Serial.println(pct, 4);
-              strip.setBrightness((uint8_t)((uint16_t)(255*(pct/100.0))));
-          }
-          strip.show();
-      }
-
-      dir++;
-      if( dir >= NUM_STRINGS )
-          dir = 0;
-  }
-
-
+    // Update one strand each time through the loop
+    dir = (dir + 1) % NUM_STRINGS;
 }


50Byte savings by removing Serial.println() call

--- arduboy-game/arduboy-game.ino
+++ arduboy-game/arduboy-game.ino
@@ -400,7 +400,7 @@
       }

-
+
       if (arduboy.pressed(A_BUTTON) || arduboy.pressed(B_BUTTON)) {
         switch (selectedItem) {
           case SETTINGS_EXIT:
@@ -409,7 +409,7 @@

           case SETTINGS_SOUND:
             soundOn = !soundOn;
-            Serial.println(soundOn, BIN);
+//            Serial.println(soundOn, BIN);
             printsoundOnOff();
             break;

@@ -422,7 +422,6 @@
         }

         lastDebounceTime = currentMilliseconds; //set the current time
-
       }

       delay(15);


improved halt function: this shortens the braking distance by turning the wheels in reversed direction

--- arduino/pi_rover/pi_rover.ino
+++ arduino/pi_rover/pi_rover.ino
@@ -24,7 +24,7 @@
   while(Serial.available()) {
     character = Serial.read();
     input.concat(character);
-    delay(25);
+    delay(2);
   }

   if (input != "") {
@@ -136,6 +136,23 @@

 String halt(int argument)
 {
+  int currentMotorSpeedInPercentage = map(
+    motorSpeed,
+    0, 255,
+    0, 100
+  );
+
+  if (isMovingForward)
+  {
+    backward(80);
+    delay(currentMotorSpeedInPercentage * 2);
+  }
+  else if(isMovingBackward)
+  {
+    forward(80);
+    delay(currentMotorSpeedInPercentage * 2);
+  }
+
   turnMotorsOff();

   isMovingForward = false;


Remove showing the path with LEDs to make it ready for Bluetooth

those stupid line endings are really annoying

--- ArduinoMazeSolver/ArduinoMazeSolver.ino
+++ ArduinoMazeSolver/ArduinoMazeSolver.ino
@@ -1,22 +1,22 @@
-#include "Motor.h"
+#include "Motor.h"
 #include <QTRSensors.h>
 #include "Direction.h"
 #include <SoftwareSerial.h>

-#pragma region "Pin declarations"
+#pragma region "Pin declarations"
 const unsigned char ledPins[] = { 4, 5, 6, 7 };
-unsigned char sensorPins[] = { 0, 1, 2, 3, 4, 5 };
-SoftwareSerial bluetooth(7, 10); // RX, TX
-#pragma endregion
-
-#pragma region "Variable declarations"
+unsigned char sensorPins[] = { 0, 1, 2, 3, 4, 5 };
+SoftwareSerial bluetooth(7, 10);
+#pragma endregion
+
+#pragma region "Constant declarations"
 const int threshold = 400;

 // pd loop constants
 const float proportionalConst = 0.2f;
 const float derivateConst = 1.0f;

-const int maxMotorSpeed = 250;
+const int maxMotorSpeed = 255;

 Direction path[300];

@@ -124,19 +124,21 @@

 void loop()
 {
-	while (bluetooth.available()) {
-		myChar = bluetooth.read();
-		Serial.print(myChar);
-	}
-
-	while (Serial.available()) {
-		myChar = Serial.read();
-		bluetooth.print(myChar);
-	}
-
-	if (myChar == 9)
-	{
-		shutDown();
+	while (bluetooth.available())
+	{
+		myChar = bluetooth.read();
+		Serial.print(myChar);
+	}
+
+	while (Serial.available())
+	{
+		myChar = Serial.read();
+		bluetooth.print(myChar);
+	}
+
+	if (myChar == 's')
+	{
+		shutDown();
 	}

 	drive();
@@ -232,12 +234,12 @@
 unsigned char getNumberOfCurrentlyWhiteSensors()
 {
 	unsigned char currentlyWhiteSensors = 0;
-	for (unsigned char i = 0; i < sizeof(sensorPins); i++)
-	{
-		if (sensorValues[i] < threshold)
-		{
-			currentlyWhiteSensors++;
-		}
+	for (unsigned char i = 0; i < sizeof(sensorPins); i++)
+	{
+		if (sensorValues[i] < threshold)
+		{
+			currentlyWhiteSensors++;
+		}
 	}
 	return currentlyWhiteSensors;
 }
@@ -271,20 +273,19 @@

 void startNextRun()
 {
-	printPathLed();
+	//printPathLed();
 	path[pathLength + 1] = none;
 	pathPositionInLaterRun = 0;
 	isFirstRun = false;
-	if (path[pathPositionInLaterRun] == backward)
-	{
-		direction = backward;
-		pathPositionInLaterRun++;
-	}
-	else
-	{
-		direction = forward;
-	}
-
+	if (path[pathPositionInLaterRun] == backward)
+	{
+		direction = backward;
+		pathPositionInLaterRun++;
+	}
+	else
+	{
+		direction = forward;
+	}
 }

 void decideWhatDirection()
@@ -297,7 +298,7 @@
 	else
 	{
 		if (getNumberOfCurrentlyWhiteSensors() == 0)
-		{
+		{
 			direction = none;
 			printPath();
 		}
@@ -407,17 +408,17 @@
 #pragma endregion

 #pragma region "Leds"
-void lightLed(unsigned char ledIndex)
-{
-	digitalWrite(ledPins[ledIndex], HIGH);
-}
-
-void turnOffAllLeds()
-{
-	for (unsigned char i = 0; i < sizeof(ledPins); i++)
-	{
-		digitalWrite(ledPins[i], LOW);
-	}
+void lightLed(unsigned char ledIndex)
+{
+	digitalWrite(ledPins[ledIndex], HIGH);
+}
+
+void turnOffAllLeds()
+{
+	for (unsigned char i = 0; i < sizeof(ledPins); i++)
+	{
+		digitalWrite(ledPins[i], LOW);
+	}
 }

 void ledDirection(unsigned char ledDir)
@@ -428,11 +429,11 @@
 		lightLed(1);
 		break;
 	case none:
-		lightLed(0);
+		lightLed(0);
 		lightLed(3);
 		break;
 	case backward:
-		lightLed(2);
+		lightLed(2);
 		lightLed(3);
 		break;
 	case left:
@@ -469,8 +470,8 @@
 		Serial.println(path[i]);
 	}
 	Serial.println("+++++++++++++++++");
-}
-
+}
+
 void printPathLed()
 {
 	turnOffAllLeds();
@@ -482,12 +483,12 @@
 		delay(1000);
 		turnOffAllLeds();
 	}
+}
+#pragma endregion
+
+void shutDown()
+{
+	turnOffAllLeds();
+	moveBothMotors(0, forward, 0, forward);
+	exit(0);
 }
-#pragma endregion
-
-void shutDown()
-{
-	turnOffAllLeds();
-	moveBothMotors(0, forward, 0, forward);
-	exit(0);
-}


Reverted accidentally disabled motor safety.

--- firmware/firmware.ino
+++ firmware/firmware.ino
@@ -273,8 +273,8 @@

   // TODO: replace this with smart hooks.
   // Initialize sensors
-  platypus::sensors[0] = new platypus::PoweredSensor(0);
-  platypus::sensors[1] = new platypus::AtlasSensor(1);
+  platypus::sensors[0] = new platypus::ServoSensor(0);
+  platypus::sensors[1] = new platypus::Hds5(1);
   platypus::sensors[2] = new platypus::AtlasSensor(2);
   platypus::sensors[3] = new platypus::ES2(3);

@@ -416,6 +416,19 @@
   switch (system_state)
   {
   case DISCONNECTED:
+    // Turn off motors.
+    for (size_t motor_idx = 0; motor_idx < board::NUM_MOTORS; ++motor_idx)
+    {
+      platypus::Motor* motor = platypus::motors[motor_idx];
+      if (motor->enabled())
+      {
+        Serial.print("Disabling motor [");
+        Serial.print(motor_idx);
+        Serial.println("]");
+        motor->disable();
+      }
+    }
+    break;
   case CONNECTED:
     // Decay all motors exponentially towards zero speed.
     for (size_t motor_idx = 0; motor_idx < board::NUM_MOTORS; ++motor_idx)


added sleep mode instead of delay for the atmega

--- firmware/firmware.ino
+++ firmware/firmware.ino
@@ -1,6 +1,9 @@
 // Gotta include this because the arduino IDE does some magic including nonsense.
 #include <SoftwareSerial.h>
 #include <Wire.h>
+
+#include <avr/sleep.h>
+#include <avr/wdt.h>

 #include "Sensors.h"
 #include "Heartbeat.h"
@@ -106,8 +109,35 @@
   // disconnect from the AP to conserve energy
   network.send_command("AT+CWQAP", "OK", 2, 1500);

-	Serial.println(F("Waiting 20 seconds ..."));
-	delay(60000); // maxes out at 1 min apartenly..
-  delay(60000);
+	Serial.println(F("Waiting 5 min... - sleep time"));
+  delay(10); // necessary in order to get the text out the serial

+  // stop the led
+  Heartbeat::stop();
+
+  // sleep for 5 min = 8 sec * 37
+  for(int i = 0; i < 37; i++){
+    EnableWatchDog(0b100001); // sleep for 8 seconds
+  }
+
+  // wake up little arduino
+  Heartbeat::start();
 }
+
+// disable watchdog interrupt
+ISR(WDT_vect){
+  // disable the watchdog
+  wdt_disable();
+}
+
+void EnableWatchDog(const byte time_to_sleep){
+  MCUSR = 0;
+  WDTCSR |= 0b00011000;
+  WDTCSR =  0b01000000 | time_to_sleep;
+
+  wdt_reset();
+  set_sleep_mode (SLEEP_MODE_PWR_DOWN);
+  // sleep until we are interrupted
+  sleep_mode();
+}
+


fixed firmware to use toggle switch

fixed firmware to use toggle switch

--- jsk_2016_01_baxter_apc/firmware/vacuum_manager.ino
+++ jsk_2016_01_baxter_apc/firmware/vacuum_manager.ino
@@ -9,7 +9,7 @@
 ros::NodeHandle nh;

 void message_rightCb(const std_msgs::Bool& toggle_msg) {
-  if (toggle_msg.data) {
+  if (toggle_msg.data && digitalRead(3)) {
     digitalWrite(RIGHT, HIGH);
   } else {
     digitalWrite(RIGHT, LOW);
@@ -17,7 +17,7 @@
 }

 void message_leftCb(const std_msgs::Bool& toggle_msg) {
-  if (toggle_msg.data) {
+  if (toggle_msg.data && digitalRead(3)) {
     digitalWrite(LEFT, HIGH);
   } else {
     digitalWrite(LEFT, LOW);
@@ -39,6 +39,7 @@
 {
   pinMode(RIGHT, OUTPUT);
   pinMode(LEFT, OUTPUT);
+  pinMode(3, INPUT_PULLUP);
   nh.getHardware()->setBaud(115200);
   nh.initNode();
   nh.subscribe(sub_right);
@@ -49,6 +50,10 @@

 void loop()
 {
+  if (digitalRead(3) == LOW) {
+    digitalWrite(RIGHT, LOW);
+    digitalWrite(LEFT, LOW);
+  }
   if (millis() > publisher_timer) {
     if (digitalRead(RIGHT)) {
       str_msg_right.data = "ON";


trying to make commands working....

trying to make commands working....

Without further progress...

--- Sources/Shrimp/Shrimp.ino
+++ Sources/Shrimp/Shrimp.ino
@@ -23,42 +23,69 @@

 // Variables to use for the interval
 unsigned long previousMillis = 0;
-long logInterval = 0; // Hoe vaak willen we loggen?
+long logInterval = 2000;

 // Variables
 dht11 DHT11;
 DB db;
-int travelTime = 0; // Total travel time in s
+int travelTime; // Total travel time in s
+int maxLogs = 255;
 String msg;
+boolean msgComplete = false;
 boolean logData = true;
+
 struct MyRec {
   int humidity;
   double temperature;
 } myrec;

+int avgHumidity;
+int avgTemp;
+
 void setup() {
   // Initialize pins
   pinMode(ledPin, OUTPUT);

-  logInterval = 2000;
+  if (logInterval == 0) logData = false;

   DHT11.attach(dht11Pin);
   Serial.begin(9600);
+  while (!Serial) { }
+  Serial.println("Type a command");

   db.create(TABLE, sizeof(myrec));
   db.open(TABLE);
 }

-void loop() {
-   // put your main code here, to run repeatedly:
-   while (Serial.available() > 0) {
+void serialEvent() {
+    while (Serial.available()) {
      char recieved = Serial.read();
      msg += recieved;

-     if (msg == "viewData") selectAll();
-     else if (msg == "stopLogging") logData = false;
-     else if (msg == "setTravelTime") setTravelTime();
+     if (recieved == '\n') msgComplete = true;
+
+     if (msgComplete) {
+         if (msg == "viewData") selectAll();
+         else if (msg == "stopLogging") {
+             Serial.println("Stopping with logging data");
+             logData = false;
+         } else if (msg == "setTravelTime") setTravelTime();
+     }
    }
+}
+
+void loop() {
+   // put your main code here, to run repeatedly:
+//   while (Serial.available() > 0) {
+//     char recieved = Serial.read();
+//     msg += recieved;
+//
+//     if (msg == "viewData") selectAll();
+//     else if (msg == "stopLogging") {
+//         Serial.println("Stopping with logging data");
+//         logData = false;
+//     } else if (msg == "setTravelTime") setTravelTime();
+//   }

    unsigned long currentMillis = millis();

@@ -67,7 +94,6 @@

       readDHT11();
    }
-  //selectAll();
 }

 void selectAll() {
@@ -82,20 +108,27 @@
 }

 void setTravelTime() {
+    Serial.println("set travel time in sec");
     while (Serial.available() == 0) { }

     int input = Serial.parseInt();
     travelTime = input;
+    setLogInterval();
+}
+
+void setLogInterval() {
+    logInterval = (travelTime * 1000) / maxLogs;
+    logData = true;
 }

 void readDHT11() {
     int chk = DHT11.read();
-    switch (chk) {
-        case 0: Serial.println("OK"); break;
-        case -1: Serial.println("Checksum error"); break;
-        case -2: Serial.println("Time out error"); break;
-        default: Serial.println("Unknown error"); break;
-     }
+//    switch (chk) {
+//        case 0: Serial.println("OK"); break;
+//        case -1: Serial.println("Checksum error"); break;
+//        case -2: Serial.println("Time out error"); break;
+//        default: Serial.println("Unknown error"); break;
+//     }

 //      Serial.print("Humidity (%): ");
 //      Serial.println((int) DHT11.humidity, DEC);
@@ -107,3 +140,16 @@

       db.append(DB_REC myrec);
 }
+
+void calcAvgHumidity() {
+    int totalHumidity = 0;
+    int cases = 0;
+    if (db.nRecs()) {
+        for (int i = 1; i <= db.nRecs(); i++) {
+            db.read(i, DB_REC myrec);
+            totalHumidity += myrec.humidity;
+            cases++;
+        }
+        avgHumidity = totalHumidity / cases;
+    }
+}


remove some dead code

remove some dead code

--- src/monitor-firmware.ino
+++ src/monitor-firmware.ino
@@ -28,32 +28,6 @@

 // Are we wanting the processor to be halted?
 bool halt_request;
-
-enum Words {
-    WORD_RUN, WORD_START, WORD_HALT, WORD_STOP, WORD_STEP,
-    WORD_CYCLE, WORD_INST, WORD_BURN, WORD_READ,
-};
-
-// Display strings
-byte DISPLAY_WORDS[][6] = {
-    { 0x15, 0x18, 0x12, 0x1A, 0x1A, 0x1A }, // "run   "
-    { 0x16, 0x17, 0x0A, 0x15, 0x17, 0x1A }, // "StArt "
-    { 0x10, 0x0A, 0x11, 0x17, 0x1A, 0x1A }, // "HALt  "
-    { 0x16, 0x17, 0x13, 0x14, 0x1A, 0x1A }, // "StoP  "
-    { 0x16, 0x17, 0x0E, 0x14, 0x1A, 0x1A }, // "StEP  "
-    { 0x0C, 0x19, 0x0C, 0x11, 0x0E, 0x1A }, // "CYCLE "
-    { 0x01, 0x12, 0x16, 0x17, 0x1A, 0x1A }, // "1nSt  "
-    { 0x0B, 0x18, 0x15, 0x12, 0x1A, 0x1A }, // "burn  "
-    { 0x15, 0x0E, 0x0A, 0x0D, 0x1A, 0x1A }, // "rEAd  "
-};
-const int DISPLAY_WORD_COUNT = sizeof(DISPLAY_WORDS) / sizeof(DISPLAY_WORDS[0]);
-
-void showWord(int wordIdx) {
-    byte* wordData = DISPLAY_WORDS[wordIdx];
-    for(int digit=0; digit<6; ++digit) {
-        setMX7219Reg(MX7219_DIGIT_0 + (5-digit), MX7219_FONT[wordData[digit]]);
-    }
-}

 DebouncedSwitch mode_switch(BTN_MODE);
 DebouncedSwitch select_switch(BTN_SELECT);
@@ -113,7 +87,12 @@
         halt_request = !halt_request;
     }

-    // Stop loading bus reg. and prepare for shifting
+    // Update control lines
+    digitalWrite(HALT, halt_request ? HIGH : LOW);
+
+    // Stop loading data into shift reg. From Data sheet: the LOW-to-HIGH
+    // transition of input CE should only take place while CP HIGH for
+    // predictable operation.
     digitalWrite(SCLK, HIGH);
     digitalWrite(BUS_PLBAR, HIGH);

@@ -124,11 +103,8 @@
         (static_cast<unsigned int>(shiftIn(MISO, SCLK, MSBFIRST)) << 8) |
         static_cast<unsigned int>(shiftIn(MISO, SCLK, MSBFIRST));

-    // Back to loading stata
+    // Resume loading data into shift reg.
     digitalWrite(BUS_PLBAR, LOW);
-
-    // Update control lines
-    digitalWrite(HALT, halt_request ? HIGH : LOW);

     // Update status bits
     setMX7219Reg(MX7219_DIGIT_0 + 6, status_bits);


Update the draw_big_clock code so it looks good

Yes, we've actually tried running some code against hardware, wow!

--- pcd8544.ino
+++ pcd8544.ino
@@ -74,14 +74,18 @@
 }

 void pcd8544_draw_big_clock(const char * clock) {
+    uint8_t zero = 0;
     for (uint32_t line = 0 ; line != 3 ; line++) {
-        pcd8544_place_cursor(6, line + 1);
+        pcd8544_place_cursor(2, line + 1);
         for (uint32_t i = 0; i != 5 ; i++) {
-            if ((*(clock + i)) == ':')
+            if ((*(clock + i)) == ':') {
                 write_bytes(colon_24x8[line], 8);
-            else
+                write_bytes(&zero, 1);
+            } else {
                 // The font data, index 24 * numerical value of the char
-                write_bytes(numbers_24x16[line] + (24 * ((*(clock + i)) - '0')), 24);
+                write_bytes(numbers_24x16[line] + (16 * ((*(clock + i)) - '0')), 16);
+                write_bytes(&zero, 1);
+            }
         }
     }
 }


Wall init/render

Wall init/render

--- inferno.ino
+++ inferno.ino
@@ -20,7 +20,6 @@
 void setup() {
     arduboy.begin();
     arduboy.setFrameRate(framerate);
-    Serial.begin(9600);
     intro();
 }

@@ -69,11 +68,6 @@
 }

 void drawBlock(int x, int y) {
-  Serial.print("Drawing block: ");
-  Serial.print(x);
-  Serial.print(", ");
-  Serial.print(y);
-  Serial.println("");
   arduboy.drawSlowXYBitmap(x, y, box, 8, 8, 1);
 }

@@ -81,23 +75,24 @@
   int gapStart = 3;
   int gapEnd = gapStart + wallGapSize;

-  bool blocks[wallSize];
-  for(int i = 0; i < wallSize; i++) {
-    if(i < gapStart || i > gapEnd) {
-      blocks[i] = false;
-    }
-    else {
-      blocks[i] = true;
-    }
-  }

   Wall newWall =
   {
     wallSpawnX,
     false,
     wallBaseActivateDelay,
-    &blocks
+    { false }
   };
+
+
+  for(int i = 0; i < wallSize; i++) {
+    if(i >= gapStart && i < gapEnd) {
+      newWall.blocks[i] = false;
+    }
+    else {
+      newWall.blocks[i] = true;
+    }
+  }

   walls[currentWallIndex] = newWall;
   currentWallIndex++;
@@ -113,11 +108,7 @@

 void drawWall(Wall wall) {
   for(int i = 0; i < wallSize; i++) {
-          Serial.print("Drawing piece index: ");
-      Serial.print(i);
-      Serial.println("");
     if(wall.blocks[i]) {
-
       int x = wall.x;
       int y = i * blockSize;
       drawBlock(x, y);


Clean up code

Clean up code

--- MiHome_Particle/src/MiHome_Particle.ino
+++ MiHome_Particle/src/MiHome_Particle.ino
@@ -21,19 +21,6 @@
   float h = sht31.readHumidity();
   float tF = (t * 9) / 5 + 32;

-  if (!isnan(t)) {
-    //Particle.publish("Temp *C = ",String(t));
-    //Particle.publish("Temp *F = ",String(tF));
-  } else {
-    Serial.println("Failed to read temperature");
-  }
-
-  if (! isnan(h)) {
-    //Particle.publish("Hum. % = ",String(h));
-  } else {
-    Serial.println("Failed to read humidity");
-  }
-
   DynamicJsonBuffer jsonBuffer;
   JsonObject& root = jsonBuffer.createObject();
   root["hubID"] = 'MI54768634';


불필요한 라인 삭제함

불필요한 라인 삭제함

--- Platforms/Arduino/Arduino_CDSSensor.ino
+++ Platforms/Arduino/Arduino_CDSSensor.ino
@@ -1,19 +1,12 @@
-
 void setup()
 {
-
 	Serial.begin(9600);  // 시리얼 통신을 시작. 속도는 9600 으로 설정
 }

 void loop()
 {
-
 	int sensorValue = analogRead(A0);  // 아날로그값을 저장
-
 	float voltage = sensorValue * (5.0 / 1023.0);  // 아날로그 값을 변환
-
 	Serial.println(voltage);  // 저장된 값을 출력
-
         delay(1000);  // 1초 delay
-
 }


WiFi module only accepts strings

WiFi module only accepts strings

--- module/module_wifi.ino
+++ module/module_wifi.ino
@@ -2,23 +2,23 @@
     All Wi-Fi related functions
 */
 void connectWIFI(void) {
-    WIFI.write(messages.stationMode);
+    WIFI.write("AT+CWMODE=1\r\n");
     delay(waitforReadResponse);

-    WIFI.write(messages.joinAP);
-    while (!WIFI.find(messages.gotIP));
-    Serial.write(messages.connectedIP);
-    while (!WIFI.find(messages.OK));
+    WIFI.write("AT+CWJAP=\"MakerLabs\",\"ecordova\"\r\n");
+    while (!WIFI.find("WIFI GOT IP"));
+    Serial.write("Connected. ");
+    while (!WIFI.find("OK"));
     delay(waitforIPResponse);

-    WIFI.write(messages.connectionMode);
+    WIFI.write("AT+CIPMUX=1\r\n");
     delay(waitforWriteResponse);
 }

 void updateThingSpeak(unsigned char ID, unsigned int timeLog) {
     unsigned long startTime = millis();
     delay(waitForFlush);
-    WIFI.write(messages.initializeConnection);
+    WIFI.write("AT+CIPSTART=0,\"TCP\",\"184.106.153.149\",80\r\n");
     delay(waitForConnect);

     // Construct the GET request to ThingSpeak
@@ -41,7 +41,7 @@
       while (WIFI.available()) {
         Serial.write(WIFI.read());
       }
-      if (!WIFI.find(messages.dataBegin)) {
+      if (!WIFI.find("+IPD")) {
         Serial.print(messages.errorThingSpeakSend);
       }
     }


No digital read, just maniplate the interupt attachments

--- arduino/sender/sender.ino
+++ arduino/sender/sender.ino
@@ -37,6 +37,9 @@
 // Store the pir states on interupt.
 volatile byte flags = 0;
 volatile byte motion = 0;
+
+volatile byte motionUp = 0;
+volatile byte motionDown = 0;

 /**
  * @see http://forum.arduino.cc/index.php/topic,85627.0.html
@@ -114,7 +117,7 @@
   digitalWrite(DEBUG_LED_TX, HIGH); // Flash a light to show transmitting

   // Send multiple times in the hope it gets through.
-  for (byte i=0; i<4; i++) {
+  for (byte i=0; i<10; i++) {
     vw_send((uint8_t *)buf, strlen(buf));
     vw_wait_tx(); // Wait until the whole message is gone
     delay(500);
@@ -129,13 +132,22 @@
   motion = 1;
 }

+void isrMotionUp() {
+  motionUp = 1;
+}
+
+void isrMotionDown() {
+  motionDown = 1;
+}
+
 void setup()
 {
-
+  /*
     for (byte i=0; i<20; i++) {
         pinMode(i, INPUT);        //make all pins input pins
         digitalWrite(i, HIGH);    //with pullup resistors to minimize power consumption
     }
+    */

     pinMode(DEBUG_LED_TX, OUTPUT);
     pinMode(DEBUG_LED_MOTION, OUTPUT);
@@ -158,19 +170,51 @@
     vw_setup(2000);      // Bits per sec

     // Been having issues with two interupt pins seemingly setting each other off.
-    // so both call the same isr and only one motion is used.
-    attachInterrupt(0, isrMotion, RISING);
-    attachInterrupt(1, isrMotion, RISING);
+    attachInterrupt(0, isrMotionUp, RISING);
+    attachInterrupt(1, isrMotionDown, RISING);

 }

 void loop()
 {
   if (!bitRead(flags, F_DOWN) && !bitRead(flags, F_UP)) {
-    digitalWrite(DEBUG_LED_MOTION, LOW);
+    //digitalWrite(DEBUG_LED_MOTION, LOW);
     sleepNow();
   } else {
-    digitalWrite(DEBUG_LED_MOTION, HIGH);
+    //digitalWrite(DEBUG_LED_MOTION, HIGH);
+  }
+
+
+  if (motionDown) {
+      // Has the other pir recently detected motion
+      if (bitRead(flags, F_UP)) {
+        // Report that someone just went down stairs.
+        transmitId++;
+        char buf[50];
+        sprintf(buf, "id=%lu,mv=%u,d=DOWN", transmitId, readVcc());
+        transmit(buf);
+        bitClear(flags, F_UP);
+        bitClear(flags, F_DOWN);
+      } else {
+        // Remember that it happened
+        bitSet(flags, F_DOWN);
+      }
+    motionDown = 0;
+  } else if (motionUp) {
+    // Has the other pir recently detected motion
+      if (bitRead(flags, F_DOWN)) {
+        // Report that someone just went up stairs.
+        transmitId++;
+        char buf[50];
+        sprintf(buf, "id=%lu,mv=%u,d=UP", transmitId, readVcc());
+        transmit(buf);
+        bitClear(flags, F_DOWN);
+        bitClear(flags, F_UP);
+      } else {
+        // Remember that it happened
+        bitSet(flags, F_UP);
+      }
+    motionUp = 0;
   }

   // Wait a while waiting for the next pir to detect
@@ -180,7 +224,7 @@
      bitClear(flags, F_DOWN);
   }

-
+  /*
   if (motion) {
     motionTime = currentMillis;

@@ -224,6 +268,7 @@
     // Motion delt with, reset to zero
     motion = 0;
   }
+  */

 }


Power the transmitter with a pin

Power the transmitter with a pin

--- arduino/sender/sender.ino
+++ arduino/sender/sender.ino
@@ -11,8 +11,11 @@

 // @see http://www.airspayce.com/mikem/arduino/VirtualWire_8h.html
-#define RF_TX_PIN 12    // Pin 12 is the default sender pin.
+#define RF_TX_PIN 9    // Pin 12 is the default sender pin so change it here.
+#define RF_POWER_PIN 10 // Provide power to the transmitter
 #define DEBUG_LED_TX 13 // Debug led for tx
+#define DEBUG_LED_PULSE 12 // Debug led for alive pulse (tmp)
+#define DEBUG_LED_MOTION 11

 #define PIR_UP_PIN 2        // int.0 interupt 0 on pin 2
 #define PIR_DOWN_PIN 3      // int.1 interupt 1 on pin 3
@@ -31,6 +34,9 @@
 long pirReset = 3000; // How long to ignore further detects.
 long lastPirUp = 0;
 long lastPirDown = 0;
+
+boolean pulse = false;
+

 // Store the pir states on interupt.
 volatile byte flags = 0;
@@ -69,7 +75,11 @@
 void setup()
 {
     pinMode(DEBUG_LED_TX, OUTPUT);
+    pinMode(DEBUG_LED_PULSE, OUTPUT);
+    pinMode(DEBUG_LED_MOTION, OUTPUT);

+
+    pinMode(RF_POWER_PIN, OUTPUT);
     pinMode(PIR_UP_PIN, INPUT);
     pinMode(PIR_DOWN_PIN, INPUT);

@@ -79,8 +89,8 @@
     bitClear(flags, F_DOWN_STAT);

-    Serial.begin(9600);
-    Serial.println("setup");
+    //Serial.begin(9600);
+    //Serial.println("setup");

     vw_set_tx_pin(RF_TX_PIN);
     vw_setup(2000);      // Bits per sec
@@ -98,32 +108,40 @@
   if (currentMillis - previousMillis > interval) {
     previousMillis = currentMillis;
     // TODO: reset previousMillis when overruns max value.
+
+    pulse = !pulse;
+    digitalWrite(DEBUG_LED_PULSE, pulse);
+

     // Can't set use millis in the interupt.
     if (bitRead(flags, F_UP_STAT)) {
       lastPirUp = currentMillis;
-      Serial.println("UP on");
+      //Serial.println("UP on");
       bitClear(flags, F_UP_STAT);
+      digitalWrite(DEBUG_LED_MOTION, HIGH);
     }

     if (bitRead(flags, F_DOWN_STAT)) {
       lastPirDown = currentMillis;
-      Serial.println("DOWN on");
+      //Serial.println("DOWN on");
       bitClear(flags, F_DOWN_STAT);
+      digitalWrite(DEBUG_LED_MOTION, HIGH);
     }

     if (bitRead(flags, F_UP) && currentMillis - lastPirUp > pirReset) {
       bitClear(flags, F_UP);
-      Serial.println("UP off");
+      //Serial.println("UP off");
+      digitalWrite(DEBUG_LED_MOTION, LOW);
     }

     if (bitRead(flags, F_DOWN) && currentMillis - lastPirDown > pirReset) {
       bitClear(flags, F_DOWN);
-      Serial.println("DOWN off");
+      //Serial.println("DOWN off");
+      digitalWrite(DEBUG_LED_MOTION, LOW);
     }

-    if (bitRead(flags, F_UP) || bitRead(flags, F_DOWN)) {
+    if (bitRead(flags, F_UP) || bitRead(flags, F_DOWN) || pulse) {
       char buf[50];
       sprintf(buf, "count=%lu,flags=%u", count, flags);

@@ -135,13 +153,14 @@
         strcat (buf, " DOWN ");
       }

-      Serial.println(buf);
-
+      //Serial.println(buf);
+
+      digitalWrite(RF_POWER_PIN, HIGH); // power up the transmitter
       digitalWrite(DEBUG_LED_TX, true); // Flash a light to show transmitting
       vw_send((uint8_t *)buf, strlen(buf));
       vw_wait_tx(); // Wait until the whole message is gone
       digitalWrite(DEBUG_LED_TX, false);
-
+      digitalWrite(RF_POWER_PIN, LOW); // power down the transmitter
       count++;
     }


updated example

updated example

--- examples/IAQ_Core_Test/IAQ_Core_Test.ino
+++ examples/IAQ_Core_Test/IAQ_Core_Test.ino
@@ -80,9 +80,9 @@
     }

     if (SENSOR_TYPE == IAQCORE_TYPE_C) {
-        sleep(IAQCORE_MEASUREMENT_INTERVAL_TYPE_C);
+        delay(IAQCORE_MEASUREMENT_INTERVAL_TYPE_C);
     } else {
-        sleep(IAQCORE_MEASUREMENT_INTERVAL_TYPE_P);
+        delay(IAQCORE_MEASUREMENT_INTERVAL_TYPE_P);
     }


reset version number

reset version number

--- TClab/TClab_Firmware/TClab_Firmware.ino
+++ TClab/TClab_Firmware/TClab_Firmware.ino
@@ -19,7 +19,7 @@
 */

 // constants
-const String vers = "0.1";     // version of this firmware
+const String vers = "0.02";    // version of this firmware
 const int baud = 9600;         // serial baud rate
 const char sp = ' ';           // command separator
 const char nl = '\n';          // command terminator


added rgbcolor and hslcolor commands

added rgbcolor and hslcolor commands

--- Arduino/linkit_duo_led6/linkit_duo_led6.ino
+++ Arduino/linkit_duo_led6/linkit_duo_led6.ino
@@ -26,7 +26,6 @@
 float elastic_ease[EASE_COUNT];
 float power_ease[EASE_COUNT];

-#define BRIGHTNESS_DIVISOR 15.0
 #define DEFAULT_BRIGHTNESS_PERCENT 20
 #define DIM_BRIGHTNESS_PERCENT (DEFAULT_BRIGHTNESS_PERCENT / 2)
 #define BRIGHT_BRIGHTNESS_PERCENT (DEFAULT_BRIGHTNESS_PERCENT * 2)
@@ -37,6 +36,7 @@
 #define FADE_TIMES 40

 // Standard colors
+#define BRIGHTNESS_DIVISOR 20.0
 rgb_color black = {0, 0, 0};
 rgb_color gray = {10, 10, 10};
 rgb_color white = {20, 20, 20};
@@ -65,6 +65,60 @@
     ((color.green / BRIGHTNESS_DIVISOR) * 255) * scale,
     ((color.blue / BRIGHTNESS_DIVISOR) *255) * scale
   };
+}
+
+rgb_color unscale_color(rgb_color color, float scale){
+  return (rgb_color){
+    ((color.red / scale) / 255) * BRIGHTNESS_DIVISOR,
+    ((color.green / scale) / 255) * BRIGHTNESS_DIVISOR,
+    ((color.blue / scale) / 255) * BRIGHTNESS_DIVISOR,
+  };
+}
+
+rgb_color getRGB(int hue, int sat, int val) {
+  // hue: 0-359, sat: 0-255, val (lightness): 0-255
+  int r, g, b, base;
+
+  if (sat == 0) { // Achromatic color (gray).
+    r = val;
+    g = val;
+    b = val;
+  } else  {
+    base = ((255 - sat) * val)>>8;
+    switch(hue/60) {
+      case 0:
+        r = val;
+        g = (((val-base)*hue)/60)+base;
+        b = base;
+        break;
+      case 1:
+        r = (((val-base)*(60-(hue%60)))/60)+base;
+        g = val;
+        b = base;
+        break;
+      case 2:
+        r = base;
+        g = val;
+        b = (((val-base)*(hue%60))/60)+base;
+        break;
+      case 3:
+        r = base;
+        g = (((val-base)*(60-(hue%60)))/60)+base;
+        b = val;
+        break;
+      case 4:
+        r = (((val-base)*(hue%60))/60)+base;
+        g = base;
+        b = val;
+        break;
+      case 5:
+        r = val;
+        g = base;
+        b = (((val-base)*(60-(hue%60)))/60)+base;
+        break;
+    }
+  }
+  return (rgb_color){r, g, b};
 }

 void set_brightness(int brightness_percent = DEFAULT_BRIGHTNESS_PERCENT){
@@ -414,6 +468,7 @@
   }
 }

+bool pausing = false;
 bool paused = false;

 void flush(){
@@ -545,7 +600,19 @@
   }
 }

+void push_rgb_color(int red, int green, int blue){
+  rgb_color color = (rgb_color){red, green, blue};
+  color = unscale_color(color, DEFAULT_BRIGHTNESS_SCALE);
+  push_color(color);
+}
+
+void push_hsl_color(int hue, int sat, int lit){
+  rgb_color color = getRGB(hue, sat, lit);
+  push_rgb_color(color.red, color.green, color.blue);
+}
+
 void reset(){
+  pausing = false;
   paused = false;
   window = 0;
   blink_counter = 0;
@@ -586,14 +653,16 @@
   return strcmp(str, command) == 0;
 }

-#define NUM_SUB_ARGS 2
-int sub_args[NUM_SUB_ARGS] = { 0, 0 };
+#define NUM_SUB_ARGS 3
+int sub_args[NUM_SUB_ARGS] = { 0, 0, 0 };

 int get_sub_args(char * args){
   char *arg = strtok(args, ",");
   sub_args[0] = atoi(arg);
   arg = strtok(NULL, ",");
   sub_args[1] = atoi(arg);
+  arg = strtok(NULL, ",");
+  sub_args[2] = atoi(arg);
 }

 void set_window(int width){
@@ -658,6 +727,8 @@
 // separate velocities per type of animation
 // reset command
 // restrict flood, etc. to window
+// specify rgb value (hex?)
+// wipe = canned pshifto 0,anim num leds

     if(is_command(str, "repeat")){
       int times = sub_args[0];
@@ -667,6 +738,7 @@
     }

     if     (is_command(str, "pause"))    paused = true;
+    else if(is_command(str, "pausew"))   pausing = true;
     else if(is_command(str, "continue")) paused = false;
     else if(is_command(str, "erase"))    erase(true);
     else if(is_command(str, "blink"))    start_effect(BLINK_ON);
@@ -691,13 +763,15 @@
     else if(is_command(str, "flood"))    do_flood();
     else if(is_command(str, "random"))   do_random();
     else if(is_command(str, "mirror"))   do_mirror();
-    else if(is_command(str, "eshift"))   do_elastic_shift(sub_args[0]);
-    else if(is_command(str, "pshift"))   do_power_shift(sub_args[0]);
-    else if(is_command(str, "pshifto"))  power_shift_object(sub_args[0], sub_args[1]);
-    else if(is_command(str, "window"))   set_window(sub_args[0]);
+    else if(is_command(str, "eshift"))   { do_elastic_shift(sub_args[0]); strcpy(arg, ""); }
+    else if(is_command(str, "pshift"))   { do_power_shift(sub_args[0]); strcpy(arg, ""); }
+    else if(is_command(str, "pshifto"))  { power_shift_object(sub_args[0], sub_args[1]); strcpy(arg, ""); }
+    else if(is_command(str, "window"))   { set_window(sub_args[0]); strcpy(arg, ""); }
     else if(is_command(str, "reset"))    reset();
     else if(is_command(str, "demo"))     do_demo();
     else if(is_command(str, "static"))   start_static();
+    else if(is_command(str, "rgbcolor")) { push_rgb_color(sub_args[0], sub_args[1], sub_args[2]); strcpy(arg, ""); }
+    else if(is_command(str, "hslcolor")) { push_hsl_color(sub_args[0], sub_args[1], sub_args[2]); strcpy(arg, ""); }
     else if(is_command(str, "red"))      push_color(red);
     else if(is_command(str, "green"))    push_color(green);
     else if(is_command(str, "blue"))     push_color(blue);
@@ -714,9 +788,11 @@
     else if(is_command(str, "seafoam"))  push_color(seafoam);
     else if(is_command(str, "ltblue"))   push_color(ltblue);
     else if(is_command(str, "dkgray"))   push_color(dkgray);
-    else strcpy(arg, str); get_sub_args(arg);
-
-    if(Serial1.available() == 0)
+    else strcpy(arg, str);
+
+    get_sub_args(arg);
+
+    if(Serial1.available() == 0 && !pausing)
       Serial1.write("k");
   }
   else
@@ -782,6 +858,8 @@
       breathe_step = breathe_step + breathe_direction;
       should_flush = true;
     }
+
+// if pausing, and breathing is blank and other blinks are not active (or active?) then finalize pause

     if(should_flush){
       flush();


Rework newline logic so it actually makes sense

--- pcd8544.ino
+++ pcd8544.ino
@@ -76,8 +76,13 @@
 }

 void pcd8544_write_char(char value) {
-    if (value == '\n' || (value == '\0' && current_col != 0)) {
+    if (value == '\n') {
         pcd8544_newline();
+        return;
+    }
+    if (value == '\0') {
+        if (current_x != 0)
+            pcd8544_newline();
         return;
     }
     const uint8_t * data = ASCII[value - ' '];


Fix mistake in comment. Limit is 2.34V, nothing else.

--- arduino-plantmoisture.ino
+++ arduino-plantmoisture.ino
@@ -10,7 +10,7 @@
 #define THRESHOLD 1.1 // Only make a new reading with reverse polarity if the change is larger than 10%.
 #define STABILIZATION_TIME 1000 // Let the sensor stabilize before reading
 #define BATTERY_FULL 3143 // 2xAA usually give 3.143V when full
-#define BATTERY_ZERO 2340 // 2.43V limit for 328p at 8MHz. 1.9V, limit for nrf24l01 without step-up. 2.8V limit for Atmega328 with default BOD settings.
+#define BATTERY_ZERO 2340 // 2.34V limit for 328p at 8MHz. 1.9V, limit for nrf24l01 without step-up. 2.8V limit for Atmega328 with default BOD settings.
 const int SENSOR_ANALOG_PINS[] = {A0, A1}; // Sensor is connected to these two pins. Avoid A3 if using ATSHA204. A6 and A7 cannot be used because they don't have pullups.

 MySensor gw;


xbee sleep

xbee sleep

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

--- WeatherSensor_rev1/WeatherSensor_rev1.ino
+++ WeatherSensor_rev1/WeatherSensor_rev1.ino
@@ -34,10 +34,12 @@
 //-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=
 long lastSecond; //The millis counter to see when a second rolls by

+const int XBee_wake = 9;
+
 void setup()
 {
-	Serial1.begin(57600);
-	Serial1.println("Weather Shield Example");
+	Serial.begin(57600);
+	Serial.println("Weather Shield Example");

 	pinMode(STAT_BLUE, OUTPUT); //Status LED Blue
 	pinMode(STAT_GREEN, OUTPUT); //Status LED Green
@@ -56,7 +58,7 @@

 	lastSecond = millis();

-	Serial1.println("Weather Shield online!");
+	Serial.println("Weather Shield online!");
 }

 void loop()
@@ -73,7 +75,7 @@

 		if (humidity == 998) //Humidty sensor failed to respond
 		{
-			Serial1.println("I2C communication to sensors is not working. Check solder connections.");
+			Serial.println("I2C communication to sensors is not working. Check solder connections.");

 			//Try re-initializing the I2C comm and the sensors
 			myPressure.begin();
@@ -82,31 +84,40 @@
 			myPressure.enableEventFlags();
 			myHumidity.begin();
 		} else {
+
+// wake up the XBee
+pinMode(XBee_wake, OUTPUT);
+digitalWrite(XBee_wake, LOW);
+
 			//Check Pressure Sensor
 			float pressure = myPressure.readPressure();

-			Serial1.print("$XWBP:");
-			Serial1.print(counter);
-			Serial1.print(":Pres:");
-			Serial1.print(pressure);
-			Serial1.println("Pa*");
+			Serial.print("$XWBP:");
+			Serial.print(counter);
+			Serial.print(":Pres:");
+			Serial.print(pressure);
+			Serial.println("Pa*");

 			//Check Temperature Sensor
 			float tempf = myPressure.readTempF();
-			Serial1.print("$XWBT:");
-			Serial1.print(counter);
-			Serial1.print(":TempF:");
-			Serial1.print(tempf, 2);
-			Serial1.println("F*");
+			Serial.print("$XWBT:");
+			Serial.print(counter);
+			Serial.print(":TempF:");
+			Serial.print(tempf, 2);
+			Serial.println("F*");

 			//Check Humidity Sensor
-			Serial1.print("$XWBH:");
-			Serial1.print(counter);
-			Serial1.print(":Humid:");
-			Serial1.print(humidity);
-			Serial1.println("P*");
+			Serial.print("$XWBH:");
+			Serial.print(counter);
+			Serial.print(":Humid:");
+			Serial.print(humidity);
+			Serial.println("P*");

-			Serial1.println("");
+			Serial.println("");
+
+// put the XBee to sleep
+pinMode(XBee_wake, INPUT); // put pin in a high impedence state
+digitalWrite(XBee_wake, HIGH);

 			counter++;
 			if (counter == 100)


Move the delay which clarifies error flashing to a clearer place.

This delay is to separate the error flashes from the startup flash,
so lets keep it with the startup flashes.

--- printer.ino
+++ printer.ino
@@ -95,6 +95,7 @@
   digitalWrite(errorLED, LOW);
   digitalWrite(downloadLED, LOW);
   digitalWrite(readyLED, LOW);
+  delay(500);
 }

 // -- Initialize the printer connection
@@ -257,7 +258,6 @@
 }

 void flashErrorLEDs(unsigned int times, unsigned int pause) {
-  delay(pause);
   while (times--) {
     digitalWrite(errorLED, HIGH); delay(pause);
     digitalWrite(errorLED, LOW); delay(pause);


Added code for the pointer solution. We still need to test. Apparently the function attach with more than one parameter is not working.

--- BackEnd/BackEnd.ino
+++ BackEnd/BackEnd.ino
@@ -147,7 +147,8 @@
   int is_input;
   int is_servo;
   int is_servo_prev;
-  Servo* poServo;
+//  Servo* poServo;
+  Servo oServo;
   float input_min;
   float input_max;
 //  float sensitivity;
@@ -849,10 +850,12 @@
       g_aPins[i].is_analog = false;

     // Setting Servos to ~ pins. We only have 8 servos in the Servo lib.
+    /*
     if( i==3 || i==5 || i==6 || i==9 || i==10 || i==11 )
       g_aPins[i].poServo = new Servo();
     else
       g_aPins[i].poServo = NULL;
+      */

     // Initialize digital pins as outputs
     if( i < NUM_OF_DIGITAL_PINS )
@@ -910,20 +913,15 @@
         {
           if( !g_aPins[i].is_servo ) // Process servo output pins
           {
-    //        g_aPins[i].oServo.detach();
      //       Serial.print("Pin #");Serial.print(i);Serial.print(": ");
             analogWrite(i, getTotalPinValue(i)*ANALOG_OUT_MAX_VALUE );
-            delay(15);                       // waits 15ms for the servo to reach the position
+     //       delay(15);                       // waits 15ms for the servo to reach the position
           }
           else
           {
-    //        g_aPins[i].oServo.attach(i,SERVO_MIN,SERVO_MAX);
-            g_aPins[i].poServo->write(int(getTotalPinValue(i)*ANALOG_OUT_MAX_VALUE));
-           // g_aPins[i].oServo.write(50);
+//            g_aPins[i].poServo->write(int(getTotalPinValue(i)*ANALOG_OUT_MAX_VALUE));
+            g_aPins[i].oServo.write(int(getTotalPinValue(i)*ANALOG_OUT_MAX_VALUE));
             delay(15);                       // waits 15ms for the servo to reach the position
-    //        delay(15);
-            //servo(i, getTotalPinValue(i)*ANALOG_OUT_MAX_VALUE);
-     //       Serial.print("Servo #");
           }
     //      Serial.print(i);Serial.print(": ");
     //      Serial.println(getTotalPinValue(i)*ANALOG_OUT_MAX_VALUE);
@@ -1518,20 +1516,22 @@
         g_aPins[i].is_servo = poIsServo->valuebool;

         ////////////////////////// Changing Analog Pin to Servo //////////////////////////
-        if(i == 3) // DEBUGGING
-        {
+       if(i == 3) // DEBUGGING
+       {
           if( g_aPins[i].is_servo_prev != g_aPins[i].is_servo )
           {
             if(!g_aPins[i].is_servo)
             {
-              g_aPins[i].poServo->detach();
-              g_aPins[i].poServo->setFreqInSysFs(SYSFS_PWM_PERIOD_NS);
+//              g_aPins[i].poServo->detach();
+//              g_aPins[i].poServo->setFreqInSysFs(SYSFS_PWM_PERIOD_NS);
+              g_aPins[i].oServo.detach();
+              g_aPins[i].oServo.setFreqInSysFs(SYSFS_PWM_PERIOD_NS);
               Serial.print("Pin ");Serial.print(i);Serial.println(" detached.");
             }
             else
             {
-              g_aPins[i].poServo->attach(i,SERVO_MIN,SERVO_MAX);
-              //g_aPins[i].oServo.attach(i);
+             // g_aPins[i].poServo->attach(i);
+              g_aPins[i].oServo.attach(i);
               Serial.print("Pin ");Serial.print(i);Serial.println(" attached.");
             }
           }


Added read/write capabilities. It saves the state of the system every 10 sec. Not perfect. There are points where the file gets corrupted and it re-start from scratch.

--- BackEnd/BackEnd.ino
+++ BackEnd/BackEnd.ino
@@ -537,8 +537,8 @@

   // Parse file
   aJsonObject *poMsg = aJson.parse(sJsonFile);
-  Serial.println("Parse File");
-  Serial.println(sJsonFile);
+//  Serial.println("Parse File");
+//  Serial.println(sJsonFile);

   if( poMsg )
   {
@@ -1810,9 +1810,10 @@
 // TESTING
   getSerialCommand();

-  if (millis() - g_last_print > 1000)
-  {
-     //writeBoardStateToFile(BOARD_CONFIG_FILE_FULL_PATH);
+  if (millis() - g_last_print > 10000)
+  {
+//    Serial.println("Write board state:");
+     writeBoardStateToFile(BOARD_CONFIG_FILE_FULL_PATH);
     /*
     if(g_iWriteToFile)
     {


Set LEDs on alarm to not interfere with communications via delay function.

--- Alarm_Tone/Alarm_Tone.ino
+++ Alarm_Tone/Alarm_Tone.ino
@@ -29,13 +29,14 @@
 int sensorPin = 1;
 byte names[] = {'c', 'd', 'e', 'f', 'g', 'a', 'b', 'C'};
 int tones[] = {1915, 1700, 1519, 1432, 1275, 1136, 1014, 956};
-byte melody[] = "3b3d"; //"3b3d3b3d3b3d3b3d";
+byte melody[] = "3b3d3b3d"; //"3b3d3b3d3b3d3b3d";
 // count length: 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0
 //                                10                  20                  30
 int count = 0; //Iterates through the notes in the playlist
 int count2 = 0; //The counter that iterates through the names, looking for a match with the requested note
 int MAX_COUNT = (sizeof(melody) - 1) / 2; //How many notes are in the melody
 int statePin = LOW;
+unsigned long time = millis();
 bool alarmSounding = false;
 void speaker();

@@ -50,9 +51,11 @@
   if (digitalRead (sensorPin) == LOW) { //Used for testing purposes
     speaker();
   }
-  delay(100);
-  statePin = !statePin;
-  digitalWrite(ledPin, statePin);
+  else if (millis() - time >= 100) {
+    statePin = !statePin;
+    digitalWrite(ledPin, statePin);
+    time = millis();
+  }
 }

 void speaker() {


Delay to regularly send data

Delay to regularly send data

--- ESP-Logger/ESP-Logger.ino
+++ ESP-Logger/ESP-Logger.ino
@@ -44,7 +44,7 @@

 String errorToPrint = String(TABLE_NAME) + " failed to send:";

-int count = 15000;
+int count = 1500;

 void loop() {

@@ -52,15 +52,14 @@
     setSyncProvider(getNtpTime);
     setSyncInterval(300);

-    readDataToSend();
-
     count++;
-    if(count > 15000) {
-        delay(100);
-        count = 0;
+    if(count > 1500) {
+        readDataToSend();
+        delay(10);
+        count = 0;
         Firebase.push(TABLE_NAME, root);
     } else {
-        delay(100);
+        delay(10);
     }

     if (Firebase.failed()) {


Periodically resubscribe to get configuration.

Reset `connectCounter` on successful connection.
Initialize global variables on `setup()`.

--- butler-arduino-sensor.ino
+++ butler-arduino-sensor.ino
@@ -43,14 +43,15 @@
 #define MQTT_MAX_PAYLOAD_SIZE						96
 #define MQTT_MAX_MESSAGE_HANDLERS					1
 #define MQTT_COMMAND_TIMEOUT_MS						(8*1000L)
-#define MQTT_KEEP_ALIVE_INTERVAL_SEC				(MQTT_PUBLISH_PERIOD_MS/1000L*3)
+#define MQTT_KEEP_ALIVE_INTERVAL_SEC				(publishPeriodMs/1000L*3)
 #define MQTT_CLIENT_ID								SENSOR_ID
-#define MQTT_SUBSCRIBE_QOS							MqttClient::QOS1
+#define MQTT_SUBSCRIBE_QOS							MqttClient::QOS0
 #define MQTT_SUBSCRIBE_TOPIC_CFG					"test/sensor/" SENSOR_ID "/config"
 #define MQTT_PUBLISH_QOS							MqttClient::QOS0
 #define MQTT_PUBLISH_TOPIC							"test/sensor/" SENSOR_ID "/data"
 #define MQTT_LISTEN_TIME_MS							(5*1000L)
 #define MQTT_PUBLISH_PERIOD_MS						(1*60*1000L)
+#define MQTT_UPDATE_CONFIG_PERIOD_MS				(publishPeriodMs*3L)
 #define MQTT_CONNECT_RETRIES_QTY					5
 #define MQTT_DISCONNECTED_IDLE_PERIOD_MS			(2*60*1000L)
 #define NETWORK_HIBERNATE_DELAY_MS					100L
@@ -71,8 +72,9 @@
 MqttClient *mqtt									= NULL;
 Sensor* sensorTemperature							= NULL;
 Sensor* sensorHumidity								= NULL;
-unsigned long publishPeriodMs						= MQTT_PUBLISH_PERIOD_MS;
+unsigned long publishPeriodMs						= 0;
 unsigned long publishTs								= 0;
+unsigned long updateConfigTs						= 0;
 int connectCounter									= 0;
 bool firstPublish									= false;

@@ -80,6 +82,7 @@
 void(* reset) (void) = 0;//declare reset function at address 0
 void check();
 void connect();
+bool updateConfig();
 void buildMessagePayload(char* buffer, int size);
 void processMessageConfig(MqttClient::MessageData& md);
 void networkHibernate(unsigned long);
@@ -101,6 +104,12 @@
 /** Called once at startup */
 void setup() {
 	////// INIT //////
+	// TODO: Get publishPeriodMs from EEPROM
+	publishPeriodMs = MQTT_PUBLISH_PERIOD_MS;
+	publishTs = 0;
+	updateConfigTs = 0;
+	connectCounter = 0;
+	firstPublish = false;

 	/// HW UART ///
 	Uart *hwUart = new HwUart({HW_UART_SPEED});
@@ -184,11 +193,9 @@
 			Lpm::idle(MQTT_DISCONNECTED_IDLE_PERIOD_MS);
 			networkWakeUp(NETWORK_WAKE_UP_DELAY_MS);
 		} else {
+			connectCounter = 0;
 			// Do the publish immediately after reconnect
 			firstPublish = true;
-			// Listen for configuration
-			LOG_PRINTFLN("Waiting the configuration for %lu ms", MQTT_LISTEN_TIME_MS);
-			mqtt->yield(MQTT_LISTEN_TIME_MS);
 		}
 	} else {
 		// Connected
@@ -215,13 +222,27 @@
 				firstPublish = false;
 			}
 		}
+		// Check if time to Update configuration
+		if (isTimePassed(updateConfigTs, MQTT_UPDATE_CONFIG_PERIOD_MS)) {
+			if (updateConfig()) {
+				updateConfigTs = time.millis();
+			}
+		}
 		// Idle until next event
-		LOG_PRINTFLN("Idle for %lu ms", min(timeLeft(publishTs, publishPeriodMs), mqtt->getIdleInterval()));
+		unsigned long nextEventDelay = min(
+			timeLeft(publishTs, publishPeriodMs),
+			timeLeft(updateConfigTs, MQTT_UPDATE_CONFIG_PERIOD_MS)
+		);
+		LOG_PRINTFLN("Idle for %lu ms", min(nextEventDelay, mqtt->getIdleInterval()));
 		networkHibernate(NETWORK_HIBERNATE_DELAY_MS);
-		Lpm::idle(min(timeLeft(publishTs, publishPeriodMs), mqtt->getIdleInterval()));
+		Lpm::idle(min(nextEventDelay, mqtt->getIdleInterval()));
 		networkWakeUp(NETWORK_WAKE_UP_DELAY_MS);
-		// Determine the next event
-		if (timeLeft(publishTs, publishPeriodMs) > mqtt->getIdleInterval()) {
+		// Determine the next event after wake up
+		nextEventDelay = min(
+			timeLeft(publishTs, publishPeriodMs),
+			timeLeft(updateConfigTs, MQTT_UPDATE_CONFIG_PERIOD_MS)
+		);
+		if (nextEventDelay > mqtt->getIdleInterval()) {
 			// Need to call yield
 			while(mqtt->isConnected() && mqtt->getIdleInterval() < MQTT_COMMAND_TIMEOUT_MS) {
 				mqtt->yield();
@@ -293,21 +314,43 @@
 		if (rc != MqttClient::Error::SUCCESS) {
 			LOG_PRINTFLN("ERROR, Connect, rc:%i", rc);
 		} else {
-			const char* topic = MQTT_SUBSCRIBE_TOPIC_CFG;
-			LOG_PRINTFLN("Subscribe to %s", topic);
-			rc = mqtt->subscribe(topic, MQTT_SUBSCRIBE_QOS, processMessageConfig);
+			if (updateConfig()) {
+				// Success
+				updateConfigTs = time.millis();
+				return;
+			}
+		}
+	}
+	// Failure => disconnect
+	network->disconnect();
+}
+
+bool updateConfig() {
+	bool res = false;
+	if (mqtt->isConnected()) {
+		const char* topic = MQTT_SUBSCRIBE_TOPIC_CFG;
+		LOG_PRINTFLN("Subscribe to %s", topic);
+		MqttClient::Error::type rc = mqtt->subscribe(topic, MQTT_SUBSCRIBE_QOS, processMessageConfig);
+		if (rc != MqttClient::Error::SUCCESS) {
+			LOG_PRINTFLN("ERROR, Subscribe, rc:%i", rc);
+		} else {
+			// Listen for configuration
+			LOG_PRINTFLN("Waiting the configuration for %lu ms", MQTT_LISTEN_TIME_MS);
+			mqtt->yield(MQTT_LISTEN_TIME_MS);
+			rc = mqtt->unsubscribe(topic);
 			if (rc != MqttClient::Error::SUCCESS) {
-				LOG_PRINTFLN("ERROR, Subscribe, rc:%i", rc);
-				LOG_PRINTFLN("Drop connection");
-				mqtt->disconnect();
+				LOG_PRINTFLN("ERROR, Unsubscribe, rc:%i", rc);
 			} else {
 				// Success
-				return;
-			}
-		}
-	}
-	// Failure => disconnect
-	network->disconnect();
+				res = true;
+			}
+		}
+	}
+	if (!res) {
+		LOG_PRINTFLN("Drop connection");
+		mqtt->disconnect();
+	}
+	return res;
 }

 void processMessageConfig(MqttClient::MessageData& md) {
@@ -321,16 +364,18 @@
 	);
 	const int NUMBER_OF_ROOT_PARAMETERS = 1;
 	// See JSON_OBJECT_SIZE to predict buffer size
-	// Let's make double the prediction
-	const int BUFFER_SIZE = 2 * (JSON_OBJECT_SIZE(NUMBER_OF_ROOT_PARAMETERS));
+	// Let's make 3x of the prediction
+	const int BUFFER_SIZE = 3 * (JSON_OBJECT_SIZE(NUMBER_OF_ROOT_PARAMETERS));
 	StaticJsonBuffer<BUFFER_SIZE> jsonBuffer;
-	JsonObject& root = jsonBuffer.parseObject((char*)payload);
+	JsonObject& root = jsonBuffer.parseObject(&payload[0]);
 	// Check if parsing succeeds
 	if (!root.success()) {
 		LOG_PRINTFLN("ERROR, Can't pars configuration");
 		return;
 	}
 	publishPeriodMs = root["period"];
+	// TODO: Store publishPeriodMs to EEPROM
+	// TODO: Reconnect if publishPeriodMs is changed to update keep-alive timer
 }

 void networkHibernate(unsigned long delay) {


Update method to read the gps data

Update method to read the gps data

--- Sensors/GpsDataToSerial/GpsDataToSerial.ino
+++ Sensors/GpsDataToSerial/GpsDataToSerial.ino
@@ -1,7 +1,7 @@
 #include <SoftwareSerial.h>

 SoftwareSerial SoftSerial(2, 3);
-char buffer[265];
+char buffer[256];
 int count=0;

 void setup()
@@ -17,7 +17,7 @@
     while(SoftSerial.available())
     {
       buffer[count++]=SoftSerial.read();
-      if(count == 265)break;
+      if(count == 256)break;
     }

     String value = "";
@@ -30,13 +30,14 @@
         if(buffer[i] == 44)
           commaCount++;

-        if(commaCount == 14)
+        if(commaCount == 15)
           isEnd = true;

         if(isEnd == true){
-          i -= 6;
           for(int x = 0; x <= i; x++){
             char current = char(buffer[x]);
+            if(current == '\r')
+              break;
             value += current;
           }

@@ -45,6 +46,7 @@
           Serial.println(getValue(value,',',1));
           Serial.println(getValue(value,',',2));
           Serial.println(getValue(value,',',4));
+          Serial.println(getValue(value,',',11));
         }
       }
     }


Improved readability Renamed functions Renamed variables Renamed macros

--- EmbedVM_Arduino.ino
+++ EmbedVM_Arduino.ino
@@ -4,30 +4,31 @@

 #define UNUSED __attribute__((unused))

-#define MEM_SIZE 1*1024 //bytes of RAM allocated to the VM
-#define PROG_LENGTH 128 //bytes of instruction read by the VM
-#define PROG_OFFSET 0 //address of program in EEPROM
-#define PROG_START 0 //address of first instruction (relative to PROG_OFFSET
+#define MEMORY_SIZE 1*1024 //bytes of RAM allocated to the VM
+#define PROGRAM_LENGTH 128 //bytes of instruction read by the VM
+#define PROGRAM_OFFSET 0 //addressess of program in EEPROM
+#define PROGRAM_ENTRY 0 //addressess of first instruction (relative to PROGRAM_OFFSET
+
 #define BAUDRATE 9600 //UART baudrate
 #define VERBOSE false //verbose mode

 boolean stop = false;
-byte memory[MEM_SIZE];
+byte memory[MEMORY_SIZE];

 //put in seperate namespace to prevent Arduino IDE from preprocessing it; Arduino preprocessor is ST00PID
 namespace no {
   struct embedvm_s vm = {
     0xffff, 0, 0, NULL,
-    &mem_read, &mem_write, &call_user
+    &memoryRead, &memoryWrite, &callUserFunction
   };
 }

 void setup()
 {
   Serial.begin(BAUDRATE);
-  for(int addr = 0; addr < PROG_LENGTH; addr++)
-    memory[addr] = EEPROM.read(addr + PROG_OFFSET);
-  embedvm_interrupt(&no::vm, PROG_START);
+  for(int address = 0; address < PROGRAM_LENGTH; address++)
+    memory[address] = EEPROM.read(address + PROGRAM_OFFSET);
+  embedvm_interrupt(&no::vm, PROGRAM_ENTRY);
 }

 void loop()
@@ -49,7 +50,7 @@
   {
     Serial.print("IP: " + String(no::vm.ip) + " (" + String(memory[no::vm.ip]) + " " + String(memory[no::vm.ip + 1]) + " " + String(memory[no::vm.ip + 2]) + " " + String(memory[no::vm.ip + 3]) + "),  "); //print next instruction to execute
     Serial.print("SP: " + String(no::vm.sp) + " (" + String(memory[no::vm.sp]) + String(memory[no::vm.sp + 1]) + " " + String(memory[no::vm.sp + 2]) + String(memory[no::vm.sp + 3]) + " " + String(memory[no::vm.sp + 4]) + String(memory[no::vm.sp + 5]) + " " + String(memory[no::vm.sp + 6]) + String(memory[no::vm.sp + 7]) + "),  "); //print last pushed words on the stack
-    Serial.print("SFP: " + String(no::vm.sfp)); //print the address of the first local variable on the stack
+    Serial.print("SFP: " + String(no::vm.sfp)); //print the addressess of the first local variable on the stack
     Serial.println("");
     Serial.flush();
   }
@@ -58,36 +59,36 @@
 }

-static int16_t mem_read(uint16_t addr, bool is16bit, void *ctx UNUSED)
+static int16_t memoryRead(uint16_t address, bool is16bit, void *ctx UNUSED)
 {
   if (is16bit)
-    return (memory[addr] << 8) | memory[addr+1];
-  return memory[addr];
+    return (memory[address] << 8) | memory[address+1];
+  return memory[address];
 }

-static void mem_write(uint16_t addr, int16_t value, bool is16bit, void *ctx UNUSED)
+static void memoryWrite(uint16_t address, int16_t value, bool is16bit, void *ctx UNUSED)
 {
   if (is16bit) {
-    memory[addr] = value >> 8;
-    memory[addr+1] = value;
+    memory[address] = value >> 8;
+    memory[address+1] = value;
   }
   else
-    memory[addr] = value;
+    memory[address] = value;
 }

-static int16_t call_user(uint8_t funcid, uint8_t argc, int16_t *argv, void *ctx UNUSED)
+static int16_t callUserFunction(uint8_t function, uint8_t argc, int16_t *argv, void *ctx UNUSED)
 {
   int16_t ret = 0;
   int i;

-  if (funcid == 0) {
+  if (function == 0) {
     stop = true;
     Serial.println("Called user function 0 => stop.");
     Serial.flush();
     return ret;
   }

-  Serial.print("Called user function " + String(funcid) + " with " + String(argc) + " args:");
+  Serial.print("Called user function " + String(function) + " with " + String(argc) + " args:");

   for (i = 0; i < argc; i++) {
     Serial.print(" " + argv[i]);
@@ -97,7 +98,7 @@
   Serial.println("");
   Serial.flush();

-  return ret ^ funcid;
+  return ret ^ function;
 }


Portland Art Museum triangles with amplitude and frequency (yuh)

--- examples/pam-triangles/pam-triangles.ino
+++ examples/pam-triangles/pam-triangles.ino
@@ -127,9 +127,9 @@
 // Audio shield setup
 AudioInputI2S audio;
 AudioAnalyzePeak peak;
-AudioAnalyzeNoteFrequency freq;
+AudioAnalyzeNoteFrequency note;
 AudioConnection patchCord1(audio, peak);
-AudioConnection patchCord2(audio, freq);
+AudioConnection patchCord2(audio, note);
 AudioControlSGTL5000 audioShield;

 void setup() {
@@ -139,14 +139,15 @@
   Serial.flush();
   delay(1000);

-  AudioMemory(5);
+  AudioMemory(30);
   audioShield.enable();
   audioShield.inputSelect(AUDIO_INPUT_MIC);
   audioShield.micGain(50);
+  note.begin(.75);

-  input = new AudioShieldInput(&peak);
+  input = new AudioShieldInput(&peak, &note);

-  viz = new RippleVisualization(input, 150, 1);
+  viz = new RippleVisualization(input, 150, 1, true);

   anim1 = new TriangleAnimation(viz, inner_leds, 3);
   anim2 = new TriangleAnimation(viz, outer_leds, 6);
@@ -156,7 +157,7 @@

   FastLED.addLeds<WS2811, 6, GRB>(strip.leds, STRIP);

-  FastLED.setBrightness(32);
+  FastLED.setBrightness(255);

   Looper* looper = Looper::instance();
   looper->addInput(input);


Updated bond storage process and updated pin configuration

--- demos/ble_HID_template/ble_HID_template.ino
+++ demos/ble_HID_template/ble_HID_template.ino
@@ -401,6 +401,17 @@
       case ACI_EVT_TIMING:
         Serial.print(F("Timing change received conn Interval: 0x"));
         Serial.println(aci_evt->params.timing.conn_rf_interval, HEX);
+        //Disconnect as soon as we are bonded and required pipes are available
+        //This is used to store the bonding info on disconnect and then re-connect to verify the bond
+        if((ACI_BOND_STATUS_SUCCESS == aci_state.bonded) &&
+           (true == bonded_first_time) &&
+           (GAP_PPCP_MAX_CONN_INT >= aci_state.connection_interval) &&
+           (GAP_PPCP_MIN_CONN_INT <= aci_state.connection_interval) && //Timing change already done: Provide time for the the peer to finish
+           (lib_aci_is_pipe_available(&aci_state, PIPE_HID_SERVICE_HID_REPORT_ID1_TX) &&
+           (lib_aci_is_pipe_available(&aci_state, PIPE_HID_SERVICE_HID_REPORT_ID2_TX))))
+           {
+             lib_aci_disconnect(&aci_state, ACI_REASON_TERMINATE);
+           }
         break;

       case ACI_EVT_DATA_CREDIT:
@@ -554,7 +565,7 @@

   aci_state.aci_pins.spi_clock_divider     = SPI_CLOCK_DIV8;

-  aci_state.aci_pins.reset_pin             = UNUSED;
+  aci_state.aci_pins.reset_pin             = 4;
   aci_state.aci_pins.active_pin            = UNUSED;
   aci_state.aci_pins.optional_chip_sel_pin = UNUSED;

@@ -566,8 +577,8 @@
    */
   lib_aci_init(&aci_state);

-  pinMode(8, INPUT); //Pin #8 on Arduino -> PAIRING CLEAR pin: Connect to 3.3v to clear the pairing
-  if (0x01 == digitalRead(8))
+  pinMode(6, INPUT); //Pin #6 on Arduino -> PAIRING CLEAR pin: Connect to 3.3v to clear the pairing
+  if (0x01 == digitalRead(6))
   {
     //Clear the pairing
     Serial.println(F("Pairing cleared. Remove the wire on Pin 8 and reset the board for normal operation."));


Added delay for case when NTP is gone

Added delay for case when NTP is gone

--- projects/clock/clock.ino
+++ projects/clock/clock.ino
@@ -52,6 +52,7 @@
   if (!wasSynchronized && millis() > NTP_TIMEOUT * 1000) {
     display.setText("NO NTP");
     display.update();
+    delay(30000);
     return;
   }


Config change.

Config change.

--- sketch/arduino-butler/arduino-butler.ino
+++ sketch/arduino-butler/arduino-butler.ino
@@ -105,8 +105,9 @@
   switch12->Backend().Index(2).Modcode(1);
   switch_collection.SetSwitch(switch12, 12);

-  PlainSwitchController<CustomSwitch1>* switch13 = new PlainSwitchController<CustomSwitch1>();
+  StickySwitchController<CustomSwitch1>* switch13 = new StickySwitchController<CustomSwitch1>();
   switch13->Backend().Index(3).Modcode(1);
+  switch13->Toggle(true);
   switch_collection.SetSwitch(switch13, 13);

   PlainSwitchController<CustomSwitch1>* switch14 = new PlainSwitchController<CustomSwitch1>();


Added serial command mode. Incomplete..

Added serial command mode. Incomplete..

--- chicken_door_timer_v2.ino
+++ chicken_door_timer_v2.ino
@@ -23,12 +23,14 @@
 #include "RTClib.h"
 #include "encoder.h"
 //#define DEBUG_EN true
+#define DEBUG_EN_S true
 #define ERR_EN true
 #include "main.h"

 #define LATITUDE -42.9166667
 #define LONGITUDE 147.3333282

+#define SERIAL_WAIT 6000
 #define TIMEOUT_MAX 220
 #define DELAY_MS 10
 #define MAX_DELAY_MINUTES 100
@@ -259,6 +261,8 @@
     ERRLN("RTC is not running! PANIC!");
     rtc.adjust(DateTime(F(__DATE__), F(__TIME__)));
   }
+
+  //waitForSerialConnection();

   // Date testing using Datetime from RTC library
   now = rtc.now();
@@ -279,6 +283,8 @@

   // Initial time check to start things rolling..
   checkTime();
+
+

   // enable watchdog timer
   wdt_enable(WDTO_4S);
@@ -310,6 +316,60 @@

   /* Re-enable the peripherals. */
   power_all_enable();
+}
+
+
+// parse input from serial
+void parseInput(char * input){
+  DEBUGSLN("Entered: %s\n");
+
+}
+
+// check for user input via serial
+// if user enters 'i' within allowed time, start accepting input commands
+void waitForSerialConnection(){
+
+  volatile long int serial_wait_c = SERIAL_WAIT;
+  char * input_str = (char *) malloc(sizeof(char) * 32);
+  bool read_line = false;
+  bool accepting_input = false;
+
+  Serial.print("Enter i to enter serial command mode.\n");
+
+  while(serial_wait_c > 0 ){
+    while(Serial.available() > 0){
+      char in_c = Serial.read();
+      if (in_c == 'i'){
+	accepting_input = true;
+      }
+    }
+    _delay_ms(10);
+    serial_wait_c -= 10;
+  }
+
+  if(serial_wait_c == 0 || !accepting_input){
+    Serial.print("Serial command mode timeout..\n");
+  }
+
+  // if user entered 'i'
+  // TODO: add timeout for this, longer - eg 20-30 seconds
+  if(accepting_input){
+    while(!read_line){
+      char in_c;
+      while(Serial.available() > 0){
+	in_c = Serial.read();
+      }
+
+      // if user pressed enter, finish up
+      if(in_c == '\n' || in_c == '\r'){
+	read_line = true;
+	parseInput(input_str);
+	break;
+      } else {
+	*(input_str)++ = Serial.read();
+      }
+    }
+  }
 }

 // Draw a number on the lcd with a leding zero
@@ -538,7 +598,6 @@
     wdt_reset();
   }

-  // TODO: fix this..
   // if user wants to operate on door or something.. Leave door open/close (for a fair while)
   if(pausedForUser){
     lcd.clear();
@@ -622,36 +681,38 @@
 void checkLimitSwitches(){
   // If daytime, only check if door has been manually or accidentally closed
   if(is_day_time){
-    DEBUGLN("Checking if door closed at daytime.");
+    DEBUGSLN("Checking if door closed at daytime.");
     // quickly power motor to check if door is hitting wrong limit switch
     // if down switch pressed and day time
     digitalWrite(PIN_DOOR_DN, HIGH);
+    delay(1);
     if(digitalRead(PIN_LIMSW_DN) == HIGH){
-      DEBUGLN("Hit bottom!");
+      DEBUGSLN("Hit bottom!");
       hit_bottom = true;
     }
-    delay(1);
     digitalWrite(PIN_DOOR_DN, LOW);
     digitalWrite(PIN_DOOR_UP, HIGH);
     delay(2);
     digitalWrite(PIN_DOOR_UP, LOW);
+
     if(hit_bottom){
       waitForUserResetOpen();
     }
   } else {
-    DEBUGLN("Checking if door opened at night time.");
+    DEBUGSLN("Checking if door opened at night time.");

     // if up switch is pressed at day time
     digitalWrite(PIN_DOOR_UP, HIGH);
+    delay(1);
     if(digitalRead(PIN_LIMSW_UP) == HIGH){
       hit_top = true;
-      DEBUGLN("Hit bottom!");
-    }
-    delay(1);
+      DEBUGSLN("Hit bottom!");
+    }
     digitalWrite(PIN_DOOR_UP, LOW);
     digitalWrite(PIN_DOOR_DN, HIGH);
     delay(2);
     digitalWrite(PIN_DOOR_DN, LOW);
+
     if(hit_top){
       waitForUserResetOpen();
     }


Added debug preprocessor macro to save program size..

--- chicken_door_timer_v2.ino
+++ chicken_door_timer_v2.ino
@@ -22,6 +22,24 @@
 #include "RTClib.h"
 #include "encoder.h"

+//#define DEBUG_EN
+#ifdef DEBUG_EN
+  #define DEBUG(c) Serial.print(c);
+  #define DEBUGLN(c) Serial.println(c);
+#else
+  #define DEBUG(c) ;
+  #define DEBUGLN(c) ;
+#endif
+
+#define ERR_EN
+#ifdef ERR_EN
+  #define ERR(c) Serial.print(c);
+  #define ERRLN(c) Serial.println(c);
+#else
+  #define ERR(c) ;
+  #define ERRLN(c) ;
+#endif
+
 #define LATITUDE -42.9166667
 #define LONGITUDE 147.3333282

@@ -73,6 +91,7 @@

 #define MENU_COUNT 2

+
 volatile byte f_timer=0;

 char menu_pos = 0;
@@ -143,11 +162,11 @@
     lcd.print("EEPROM checksum");
     lcd.setCursor(0, 1);
     lcd.print("error :(");
-    Serial.println("EEPROM checksum error - Writing defeault values for sunrise delay.");
+    ERRLN("EEPROM checksum error - Writing defeault values for sunrise delay.");
     EEPROM.write(SUNRISE_DT_0_P, SUNRISE_DT_0_V);
     EEPROM.write(SUNRISE_DT_1_P, SUNRISE_DT_1_V);
     EEPROM.write(SUNRISE_DT_C_P, SUNRISE_DT_C_V);
-    Serial.println("Done.");
+    DEBUGLN("Done.");
     delay_time_before_sunrise = (SUNRISE_DT_0_V << 4) + SUNRISE_DT_1_V;
   } else {
     delay_time_before_sunrise = (sunrise_dt_v0 << 4) + sunrise_dt_v1;
@@ -163,11 +182,11 @@
     lcd.print("EEPROM checksum");
     lcd.setCursor(0, 1);
     lcd.print("error :(");
-    Serial.println("Writing default values for sunset delay.");
+    DEBUGLN("Writing default values for sunset delay.");
     EEPROM.write(SUNSET_DT_0_P, SUNSET_DT_0_V);
     EEPROM.write(SUNSET_DT_1_P, SUNSET_DT_1_V);
     EEPROM.write(SUNSET_DT_C_P, SUNSET_DT_C_V);
-    Serial.println("Done.");
+    DEBUGLN("Done.");
     delay_time_after_sunset = (SUNSET_DT_0_V << 4) + SUNSET_DT_1_V;
   } else {
     delay_time_after_sunset = (sunset_dt_v0 << 4) + sunset_dt_v1;
@@ -175,7 +194,9 @@
   }

   if(eeprom_success == 0x11){
-    Serial.println("EEPROM read successfully.");
+    DEBUGLN("EEPROM read successfully.");
+  } else{
+    ERRLN("Error reading EEPROM!");
   }
 }

@@ -257,12 +278,12 @@

   // setup RTC
   if (! rtc.begin()) {
-    Serial.println("Couldn't find RTC");
+    ERRLN("Couldn't find RTC");
     while (1);
   }

   if (! rtc.isrunning()) {
-    Serial.println("RTC is not running! PANIC!");
+    ERRLN("RTC is not running! PANIC!");
     rtc.adjust(DateTime(F(__DATE__), F(__TIME__)));
   }

@@ -279,7 +300,7 @@

   showSplash();

-  // testing..
+  /* testing..
   Serial.print("Date: ");
   Serial.print(now.day());
   Serial.print(" : ");
@@ -292,7 +313,7 @@
   Serial.print(now.minute(), DEC);
   Serial.print(" : ");
   Serial.print(now.second(), DEC);
-  Serial.print("\n");
+  Serial.print("\n"); */

   // Initial time check to start things rolling..
   checkTime();
@@ -334,36 +355,36 @@
   lcd.clear();
   lcd.setCursor(0, 0);
   lcd.print("Opening door");
-  Serial.println("Opening the door..");
+  DEBUGLN("Opening the door..");
   // send high to door open motor pin
   digitalWrite(PIN_DOOR_UP, HIGH);

   byte timeoutcount = 0;

   // loop until limit switch is hit (also add timeout)
-  Serial.print("Waiting for door to open");
+  DEBUGLN("Waiting for door to open");
   while(digitalRead(PIN_LIMSW_UP) == LOW){
     wdt_reset();
     delay(DELAY_MS);
     timeoutcount++;
     if(timeoutcount > TIMEOUT_MAX){
-      Serial.print("\nERROR! door not closing properly. Check limit switch.\n");
-      Serial.print("Pretending that it's closed for now..");
+      ERRLN("\nERROR! door not closing properly. Check limit switch.\n");
+      ERRLN("Pretending that it's closed for now..");
       couldnt_open_door = true;
       break;
     }
-    Serial.print(".");
+    DEBUG(".");
   }
   if(timeoutcount <= TIMEOUT_MAX){
     couldnt_open_door = false;
   }
   hit_top = true;
-  Serial.println();
+  DEBUGLN();

   // send low to door open motor pin
   digitalWrite(PIN_DOOR_UP, LOW);

-  Serial.println("Door opened!!");
+  DEBUGLN("Door opened!!");
   // set door is open bool to true
   door_open = true;

@@ -379,28 +400,28 @@
   byte timeoutcount = 0;

   // loop until limit switch is hit  (also add timeout)
-  Serial.print("Waiting for door to close");
+  DEBUGLN("Waiting for door to close");
   while(digitalRead(PIN_LIMSW_DN) == LOW){
     wdt_reset();
     delay(DELAY_MS);
     timeoutcount++;
     if(timeoutcount > TIMEOUT_MAX){
-      Serial.print("\nERROR! door not opening properly. Check limit switch.\n");
-      Serial.print("Pretending that it's open for now..");
+      ERR("\nERROR! door not opening properly. Check limit switch.\n");
+      ERRLN("Pretending that it's open for now..");
       couldnt_close_door = true;
       break;
     }
-     Serial.print(".");
+     DEBUG(".");
   }
   if(timeoutcount <= TIMEOUT_MAX){
     couldnt_close_door = false;
   }
   hit_bottom = true;
-  Serial.println();
+  DEBUGLN();

   // send low to door close motor pin
   digitalWrite(PIN_DOOR_DN, LOW);
-  Serial.println("Door closed!!");
+  DEBUGLN("Door closed!!");
   // set door is open bool to false
   door_open = false;

@@ -408,10 +429,10 @@

 void updateDoor(){
   if(is_day_time && !door_open){
-    Serial.print("It's daytime and we are now opening the door!");
+    DEBUGLN("It's daytime and we are now opening the door!");
     openDoor();
   } else if (!is_day_time && door_open){
-    Serial.print("It's night time and we are now closing the door!");
+    DEBUGLN("It's night time and we are now closing the door!");
     closeDoor();
   }
   door_retry_seconds_c += 4;
@@ -543,12 +564,12 @@
 void checkLimitSwitches(){
   // If daytime, only check if door has been manually or accidentally closed
   if(is_day_time){
-    Serial.print("Checking if door closed at daytime.");
+    DEBUGLN("Checking if door closed at daytime.");
     // quickly power motor to check if door is hitting wrong limit switch
     // if down switch pressed and day time
     digitalWrite(PIN_DOOR_DN, HIGH);
     if(digitalRead(PIN_LIMSW_DN) == HIGH){
-      Serial.print("Hit bottom!");
+      DEBUGLN("Hit bottom!");
       hit_bottom = true;
     }
     delay(1);
@@ -560,13 +581,13 @@
       waitForUserResetOpen();
     }
   } else {
-    Serial.print("Checking if door opened at night time.");
+    DEBUGLN("Checking if door opened at night time.");

     // if up switch is pressed at day time
     digitalWrite(PIN_DOOR_UP, HIGH);
     if(digitalRead(PIN_LIMSW_UP) == HIGH){
       hit_top = true;
-      Serial.print("Hit bottom!");
+      DEBUGLN("Hit bottom!");
     }
     delay(1);
     digitalWrite(PIN_DOOR_UP, LOW);
@@ -601,32 +622,39 @@
   bool evening = false;
   if (tardis.SunSet(sunset)) // if the sun will set today (it might not, in the [ant]arctic)
   {
+#ifdef DEBUG_EN
     Serial.print("Sunset: ");
     Serial.print((int) sunset[tl_hour]);
     Serial.print(":");
     Serial.println((int) sunset[tl_minute]);
+#endif

     char delta_mins = (now.hour() * 60 - sunset[tl_hour] * 60) + now.minute() - sunset[tl_minute];

     if(delta_mins > 0){
+#ifdef DEBUG_EN
       Serial.print("Time after sunset: ");
       Serial.print((int)delta_mins / 60);
       Serial.print(":");
       Serial.println(delta_mins % 60);
+#endif
       is_day_time = false;
     } else {
+#ifdef DEBUG_EN
       Serial.print("Time until sunset: ");
       Serial.print(-delta_mins / 60);
       Serial.print(":");
       Serial.println(-delta_mins % 60);
+#endif
       is_day_time = true;
     }
+
   }
   // get day for tomorrow if the sun has gone down already
   if(!is_day_time){
     // If in the evening, before the next day
     if(now.hour() > sunset[tl_hour]){
-      Serial.println("Checking sunrise for tomorrow..?");
+      DEBUGLN("Checking sunrise for tomorrow..?");
       // get tomorrow's sunrise
       DateTime tomorrow = now + TimeSpan(1, 0, 0, 0);
       sunrise[0] = tomorrow.second();
@@ -645,10 +673,12 @@
     //DateTime midnight(now.year(), now.month(), now.day(), 0, 0, 0);
     //DateTime now_plus_sunrise = now - (sunrise_dt - midnight);

+#ifdef DEBUG_EN
     Serial.print("Sunrise: ");
     Serial.print((int) sunrise[tl_hour]);
     Serial.print(":");
     Serial.print((int) sunrise[tl_minute]);
+#endif
     char delta_mins;
     if(!is_day_time){
       if(evening){
@@ -662,20 +692,21 @@
       // time after sunrise - will be negative so below can say time after sunrise
       delta_mins = (sunrise[tl_hour] * 60 - now.hour() * 60) + sunrise[tl_minute] - now.minute();
     }
-
+#ifdef DEBUG_EN
     if(delta_mins < 0){
       Serial.print("Time after sunrise: ");
       Serial.print((int)-delta_mins / 60);
       Serial.print(":");
       Serial.println(-delta_mins % 60);
-    } else {
+    } else {
       Serial.print("Time until sunrise: ");
       Serial.print(delta_mins / 60);
       Serial.print(":");
       Serial.println(delta_mins % 60);
     }
-  }
-  Serial.println();
+#endif
+  }
+  DEBUGLN();

 }

@@ -911,13 +942,13 @@
       menu_pos = (menu_pos - 1);
     }
     drawSelectedMenu();
-    Serial.print("Menu item: ");
-    Serial.println(menu_pos);
+    DEBUG("Menu item: ");
+    DEBUGLN(menu_pos);
   } else if (eState == ENC_INC) {
     tone(PIN_PIEZO, 400, 25);
     menu_pos = (menu_pos + 1) % (MENU_COUNT);
-    Serial.print("Menu item: ");
-    Serial.println(menu_pos);
+    DEBUG("Menu item: ");
+    DEBUGLN(menu_pos);
     drawSelectedMenu();
   }
 }
@@ -939,16 +970,16 @@
     } else if(in_delay_adj_menu){ /* user chose delay adjustion - draw first menu, set pre-delay */
       in_main_menu = false;
       in_delay_adj_menu = false;
-      Serial.println("Entering delay adjust options menu.");
+      DEBUGLN("Entering delay adjust options menu.");
       drawPreDelayMenu();
     } else if (in_time_adj_menu){ /* user chose time adjustion - run time adjust loop */
       in_main_menu = false;
       in_time_adj_menu = false;
-      Serial.println("Entering time adjust options menu.");
+      DEBUGLN("Entering time adjust options menu.");
       adjustTimeLoop();
       in_options_menu = false;
     } else if (in_pre_delay_menu || in_post_delay_menu){ /* user chose pre/post delay - run delay adjust loop */
-      Serial.println("drawing menu screen to update delay value");
+      DEBUGLN("drawing menu screen to update delay value");

       updateDelayLoop();
       in_options_menu = false;
@@ -969,7 +1000,7 @@
     // main loop - sleep for about 4s (maximum for timer?) then check time and update door
     if(f_timer==1) {
       f_timer = 0;
-      Serial.println("Waking from sleep..");
+      DEBUGLN("Waking from sleep..");

       // get time from rtc and check if it's day time/night time
       checkTime();


Set up serial interface

Set up serial interface

--- arduino/floppy_control/floppy_control.ino
+++ arduino/floppy_control/floppy_control.ino
@@ -7,36 +7,43 @@
 const byte HEAD_MIN = 0;
 const byte HEAD_MAX = 82;

+// frequency range (A0 through B4)
+const int FREQUENCY_MIN = 27;
+const int FREQUENCY_MAX = 494;
+
 // number of drives
 const byte DRIVE_COUNT = 3;

-// starting step control pin
+// starting direction pin
 const byte STARTING_PIN = 2;
-// we assume step control pins occur on evens and direction pins occur on odds
-// (so for drive 1, step control is pin 4 and direction is pin 5)
-
-// head directions (by drive):
+// we assume direction pins occur on evens and step pins occur on odds
+// (so for drive 0, direction is pin 2 and step is pin 3)
+
+// all of the following arrays need to be initialized with DRIVE_COUNT items...
+// this could maybe be avoided with enums or something
+
+// head directions (by drive)
 byte directions[] = {
   LOW,
   LOW,
   LOW
 };

-// active periods (by drive):
+// active periods (by drive)
 int periods[] = {
   0,
   0,
   0
 };

-// head positions (by drive):
+// head positions (by drive)
 byte positions[] = {
   0,
   0,
   0
 };

-// elapsed ticks (by drive):
+// elapsed ticks (by drive)
 // used to know when to step
 int ticks[] = {
   0,
@@ -44,33 +51,113 @@
   0
 };

+// serial command codes
+enum {
+  MESSAGE_READY = 000,
+  MESSAGE_INVALID = 001,
+  MESSAGE_ACTIVE = 010,
+  MESSAGE_RESET_ALL = 011,
+  MESSAGE_RESET_ONE = 012,
+  MESSAGE_SET_FREQUENCY = 020,
+};
+
 void setup() {
-  // set all needed pin modes
-  pinMode(2, OUTPUT); // 0: step control
-  pinMode(3, OUTPUT); // 0: direction
-  pinMode(4, OUTPUT); // 1: step control
-  pinMode(5, OUTPUT); // 1: direction
-  pinMode(6, OUTPUT); // 2: step control
-  pinMode(7, OUTPUT); // 2: direction
+  // sets all needed pins to output
+  for (byte drive = 0; drive < DRIVE_COUNT; drive++) {
+    byte direction = STARTING_PIN + (drive * 2);
+    byte step = direction + 1;
+
+    pinMode(direction, OUTPUT);
+    pinMode(step, OUTPUT);
+  }

   // initialize serial interface
   Serial.begin(9600);

   // set the drives to starting position if they aren't already
   resetDrives();
-
-  // @todo remove this, it's for testing
-  setFrequency(0, 73);  // D2
-  setFrequency(1, 110); // A2
-  setFrequency(2, 185); // F#3

   // initialize the timing loop
   Timer1.initialize(LOOP_RESOLUTION);
   Timer1.attachInterrupt(tick);
 }

+// handles serial communication
 void loop() {
-  // everything is done within the tick!
+  // each command is four bytes
+  static byte buffer[4];
+  static int index;
+
+  while (Serial.available() > 0) {
+    buffer[index] = Serial.read();
+    index++;
+
+    if (index > 3) {
+      index = 0;
+      process(buffer);
+    }
+  }
+}
+
+// responds to a command
+void process(byte command[4]) {
+  // each response is two bytes
+  byte response[2];
+
+  switch (command[0]) {
+    // simple ping
+  case MESSAGE_READY:
+    response[0] = MESSAGE_READY;
+    break;
+
+    // gets active drive count
+  case MESSAGE_ACTIVE:
+    response[0] = MESSAGE_ACTIVE;
+    response[1] = DRIVE_COUNT;
+    break;
+
+    // resets all drives
+  case MESSAGE_RESET_ALL:
+    resetDrives();
+    response[0] = MESSAGE_RESET_ALL;
+    break;
+
+    // resets one drive
+  case MESSAGE_RESET_ONE:
+    // check to make sure the drive is in bounds
+    if (command[1] < 0 || command[1] >= DRIVE_COUNT) {
+      break;
+    }
+
+    resetDrive(command[1]);
+    response[0] = MESSAGE_RESET_ONE;
+    response[1] = command[1];
+    break;
+
+    // sets a drive to a frequency
+  case MESSAGE_SET_FREQUENCY:
+    // check to make sure the drive is in bounds
+    if (command[1] < 0 || command[1] >= DRIVE_COUNT) {
+      break;
+    }
+
+    int frequency;
+    frequency = command[2] + command[3];
+
+    // check to make sure the frequency is in bounds
+    if (frequency != 0 && (frequency < FREQUENCY_MIN || frequency > FREQUENCY_MAX)) {
+      break;
+    }
+
+    setFrequency(command[1], frequency);
+    break;
+
+  default:
+    response[0] = MESSAGE_INVALID;
+  }
+
+  Serial.write(response[0]);
+  Serial.write(response[1]);
 }

 // steps drives according to their frequencies
@@ -87,7 +174,7 @@
   }
 }

-// steps a head
+// steps a head, reversing direction if necessary
 void step(byte drive) {
   byte d = getDirectionPin(drive);
   byte s = getStepPin(drive);
@@ -109,6 +196,21 @@
   digitalWrite(d, directions[drive]);
   digitalWrite(s, HIGH);
   digitalWrite(s, LOW);
+}
+
+void resetDrive(byte drive) {
+  directions[drive] = LOW;
+  periods[drive] = 0;
+  positions[drive] = 0;
+  ticks[drive] = 0;
+
+  for (byte step = HEAD_MIN; step <= HEAD_MAX; step++) {
+    digitalWrite(getDirectionPin(drive), HIGH);
+    digitalWrite(getStepPin(drive), HIGH);
+    digitalWrite(getStepPin(drive), LOW);
+
+    delay(5);
+  }
 }

 // sets everything to a clean starting state
@@ -121,7 +223,7 @@
     ticks[drive] = 0;
   }

-  // the drives won't go past 0, so that's cool
+  // the drives won't go past 0, so no worries about wrecking stuff
   for (byte step = HEAD_MIN; step <= HEAD_MAX; step++) {
     for (byte drive = 0; drive < DRIVE_COUNT; drive++) {
       digitalWrite(getDirectionPin(drive), HIGH);
@@ -153,3 +255,4 @@
   return STARTING_PIN + (drive * 2) + 1;
 }

+


Fix TCP request URI contents

Fix TCP request URI contents

--- ins-node/src/wifi_module/wifi_module.ino
+++ ins-node/src/wifi_module/wifi_module.ino
@@ -64,19 +64,23 @@
   }

   // Compose a request for the server according to the agreed format:
-  // /set_rssi/:device_id/:mac_addr1/:rssi1/:mac_addr2?/ ... /:mac_addr10?/:rssi10/?
+  // /set_rssi/device_id/mac_addr1/rssi1/mac_addr2/ ... /mac_addr10/:rssi10/
   String request = "/set_rssi/:";
   request += DEVICE_ID;
-  request += "/:";
+  request += "/";
   for (auto datapoint : datapoints) {
+    // We don't put everything in the same expression since std::string
+    // (used in testing) is not exactly the same as Arduino String. Therefore
+    // we go with this way of concatinating the string which is compatible with
+    // both implementations.
     request += datapoint.first; // The MAC address
-    request += "/:";
+    request += "/";
     request += datapoint.second; // The RSSI value
+    request += "/";
   }
-  request += "/?";

   // Send the TCP request to the rest server
-  client.print(String("PUT ") + request + " HTTP/1.1\r\n" +
+  client.print("PUT " + request + " HTTP/1.1\r\n" +
                "SERVER_IP: " + SERVER_IP + "\r\n" +
                "Connection: close\r\n\r\n");


doc: add note about addressing

doc: add note about addressing

--- examples/Expander32/EchoInput/EchoInput.ino
+++ examples/Expander32/EchoInput/EchoInput.ino
@@ -1,3 +1,5 @@
+// This example demonstrates how to use 2 MCP23S17 chips.
+
 #include <MCP23S17.h>

 #ifdef __PIC32MX__
@@ -9,24 +11,24 @@
 #include <SPI.h>
 #endif

+const uint8_t targetPin = 15;
 const uint8_t chipSelect = 10;

 // Create an object for each chip
-// Bank 0 is address 0
-// Bank 1 is address 1.
+// Bank0 uses address 0: Pins A0,A1,A2 grounded.
+// Bank1 uses address 1: Pin A0=+5V, A1,A2 grounded.
 // Increase the addresses by 2 for each BA value.
-
 MCP23S17 Bank1(&SPI, chipSelect, 0);
 MCP23S17 Bank2(&SPI, chipSelect, 1);

 void setup() {
-	Bank1.begin();
-	Bank2.begin();
+    Bank1.begin();
+    Bank2.begin();

-	Bank1.pinMode(15, OUTPUT);
-	Bank2.pinMode(15, INPUT_PULLUP);
+    Bank1.pinMode(targetPin, OUTPUT);
+    Bank2.pinMode(targetPin, INPUT_PULLUP);
 }

 void loop() {
-	Bank1.digitalWrite(15, !Bank2.digitalRead(15));
+    Bank1.digitalWrite(targetPin, !Bank2.digitalRead(targetPin));
 }