Added the REPLAY command

Added the REPLAY command

--- arduino_wifi_duck/arduino_wifi_duck.ino
+++ arduino_wifi_duck/arduino_wifi_duck.ino
@@ -1,116 +1,127 @@
-#include <Keyboard.h>
-#define BAUD_RATE 115200
-#define ExternSerial Serial1
-
-String bufferStr = "";
-
-void Line(String _line)
-{
-  int firstSpace = _line.indexOf(" ");
-  if(firstSpace == -1) Press(_line);
-  else if(_line.substring(0,firstSpace) == "STRING"){
-    for(int i=firstSpace+1;i<_line.length();i++) Keyboard.write(_line[i]);
-  }
-  else if(_line.substring(0,firstSpace) == "DELAY"){
-    int delaytime = _line.substring(firstSpace + 1).toInt();
-    delay(delaytime);
-  }
-  else if(_line.substring(0,firstSpace) == "REM"){
-    //nothing :/
-  }
-  else{
-      String remain = _line;
-
-      while(remain.length() > 0){
-        int latest_space = remain.indexOf(" ");
-        if (latest_space == -1){
-          Press(remain);
-          remain = "";
-        }
-        else{
-          Press(remain.substring(0, latest_space));
-          remain = remain.substring(latest_space + 1);
-        }
-        delay(5);
-      }
-  }
-
-  Keyboard.releaseAll();
-}
-
-
-void Press(String b)
-{
-  if(b.length() == 1) Keyboard.press(char(b[0]));
-  else if (b.equals("ENTER")) Keyboard.press(KEY_RETURN);
-  else if (b.equals("CTRL")) Keyboard.press(KEY_LEFT_CTRL);
-  else if (b.equals("SHIFT")) Keyboard.press(KEY_LEFT_SHIFT);
-  else if (b.equals("ALT")) Keyboard.press(KEY_LEFT_ALT);
-  else if (b.equals("GUI")) Keyboard.press(KEY_LEFT_GUI);
-  else if (b.equals("UP") || b.equals("UPARROW")) Keyboard.press(KEY_UP_ARROW);
-  else if (b.equals("DOWN") || b.equals("DOWNARROW")) Keyboard.press(KEY_DOWN_ARROW);
-  else if (b.equals("LEFT") || b.equals("LEFTARROW")) Keyboard.press(KEY_LEFT_ARROW);
-  else if (b.equals("RIGHT") || b.equals("RIGHTARROW")) Keyboard.press(KEY_RIGHT_ARROW);
-  else if (b.equals("DELETE")) Keyboard.press(KEY_DELETE);
-  else if (b.equals("PAGEUP")) Keyboard.press(KEY_PAGE_UP);
-  else if (b.equals("PAGEDOWN")) Keyboard.press(KEY_PAGE_DOWN);
-  else if (b.equals("HOME")) Keyboard.press(KEY_HOME);
-  else if (b.equals("ESC")) Keyboard.press(KEY_ESC);
-  else if (b.equals("INSERT")) Keyboard.press(KEY_INSERT);
-  else if (b.equals("TAB")) Keyboard.press(KEY_TAB);
-  else if (b.equals("END")) Keyboard.press(KEY_END);
-  else if (b.equals("CAPSLOCK")) Keyboard.press(KEY_CAPS_LOCK);
-  else if (b.equals("F1")) Keyboard.press(KEY_F1);
-  else if (b.equals("F2")) Keyboard.press(KEY_F2);
-  else if (b.equals("F3")) Keyboard.press(KEY_F3);
-  else if (b.equals("F4")) Keyboard.press(KEY_F4);
-  else if (b.equals("F5")) Keyboard.press(KEY_F5);
-  else if (b.equals("F6")) Keyboard.press(KEY_F6);
-  else if (b.equals("F7")) Keyboard.press(KEY_F7);
-  else if (b.equals("F8")) Keyboard.press(KEY_F8);
-  else if (b.equals("F9")) Keyboard.press(KEY_F9);
-  else if (b.equals("F10")) Keyboard.press(KEY_F10);
-  else if (b.equals("F11")) Keyboard.press(KEY_F11);
-  else if (b.equals("F12")) Keyboard.press(KEY_F12);
-  else if (b.equals("SPACE")) Keyboard.press(' ');
-  //else Serial.println("not found :'"+b+"'("+String(b.length())+")");
-}
-
-void setup() {
-  Serial.begin(BAUD_RATE);
-  ExternSerial.begin(BAUD_RATE);
-
-  Keyboard.begin();
-}
-
-void loop() {
-
-  if(ExternSerial.available() > 0) {
-    bufferStr = ExternSerial.readString();
-    Serial.println(bufferStr);
-  }
-
-  if(bufferStr.length() > 0){
-
-    bufferStr.replace("\r","\n");
-    bufferStr.replace("\n\n","\n");
-
-    while(bufferStr.length() > 0){
-      int latest_return = bufferStr.indexOf("\n");
-      if(latest_return == -1){
-        Serial.println("run: "+bufferStr);
-        Line(bufferStr);
-        bufferStr = "";
-      } else{
-        Serial.println("run: '"+bufferStr.substring(0, latest_return)+"'");
-        Line(bufferStr.substring(0, latest_return));
-        bufferStr = bufferStr.substring(latest_return + 1);
-      }
-    }
-
-    bufferStr = "";
-    ExternSerial.write(0x99);
-  }
-
-}
+#include <Keyboard.h>
+#define BAUD_RATE 115200
+#define ExternSerial Serial1

+String bufferStr = "";
+String last = "";
+
+void Line(String _line)
+{
+  int firstSpace = _line.indexOf(" ");
+  if(firstSpace == -1) Press(_line);
+  else if(_line.substring(0,firstSpace) == "STRING"){
+    for(int i=firstSpace+1;i<_line.length();i++) Keyboard.write(_line[i]);
+  }
+  else if(_line.substring(0,firstSpace) == "DELAY"){
+    int delaytime = _line.substring(firstSpace + 1).toInt();
+    delay(delaytime);
+  }
+  else if(_line.substring(0,firstSpace) == "REM"){
+    //nothing :/
+  }
+  else if(_line.substring(0,firstSpace) == "REPLAY")
+  {
+    int replaynum = _line.substring(firstSpace + 1).toInt();
+    while(replaynum)
+    {
+      Line(last);
+      --replaynum;
+    }
+  }
+  else{
+      String remain = _line;
+
+      while(remain.length() > 0){
+        int latest_space = remain.indexOf(" ");
+        if (latest_space == -1){
+          Press(remain);
+          remain = "";
+        }
+        else{
+          Press(remain.substring(0, latest_space));
+          remain = remain.substring(latest_space + 1);
+        }
+        delay(5);
+      }
+  }
+
+  Keyboard.releaseAll();
+}
+
+
+void Press(String b)
+{
+  if(b.length() == 1) Keyboard.press(char(b[0]));
+  else if (b.equals("ENTER")) Keyboard.press(KEY_RETURN);
+  else if (b.equals("CTRL")) Keyboard.press(KEY_LEFT_CTRL);
+  else if (b.equals("SHIFT")) Keyboard.press(KEY_LEFT_SHIFT);
+  else if (b.equals("ALT")) Keyboard.press(KEY_LEFT_ALT);
+  else if (b.equals("GUI")) Keyboard.press(KEY_LEFT_GUI);
+  else if (b.equals("UP") || b.equals("UPARROW")) Keyboard.press(KEY_UP_ARROW);
+  else if (b.equals("DOWN") || b.equals("DOWNARROW")) Keyboard.press(KEY_DOWN_ARROW);
+  else if (b.equals("LEFT") || b.equals("LEFTARROW")) Keyboard.press(KEY_LEFT_ARROW);
+  else if (b.equals("RIGHT") || b.equals("RIGHTARROW")) Keyboard.press(KEY_RIGHT_ARROW);
+  else if (b.equals("DELETE")) Keyboard.press(KEY_DELETE);
+  else if (b.equals("PAGEUP")) Keyboard.press(KEY_PAGE_UP);
+  else if (b.equals("PAGEDOWN")) Keyboard.press(KEY_PAGE_DOWN);
+  else if (b.equals("HOME")) Keyboard.press(KEY_HOME);
+  else if (b.equals("ESC")) Keyboard.press(KEY_ESC);
+  else if (b.equals("INSERT")) Keyboard.press(KEY_INSERT);
+  else if (b.equals("TAB")) Keyboard.press(KEY_TAB);
+  else if (b.equals("END")) Keyboard.press(KEY_END);
+  else if (b.equals("CAPSLOCK")) Keyboard.press(KEY_CAPS_LOCK);
+  else if (b.equals("F1")) Keyboard.press(KEY_F1);
+  else if (b.equals("F2")) Keyboard.press(KEY_F2);
+  else if (b.equals("F3")) Keyboard.press(KEY_F3);
+  else if (b.equals("F4")) Keyboard.press(KEY_F4);
+  else if (b.equals("F5")) Keyboard.press(KEY_F5);
+  else if (b.equals("F6")) Keyboard.press(KEY_F6);
+  else if (b.equals("F7")) Keyboard.press(KEY_F7);
+  else if (b.equals("F8")) Keyboard.press(KEY_F8);
+  else if (b.equals("F9")) Keyboard.press(KEY_F9);
+  else if (b.equals("F10")) Keyboard.press(KEY_F10);
+  else if (b.equals("F11")) Keyboard.press(KEY_F11);
+  else if (b.equals("F12")) Keyboard.press(KEY_F12);
+  else if (b.equals("SPACE")) Keyboard.press(' ');
+  //else Serial.println("not found :'"+b+"'("+String(b.length())+")");
+}
+
+void setup() {
+  Serial.begin(BAUD_RATE);
+  ExternSerial.begin(BAUD_RATE);
+
+  Keyboard.begin();
+}
+
+void loop() {
+
+  if(ExternSerial.available() > 0) {
+    bufferStr = ExternSerial.readString();
+    Serial.println(bufferStr);
+  }
+
+  if(bufferStr.length() > 0){
+
+    bufferStr.replace("\r","\n");
+    bufferStr.replace("\n\n","\n");
+
+    while(bufferStr.length() > 0){
+      int latest_return = bufferStr.indexOf("\n");
+      if(latest_return == -1){
+        Serial.println("run: "+bufferStr);
+        Line(bufferStr);
+        bufferStr = "";
+      } else{
+        Serial.println("run: '"+bufferStr.substring(0, latest_return)+"'");
+        Line(bufferStr.substring(0, latest_return));
+        last=bufferStr.substring(0, latest_return);
+        bufferStr = bufferStr.substring(latest_return + 1);
+      }
+    }
+
+    bufferStr = "";
+    ExternSerial.write(0x99);
+  }
+
+}
+


Return true or false from the payload callback in the publish_large example

--- examples/mqtt_publish_large/mqtt_publish_large.ino
+++ examples/mqtt_publish_large/mqtt_publish_large.ino
@@ -32,9 +32,12 @@
     int len = sprintf(buf, "%d", l);
     buf[len] = 32;
     buf[63] = '\n';
-    client.write((const uint8_t*)buf, 64);
+    uint32_t sent = client.write((const uint8_t*)buf, 64);
+    if (sent < 64)
+      return false;
   }
   Serial.println("Published large message.");
+  return true;
 }

 void loop() {


Try faster comms

Try faster comms

--- arduino/led_matrix/led_matrix.ino
+++ arduino/led_matrix/led_matrix.ino
@@ -8,7 +8,7 @@
 #define BAUD 115200
 #define BRIGHTNESS 64

-CGRB leds[NUM_LEDS];
+CRGB leds[NUM_LEDS];
 int r, g, b;
 int x, y, yy;

@@ -33,7 +33,7 @@
       } else {
         yy = HEIGHT - y - 1;
       }
-      leds[yy + x * HEIGHT] = CGRB(g, r, b);
+      leds[yy + x * HEIGHT] = CRGB(g, r, b);  // Seems to be running as GRB, not RGB
     }
   }
   FastLED.show();


rename included  files as per spark.json

rename included  files as per spark.json

--- firmware/examples/readTag/readtag.ino
+++ firmware/examples/readTag/readtag.ino
@@ -1,4 +1,4 @@
-#include "pn532_i2c_particle/pn532_i2c.h"
+#include "pn532_i2c_particle/pn532_i2c_particle.h"
 #include "pn532_i2c_particle/PN532.h"
 #include "pn532_i2c_particle/NfcAdapter.h"


Update Modbus-Energy-Monitor-Arduino.ino

--- Modbus-Energy-Monitor-Arduino/Modbus-Energy-Monitor-Arduino.ino
+++ Modbus-Energy-Monitor-Arduino/Modbus-Energy-Monitor-Arduino.ino
@@ -146,29 +146,29 @@

     SERIAL_PRINT(currentMillis / 1000);
     SERIAL_PRINT(",");
-    SERIAL_PRINT(maxVoltage / VOL_FAC, 1);
+    SERIAL_PRINT((float)maxVoltage / VOL_FAC, 1);
     SERIAL_PRINT(",");
-    SERIAL_PRINT(minVoltage /VOL_FAC, 1);
+    SERIAL_PRINT((float)minVoltage /VOL_FAC, 1);
     SERIAL_PRINT(",");
-    SERIAL_PRINT(maxCurrent /CUR_FAC, 2);
+    SERIAL_PRINT((float)maxCurrent /CUR_FAC, 2);
     SERIAL_PRINT(",");
-    SERIAL_PRINT(minCurrent / CUR_FAC, 2);
+    SERIAL_PRINT((float)minCurrent / CUR_FAC, 2);
     SERIAL_PRINT(",");
-    SERIAL_PRINT(maxPower / POW_FAC, 2);
+    SERIAL_PRINT((float)maxPower / POW_FAC, 2);
     SERIAL_PRINT(",");
-    SERIAL_PRINT(minPower / POW_FAC, 2);
+    SERIAL_PRINT((float)minPower / POW_FAC, 2);
     SERIAL_PRINT(",");
-    SERIAL_PRINT(maxApower / POW_FAC, 2);
+    SERIAL_PRINT((float)maxApower / POW_FAC, 2);
     SERIAL_PRINT(",");
-    SERIAL_PRINT(minApower /POW_FAC, 2);
+    SERIAL_PRINT((float)minApower /POW_FAC, 2);
     SERIAL_PRINT(",");
-    SERIAL_PRINT(maxFreq / FRE_FAC, 2);
+    SERIAL_PRINT((float)maxFreq / FRE_FAC, 2);
     SERIAL_PRINT(",");
-    SERIAL_PRINT(minFreq / FRE_FAC, 2);
+    SERIAL_PRINT((float)minFreq / FRE_FAC, 2);
     SERIAL_PRINT(",");
-    SERIAL_PRINT(avgPower / ENE_FAC, 2);
+    SERIAL_PRINT((float)avgPower / ENE_FAC, 2);
     SERIAL_PRINT(",");
-    SERIAL_PRINTLN(energy /ENE_FAC, 2);
+    SERIAL_PRINTLN((float)energy /ENE_FAC, 2);

   }
 }


Added hysteresis of 0.1V in order to send data

--- arduino_src/SerialSendAnalogVoltage/SerialSendAnalogVoltage.ino
+++ arduino_src/SerialSendAnalogVoltage/SerialSendAnalogVoltage.ino
@@ -16,14 +16,15 @@
   float oldVoltage=-1;
   while(true)
   { // read the input on analog pin 0:
-    int sensorValue = analogRead(A1);
-    // Convert the analog reading (which goes from 0 - 1023) to a voltage (0 - 5V):
-    float voltage = sensorValue * (5.0 / 1023.0);
-    if(voltage!=oldVoltage) //Transfer voltage on change
-    {
-      //Transfer the serial data
+     int sensorValue = analogRead(A1);
+     // Convert the analog reading (which goes from 0 - 1023) to a voltage (0 - 5V):
+     float voltage =  sensorValue * (5.0 / 1023.0);
+     //Use a hysteresis of 0.1V to avoid trasmission of noice
+     if ((voltage > (oldVoltage+.01)) | (voltage < (oldVoltage-.01)))
+     {//Transfer the serial data
       Serial.print("$VOLTAGE,A1," );
       Serial.println(voltage);
+      oldVoltage=voltage;
     }//end if
   }//end while
 }


Update MifareClassicValueBlock.ino

Update MifareClassicValueBlock.ino

Updated code to account for serial behavior change in ATMEGA32U4

--- examples/MifareClassicValueBlock/MifareClassicValueBlock.ino
+++ examples/MifareClassicValueBlock/MifareClassicValueBlock.ino
@@ -43,6 +43,7 @@
  */
 void setup() {
     Serial.begin(9600);	// Initialize serial communications with the PC
+    while (!Serial);    // Do nothing if no serial port is opened (added for Arduinos based on ATMEGA32U4)
     SPI.begin();		// Init SPI bus
     mfrc522.PCD_Init();	// Init MFRC522 card


Added most of JSON communication code.

Added most of JSON communication code.

--- firmware/firmware.ino
+++ firmware/firmware.ino
@@ -39,12 +39,19 @@
 platypus::LED rgb_led;
 platypus::VaporPro motor(0);

+/**
+ * Returns a JSON error message to the connected USB device and the
+ * serial debugging console.
+ */
 void reportJsonError(jsmnerr_t error)
 {
   char *error_message;

   // Fill in the appropriate JSON error description.
   switch(error) {
+    case JSMN_SUCCESS:
+      // If we were successful, there is nothing to report.
+      return;
     case JSMN_ERROR_NOMEM:
       error_message = "Insufficient memory.";
       break;
@@ -75,6 +82,36 @@
   Serial.println(output_buffer);
 }

+/**
+ * Copies a JSON string token into a provided char* buffer.
+ */
+jsmnerr_t json_string(const jsmntok_t &token, const char *json_str, char *output_str, size_t output_len)
+{
+  if (token.type != JSMN_STRING) return JSMN_ERROR_INVAL;
+
+  size_t len = min(token.end - token.start, output_len - 1);
+  strncpy(output_str, &json_str[token.start], len);
+  output_str[len] = '\0';
+
+  return JSMN_SUCCESS;
+}
+
+/**
+ * Extracts a floating point value from a JSON token.
+ */
+jsmnerr_t json_float(const jsmntok_t &token, const char *json_str, float &output_float)
+{
+  if (token.type != JSMN_PRIMITIVE) return JSMN_ERROR_INVAL;
+
+  const size_t len = token.end - token.start;
+  char float_buffer[len];
+  strncpy(float_buffer, &json_str[token.start], len);
+  float_buffer[len] = '\0';
+
+  output_float = atof(float_buffer);
+  return JSMN_SUCCESS;
+}
+
 void setup()
 {
   // Initialize debugging serial console.
@@ -93,9 +130,6 @@
   // Number of bytes received from USB.
   uint32_t bytes_read = 0;

-  // Signed char pointer to head of buffer.
-  char *input_buffer_ptr = (char *)input_buffer;
-
   // Result of JSON parsing.
   jsmnerr_t json_result;

@@ -136,7 +170,68 @@
     return;
   }

-  // TODO: read these inputs and do things.
+  // Get the first token and make sure it is a JSON object.
+  jsmntok_t *token = json_tokens;
+  if (token->type != JSMN_OBJECT)
+  {
+    reportJsonError(JSMN_ERROR_INVAL);
+    return;
+  }
+
+  // Read each field of the JSON object and act accordingly.
+  size_t num_entries = token->size;
+  for (size_t entry_idx = 0; entry_idx < num_entries; entry_idx++)
+  {
+    // Get the name field for this entry.
+    token++;
+    char entry_name[64];
+    if (json_string(*token, input_buffer, entry_name, 64)) {
+      reportJsonError(JSMN_ERROR_INVAL);
+      return;
+    }
+
+    // The following token should always be the entry object.
+    token++;
+    if (token->type != JSMN_OBJECT) {
+      reportJsonError(JSMN_ERROR_INVAL);
+      return;
+    }
+
+    // Based on the name token, parse the entry object parameters.
+    size_t num_params = token->size;
+    if (!strncmp("motor", entry_name, 6))
+    {
+      for (size_t param_idx = 0; param_idx < num_params; param_idx++)
+      {
+        // Get the name field for this parameter.
+        token++;
+        char param_name[64];
+        if (json_string(*token, input_buffer, param_name, 64)) {
+          reportJsonError(JSMN_ERROR_INVAL);
+          return;
+        }
+
+        // TODO: parse something based on this
+        token++;
+      }
+    }
+    else if (!strncmp("sensor", entry_name, 6))
+    {
+      for (size_t param_idx = 0; param_idx < num_params; param_idx++)
+      {
+        // Get the name field for this parameter.
+        token++;
+        char param_name[64];
+        if (json_string(*token, input_buffer, param_name, 64)) {
+          reportJsonError(JSMN_ERROR_INVAL);
+          return;
+        }
+
+        // TODO: parse something based on this
+        token++;
+      }
+    }
+  }

   // Send back response.
   //adk.write(bytes_read, input_buffer);


Added GenericSerial.

Added GenericSerial.

--- firmware/firmware.ino
+++ firmware/firmware.ino
@@ -8,6 +8,7 @@
 #include "ConstantVariable.h"
 #include "SavedVariable.h"
 #include "BetterMap.h"
+#include "GenericSerial.h"
 #include "ModularDevice.h"
 #include "NewhavenDisplay.h"
 #include "Encoder.h"


changing controller address

changing controller address

--- firmware/firmware.ino
+++ firmware/firmware.ino
@@ -307,7 +307,7 @@
 #define TAD_BASE  0x40
 #define SAD_BASE  0x60

-byte_t self_gpib_address = 30;
+byte_t self_gpib_address = 21; // By convention, the controller is typically address 21.

 // "Device Listen Address": configure the device at the given address to be a listener.
 void LAD(byte_t address) {
@@ -352,8 +352,8 @@
     settle();

     UNL();
+    LAD(address);
     TAD(self_gpib_address);
-    LAD(address);

     unassert_atn();
     settle();


Added player fire mechanism. Added collision detection screen edges.

--- space/space.ino
+++ space/space.ino
@@ -5,8 +5,8 @@

 PROGMEM const unsigned char playerShip [] = {0x10, 0x38, 0x7C, 0xFE};

-byte playerWidth = 7;
-byte playerHeight = 4;
+//byte playerWidth = 7;
+//byte playerHeight = 4;

 PROGMEM const unsigned char ship1 [] = {0x38, 0x7C, 0xFE, 0xFE, 0x82, 0xC6};

@@ -17,34 +17,39 @@
 char gameState = 'T';
 bool sound = false;

-struct coords
-{
-  public:
+const byte maxProjs = 3;
+byte fireDelay = 0;
+
+
+struct Proj
+{
+  //public:
   byte X = 0;
   byte Y = 0;
   bool Active = false;
 };

-typedef struct coords Coords;
-
 struct player
 {
   byte X = 0;
   byte Y = 0;
-    char dir = '-';
+  byte W = 7;
+  byte H = 4;
 };

 typedef struct player Player;

 Player p1;
+
+Proj projs[maxProjs];

 int score = 0;
 int arrayPosition = 0;

 void StartGame()
 {
-  p1.X = maxX / 2;
-  p1.Y = maxY - playerHeight;
+  p1.X = (maxX / 2) - (p1.W / 2);
+  p1.Y = maxY - p1.H;
   score = 0;

   gameState = 'G';
@@ -72,8 +77,37 @@
 void DrawFrame()
 {
   //arduboy.drawRect(minX,minY, maxX +1, (maxY - minY) +1, WHITE);
-
-  arduboy.drawSlowXYBitmap(p1.X -2,p1.Y, playerShip, playerWidth, playerHeight, WHITE);
+
+  for (int i = 0; i < maxProjs; i++)
+  {
+    Serial.print("\nproj ");
+    Serial.print(i);
+    Serial.print("\nActive ");
+    Serial.print(projs[i].Active);
+    Serial.print("\nX ");
+    Serial.print(projs[i].X);
+    Serial.print("\nY ");
+    Serial.print(projs[i].Y);
+      if(projs[i].Active == true)
+      {
+        projs[i].Y -= 1;
+        if(projs[i].Y == 0)
+        {
+          projs[i].Active = false;
+        }
+        else
+        {
+          arduboy.drawPixel(projs[i].X, projs[i].Y, WHITE);
+        }
+      }
+      Serial.print("\nActive ");
+      Serial.print(projs[i].Active);
+  }
+
+  arduboy.drawSlowXYBitmap(p1.X,p1.Y, playerShip, p1.W, p1.H, WHITE);
+  arduboy.drawSlowXYBitmap(5,5, ship1, 8 , 6, WHITE);
+
+
 }

 // This function runs once in your game.
@@ -104,55 +138,39 @@
     DrawFrame();

     if(arduboy.pressed(RIGHT_BUTTON)) {
-      p1.X += 1;
+      if((p1.X) < (maxX - p1.W))
+      {
+        p1.X += 1;
+      }
     }

     if(arduboy.pressed(LEFT_BUTTON)) {
-      p1.X -= 1;
-    }
-
-    if(arduboy.pressed(UP_BUTTON)) {
-//      if(p1.dir != 'D')
-//      {
-//        p1.dir = 'U';
-//      }
-    }
-
-    if(arduboy.pressed(DOWN_BUTTON)) {
-//      if(p1.dir != 'U')
-//      {
-//        p1.dir = 'D';
-//      }
-    }
-
-//    switch(p1.dir)
-//    {
-//      case 'U':
-//        if(p1.Y > minY)
-//        {
-//          p1.Y -= 1;
-//        }
-//        break;
-//      case 'D':
-//        if(p1.Y < maxY)
-//        {
-//          p1.Y += 1;
-//        }
-//        break;
-//      case 'L':
-//        if(p1.X > minX)
-//        {
-//          p1.X-= 1;
-//        }
-//        break;
-//      case 'R':
-//        if(p1.X < maxX)
-//        {
-//          p1.X+= 1;
-//        }
-//
-//      break;
-//    }
+      if(p1.X > 0)
+      {
+        p1.X -= 1;
+      }
+    }
+
+    if(arduboy.pressed(B_BUTTON))
+    {
+      if(fireDelay == 0)
+      {
+        for (int i = 0; i < maxProjs; i++)
+        {
+          if(projs[i].Active == false)
+          {
+            projs[i].X = p1.X + (p1.W /2);
+            projs[i].Y = p1.Y - 1;
+            projs[i].Active = true;
+            fireDelay = 20;
+            break;
+          }
+        }
+      }
+    }
+
+
+

     CollisionDetection();

@@ -163,6 +181,11 @@
     sprintf(scoreBuff, "%05d", score);

     arduboy.print(scoreBuff);
+
+    if(fireDelay > 0)
+    {
+      fireDelay --;
+    }
   }
   else if(gameState == 'E')
   {
@@ -200,8 +223,6 @@

     arduboy.setCursor(109, 55);
     arduboy.print("Off");
-
-    arduboy.drawSlowXYBitmap(5,5, ship1, 8 , 6, WHITE);

     if(arduboy.pressed(A_BUTTON) || arduboy.pressed(B_BUTTON)) {
       StartGame();


Update Nucleo benchmark; improved with 2-8%.

--- examples/Benchmarks/CosaBenchmarkNucleo/CosaBenchmarkNucleo.ino
+++ examples/Benchmarks/CosaBenchmarkNucleo/CosaBenchmarkNucleo.ino
@@ -22,9 +22,9 @@
  *
  * @section Description
  * Cosa Nucleo benchmarks;
- * 1) Thread context switches, measured with yield (12 us)
- * 2) Thread context switches, measured with resume(this) (12 us)
- * 3) Semaphore signal-wait, measured between two threads (42 us)
+ * 1) Thread context switches, measured with yield (11 us)
+ * 2) Thread context switches, measured with resume(this) (11 us)
+ * 3) Semaphore signal-wait, measured between two threads (41 us)
  *
  * This file is part of the Arduino Che Cosa project.
  */


fixed bug: turn+1

fixed bug: turn+1

--- tictactoe/tictactoe.ino
+++ tictactoe/tictactoe.ino
@@ -229,6 +229,8 @@
       display.drawImage(0x0000, WINNER, 0, DOWN_OFFSET);
       soundPlayer.play(YOU_WIN);
       victoryLoop('g');
+    } else{
+      turn = turn + 1;
     }
   }

@@ -261,6 +263,8 @@
       display.drawImage(0x0000, GAME_OVER, 0, DOWN_OFFSET);
       soundPlayer.play(YOU_LOSE);
       victoryLoop('r');
+    } else{
+      turn = turn + 1;
     }
   }
 }


now controling 3 leds with 2 chainned shif registers

--- tictactoe/tictactoe.ino
+++ tictactoe/tictactoe.ino
@@ -2,14 +2,17 @@

 Shift shift;

+//LEDs
 int red1 = 4;
 int green1 = 3;
 int red2 = 2;
 int green2 = 1;
+int red3 = 10;
+int green3 = 9;

+//Voltages for each color
 float volRedLow= 0.0;
 float volRedHigh = 1.0;
-
 float volGreenLow= 1.0;
 float volGreenHigh = 1.8;

@@ -34,6 +37,11 @@
   adjust2(voltage2);
   Serial.println(voltage2);

+  int sensorValue3 = analogRead(A7);
+  // Convert the analog reading (which goes from 0 - 1023) to a voltage (0 - 5V):
+  float voltage3 = sensorValue3 * (5.0 / 1023.0);
+  adjust3(voltage3);
+
 }

 void adjust1(float v){
@@ -51,6 +59,16 @@
     showRed2();
   }else if (v > 1.01 && v < 2.0) {
     showGreen2();
+  } else {
+    turnOff();
+  }
+}
+
+void adjust3(float v){
+  if (v < 1){
+    showRed3();
+  }else if (v > 1.01 && v < 2.0) {
+    showGreen3();
   } else {
     turnOff();
   }
@@ -80,6 +98,18 @@
   shift.writeRegisters();
 }

+void showRed3(){
+  shift.setRegisterPin(green3, LOW);
+  shift.setRegisterPin(red3, HIGH);
+  shift.writeRegisters();
+}
+
+void showGreen3(){
+  shift.setRegisterPin(green3, HIGH);
+  shift.setRegisterPin(red3, LOW);
+  shift.writeRegisters();
+}
+
 void turnOff(){
   shift.clearRegisters();
   shift.writeRegisters();


Update ncd-gateway.ino

Update ncd-gateway.ino

--- firmware/ncd-gateway.ino
+++ firmware/ncd-gateway.ino
@@ -1,8 +1,5 @@
-// This #include statement was automatically added by the Particle IDE.
 #include "i2c_comm.h"
-
-// This #include statement was automatically added by the Particle IDE.
-#include "master_gateway.h"
+#include "ncd_gateway.h"

 String ncd_firmware = "gateway:v1.0";


Added while loop

Added while loop

--- arduino/arduino.ino
+++ arduino/arduino.ino
@@ -62,39 +62,38 @@

   int incomingByte = get_next_byte();

-  if(incomingByte != -1) {
-    if(incomingByte == 58) {
-      py_log("Parsing message");
-
-      msg_length = get_next_byte();
-      command = get_next_byte();
+  if(incomingByte == 58) {
+    py_log("Parsing message");
+
+    msg_length = get_next_byte();
+    command = get_next_byte();

-      py_log("Length: " + String(msg_length));
-      py_log("Command: " + String(command));
+    py_log("Length: " + String(msg_length));
+    py_log("Command: " + String(command));

-      char message[msg_length];
-      for(int i=0; i<msg_length; i++) {
-        message[i] = get_next_byte();
-      }
+    char message[msg_length];
+    for(int i=0; i<msg_length; i++) {
+      message[i] = get_next_byte();
+    }

-      py_log("Message Parsed");
+    py_log("Message Parsed");

-      checksum = get_next_byte();
+    checksum = get_next_byte();

-      py_log("checksum: " + String(checksum));
-
-      py_log(String(message));
-    } else {
-      py_log("The incomingByte was wrong");
-    }
+    py_log("checksum: " + String(checksum));

+    py_log(String(message));
+  } else {
+    py_log("The incomingByte was wrong");
   }
 }

 int get_next_byte() {
-  int incomingByte = Serial.read();
-  if(incomingByte != -1) {
-    return incomingByte;
+  while(true) {
+    int incomingByte = Serial.read();
+    if(incomingByte != -1) {
+      return incomingByte;
+    }
   }
 }


Fix the high beam indicator

Fix the high beam indicator

--- Event_Printer/Event_Printer.ino
+++ Event_Printer/Event_Printer.ino
@@ -69,12 +69,12 @@

           case MSG_ID_ABS_Control_Module:
           {
-
+
           } break;

           case MSG_ID_ABS_Control_Module_2:
           {
-
+
           } break;

           case MSG_ID_Instrument_Cluster:
@@ -104,18 +104,18 @@

 void handle_MSG_ID_BMSK_Control_Module(unsigned char *data, unsigned char length)
 {
-    Serial.print("BMSK ");
+
 }

 void handle_MSG_ID_ZFE_Control_Module(unsigned char *data, unsigned char length)
 {
-    Serial.println("ZFE:");
+

     // HIGH BEAM
-    unsigned char hbyte7 = HI_NIBBLE(data[6]);
-    Serial.print("High beam ");
-    if( hbyte7 == 0x09 ) Serial.print("ON");
-    else if( hbyte7 == 0x0A ) Serial.print("OFF");
+    unsigned char lnibble7 = LO_NIBBLE(data[6]);
+    Serial.print("High beam ");
+    if( lnibble7 == 0x09 ) Serial.print("ON");
+    else if( lnibble7 == 0x0A ) Serial.print("OFF");
     else Serial.print("ERROR-Other");
     Serial.println("");


Forgot to update the example code

Forgot to update the example code

It was a commented test code, anyway.

--- examples/JTAGTest/JTAGTest.ino
+++ examples/JTAGTest/JTAGTest.ino
@@ -27,7 +27,7 @@

 	uint32_t n = 0;
 	while (true) {
-		//p.test_xsir(2);
+		//p.test_code(2);
 		++n;
 		if (!p.handle_next_instruction()) {
 			if (!p.reached_xcomplete()) {


Re-integrated RF message send into laundrymote_v0_2

--- laundrymote_v0_2/laundrymote_v0_2.ino
+++ laundrymote_v0_2/laundrymote_v0_2.ino
@@ -1,18 +1,45 @@
+/* -----------------------------------------------------------------------------
+   Laundry Mote Sensor
+
+   Monitors a washer and dryer.
+
+   Circuit:
+   * Moteino R4 w/ RFM69HW RF module
+   * A0 - Battery voltage monitor
+   * A1 - Light detector
+   * A2 - Temperature
+   * D3 - Water Leak detector
+
+   Created 12-APR-2015 by Jon Brule
+----------------------------------------------------------------------------- */
 #include <LowPower.h>
+#include <Message.h>
+#include <RFM69.h>
 #include <Reading.h>
+#include <SPI.h>
 #include "Sensors.h"
+
+#define VERSION    "v0.1"

 #define SERIAL     1
 #define DEBUG      1
 #define BAUD_RATE  9600

-#define VERSION    "v0.1"
+#define REPORT_PERIOD  1000 * 1000
+
+#define NODEID         7   // unique for each node on same network
+#define GATEWAYID      1
+#define NETWORKID      99  // same for all nodes that talk to each other
+#define FREQUENCY      RF69_915MHZ

 const int MOTE_LED_PIN = 9;
 const int EXTR_LED_PIN = 13;

 Sensors* sensors;
 SensorData* sensorData;
+
+RFM69 radio;
+Message inbound, outbound;

 //-----------------------------------------------------------------------------
@@ -29,6 +56,7 @@

   setupPorts();
   setupLeds();
+  setupRadio();
   setupSensors();
 }

@@ -46,6 +74,20 @@
   digitalWrite(EXTR_LED_PIN, LOW);
 }

+void setupRadio() {
+  #if DEBUG
+    Serial.print("setup radio...");
+  #endif
+
+  radio.initialize(FREQUENCY,NODEID,NETWORKID);
+  radio.setHighPower();
+  delay(1000);
+
+  #if DEBUG
+    Serial.println("ok!");
+  #endif
+}
+
 void setupSensors() {
   sensors = new Sensors();
   sensorData = new SensorData();
@@ -57,26 +99,24 @@
 //-----------------------------------------------------------------------------
 // Main Loop
 //
-void loop() {
-  enableISRs();
-  LowPower.powerDown(SLEEP_4S, ADC_OFF, BOD_OFF);
-  disableISRs();
-
+void loop() {
   sensors->measure();
   sensors->report(sensorData);
+  sendToRF((sensorData->waterLeak) ? MSG_ALERT : MSG_READING, 0);

   blink(MOTE_LED_PIN, EXTR_LED_PIN, sensorData);
+
+  sleep(sensorData);
 }

 //-----------------------------------------------------------------------------
 // Support routines
 //
-void enableISRs() {
+void sleep(SensorData* sensorData) {
   attachInterrupt(1, waterLeakChange, CHANGE);
-}
-
-void disableISRs() {
+  period_t period = (sensorData->waterLeak) ? SLEEP_1S : SLEEP_8S;
+  LowPower.powerDown(period, ADC_OFF, BOD_OFF);
   detachInterrupt(1);
 }

@@ -88,6 +128,30 @@
   digitalWrite(pin2, LOW);
 }

+// Generates a sensor report, sending it to the RF gateway
+void sendToRF(byte type, byte component) {
+  memset(&outbound, 0, sizeof(outbound));
+  outbound.msg.type = type;
+  outbound.msg.source = NODEID;
+  outbound.msg.destination = 0;
+  outbound.msg.component = component;
+  outbound.msg.rssi = 0;
+  memcpy(&outbound.msg.data, sensorData, sizeof(*sensorData));
+
+  #if DEBUG
+    Serial.print("Broadcasting report to gateway...");
+  #endif
+  if (radio.sendWithRetry(GATEWAYID, outbound.raw, MSG_LENGTH)) {
+    #if DEBUG
+      Serial.println("ACK");
+    #endif
+  } else {
+    #if DEBUG
+      Serial.println("No ACK!");
+    #endif
+  }
+}
+
 void waterLeakChange() {
   #if DEBUG
     Serial.println("WATER LEAK Change");


Set the initial value to max

Set the initial value to max

--- cv/cv.ino
+++ cv/cv.ino
@@ -10,7 +10,7 @@

 // Value to send to DAC
 volatile int value = 0;
-volatile int new_value = 500;
+volatile int new_value = 4095;

 // Used to limit the frequency of timer updates to 30 times per sec
 int old_time = 0;


Fix time window

Fix time window

--- src/lcd.ino
+++ src/lcd.ino
@@ -22,7 +22,7 @@
 double input;     // current temperature
 double output;    // for PID
 PID myPID(&input, &output, &setPoint, 2, 5, 1, REVERSE);
-int windowSize = 1000;  // 5 minutes in ms
+int windowSize = 5*60*1000;  // 5 minutes in ms
 unsigned long windowStartTime;

 // pot


switched librariy for RTC and read temp from the new clock

--- control/control.ino
+++ control/control.ino
@@ -10,7 +10,8 @@
 #include <SoftwareSerial.h>
 #include <Time.h>
 #include <TimeAlarms.h>
-#include <DS1307RTC.h>  // a basic DS1307 library that returns time as a time_t
+//#include <DS1307RTC.h>  // a basic DS1307 library that returns time as a time_t
+#include <DS3232RTC.h>  //http://github.com/JChristensen/DS3232RTC
 #include "tx433_Nexa.h" // Nexa headers
 #include <buttons.h>  // Button sensing

@@ -254,11 +255,15 @@

 void readTemp()
 {
-  float tmp = 0;
+  int temp = RTC.temperature();
+  tempC = temp / 4.0;
+  /*
+  int tmp = 0;
   for (int i=0; i < 10; i++)
-    tmp += analogRead(TEMP_PIN) / 9.31;
-
-  tempC = tmp / 10;
+    tmp += analogRead(TEMP_PIN);
+
+  tempC = (tmp / 10) / 9.31;
+  */
   }

 void digitalClockDisplay()


Return command queue status to esp.

Return command queue status to esp.

--- software/firmware/LogoBotWifiScribbler/LogoBotWifiScribbler.ino
+++ software/firmware/LogoBotWifiScribbler/LogoBotWifiScribbler.ino
@@ -163,9 +163,11 @@
     char c = Serial.read();
     if (c == '\r' || c == '\n') {
       if (cmd != "") {
-        Serial.println("OK:" + cmd);
-        //doLogoCommand(cmd);
-        pushCmd(cmd);
+        if (pushCmd(cmd))
+          Serial.println("OK:" + cmd);
+        else
+          Serial.println("BUSY");
+
         cmd = "";
       }
     } else {
@@ -226,9 +228,9 @@
   /* Official Logo Commands
        Implemented
          -FD, BK, LT, RT
-       Todo
          -PU - Pen Up
          -PD - Pen Down
+       Todo
          -ARC
    */
   /* Unofficial extensions


increased tap threshold

increased tap threshold

--- touch/touch.ino
+++ touch/touch.ino
@@ -27,7 +27,7 @@
   int diff = abs(base[2]-reading[2]);
   if (diff > 3) { // lower to increase sensitivity hight to decrease
     tap();
-    delay(200); // controlls the double tap thing high is less senistive
+    delay(300); // controlls the double tap thing high is less senistive
   }
 }


update tank.ino

update tank.ino

--- tank/src/sketch.ino
+++ tank/src/sketch.ino
@@ -66,98 +66,92 @@

 //右側モーターに関する関数
 //右のモーターを前に回転させる
-void Right_go(void){
-  digitalWrite(Right_A,HIGH);
-  digitalWrite(Right_B,LOW);
-  analogWrite(Right_PWM,MAX);
-}
-
-//右のモーターを後ろに回転させる
-void Right_back(void){
-  digitalWrite(Right_A,LOW);
-  digitalWrite(Right_B,HIGH);
-  analogWrite(Right_PWM,MAX);
+void Right_go(String val){
+  if(val != "x"){
+	int vali = atoi(val);
+	if(vali == 5){
+	  digitalWrite(Right_A,LOW);
+	  digitalWrite(Right_B,LOW);
+	}else(vali > 5){
+	  digitalWrite(Right_A,HIGH);
+	  digitalWrite(Right_B,LOW);
+	  analogWrite(Right_PWM,NOM + ((vali - 5) * 10));
+	}else{
+	  digitalWrite(Right_A,LOW);
+	  digitalWrite(Right_B,HIGH);
+	  analogWrite(Right_PWM,NOM + (-(vali - 6) * 10));
+	}
+  }
 }
-
-//右のモーターを止める
-void Right_stop(void){
-  digitalWrite(Right_A,LOW);
-  digitalWrite(Right_B,LOW);
+  //左側のモーターに関する関数
+void Left_go(String val){
+  if(val != "x"){
+	int vali = atoi(val);
+	if(vali == 5){
+	digitalWrite(Left_A,LOW);
+	digitalWrite(Left_B,LOW);
+	}else(vali > 5){
+	digitalWrite(Left_A,HIGH);
+	digitalWrite(Left_B,LOW);
+	analogWrite(Left_PWM,NOM + ((vali - 5) * 10));
+    }else{
+	digitalWrite(Left_A,LOW);
+	digitalWrite(Left_B,HIGH);
+	analogWrite(Left_PWM,NOM + (-(vali - 6) * 10));
+	}
+  }
 }
-
-//左側のモーターに関する関数
-//左のモーターを前に回転させる
-void Left_go(void){
-  digitalWrite(Left_A,HIGH);
-  digitalWrite(Left_B,LOW);
-  analogWrite(Left_PWM,MAX);
-}
-
-//左のモーターを後ろに回転させる
-void Left_back(void){
-  digitalWrite(Left_A,LOW);
-  digitalWrite(Left_B,HIGH);
-  analogWrite(Left_PWM,MAX);
-}
-
-//左のモーターを止める
-void Left_stop(void){
-  digitalWrite(Left_A,LOW);
-  digitalWrite(Left_B,LOW);
-}
-
-//砲台の上下に関する関数
+  //砲台の上下に関する関数

-void loop(){
-  while(Serial.available()){
-	ch = Serial.read();
-	switch(ch){
-	  //Car Right Moter
-	  case 'R':{
-				 do {
+  void loop(){
+	while(Serial.available()){
+	  ch = Serial.read();
+	  switch(ch){
+		//Car Right Moter
+		case 'R':{
+				   ch = Serial.read();

-				 }while(ch != '-');
-				 break;
-			   }
-			   //Car Left Moter
-	  case 'L':{
-				 do{
-				 }while(ch != '-');
-				 break;
-			   }
-			   //Car battery's servo moter
-	  case 'H':{
-				 do{
-				 }while(ch != '-');
-				 break;
-			   }
-			   //B1:Battery right moter B2:Battery left Moter B3:Firing
-	  case 'B':{
-				 ch = Serial.read();
-				 if(ch == "1"){
-				   Turn_Right();
-				   r = 1;
-				 }else{
-				   r = 0;
+				   break;
+				 }
+				 //Car Left Moter
+		case 'L':{
+				   ch = Serial.read();
+				   break;
+				 }
+				 //Car battery's servo moter
+		case 'H':{
+				   ch = Serial.read();
+
+				   break;
 				 }
-				 ch = Serial.read();
-				 if(ch == "1"){
-				   Turn_Lefti();
-				   l = 1;
-				 }else{
-				   l = 0;
+				 //B1:Battery right moter B2:Battery left Moter B3:Firing
+		case 'B':{
+				   ch = Serial.read();
+				   if(ch == "1"){
+					 Turn_Right();
+					 r = 1;
+				   }else{
+					 r = 0;
+				   }
+				   ch = Serial.read();
+				   if(ch == "1"){
+					 Turn_Lefti();
+					 l = 1;
+				   }else{
+					 l = 0;
+				   }
+				   if(r == 0 && l == 0){
+					 Turn_Stop();
+				   }
+				   ch = Serial.read();
+				   if(ch == "1"){
+
+				   }
+				   break;
 				 }
-				 if(r == 0 && l == 0){
-				   Turn_Stop();
-				 }
-				 ch = Serial.read();
-				 if(ch == "1"){
-
-				 }
-				 break;
-			   }
+	  }
 	}
   }
 }


Update the display more efficiently in the interface loop.

--- examples/seq/seq.ino
+++ examples/seq/seq.ino
@@ -197,10 +197,6 @@
     // initialize interface
     main_selected = 2;
     top_selected = 0;
-    for(uint8_t i = 0; i < 6; ++i)
-    {
-      display_changed[i] = false;
-    }
     last_gate = false;
     last_stage = 0;
     last_diradd_mode = false;
@@ -342,7 +338,7 @@
           {
             save_params(0, params.bytes, 30);
             display->fill_rect(123, 2, 3, 3, DUINO_SSD1306::Black);
-            display_changed[0] = true;
+            display->display(121, 127, 0, 0);
           }
           break;
         case 1: // top
@@ -384,6 +380,7 @@
               seq_values.stage_count = params.vals.stage_count;
               display->fill_rect(10, 12, 5, 7, DUINO_SSD1306::White);
               display->draw_char(10, 12, '0' + params.vals.stage_count, DUINO_SSD1306::Black);
+              display->display(10, 14, 1, 2);
               break;
             case 1: // dir/add
               if(v < 0)
@@ -397,6 +394,7 @@
               seq_values.diradd_mode = (bool)params.vals.diradd_mode;
               display->fill_rect(22, 12, 5, 7, DUINO_SSD1306::White);
               display->draw_char(22, 12, params.vals.diradd_mode ? 'A' : 'D', DUINO_SSD1306::Black);
+              display->display(22, 26, 1, 2);
               break;
             case 2: // slew
               params.vals.slew_rate += v;
@@ -412,6 +410,7 @@
               slew_filter->set_frequency(seq_values.slew_hz);
               display->fill_rect(60, 13, 16, 5, DUINO_SSD1306::White);
               display_slew_rate(60, 13, params.vals.slew_rate, DUINO_SSD1306::Black);
+              display->display(60, 75, 1, 2);
               break;
             case 3: // gate
               params.vals.gate_time += v;
@@ -426,6 +425,7 @@
               seq_values.gate_ms = params.vals.gate_time * (uint16_t)(seq_values.clock_period / 8000);
               display->fill_rect(85, 13, 16, 5, DUINO_SSD1306::White);
               display_gate_time(85, 13, params.vals.gate_time, DUINO_SSD1306::Black);
+              display->display(85, 100, 1, 2);
               break;
             case 4: // clock
               params.vals.clock_bpm += v;
@@ -442,9 +442,9 @@
               display->fill_rect(109, 12, 17, 7, DUINO_SSD1306::White);
               display_clock(109, 12, params.vals.clock_bpm, DUINO_SSD1306::Black);
               update_clock();
+              display->display(109, 125, 1, 2);
               break;
           }
-          display_changed[1] = true;
           break;
         case 2: // pitch
           params.vals.stage_pitch[stage_selected] += v;
@@ -459,7 +459,7 @@
           seq_values.stage_cv[stage_selected] = note_to_cv(params.vals.stage_pitch[stage_selected]);
           display->fill_rect(16 * stage_selected, 32, 16, 15, DUINO_SSD1306::White);
           display_note(16 * stage_selected, 32, params.vals.stage_pitch[stage_selected], DUINO_SSD1306::Black);
-          display_changed[3] = true;
+          display->display(16 * stage_selected, 16 * stage_selected + 15, 4, 5);
           break;
         case 3: // steps
           params.vals.stage_steps[stage_selected] += v;
@@ -475,7 +475,7 @@
           display->fill_rect(16 * stage_selected + 1, 49, 5, 7, DUINO_SSD1306::White);
           display->draw_char(16 * stage_selected + 1, 49, '0' + params.vals.stage_steps[stage_selected],
               DUINO_SSD1306::Black);
-          display_changed[4] = true;
+          display->display(16 * stage_selected + 1, 16 * stage_selected + 5, 6, 7);
           break;
         case 4: // gate
           params.vals.stage_gate[stage_selected] += v;
@@ -491,7 +491,7 @@
           display->fill_rect(16 * stage_selected + 8, 49, 7, 7, DUINO_SSD1306::White);
           display->draw_icon_7(16 * stage_selected + 8, 49, gate_mode_icons,
               (GateMode)params.vals.stage_gate[stage_selected], DUINO_SSD1306::Black);
-          display_changed[4] = true;
+          display->display(16 * stage_selected + 8, 16 * stage_selected + 14, 6, 7);
           break;
         case 5: // slew
           if(v < 0)
@@ -506,7 +506,7 @@
           display->fill_rect(16 * stage_selected + 1, 59, 14, 4, DUINO_SSD1306::Black);
           display->fill_rect(16 * stage_selected + 2 + 6 * (~(params.vals.stage_slew >> stage_selected) & 1), 60, 6, 2,
               DUINO_SSD1306::White);
-          display_changed[5] = true;
+          display->display(16 * stage_selected + 1, 16 * stage_selected + 14, 7, 7);
           break;
       }

@@ -517,7 +517,7 @@
         {
           saved = false;
           display->fill_rect(123, 2, 3, 3, DUINO_SSD1306::Black);
-          display_changed[0] = true;
+          display->display(121, 127, 0, 0);
         }
       }
     }
@@ -530,7 +530,7 @@
       display_reverse_address(30, 12);
       last_diradd_mode = seq_values.diradd_mode;
       last_reverse = reverse;
-      display_changed[1] = true;
+      display->display(30, 34, 1, 2);
     }

     // display gate
@@ -549,9 +549,11 @@
         display_gate(last_stage, DUINO_SSD1306::Black);
       }

+      display->display(16 * last_stage + 6, 16 * last_stage + 9, 3, 3);
+      display->display(16 * stage + 6, 16 * stage + 9, 3, 3);
+
       last_gate = gate;
       last_stage = stage;
-      display_changed[2] = true;
     }

     // update clock from input
@@ -560,30 +562,8 @@
       bool clock_selected = (main_selected == 1) && (top_selected == 4);
       display->fill_rect(109, 12, 17, 7, clock_selected ? DUINO_SSD1306::White : DUINO_SSD1306::Black);
       display_clock(109, 12, params.vals.clock_bpm, clock_selected ? DUINO_SSD1306::Black : DUINO_SSD1306::White);
-      display_changed[1] = true;
+      display->display(109, 125, 1, 2);
       ext_clock_received = false;
-    }
-
-    // update display
-    if(display_changed[0])
-    {
-      display->display(121, 127, 0, 0);
-    }
-    if(display_changed[1])
-    {
-      display->display(9, 126, 1, 2);
-    }
-    if(display_changed[2])
-    {
-      display->display(6, 121, 3, 3);
-    }
-    if(display_changed[3])
-    {
-      display->display(0, 127, 4, 5);
-    }
-    if(display_changed[4] || display_changed[5])
-    {
-      display->display(0, 127, display_changed[4] ? 6 : 7, 7);
     }
   }

@@ -696,44 +676,48 @@
     {
       case 0: // save
         display->fill_rect(121, 0, 7, 7, DUINO_SSD1306::Inverse);
-        display_changed[0] = true;
+        display->display(121, 127, 0, 0);
         break;
       case 1: // top
         switch(top_selected)
         {
           case 0: // count
             display->fill_rect(9, 11, 7, 9, DUINO_SSD1306::Inverse);
+            display->display(9, 15, 1, 2);
             break;
           case 1: // dir/add
             display->fill_rect(21, 11, 7, 9, DUINO_SSD1306::Inverse);
+            display->display(21, 27, 1, 2);
             break;
           case 2: // slew
             display->fill_rect(58, 11, 20, 9, DUINO_SSD1306::Inverse);
+            display->display(58, 77, 1, 2);
             break;
           case 3: // gate
             display->fill_rect(83, 11, 20, 9, DUINO_SSD1306::Inverse);
+            display->display(83, 102, 1, 2);
             break;
           case 4: // clock
             display->fill_rect(108, 11, 19, 9, DUINO_SSD1306::Inverse);
+            display->display(108, 126, 1, 2);
             break;
         }
-        display_changed[1] = true;
         break;
       case 2: // pitch
         display->fill_rect(16 * stage_selected, 32, 16, 15, DUINO_SSD1306::Inverse);
-        display_changed[3] = true;
+        display->display(16 * stage_selected, 16 * stage_selected + 15, 4, 5);
         break;
       case 3: // steps
         display->fill_rect(16 * stage_selected, 48, 7, 9, DUINO_SSD1306::Inverse);
-        display_changed[4] = true;
+        display->display(16 * stage_selected, 16 * stage_selected + 6, 6, 7);
         break;
       case 4: // gate
         display->fill_rect(16 * stage_selected + 7, 48, 9, 9, DUINO_SSD1306::Inverse);
-        display_changed[4] = true;
+        display->display(16 * stage_selected + 7, 16 * stage_selected + 15, 6, 7);
         break;
       case 5: // slew
         display->fill_rect(16 * stage_selected, 58, 16, 6, DUINO_SSD1306::Inverse);
-        display_changed[5] = true;
+        display->display(16 * stage_selected, 16 * stage_selected + 15, 7, 7);
         break;
     }
   }
@@ -753,8 +737,6 @@
   bool last_reverse;

   bool ext_clock_received;
-
-  bool display_changed[6];

   struct DU_SEQ_Parameter_Values {
     int8_t stage_pitch[8];


Fixed temperature background.

Fixed temperature background.

--- tfttask.ino
+++ tfttask.ino
@@ -250,6 +250,7 @@
       tempArea[thisSensor].y = 70 + thisSensor * 50;
       tempArea[thisSensor].w = TFT_BUTTON_WIDTH - 20;
       tempArea[thisSensor].h = 30;
+      tempArea[thisSensor].color = TFT_BACK_COLOR;
       tempArea[thisSensor].labelcolor = ILI9341_WHITE;
       tempArea[thisSensor].fontsize = size2;
       button.updateSensorLabel( tempArea[thisSensor], sensor[thisSensor].name );


temproto

temproto

--- arduino/TempProto/TempProto.ino
+++ arduino/TempProto/TempProto.ino
@@ -2,16 +2,20 @@

 ComputerSerial comp;

-void* analogTemp(byte flag, byte content[], byte contentSize){
-	int *status = (int*)malloc(sizeof(int));
-	*status = analogRead(flag < 2 ? flag : 0);
-	return status;
+void* analogTemp(byte flag, byte content[], word contentSize){
+  int *status = (int*)malloc(sizeof(int));
+  *status = analogRead(flag < 2 ? flag : 0);
+  return status;
 }

 static unsigned long bytes = 0;
 void setup(){
-	comp.begin(9600);
-	comp.attachFunction(comp.OPCODE_SENSOR, &analogTemp);
+  comp.begin(9600);
+  comp.setDeviceName("Temperature prototype");
+  comp.setDeviceVersion("2.0");
+
+  comp.attachFunction(comp.OPCODE_SENSOR, &analogTemp);
+
 }

 void loop(){
@@ -20,7 +24,8 @@

 void serialEvent(){
-	bytes += Serial.available();
-
-	comp.serialEvent();
+  bytes += Serial.available();
+
+  comp.serialEvent();
 }
+


Duino says game loop complete

Duino says game loop complete

the game loop is completed - you can play this memory game and restart it
again.

--- arduino/duinosays/duinosays.ino
+++ arduino/duinosays/duinosays.ino
@@ -104,9 +104,20 @@
     ScreenButtonId btn;
     uint16_t normalColor;
     uint16_t pressedColor;
+    bool isEnabled;
+    bool isPressed;
 public:
     Button(ScreenButtonId btn, uint8_t x, uint8_t y, uint16_t normalColor, uint16_t pressedColor):
-        x(x), y(y), btn(btn), normalColor(normalColor), pressedColor(pressedColor) {};
+        x(x), y(y), btn(btn), normalColor(normalColor), pressedColor(pressedColor), isEnabled(true) {};
+    void setEnabled(bool on) {
+        isEnabled = on;
+    }
+    uint16_t getNormalColor() {
+        return normalColor;
+    }
+    bool getIsPressed() {
+        return isPressed;
+    }
     void draw(DuinoSays *duinoSays);
 };

@@ -116,6 +127,8 @@
     uint16_t seed;
     uint16_t currentLevel;
     uint16_t currentStep;
+    uint16_t progressCounter;
+    bool isShowingColors;
     DuinoSaysGameMode mode;
     TinyScreen display;
     Button btnTopLeft;
@@ -138,6 +151,16 @@

     }

+    Button* getButton(uint8_t n) {
+        switch (n%4) {
+        case 0: return &btnTopLeft;
+        case 1: return &btnTopRight;
+        case 2: return &btnBottomLeft;
+        case 3: return &btnBottomRight;
+        }
+        return 0;
+    }
+
     void setup() {
         Wire.begin();
         display.begin();
@@ -175,13 +198,109 @@
         }
     }

+    void nextLevel() {
+        currentLevel += 1;
+        progressCounter = 0;
+        currentStep = 0;
+        isShowingColors = true;
+        btnTopLeft.setEnabled(false);
+        btnTopRight.setEnabled(false);
+        btnBottomLeft.setEnabled(false);
+        btnBottomRight.setEnabled(false);
+    }
+
     void switchToPlaying() {
         mode = DSMODE_PLAYING;
+        currentLevel = 0;
         seed = millis();
+        nextLevel();
+    }
+
+    void switchToGameOver() {
+        mode = DSMODE_GAMEOVER;
+        progressCounter = 0;
+    }
+
+
+    void switchToMainMenu() {
+        mode = DSMODE_MAINMENU;
+        setButtonsEnabled(true);
+    }
+
+    void setButtonsEnabled(bool enabled) {
+        btnTopLeft.setEnabled(enabled);
+        btnTopRight.setEnabled(enabled);
+        btnBottomLeft.setEnabled(enabled);
+        btnBottomRight.setEnabled(enabled);
+    }
+
+    uint8_t getColor(uint16_t n) const {
+        uint16_t a = seed;
+        uint16_t b = seed ^ 0x2945;
+        uint16_t c = seed << 8 | seed >> 8;
+        while (n-- > 0) {
+            a = a << 2 ^ b >> 3 ^ c << 2;
+            b = a >> 4 ^ b >> 5 ^ c >> 4;
+            c = a >> 1 ^ b >> 1 ^ c >> 6;
+        }
+        return c % 4;
     }

     void loopPlaying() {
         drawButtons();
+        if (isShowingColors) {
+            if (currentStep == 0) {
+                buffer.drawText(stringBuffer.start()->load(PSTR("duino says ..."))->get(),16,28,buffer.rgb(255,128,32), &virtualDJ_5ptFontInfo);
+            }
+            if (currentStep <= currentLevel && currentStep > 0) {
+                const uint8_t w = 4 + progressCounter, h = 4 + progressCounter;
+                uint8_t col = getColor(currentStep);
+                Button *button = getButton(col);
+                buffer.drawRect(48-w/2,32-h/2,w,h)->filledRect(button->getNormalColor());
+                buffer.drawText(stringBuffer.start()->put(currentStep)->get(),44,52,buffer.rgb(255,128,32), &virtualDJ_5ptFontInfo);
+            }
+            if (progressCounter++ > 30) {
+                currentStep += 1;
+                progressCounter = 0;
+                if (currentStep > currentLevel) {
+                    isShowingColors = false;
+                    setButtonsEnabled(true);
+                    currentStep = 1;
+                }
+            }
+        } else {
+            uint8_t col = getColor(currentStep);
+            for (uint8_t i=0;i<4;i+=1) {
+                Button *button = getButton(i);
+                if (button->getIsPressed()) {
+                    if (i == col) {
+                        currentStep+=1;
+                    } else {
+                        switchToGameOver();
+                    }
+                }
+            }
+            if (currentStep > currentLevel) {
+                nextLevel();
+            } else {
+                buffer.drawText(stringBuffer.start()->put(currentStep)->get(),44,52,buffer.rgb(255,128,32), &virtualDJ_5ptFontInfo);
+            }
+        }
+
+
+    }
+
+    void loopGameOver() {
+        buffer.drawText(stringBuffer.start()->load(PSTR("game over"))->get(),16,28,buffer.rgb(255,128,32), &virtualDJ_5ptFontInfo);
+        buffer.drawText(stringBuffer.start()->load(PSTR("score: "))->put(currentLevel)->get(),24,38,buffer.rgb(192,192,192), &virtualDJ_5ptFontInfo);
+        if (progressCounter < 50) {
+            progressCounter++;
+        } else {
+            drawButtons();
+            if (ScreenButtonState::wasAnyButtonReleased()) {
+                switchToMainMenu();
+            }
+        }
     }

     void loop() {
@@ -191,10 +310,11 @@
         static unsigned long t = millis();
         unsigned long t2 = millis();

-        buffer.drawText(stringBuffer.start()->put(t2-t)->put("ms")->get(),2,2,buffer.rgb(255,255,255), &virtualDJ_5ptFontInfo);
+        //buffer.drawText(stringBuffer.start()->put(t2-t)->put("ms")->get(),2,2,buffer.rgb(255,255,255), &virtualDJ_5ptFontInfo);
         switch (mode) {
         case DSMODE_MAINMENU: loopMainMenu(); break;
         case DSMODE_PLAYING: loopPlaying(); break;
+        case DSMODE_GAMEOVER: loopGameOver(); break;
         }

         particleSystem.draw(this);
@@ -226,8 +346,8 @@
     duinoSays->buffer.drawRect((x>>8) - width / 2,(y>>8) - height / 2,width,height)->filledRect(duinoSays->buffer.rgb(rel * r >> 8,rel * g >> 8,rel * b >> 8));
     x+=vx;
     y+=vy;
-    vx -= vx>>3;
-    vy -= vy>>3;
+    vx -= vx>>2;
+    vy -= vy>>2;
 }

 template<uint8_t maxParticles>
@@ -243,12 +363,17 @@
 }

 void Button::draw(DuinoSays* duinoSays) {
-    const bool on = ScreenButtonState::isButtonOn(btn);
-    const int width = on ? 7 : 5;
-    const int height = on ? 23 : 25;
-    duinoSays->buffer.drawRect(x - width / 2,y - height / 2,width,height)->filledRect(on ? pressedColor : normalColor);
+    const bool on = isEnabled && ScreenButtonState::isButtonOn(btn);
+    const int width = on ? 8 : 6;
+    const int height = on ? 24 : 26;
+    const int xOffset = isEnabled ? 0 : ((x > 48) * 2 - 1) * 3;
+
+    duinoSays->buffer.drawRect(x - width / 2 + xOffset,y - height / 2,width,height)->filledRect(on ? pressedColor : normalColor);
     if (on && ScreenButtonState::isButtonActivated(btn)) {
-        duinoSays->particleSystem.spawn(btn, x,y,x<48?2000:-2000,0, 16);
+        isPressed = true;
+        duinoSays->particleSystem.spawn(btn, x,y,x<48?4000:-4000,0, 8);
+    } else {
+        isPressed = false;
     }
 }


tuning the system

tuning the system

--- arduino/catdoor/catdoor.ino
+++ arduino/catdoor/catdoor.ino
@@ -11,12 +11,12 @@
 Adafruit_VCNL4010 proxim_sensor;

 #define NB_PROXIM_SAMPLES 20
-#define NB_ANOMALY_COUNTS 15
+#define NB_ANOMALY_COUNTS 9

 #define MAX_CLIENT_RETRIES 10

-uint16_t proxim_nominal = 1960;
-uint16_t proxim_anomaly = 160;
+uint16_t proxim_nominal = 2000;
+uint16_t proxim_anomaly = 240;
 uint16_t event_count = 0;

 uint16_t proxim_samples[NB_PROXIM_SAMPLES];
@@ -38,8 +38,12 @@
 void update() {
   static uint16_t counter = 0;
   static uint16_t index = 0;
+  static uint16_t printer_count = 0;
+
   uint16_t proxim_value = proxim_sensor.readProximity();
+
   if ( proxim_value > proxim_nominal + proxim_anomaly ) {
+    printer_count = 2 * 1000 / 54;    // print 2 seconds of reading
     // integrate the anomaly
     if (event_count < NB_ANOMALY_COUNTS) {
       event_count++;
@@ -53,6 +57,9 @@
   } else {
     if ( event_count > 0 ) {
       event_count--;
+    }
+    if ( printer_count > 0) {
+      printer_count--;
     }
     if ( counter == 0 ) {
       proxim_samples[index] = proxim_value;
@@ -74,6 +81,14 @@
   if ( counter >= 20 ) {
     counter = 0;
   }
+  // print to serial values around anomaly
+  if ( printer_count > 0) {
+    Serial.print("millis proxim: ");
+    Serial.print(millis());
+    Serial.print(" ");
+    Serial.println(proxim_value);
+  }
+
 }

 bool connectClient() {
@@ -194,15 +209,16 @@

 void loop() {
   static bool raised = false;
-  static uint8_t counter = 0;
+  static uint16_t counter = 0;
+  static uint16_t hearbeat_period_ticks = 30000 / 54; // average loop period = 54ms
   static unsigned long last_millis = millis();

-  // publish heartbeat
   unsigned long now_millis = millis();
   if ( now_millis - last_millis > 50 ) {
     update();
     counter++;
-    if ( counter == 200 ) {
+    if ( counter > hearbeat_period_ticks ) {
+      // publish heartbeat
       heartbeat();
       counter = 0;
     }


delete old sendData function

delete old sendData function

--- TeensyLogicAnalyzer.ino
+++ TeensyLogicAnalyzer.ino
@@ -609,110 +609,6 @@
   digitalWriteFast (LED_PIN, LOW);
 }

-void sendData (struct sumpVariableStruct sv) {
-
-   // number of pre-trigger samples beyond a byte boundary
-   const int delayCount = sv.delaySamples % sv.samplesPerByte;
-
-   // set unused channels to alternating 1's and 0's
-   byte unusedValue = 0x55;
-
-   byte value;
-   int extraCount;
-   int index;
-   int numSamplesNotInBuffer;
-   byte workingValue = 0;
-   int workingCount;
-
-  byte sampleMask = sv.sampleMask;
-  byte sampleShift = sv.sampleShift;
-  byte *inputPtr;
-
-  // swap 4 bytes
-  if (1)
-  {
-    byte temp;
-
-    for (index = 0; index < sumpSamples / sv.samplesPerByte; index = index + 4)
-    {
-      temp = logicData[index];
-      logicData[index] = logicData[index+3];
-      logicData[index+3] = temp;
-      temp = logicData[index+1];
-      logicData[index+1] = logicData[index+2];
-      logicData[index+2] = temp;
-    }
-  }
-
-   if (0)
-   {
-      byte temp;
-
-      for (index = 0; index < sumpSamples; index = index + 2)
-      {
-        temp = logicData[index];
-        logicData[index] = logicData[index+1];
-        logicData[index+1] = temp;
-      }
-   }
-
-   // if samples were limited, send bogus data to indicate it is done.
-   // Send these first since sent backwards in time
-   for (index = sumpSamples; index < sumpRequestedSamples; index = index + 2)
-   {
-      // send alternating 1's and 0's
-      Serial.write(0x55);
-      Serial.write(0xAA);
-   }
-
-   workingCount = 0;
-
-   // number of samples in the 2 extra words
-   extraCount = sv.samplesPerByte * 2;
-
-   inputPtr = sv.startPtr - 1;
-
-   // adjust for circular buffer
-   if (inputPtr >= sv.endOfBuffer) {
-      inputPtr = sv.startOfBuffer;
-   }
-
-   // send back to SUMP, backwards
-   while (1)
-   {
-      // account for wrap-around of circular buffer
-      if (inputPtr < sv.startOfBuffer) {
-         inputPtr = inputPtr + sv.bufferSize;
-      }
-
-      workingValue = *inputPtr;
-
-         for (index = 0; index < sv.samplesPerByte; index++)
-         {
-            value = (unusedValue & ~sampleMask) + (workingValue & sampleMask);
-            Serial.write(value);
-
-            workingCount++;
-            workingValue >>= sampleShift; // shift to next value
-            unusedValue = ~unusedValue;   // toggle 1's and 0's
-
-            // if done
-            if (workingCount == sumpSamples)
-            {
-               break;
-            }
-         }
-
-      // if done
-      if (workingCount == sumpSamples)
-      {
-         break;
-      }
-
-      inputPtr--;
-   }
-}
-
 ///////////
 //
 // PIT Timer routines


Switch on GPIO16

Switch on GPIO16

--- arduino/SmokeTest/SmokeTest.ino
+++ arduino/SmokeTest/SmokeTest.ino
@@ -5,7 +5,7 @@
 #define LED_RGB_GREEN 14 // D5
 #define LED_RGB_BLUE  10 // SD3
 #define SW1 2
-#define SW2 0
+#define SW2 16

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


revert my local ipaddr change

revert my local ipaddr change

--- Wikiduino/Wikiduino.ino
+++ Wikiduino/Wikiduino.ino
@@ -1,3 +1,4 @@
+
 // Copyright (c) 2011, Ward Cunningham
 // Released under MIT and GPLv2

@@ -16,8 +17,8 @@
 byte mac[] = { 0xEE, 0xAD, 0xBE, 0xEF, 0xFE, 0xED   };
 //IPAddress ip[] = { 10, 94, 54, 2   };
 //IPAddress gateway[] = { 10, 94, 54, 1 };
-IPAddress ip(192, 168, 0, 201 );
-IPAddress gateway( 192, 168, 0, 1 );
+IPAddress ip(10, 0, 3, 201 );
+IPAddress gateway( 10, 0, 3, 1 );
 IPAddress subnet( 255, 255, 255, 0 );

 EthernetServer server(1111);


commentary

commentary

--- arduino/due/due.ino
+++ arduino/due/due.ino
@@ -35,7 +35,7 @@
 void setup() {
   SerialUSB.begin(230400);
   //Pin structs take care of themselves, unless you need special modes outside arduino's libraries.
-  greenirq.attach();
+  greenirq.attach();//we don't build in attach() to the constructor as in many cases the isr needs stuff that isn't initialized until setup() is run.
 }

 void loop() {


Misc fixes

Misc fixes

--- MStation/MStation.ino
+++ MStation/MStation.ino
@@ -1,11 +1,12 @@
 //
 //    FILE: MStation.ino
 //  AUTHOR: Edgar Cherkasov
-// VERSION: 0.1.1
+// VERSION: 0.1.2
 // PURPOSE: Code for DIY meteostation
 //     URL:
 //
-// Released to the public domain
+// Released under MIT License
+// See LICENSE.md
 //

 #include <dht.h>
@@ -143,7 +144,7 @@
     //lcd.print("Humid: ");
     lcd.print("\x42\xBB\x61\xB6\xBD"": ");
     lcd.print((int) DHT.humidity);
-    lcd.print(" %");
+    lcd.print(" %%");
   }
 }

@@ -170,7 +171,7 @@
     return false;
   }

-  ds18_temp = ((data[1] << 8) + data[0])*0.0625; // convert temperaturen
+  ds18_temp = ((data[1] << 8) | data[0]) * 0.0625; // convert temperature

   return true;
 }


move inappropriate defines to SALT_JX, use new J_data struct, remove extraneous

--- examples/PCA9557_J2/PCA9557_J2.ino
+++ examples/PCA9557_J2/PCA9557_J2.ino
@@ -31,66 +31,6 @@
 #include <SALT_FETs.h>
 #include <NAP_pod_load_defs.h>

-/**
- * These are the addresses of the I2C devices which drive the related
- * Core DB15 connector and the Core FETs
- * @TODO make these addresses manifest constants in some appropriate way; put them in a common .h file somewhere if they are needed in more than one file
- */
-#define I2C_J2 0x1B
-#define I2C_J3 0x1A
-#define I2C_J4 0x19
-
-// TODO: move to common .h file
-#define JX_LED_ON	false		// yes, opposite to the other bits.  writing a 1 to the 9557 output register
-#define JX_LED_OFF	true		// turns the output FET OFF
-
-
-/**
- *  These are signal names specific to our custom SALT2 hardware; TODO: move to common .h file
- */
-
-// SALT2 Core SDOUT on J2,3,4 pins 1/2 to '595 SDIN of DC and AC boards: 9557 IO7, 0x80
-// output from 9557 to '595 Din
-#define SDOUT BIT7 	// 0x80
-
-// SALT2 Core SCLK on J2,3,4 pins 5/6 to '595 and '165 SCLK of DC and AC boards: 9557 IO6, 0x40,
-// serial clock, used by both 595 and 165
-#define SCLK BIT6	// 0x40
-
-// SALT2 J2,3,4 pins 9/10 to '165 Shift/Load of DC boards: Core SH/LD is 9557 IO5, 0x20
-// SHIFT(H), LOAD(L) only used by DC board '165
-#define SHIFT165 BIT5	// 0x20
-
-// SALT2 Core SDIN on J2,3,4 pins 3/4 from '165 SDOUT of DC boards: 9557 IO4, 0x10
-// input to 9577 from '165 Qout
-#define SDIN BIT4	// 0x10
-
-// SALT2 RCLK on J2,3,4 pins 7/8 to DC and AC boards '595 RCLK: 9557 IO3, 0x08
-// only used by '595, must idle high
-#define RCLK595 BIT3	// 0x08
-
-// bits 1 and 2 (0x02, 0x04) not connected
-
-// SALT2 yellow LED for J2,3,4 intended to show activity on that port: 9557 IO0, 0x01
-// open drain, SETTING (yes, opposite to the other bits) this bit drives output low = LED on
-#define LED BIT0	// 0x01
-
-
-
-
-/**
- *  bit 5 is input; bits 2 and 1 are not connected, Bit 0 is the activity LED for that device
- *  so this mask has a '1' for every bit which is used as output
- *  Note: enclosing parentheses are required to force the '~' operator to operate on the whole quantity
- *  not just the first manifest constant! TODO: move to common .h file
- */
-#define OUTMASK (RCLK595 | SCLK | SDOUT | SHIFT165 | LED)
-
-/**
- *  Only one actual input, serial data in; TODO: move to common .h file
- */
-#define INMASK (SDIN)
-
 #ifdef USE_CLASS
 SALT_JX coreJ2 (2);
 //SALT_JX coreJ3 (3);
@@ -99,6 +39,7 @@
 extern void J2_update (void);
 extern void J3_update (void);
 extern void J4_update (void);
+extern void JX_init (void);
 extern struct J_data J2_data, J3_data, J4_data;
 #endif

@@ -108,18 +49,9 @@
 Systronix_PCA9557 coreJ3reg(I2C_J3);
 Systronix_PCA9557 coreJ4reg(I2C_J4);

-
-
 // TODO: move to common .h file as #defines;
 uint8_t periph_rst = 22;	// peripheral reset asserted LOW to PCA9557, etc on board
 uint8_t ether_rst = 8;		// Wiznet module reset LOW
-
-//struct J_data
-//	{
-//	uint32_t	DC_data_in;			// data read from the DC board '165 shift register
-//	uint16_t	AC_data_out;		// data sent to the AC board; send this before sending DC
-//	uint16_t	DC_data_out;		// data sent to the DC board
-//	} J2_data , J3_data, J4_data;

 //---------------------------< S E T U P >--------------------------------------------------------------------
@@ -148,16 +80,15 @@
 	/**
 	* Start, now inits invert and output bit enable, clears outputs
 	*/
-	coreJ2reg.begin();
+	coreJ2reg.begin();	// join I2C as master
 	coreJ3reg.begin();
 	coreJ4reg.begin();
-//	coreFETreg.begin();

 	// outmask, outdata, inputinvert
-//	coreJ2reg.init(OUTMASK, (SCLK | RCLK595 | LED), 0);
-//	coreJ3reg.init(OUTMASK, (SCLK | RCLK595 | LED), 0);
-//	coreJ4reg.init(OUTMASK, (SCLK | RCLK595 | LED), 0);
-
+//	coreJ2reg.init(OUTMASK, LED, 0);	// all outputs low, LED off
+//	coreJ3reg.init(OUTMASK, LED, 0);
+//	coreJ4reg.init(OUTMASK, LED, 0);
+	JX_init();			// initialize the three JX 9557 registers
 	coreFETs.init ();

 #ifdef USE_CLASS
@@ -170,29 +101,25 @@
 	coreJ2.update ();					// do it
 //	coreJ3.update (coreJ3reg);			// do it
 //	coreJ3.update (coreJ4reg);			// do it
-	coreJ2.AC_data_out = 0x8000;	// setup for walking-ones test
-//	coreJ3.AC_data_out = 0x8000;	// setup for walking-ones test
-//	coreJ3.AC_data_out = 0x8000;	// setup for walking-ones test
+	coreJ2.AC_data_out = 0x8000;		// setup for walking-ones test
+//	coreJ3.AC_data_out = 0x8000;		// setup for walking-ones test
+//	coreJ3.AC_data_out = 0x8000;		// setup for walking-ones test
 #else
-	J2_data.AC_data_out = 0;				// clear DC and AC 595 registers
-	J2_data.DC_data_out = 0;
-	J3_data.AC_data_out = 0;				// clear DC and AC 595 registers
-	J3_data.DC_data_out = 0;
-	J4_data.AC_data_out = 0;				// clear DC and AC 595 registers
-	J4_data.DC_data_out = 0;
+	J2_data.outdata.as_word = 0;		// clear DC and AC 595 registers
+	J3_data.outdata.as_word = 0;
+	J4_data.outdata.as_word = 0;

-	J2_update ();					// do it
-	J3_update ();					// do it
-	J4_update ();					// do it
+	J2_update ();						// do it
+	J3_update ();						// do it
+	J4_update ();						// do it

-	J2_data.AC_data_out = 0x8000;	// setup for walking-ones test
-	J3_data.AC_data_out = 0x8000;	// setup for walking-ones test
-	J4_data.AC_data_out = 0x8000;	// setup for walking-ones test
+	J2_data.outdata.as_word = 0x80000000;	// setup for walking-one test
+	J3_data.outdata.as_word = 0x80000000;
+	J4_data.outdata.as_word = 0x80000000;
+
 #endif
-	coreFETs.FET_settings = 0x80;	// init for walking one test
+	coreFETs.FET_settings = 0x80;		// init for walking-one test
 	}
-
-//	uint8_t fet_test = 0x80;

 //---------------------------< L O O P >----------------------------------------------------------------------
@@ -204,17 +131,11 @@
 	else
 		coreFETs.FET_settings <<= 1;

-//	coreFETreg.pin_drive ((fet_test | LED), HIGH);		// HIGH turn the LED off and the FET on
 	coreFETs.update();		// update the fets
 	delay(20);

 	coreFETs.update();		// update the fets
-//	coreFETs.LED_off ();	// turn off the 9557 LED
 	delay(1000);
-
-//	coreFETreg.pin_drive ((fet_test | LED), LOW);		// LOW turn the LED on and the FET off
-//	coreFETs.update();		// turn off the LED
-

 	Serial.print("------INPUT------0x");

@@ -253,37 +174,22 @@
 	Serial.println(coreJ2.DC_data_in, HEX);

 #else
-	if (0x8000 & J2_data.AC_data_out)			// when the '1' is in the MSB (bit 31)
+	if (0x80000000 & J2_data.outdata.as_word)		// when the '1' is in the MSB (bit 31) (AC data)
 		{
-		J2_data.AC_data_out = 0;				// clear so there is only one '1'
-		J2_data.DC_data_out = 1;				// shift the '1' to lsb of DC data
-		J3_data.AC_data_out = 0;				// clear so there is only one '1'
-		J3_data.DC_data_out = 1;				// shift the '1' to lsb of DC data
-		J4_data.AC_data_out = 0;				// clear so there is only one '1'
-		J4_data.DC_data_out = 1;				// shift the '1' to lsb of DC data
-		}
-	else if (0x8000 & J2_data.DC_data_out)		// when the '1' is in the DC board's MSB (bit 15)
-		{
-		J2_data.AC_data_out = 1;				// shift the '1' to lsb of DC data
-		J2_data.DC_data_out = 0;				// clear so there is only one '1'
-		J3_data.AC_data_out = 1;				// shift the '1' to lsb of DC data
-		J3_data.DC_data_out = 0;				// clear so there is only one '1'
-		J4_data.AC_data_out = 1;				// shift the '1' to lsb of DC data
-		J4_data.DC_data_out = 0;				// clear so there is only one '1'
+		J2_data.outdata.as_word = 1;		// shift the '1' to lsb of DC data
+		J3_data.outdata.as_word = 1;
+		J4_data.outdata.as_word = 1;
 		}
 	else
 		{
-		J2_data.AC_data_out <<= 1;			// shift both registers toward msb
-		J2_data.DC_data_out <<= 1;
-		J3_data.AC_data_out <<= 1;			// shift both registers toward msb
-		J3_data.DC_data_out <<= 1;
-		J4_data.AC_data_out <<= 1;			// shift both registers toward msb
-		J4_data.DC_data_out <<= 1;
+		J2_data.outdata.as_word <<= 1;		// shift both registers toward msb
+		J3_data.outdata.as_word <<= 1;
+		J4_data.outdata.as_word <<= 1;
 		}

-	J2_update ();						// do it
-	J3_update ();						// do it
-	J4_update ();						// do it
+	J2_update ();							// do it
+	J3_update ();							// do it
+	J4_update ();							// do it
 	Serial.println(J4_data.DC_data_in, HEX);
 #endif


examples/PubNubJson: Tighten msgStr memory buffer

--- examples/PubNubJson/PubNubJson.ino
+++ examples/PubNubJson/PubNubJson.ino
@@ -146,6 +146,11 @@
 	aJsonObject *msg = createMessage();
 	char *msgStr = aJson.print(msg);
 	aJson.deleteItem(msg);
+
+	// msgStr is returned in a buffer that can be potentially
+	// needlessly large; this call will "tighten" it
+	msgStr = (char *) realloc(msgStr, strlen(msgStr) + 1);
+
 	Serial.println(msgStr);
 	client = PubNub.publish(channel, msgStr);
 	free(msgStr);


Control send rate

Control send rate

--- arduino/arduino.ino
+++ arduino/arduino.ino
@@ -1,47 +1,27 @@
-/*
-  Web Server
-
- A simple web server that shows the value of the analog input pins.
- using an Arduino Wiznet Ethernet shield.
-
- Circuit:
- * Ethernet shield attached to pins 10, 11, 12, 13
- * Analog inputs attached to pins A0 through A5 (optional)
-
- created 18 Dec 2009
- by David A. Mellis
- modified 9 Apr 2012
- by Tom Igoe
-
- */
-
 #include <SPI.h>
 #include <Ethernet.h>

 // Enter a MAC address and IP address for your controller below.
 // The IP address will be dependent on your local network:
-byte mac[] = {
-  0xDE, 0xAD, 0xBE, 0xEF, 0xFE, 0xED
-};
+byte mac[] = { 0xDE, 0xAD, 0xBE, 0xEF, 0xFE, 0xED };

+// Arduino IP
 IPAddress ip(192, 168, 2, 15);

 // Google DNS
 IPAddress myDns(8, 8, 8, 8);

-// Initialize the Ethernet server library
-// with the IP address and port you want to use
-// (port 80 is default for HTTP):
-// EthernetServer server(80);
-
 char serverName[] = "smart-trash.app.hackinpoa.tsuru.io";

 EthernetClient sendClient;

-unsigned long lastConnectionTime = 0;             // last time you connected to the server, in milliseconds
-const unsigned long postingInterval = 10L * 1000L; // Every second (10000)
+// Variaveis que controlam o ultimo envio da porta
+int sensor0 = 0;
+int sensor1 = 0;
+float diff = 5;

-String postData;
+// Indica que pode ser enviado uma nova requisicao
+boolean readyToSend = false;

 void setup() {
   // Open serial communications and wait for port to open:
@@ -50,91 +30,55 @@
     ; // wait for serial port to connect. Needed for Leonardo only
   }

-
   // start the Ethernet connection and the server:
   Ethernet.begin(mac, ip, myDns);
-  //server.begin();
-  //Serial.print("server is at ");
   Serial.println(Ethernet.localIP());
+  readyToSend = true;
 }
-

 void loop() {

   readResponse();
+
+  float s0 = analogRead(0);
+  float v0 = abs(sensor0 - s0);
+
+  if(v0 > diff && readyToSend == true) {
+    Serial.println(String(v0));
+    readyToSend = false;
+    sensor0 = s0;
+    httpRequest(0, sensor0);
+  }
+
+  float s1 = analogRead(1);
+  float v1 = abs(sensor1 - s1);
+
+  if(v1 > diff && readyToSend == true) {
+    readyToSend = false;
+    sensor1 = s1;
+    httpRequest(1, sensor1);
+  }

-  // listen for incoming clients
-  /*
-  EthernetClient client = server.available();
-  if (client) {
-    Serial.println("new client");
-    // an http request ends with a blank line
-    boolean currentLineIsBlank = true;
-    while (client.connected()) {
-      if (client.available()) {
-        char c = client.read();
-        Serial.write(c);
-        // if you've gotten to the end of the line (received a newline
-        // character) and the line is blank, the http request has ended,
-        // so you can send a reply
-        if (c == '\n' && currentLineIsBlank) {
-          // send a standard http response header
-          client.println("HTTP/1.1 200 OK");
-          client.println("Content-Type: text/html");
-          client.println("Connection: close");  // the connection will be closed after completion of the response
-          client.println("Refresh: 5");  // refresh the page automatically every 5 sec
-          client.println();
-          client.println("<!DOCTYPE HTML>");
-          client.println("");
-          // output the value of each analog input pin
-          for (int analogChannel = 0; analogChannel < 6; analogChannel++) {
-            int sensorReading = analogRead(analogChannel);
-            client.print("analog input ");
-            client.print(analogChannel);
-            client.print(" is ");
-            client.print(sensorReading);
-            client.println("
");
-          }
-          client.println("");
-          break;
-        }
-        if (c == '\n') {
-          // you're starting a new line
-          currentLineIsBlank = true;
-        }
-        else if (c != '\r') {
-          // you've gotten a character on the current line
-          currentLineIsBlank = false;
-        }
-      }
-    }
-    // give the web browser time to receive the data
-    delay(1);
-    // close the connection:
-    client.stop();
-    Serial.println("client disconnected");
-  }
-  */
-
-  // if ten seconds have passed since your last connection,
-  // then connect again and send data:
-  if (millis() - lastConnectionTime > postingInterval) {
-    httpRequest(0, analogRead(0));
-  }
 }

 void readResponse() {
   //Read http response
   if (sendClient.available()) {
     char c = sendClient.read();
-    Serial.write(c);
+    //Serial.write(c);
+  }
+
+  if (readyToSend == false && sendClient.connected() == false) {
+    Serial.println("end of connection");
+    readyToSend = true;
   }
 }

 // this method makes a HTTP connection to the server:
 void httpRequest(int sensor, int value) {
-  Serial.println("sending...");
-
+
+  Serial.println("sending: sensor = " + String(sensor) + " - value = " + String(value) + " ...");
+
   // close any connection before send a new request.
   // This will free the socket on the WiFi shield
   sendClient.stop();
@@ -143,32 +87,23 @@

   // if there's a successful connection:
   int connected = sendClient.connect(serverName, 80);
+
   if (connected) {
-    Serial.println("connected");
+    Serial.println("connected...");
     // send the HTTP PUT request:
     sendClient.println("GET " + path + " HTTP/1.1");
     sendClient.println("Host: smart-trash.app.hackinpoa.tsuru.io");
     sendClient.println("User-Agent: arduino-ethernet");
     sendClient.println("Connection: close");
     sendClient.println();
+
+    Serial.println("sent...");

-    Serial.println("sent");
-
-    //sendClient.print("Content-Length: ");
-    //sendClient.println(postData.length());
-    //sendClient.println();
-    //sendClient.println(postData);
-    // sendClient.println();
-
-    // note the time that the connection was made:
-    lastConnectionTime = millis();
-
-    // give time to se
-    //delay(1);
   }
   else {
     // if you couldn't make a connection:
-    Serial.println("connection failed" + String(connected));
+    Serial.println("connection failed : error = " + String(connected));
+    readyToSend = true;
   }
 }


Add battery health check

Add battery health check

--- home_02_garage/home_02_garage.ino
+++ home_02_garage/home_02_garage.ino
@@ -29,6 +29,9 @@
 const int DOOR_CLOSED = LOW;   // Door closed when LOW
 const int DIO_OFFSET = 3;      // DIO is port num + 3

+// global variables
+int batt_loop_count = 99;      // Make high so we get data first time
+int has_lowbat = false;        // Start out assuming it's fine

 // Basic macro for debugging
 // Ideally change this to a function once I figure out how to accept anything
@@ -97,13 +100,23 @@
 }

+// Payload consists of 5 words:
+// - Is battery low? (will be 1 if so)
+// - Values from each of the 4 ports
 void loop() {
   float tempc = 0;
   int door_status_4 = digitalRead(DIO4);
-  word payload[4] = {0,0,0,0};
+  word payload[5] = {0,0,0,0,0};

-  // 4th word is index 3
-  payload[3] = door_status_4;
+  // Update low battery every 30 minutes
+  // TODO: Does this even save power?
+  if (batt_loop_count >= 30) {
+    has_lowbat = rf12_lowbat();
+    batt_loop_count = 0;
+  }
+  else {
+    batt_loop_count++;
+  }

 #ifdef DEBUG
   if (door_status_4 == DOOR_OPEN) {
@@ -116,8 +129,11 @@

   tempc = get_temperature(temp_dev1);
   DEBUG_PRINT(tempc);
-  payload[0] = int(tempc * 100);

+  payload[0] = has_lowbat;
+  payload[1] = int(tempc * 100);
+  payload[4] = door_status_4;
+
   rf12_sleep(RF12_WAKEUP);
   rf12_sendNow(JEELINK_ID, &payload, sizeof payload);
   rf12_sendWait(2);


Updates xadow-watch to use new millis* types

--- xadow-watch.ino
+++ xadow-watch.ino
@@ -5,6 +5,7 @@
 #include "SGL.h"
 #include "SSD1331.h"

+#include "defs.h"
 #include "xadow.h"

 // These are arduino pin definitions. Note that on leonardo
@@ -21,6 +22,7 @@

 #define SLEEP_TIME_MS       (250)

+
 SSD1331 oled = SSD1331(cs, dc, mosi, sclk);

 char *test_menu[] = {"hello", "world", "here be", "dragons", NULL};
@@ -28,8 +30,14 @@
 char _sbuf[256];
 char _sbuf2[64];

-uint16_t now = 0;
-uint16_t checkpoint;
+millis_t now = 0;
+millis_t checkpoint;
+
+typedef enum {
+  OK,
+  ERROR,
+  ERROR_SYNC_TIMEOUT,
+};

 typedef enum {
   SCREEN_WATCH,
@@ -120,7 +128,7 @@
   }

-  uint16_t t = millis();
+  millis_t t = millis();
   now += t - checkpoint;
   checkpoint = t;
 }


added cool sideways messages

added cool sideways messages

--- display/display.ino
+++ display/display.ino
@@ -39,11 +39,17 @@
 Button alarm_button = Button(0,BOXSIZE*3,BOXSIZE,BOXSIZE,ILI9341_MAGENTA,true,&tft);

 // Create ECG trace
-ECGReadout ecg = ECGReadout(0,60,tft.height(), tft.width()/2, 15 , 500, &tft);
+ECGReadout ecg = ECGReadout(10,60,tft.height(), tft.width()/2, 15 , 500, &tft);

 /*
  * draw_submenu() - draws color box submenu on left of screen
  */
+
+ //Write labels
+char ecgLabel[4] = "ECG";
+char satLabel[5] = "sp02";
+
+//old model interface
 void draw_submenu() {
 	hr_button.draw();
 	sp_button.draw();
@@ -60,6 +66,9 @@
   tft.println("Texas Engineering World Health");
   tft.setCursor(BOXSIZE + 40, 10);
   tft.println("Patient Monitor v1.0");
+  tft.drawFastVLine(BOXSIZE + 17, 0, 20, ILI9341_WHITE);
+  tft.drawFastHLine(BOXSIZE + 17, 20, 185, ILI9341_WHITE);
+  tft.drawFastVLine(BOXSIZE + 202, 0, 20, ILI9341_WHITE);
 }

 /*
@@ -74,6 +83,19 @@
 	//draw_submenu();
 }

+void label_setup(int y_coord, char* letter){
+  while(*letter){
+    tft.setCursor(0,y_coord);
+    tft.printf("%c", *letter);
+    letter += 1;
+    y_coord += 8;
+  }
+}
+void ECG_setup(){
+  tft.setCursor(BOXSIZE + 55, 30);
+  tft.setTextSize(1);
+  tft.println("HR (bpm) - ECG");
+}
 void clearScreen(int color){
     tft.fillRect(BOXSIZE,0,tft.width()-BOXSIZE,tft.height(),color);
 }
@@ -81,6 +103,11 @@
 void setup(void){
   gui_setup();
   product_title();
+  ECG_setup();
+  tft.setTextColor(ILI9341_MAGENTA);
+  label_setup(65, ecgLabel);
+  tft.setTextColor(ILI9341_MAGENTA);
+  label_setup(95, satLabel);
 }

 void loop(void) {


implement OLED graphics command string and splash screen use reduced font (only 0x20-0x7f glyphs)

--- ksp-gegi-microusb/ksp-gegi-microusb.ino
+++ ksp-gegi-microusb/ksp-gegi-microusb.ino
@@ -190,7 +190,6 @@
   // while (!Serial);
   // set timeout to 200ms
   Serial.setTimeout(200);
-  // start blink counter
   lcd.begin(16,2);   // initialize the lcd for 16 chars 2 lines, turn on backlight
   lcd.setCursor(0,0);
   lcd.print("KSP-Gegi");
@@ -198,6 +197,8 @@
   lcd.print("Ready for action");
   // joystick setup
   Joystick.begin(true);	// do auto send state
+  // show something on OLED
+  oledRedraw();
   // request status update
   Serial.println("I");
 }
@@ -242,6 +243,126 @@
   }
 }

+#define OLEDBUFSIZE 512
+// initialization stuff
+uint8_t oledBuf[OLEDBUFSIZE+1] = { 0x01,0x00,0x20,0x4b,0x53,0x50,0x2d,0x47,0x65,0x67,0x69,0x00,
+  0x01,0x00,0x30,0x52,0x65,0x61,0x64,0x79,0x20,0x66,0x6F,0x72,0x20,0x61,0x63,0x74,0x69,0x6F,0x6E,0x00,
+  7,128,0,0,15,7,128,0,32,15,7,128,0,64,15,
+  7,128,64,0,49,7,128,64,32,49,7,128,64,64,49,
+  0x00 };
+
+// OLED commands
+#define OLED_DRAW_STOP  0
+#define OLED_DRAW_STR   1 // followed by x y string\, like "Line2\"
+#define OLED_DRAW_BOX   2 // followed by x y width height
+#define OLED_DRAW_FRAME 3 // followed by x y width height
+#define OLED_DRAW_PIXEL 4 // followed by x y
+#define OLED_DRAW_HLINE 5 // followed by x y width
+#define OLED_DRAW_VLINE 6 // followed by x y height
+#define OLED_DRAW_LINE  7 // followed by x1 y1 x2 y2
+
+void drawOLED(void) {
+  // graphic commands to redraw the complete screen should be placed here
+  u8g.setFont(u8g_font_unifontr); // reduced font, only glyphs 0x20-0x7f
+  uint8_t i=0;
+  uint8_t cmd, x, y, w, h, x2, y2;
+  while ((i<OLEDBUFSIZE) && oledBuf[i]!=0) {
+    cmd = oledBuf[i++];
+    if (OLED_DRAW_STOP==cmd) break; // stop immediately if commanded
+    x=oledBuf[i++]; y=oledBuf[i++];
+//    Serial.print("cmd"); Serial.print(cmd); Serial.print(" x="); Serial.print(x); Serial.print(" y="); Serial.println(y);
+    switch(cmd) {
+        case OLED_DRAW_STR:
+//          Serial.print("["); Serial.print((const char*)&oledBuf[i]); Serial.println("]");
+          u8g.drawStr(x,y,(const char*)&oledBuf[i]);
+          // skip to the end of string;
+          while (i<OLEDBUFSIZE && oledBuf[i]!=0) {
+            i++;
+          }
+          i++; // skip past ending 0
+          break;
+        case OLED_DRAW_BOX:
+          w = oledBuf[i++]; h = oledBuf[i++];
+//          Serial.print("w="); Serial.print(w); Serial.print(" h="); Serial.println(h);
+          u8g.drawBox(x,y,w,h);
+          break;
+        case OLED_DRAW_FRAME:
+          w = oledBuf[i++]; h = oledBuf[i++];
+//          Serial.print("w="); Serial.print(w); Serial.print(" h="); Serial.println(h);
+          u8g.drawFrame(x,y,w,h);
+          break;
+        case OLED_DRAW_PIXEL:
+          u8g.drawPixel(x,y);
+          break;
+        case OLED_DRAW_HLINE:
+          w = oledBuf[i++];
+//          Serial.print("w="); Serial.println(w);
+          u8g.drawHLine(x,y,w);
+          break;
+        case OLED_DRAW_VLINE:
+          h = oledBuf[i++];
+//          Serial.print("h="); Serial.println(h);
+          u8g.drawVLine(x,y,h);
+          break;
+        case OLED_DRAW_LINE:
+          x2 = oledBuf[i++]; y2 = oledBuf[i++];
+//          Serial.print("x2="); Serial.print(x2); Serial.print(" y2="); Serial.println(y2);
+          u8g.drawLine(x,y,x2,y2);
+          break;
+    }
+  }
+}
+
+// read a string of gfx commands and keep them in a buffer so drawOLED() can use them
+// test:
+// O3 0 0 10 16 3 10 0 10 24 3 0 16 127 16 4 23 23 5 15 55 100 6 64 15 70 7 15 15 120 90 1 0 16 Line1\ 1 0 32 Line2\ 1 0 48 Line3\ 7 120 15 15 90
+// O7,128,0,0,15,7,128,0,32,15,7,128,0,64,15,7,128,64,0,48,7,128,64,32,48,7,128,64,64,48,1,0,32,KSP\,1,0,48,Ready\
+void handleSerialInputOLED() {
+  uint8_t i=0;
+  uint8_t cmd, c;
+//  Serial.println("OLEDstart");
+  while ((i<OLEDBUFSIZE) && (Serial.available()>0) && (Serial.peek()!= '\n')) {
+    cmd = Serial.parseInt();
+    oledBuf[i++] = cmd;
+    oledBuf[i++] = Serial.parseInt(); // x
+    oledBuf[i++] = Serial.parseInt(); // y
+    switch(cmd) {
+        case OLED_DRAW_STR:
+          Serial.read();  // skip separator
+          while (i<OLEDBUFSIZE) {
+            while (Serial.available()==0) { };
+            c = Serial.read();
+            if (c == '\\') break; // end marker
+            oledBuf[i++] = c;
+          }
+          oledBuf[i++] = '\0'; // string terminator
+          break;
+        case OLED_DRAW_BOX:
+        case OLED_DRAW_FRAME:
+        case OLED_DRAW_LINE:
+          oledBuf[i++] = Serial.parseInt(); // read two more bytes (one here, one below)
+        case OLED_DRAW_HLINE:
+        case OLED_DRAW_VLINE:
+          oledBuf[i++] = Serial.parseInt(); // read one more byte
+        case OLED_DRAW_STOP:
+        case OLED_DRAW_PIXEL:
+          break;
+    }
+  }
+  oledBuf[i]=0; // command string terminator
+//  Serial.println("OLEDredraw");
+  oledRedraw();
+//  Serial.println("OLEDend");
+}
+
+void oledRedraw() {
+  // redraw screen
+  u8g.firstPage();
+  do {
+    drawOLED();
+  } while( u8g.nextPage() );
+}
+
 // called after UART slave reports button press/release
 // map switch IDs to joystick buttons
 void handleSlaveButton(const uint8_t id, const uint8_t state) {
@@ -301,6 +422,9 @@
     }
     else if (c == 'P') {
       handleSerialInputLCD();
+    }
+    else if (c == 'O') {
+      handleSerialInputOLED();
     }
     else if ((c == 'R') & (Serial.peek()=='\n')) {
       handleStatusReset();
@@ -349,53 +473,10 @@
   }
 }

-uint8_t offset = 0;
-
-void draw(void) {
-  // graphic commands to redraw the complete screen should be placed here
-  u8g.setFont(u8g_font_unifont);
-  u8g.drawStr( 0+0, 20+0, "Hello!");
-  u8g.drawStr( 0+2, 20+16, "Hello!");
-
-  u8g.drawBox(0, 0, 17, 17);
-  u8g.drawBox(u8g.getWidth()-20, 0, 3, 3);
-  u8g.drawBox(u8g.getWidth()-9, u8g.getHeight()-9, 9, 9);
-  u8g.drawBox(0, u8g.getHeight()-12, 12, 12);
-}
-
-void rotate(void) {
-  static  uint8_t dir = 0;
-  static  unsigned long next_rotation = 0;
-
-  if ( next_rotation < millis() )
-  {
-    switch(dir) {
-      case 0: u8g.undoRotation(); break;
-      case 1: u8g.setRot90(); break;
-      case 2: u8g.setRot180(); break;
-      case 3: u8g.setRot270(); offset = ( offset + 1 ) & 0x0f; break;
-    }
-
-    dir++;
-    dir &= 3;
-    next_rotation = millis();
-    next_rotation += 1000;
-  }
-}
-
 void loop() {
   checkSerialInputUSBtoUART();
   checkSerialInputUARTtoUSB();
   updatePins(false);
   updateAnalogs(false);
-  delay(50);
-  // screen rotation
-  rotate();
-
-  // picture loop
-  u8g.firstPage();
-  do {
-    draw();
-  } while( u8g.nextPage() );
-}
-
+}
+


COH-80: WIP

COH-80: WIP

--- COHEAT2015/20160316-COHEAT-M1/COHEAT-M1/COHEAT-M1.ino
+++ COHEAT2015/20160316-COHEAT-M1/COHEAT-M1/COHEAT-M1.ino
@@ -351,10 +351,7 @@
 #else
   uint8_t key[16];
   if(!OTV0P2BASE::getPrimaryBuilding16ByteSecretKey(key))
-    {
-    OTV0P2BASE::serialPrintlnAndFlush("!TX key");
-    return(false); // Failed.
-    }
+    { OTV0P2BASE::serialPrintlnAndFlush("!TX key"); return(false); } // FAIL
   const OTRadioLink::SimpleSecureFrame32or0BodyTXBase::fixed32BTextSize12BNonce16BTagSimpleEnc_ptr_t e = OTAESGCM::fixed32BTextSize12BNonce16BTagSimpleEnc_DEFAULT_STATELESS;
   uint8_t buf[OTRadioLink::SimpleSecureFrame32or0BodyTXBase::generateSecureBeaconMaxBufSize];
   const uint8_t bodylen = secureTXState.generateSecureBeaconRawForTX(buf, sizeof(buf), lenTXID, e, NULL, key); // 2 byte ID.
@@ -579,9 +576,7 @@
   // Get the 'building' key.
   if(!OTV0P2BASE::getPrimaryBuilding16ByteSecretKey(key))
     {
-#if 1 && defined(DEBUG)
-DEBUG_SERIAL_PRINTLN_FLASHSTRING("!RX key");
-#endif
+    DEBUG_SERIAL_PRINTLN_FLASHSTRING("!RX key");
     return; // FAIL
     }
   // Attempt to authenticate (and decrypt) the frame before inspecting content.
@@ -735,15 +730,34 @@
           // TODO: may need to insert a delay to allow hub to be ready if use of read() above is not enough.
           uint8_t txbuf[OTProtocolCC::CC1PollResponse::primary_frame_bytes+1]; // More than large enough for preamble + sync + alert message.
           const uint8_t bodylen = r.encodeSimple(txbuf, sizeof(txbuf), true);
-#if 0 && defined(DEBUG)
-OTRadioLink::printRXMsg(p, txbuf, bodylen);
-#endif
-          if(PrimaryRadio.sendRaw(txbuf, bodylen)) // Send at default volume...  One going missing won't hurt that much.
-            {
 #if 1 && defined(DEBUG)
-            p->println(F("polled")); // Done it!
-#endif
-            }
+          p->println(F("polled")); // Done it!
+#endif
+#if !defined(ENABLE_OTSECUREFRAME_ENCODING_SUPPORT)
+          // Non-secure: send raw frame as-is.
+          if(!PrimaryRadio.sendRaw(txbuf, bodylen)) // Send at default power...  One going missing won't hurt that much.
+            { OTV0P2BASE::serialPrintlnAndFlush("!TX fail"); return; } // FAIL
+#else
+          // Secure: wrap frame in encrypted layer...
+          uint8_t key[16];
+          if(!OTV0P2BASE::getPrimaryBuilding16ByteSecretKey(key))
+            { OTV0P2BASE::serialPrintlnAndFlush("!TX key"); return; } // FAIL
+          const OTRadioLink::SimpleSecureFrame32or0BodyTXBase::fixed32BTextSize12BNonce16BTagSimpleEnc_ptr_t e = OTAESGCM::fixed32BTextSize12BNonce16BTagSimpleEnc_DEFAULT_STATELESS;
+          uint8_t buf[OTRadioLink::SecurableFrameHeader::maxSmallFrameSize];
+
+
+
+
+
+// FIXME FIXME FIXME
+
+
+
+
+
+
+          OTV0P2BASE::serialPrintlnAndFlush("!TX not impl"); // FAIL
+#endif // !defined(ENABLE_OTSECUREFRAME_ENCODING_SUPPORT)
           }
         }
       return;


Update Ph_meter.ino

Update Ph_meter.ino

--- Ph_meter/Ph_meter.ino
+++ Ph_meter/Ph_meter.ino
@@ -1,113 +1,113 @@
-#include <Wire.h>
-#include "Adafruit_TCS34725.h"
-#include <ArduinoJson.h>
-#include <ESP8266WiFi.h>
-#include <ESP8266HTTPClient.h>
-
-#define API_key "Bearer <API key>"
-
-Adafruit_TCS34725 tcs = Adafruit_TCS34725(TCS34725_INTEGRATIONTIME_700MS, TCS34725_GAIN_1X);
-
-int buttonState;
-int lastButtonState = HIGH;
-
-unsigned long lastDebounceTime = 0;
-unsigned long debounceDelay = 50;
-
-const char* ssid     = "<SSID>";
-const char* password = "<Passphrase>";
-
-String url = "<Machine learning URL>";
-
-void AzureMLPost(String payload){
-  HTTPClient http;
-  http.begin(url, "FC E4 6C E7 4F DA AF 0F B5 03 66 3A 8D 6D 3F 21 1A 40 82 6E"); // SHA1 HTTPS fingerprint
-  http.addHeader("Authorization", API_key);
-  http.addHeader("Content-Type", "application/json");
-  http.addHeader("Content-Length", String(payload.length()));
-
-  int httpCode = http.POST(payload);
-
-  if(httpCode == HTTP_CODE_OK){
-    Serial.print("HTTP response code: ");
-    Serial.println(httpCode);
-    String response = http.getString();
-
-    StaticJsonBuffer<400> jsonBuffer;
-    JsonObject& root = jsonBuffer.parseObject(response);
-    float ph = root["Results"]["output1"]["value"]["Values"][0][6];
-    Serial.print("Ph: "); Serial.println(ph);
-  }else {
-    Serial.println("Error in HTTP request");
-  }
-  http.end();
-}
-
-String ReadSensorToJSON(){
-  uint16_t r, g, b, c, colorTemp, lux;
-
-  tcs.getRawData(&r, &g, &b, &c);
-  colorTemp = tcs.calculateColorTemperature(r, g, b);
-  lux = tcs.calculateLux(r, g, b);
-
-  StaticJsonBuffer<400> jsonBuffer;
-  JsonObject& root = jsonBuffer.createObject();
-  JsonObject& Inputs = root.createNestedObject("Inputs");
-  JsonObject& input1 = Inputs.createNestedObject("input1");
-  JsonArray&  ColumnNames  = input1.createNestedArray("ColumnNames");
-  ColumnNames.add("Color Temp");
-  ColumnNames.add("Lux");
-  ColumnNames.add("R");
-  ColumnNames.add("G");
-  ColumnNames.add("B");
-  ColumnNames.add("C");
-  JsonArray&  Values  = input1.createNestedArray("Values");
-  JsonArray&  in1  = Values.createNestedArray();
-  in1.add(colorTemp);
-  in1.add(lux);
-  in1.add(r);
-  in1.add(g);
-  in1.add(b);
-  in1.add(c);
-  JsonObject& GlobalParameters = root.createNestedObject("GlobalParameters");
-
-  char buffer[256];
-  root.printTo(buffer, sizeof(buffer));
-
-  return buffer;
-}
-
-void setup(void) {
-  Serial.begin(9600);
-  tcs.begin();
-  WiFi.mode(WIFI_STA);
-  Serial.print("Connecting to ");
-  Serial.println(ssid);
-  WiFi.begin(ssid, password);
-  while (WiFi.status() != WL_CONNECTED) {
-    delay(500);
-    Serial.print(".");
-  }
-  Serial.println("Connected");
-
-  pinMode(D4, INPUT_PULLUP);
-}
-
-void loop(void) {
-  int reading = digitalRead(D4);
-
-  if (reading != lastButtonState) {
-    lastDebounceTime = millis();
-  }
-
-  if ((millis() - lastDebounceTime) > debounceDelay) {
-    if (reading != buttonState) {
-      buttonState = reading;
-      if (buttonState == LOW) {
-        AzureMLPost(ReadSensorToJSON());
-      }
-    }
-  }
-
-  lastButtonState = reading;
+#include <Wire.h>
+#include "Adafruit_TCS34725.h"
+#include <ArduinoJson.h>
+#include <ESP8266WiFi.h>
+#include <ESP8266HTTPClient.h>
+
+#define API_key "Bearer <API key>"
+
+Adafruit_TCS34725 tcs = Adafruit_TCS34725(TCS34725_INTEGRATIONTIME_700MS, TCS34725_GAIN_1X);
+
+int buttonState;
+int lastButtonState = HIGH;
+
+unsigned long lastDebounceTime = 0;
+unsigned long debounceDelay = 50;
+
+const char* ssid     = "<SSID>";
+const char* password = "<Passphrase>";
+
+String url = "<Machine learning URL>";
+
+void AzureMLPost(String payload){
+  HTTPClient http;
+  http.begin(url, "FC E4 6C E7 4F DA AF 0F B5 03 66 3A 8D 6D 3F 21 1A 40 82 6E"); // SHA1 HTTPS fingerprint
+  http.addHeader("Authorization", API_key);
+  http.addHeader("Content-Type", "application/json");
+  http.addHeader("Content-Length", String(payload.length()));
+
+  int httpCode = http.POST(payload);
+
+  if(httpCode == HTTP_CODE_OK){
+    Serial.print("HTTP response code: ");
+    Serial.println(httpCode);
+    String response = http.getString();
+
+    StaticJsonBuffer<400> jsonBuffer;
+    JsonObject& root = jsonBuffer.parseObject(response);
+    float ph = root["Results"]["output1"]["value"]["Values"][0][6];
+    Serial.print("pH: "); Serial.println(ph);
+  }else {
+    Serial.println("Error in HTTP request");
+  }
+  http.end();
 }
+
+String ReadSensorToJSON(){
+  uint16_t r, g, b, c, colorTemp, lux;
+
+  tcs.getRawData(&r, &g, &b, &c);
+  colorTemp = tcs.calculateColorTemperature(r, g, b);
+  lux = tcs.calculateLux(r, g, b);
+
+  StaticJsonBuffer<400> jsonBuffer;
+  JsonObject& root = jsonBuffer.createObject();
+  JsonObject& Inputs = root.createNestedObject("Inputs");
+  JsonObject& input1 = Inputs.createNestedObject("input1");
+  JsonArray&  ColumnNames  = input1.createNestedArray("ColumnNames");
+  ColumnNames.add("Color Temp");
+  ColumnNames.add("Lux");
+  ColumnNames.add("R");
+  ColumnNames.add("G");
+  ColumnNames.add("B");
+  ColumnNames.add("C");
+  JsonArray&  Values  = input1.createNestedArray("Values");
+  JsonArray&  in1  = Values.createNestedArray();
+  in1.add(colorTemp);
+  in1.add(lux);
+  in1.add(r);
+  in1.add(g);
+  in1.add(b);
+  in1.add(c);
+  JsonObject& GlobalParameters = root.createNestedObject("GlobalParameters");
+
+  char buffer[256];
+  root.printTo(buffer, sizeof(buffer));
+
+  return buffer;
+}
+
+void setup(void) {
+  Serial.begin(9600);
+  tcs.begin();
+  WiFi.mode(WIFI_STA);
+  Serial.print("Connecting to ");
+  Serial.println(ssid);
+  WiFi.begin(ssid, password);
+  while (WiFi.status() != WL_CONNECTED) {
+    delay(500);
+    Serial.print(".");
+  }
+  Serial.println("Connected");
+
+  pinMode(D4, INPUT_PULLUP);
+}
+
+void loop(void) {
+  int reading = digitalRead(D4);
+
+  if (reading != lastButtonState) {
+    lastDebounceTime = millis();
+  }
+
+  if ((millis() - lastDebounceTime) > debounceDelay) {
+    if (reading != buttonState) {
+      buttonState = reading;
+      if (buttonState == LOW) {
+        AzureMLPost(ReadSensorToJSON());
+      }
+    }
+  }
+
+  lastButtonState = reading;
+}


Adding trigger counters for runtime, last 24 hours and last 31 days

--- arduino/arduino.ino
+++ arduino/arduino.ino
@@ -108,6 +108,12 @@
 // TimeStorage - stores the # of bytes needed to store the information
 const unsigned int timeStorage = 60 / TIMEFRAME * 60 * STORAGE_HOURS;
 byte storage[timeStorage];
+unsigned long storageRuntime = 0;
+unsigned int storageHour[24];
+unsigned int storageDay[31];
+
+byte lastDay = 0xFF;
+byte lastHour = 0xFF;

 bool useNetwork = false;
 int storagePointer = -1;
@@ -280,7 +286,26 @@
 void gotTriggered()
 {
   Serial.println("Trigger got high!");
+
   storage[storagePointer]++;
+
+  storageRuntime++;
+
+  byte day = millis() / 1000 / 60 / 24 % 31;
+  if (day != lastDay)
+  {
+    lastDay = day;
+    storageDay[day] = 1;
+  }
+  storageDay[day]++;
+
+  byte hour = millis() / 1000 / 60 % 24;
+  if (hour != lastHour)
+  {
+    lastHour = hour;
+    storageHour[hour] = 0;
+  }
+  storageHour[hour]++;
 }


added timeout to configuration portal

added timeout to configuration portal

--- SonoffBoilerplate.ino
+++ SonoffBoilerplate.ino
@@ -199,7 +199,8 @@
   //set callback that gets called when connecting to previous WiFi fails, and enters Access Point mode
   wifiManager.setAPCallback(configModeCallback);

-  //timeout
+  //timeout - this will quit WiFiManager if it's not configured in 3 minutes, causing a restart
+  wifiManager.setConfigPortalTimeout(180);

   //custom params
   EEPROM.begin(512);


Terminal: A bit slower rate to handle implicit newlines

--- Terminal/Terminal.ino
+++ Terminal/Terminal.ino
@@ -102,15 +102,15 @@
 void loop() {

   // Now send key strokes, simulating a user
-  static int n = 0;
+  static int n = 1;
   char text[200];
-  sprintf(text, "Test %d\n\n"
+  sprintf(text, " *** Test %d ***\n\n"
                 "Hello Gigatron!\n"
                 "This is Arduino Uno pretending to be an ASCII keyboard. Hope you like it!\n"
                 "The quick brown fox jumps over the lazy dog.\n\n", n++);
   for (int i=0; text[i]; i++) {
     sendController(text[i], 2);
-    delay(text[i] == '\n' ? 50 : 20);
+    delay(40);
   }
   delay(500);
 }