PID_test v3.0. working in both direcctions

--- PID_test/PID_test.ino
+++ PID_test/PID_test.ino
@@ -4,20 +4,22 @@
 extern "C" {
 #include "user_interface.h"
 }
-
-int lpwm=0, rpwm=0;   // motor pwm
+#define DEBUG 1
+
+double lpwm=0, rpwm=0;   // motor pwm
 int lmc=0,  rmc=0;    // left motor counter
 int lmc0=0, rmc0=0;   // last encoder value
 int ldir=1, rdir=1;   // motor direction
+int llevel, rlevel;
 double whesep= 0.135; // wheel separtion in m
 double whedia= 0.7;   // wheel diameter in m
 int CPR = 40;         // Encoder Count per Revolutions
 int period=50;        // PID sample timer period in ms
 double lv=0., rv=0., lvt=0., rvt=0. ;// motor speed innumber tics per period with two methods
 int ti=0;             // tic timer counter
-double lIn,rIn,lOut,rOut,lSet=0,rSet=0;   // PID Input Signal, Output command and Setting speed for each wheel
-double lkp=0.3,lki=5,lkd=0.1;     // Left/right wheel PID constants. Can be modiffied while running with:
-double rkp=0.3,rki=5,rkd=0.1;     // s nnn (setting point), p nnn (kp), i nnn (ki), d nnn (kd). nnn is divided by 10 to get decimals nnn -> nn.n
+double lIn,rIn,lOut,rOut,lSet=20,rSet=20;   // PID Input Signal, Output command and Setting speed for each wheel
+double lkp=0.5,lki=10,lkd=0.0;     // Left/right wheel PID constants. Can be modiffied while running with:
+double rkp=0.5,rki=10,rkd=0.0;     // s nnn (setting point), p nnn (kp), i nnn (ki), d nnn (kd). nnn is divided by 10 to get decimals nnn -> nn.n
 double kt=1000/period;            // number of periods/sec
 int rcurrenttime, rlasttime, lcurrenttime, llasttime;

@@ -26,6 +28,12 @@
 PID rPID(&rIn, &rOut, &rSet, rkp, rki, rkd, DIRECT);

 os_timer_t myTimer;
+
+static inline int8_t sgn(int val) {
+ if (val < 0) return -1;
+ if (val==0) return 0;
+ return 1;
+}

 // start of timerCallback, repeat every "period"
 void tic(void *pArg) {
@@ -33,15 +41,14 @@
   lmc0=lmc;
   rv=(rmc-rmc0);
   rmc0=rmc;
-  if(lv>=1.) { lIn = lvt; } else { lIn = 0; } // left instant velocity tic/period * period/sec = tic/sec
-  if(rv>=1.) { rIn = rvt; } else { rIn = 0; }
+  lIn = lv*kt;
+  rIn = rv*kt;
+  //lIn=abs(lvt)*sgn(lv);
+  //rIn=abs(rvt)*sgn(rv);
+  lPID.Compute();
+  rPID.Compute();
+  motion(lOut,rOut);
   ti+=1;                  // tic counter
-  Serial.print(lIn);
-  Serial.print(",");
-  lPID.Compute();
-  Serial.println(rIn);
-  rPID.Compute();
-  motion(lOut,rOut,HIGH,HIGH);
 }

 void stop(void){      // Stop both motors
@@ -49,108 +56,51 @@
     analogWrite(D2, 0);
 }

-void motion(double lpwm, double rpwm, int llevel, int rlevel) {
-    if (llevel==HIGH) {
+void motion(double lpwm, double rpwm) {
+  if(abs(lIn)<1){
+    if(lOut>=0){
       ldir=1;
+      llevel=HIGH;
     } else {
       ldir=-1;
-    }
-    if (rlevel==HIGH) {
+      llevel=LOW;
+    }
+  }
+  if(abs(rIn)<1){
+    if(rOut>=0){
       rdir=1;
+      rlevel=HIGH;
     } else {
       rdir=-1;
-    }
-    if(lpwm>1023)lpwm=1023;
-    if(rpwm>1023)rpwm=1023;
-    if(lpwm<0)lpwm=0;
-    if(rpwm<0)rpwm=0;
-    analogWrite(D1, lpwm);
-    analogWrite(D2, rpwm);
-    digitalWrite(D3, llevel);
-    digitalWrite(D4, rlevel);
+      rlevel=LOW;
+    }
+  }
+  analogWrite(D1, abs(lpwm));
+  analogWrite(D2, abs(rpwm));
+  digitalWrite(D3, llevel);
+  digitalWrite(D4, rlevel);
 }
 void lencode() {          // GPIO ISR Interrupt service routines for encoder changes
   lcurrenttime = millis();
-  lvt = 1000./(lcurrenttime - llasttime);
+  lvt = ldir*1000./(lcurrenttime - llasttime);
   llasttime = lcurrenttime;
   lmc=lmc+ldir;
 }
 void rencode(){
   rcurrenttime = millis();
-  rvt = 1000./(rcurrenttime - rlasttime);
+  rvt = rdir*1000./(rcurrenttime - rlasttime);
   rlasttime = rcurrenttime;
   rmc=rmc+rdir;
 }

-
-void setup() {
-  pinMode(D1, OUTPUT); // 1,2EN aka D1 pwm left
-  pinMode(D2, OUTPUT); // 3,4EN aka D2 pwm right
-  pinMode(D3, OUTPUT); // 1A,2A aka D3
-  pinMode(D4, OUTPUT); // 3A,4A aka D4
-  pinMode(D5, INPUT);  // Left encoder
-  pinMode(D6, INPUT);  // Right encoder
-  //attachInterrupt(D5, lencode, CHANGE); // Setup Interrupt
-  //attachInterrupt(D6, rencode, CHANGE); // Setup Interrupt
-  attachInterrupt(D5, lencode, RISING);   // Setup Interrupt
-  attachInterrupt(D6, rencode, RISING);   // Setup Interrupt
-  sei();                                  // Enable interrupts
-  os_timer_setfn(&myTimer, tic, NULL);
-  os_timer_arm(&myTimer, period, true);   // timer in ms
-  lPID.SetSampleTime(period);
-  rPID.SetSampleTime(period);
-  lPID.SetOutputLimits(0, 1023);
-  rPID.SetOutputLimits(0, 1023);
-  lPID.SetMode(AUTOMATIC);
-  rPID.SetMode(AUTOMATIC);
-  Serial.begin(115200);
-  Serial.println("Ready");
-}
-
-char c=0;             // input char from keys
-void loop(){
-  // watch for input
-  if(c==0){
-    if (Serial.available() != 0) {
-      c = Serial.read();
-      Serial.println(c);
-    }
-  } else {
-    if (Serial.available() != 0) {
-      int gv = Serial.parseInt();
-      if(c=='s'){
-        lSet=gv/10.;
-        rSet=gv/10.;
-      } else if(c=='p'){
-        lkp=gv/10.;
-        rkp=gv/10.;
-        lPID.SetTunings(lkp, lki, lkd);
-        rPID.SetTunings(rkp, rki, rkd);
-      } else if(c=='i'){
-        lki=gv/10.;
-        rki=gv/10.;
-        lPID.SetTunings(lkp, lki, lkd);
-        rPID.SetTunings(rkp, rki, rkd);
-      } else if(c=='d'){
-        lkd=gv/10.;
-        rkd=gv/10.;
-        lPID.SetTunings(lkp, lki, lkd);
-        rPID.SetTunings(rkp, rki, rkd);
-      } else {
-        Serial.println("Tunning command not recognized. Use s NNN, p NNN, i NNN, d NNN with NNN=n*10");
-      }
-      while (Serial.available()) Serial.read();
-      c=0;
-    }
-  }
-  /*
-  Serial.print("***lSet: ");
+void dump(){
+  Serial.print("lSet: ");
   Serial.print(lSet);
   Serial.print(" rSet: ");
   Serial.print(rSet);
-  Serial.print(" lv:");
+  Serial.print(" lIn:");
   Serial.print(lIn);
-  Serial.print(" rv:");
+  Serial.print(" rIn:");
   Serial.print(rIn);
   Serial.print(" lOut:");
   Serial.print(lOut);
@@ -168,7 +118,88 @@
   Serial.print(lki);
   Serial.print(" lkd: ");
   Serial.println(lkd);
-*/
+}
+
+void setup() {
+  pinMode(D1, OUTPUT); // 1,2EN aka D1 pwm left
+  pinMode(D2, OUTPUT); // 3,4EN aka D2 pwm right
+  pinMode(D3, OUTPUT); // 1A,2A aka D3
+  pinMode(D4, OUTPUT); // 3A,4A aka D4
+  pinMode(D5, INPUT);  // Left encoder
+  pinMode(D6, INPUT);  // Right encoder
+  attachInterrupt(D5, lencode, CHANGE); // Setup Interrupt
+  attachInterrupt(D6, rencode, CHANGE); // Setup Interrupt
+  //attachInterrupt(D5, lencode, RISING);   // Setup Interrupt
+  //attachInterrupt(D6, rencode, RISING);   // Setup Interrupt
+  sei();                                  // Enable interrupts
+  os_timer_setfn(&myTimer, tic, NULL);
+  os_timer_arm(&myTimer, period, true);   // timer in ms
+  lPID.SetSampleTime(period);
+  rPID.SetSampleTime(period);
+  lPID.SetOutputLimits(-1023, 1023);
+  rPID.SetOutputLimits(-1023, 1023);
+  lPID.SetMode(AUTOMATIC);
+  rPID.SetMode(AUTOMATIC);
+  Serial.begin(115200);
+  Serial.println("Ready");
+}
+
+char c=0;             // input char from keys
+void loop(){
+  // watch for input
+  if(c==0){
+    if (Serial.available() != 0) {
+      c = Serial.read();
+      Serial.println(c);
+    }
+  } else {
+    if (Serial.available() != 0) {
+      int gv = Serial.parseInt();
+      if(c=='r'){
+        rSet=gv/10.;
+      } else if(c=='l'){
+        lSet=gv/10.;
+      } else if(c=='p'){
+        lkp=gv/10.;
+        rkp=gv/10.;
+        lPID.SetTunings(lkp, lki, lkd);
+        rPID.SetTunings(rkp, rki, rkd);
+      } else if(c=='i'){
+        lki=gv/10.;
+        rki=gv/10.;
+        lPID.SetTunings(lkp, lki, lkd);
+        rPID.SetTunings(rkp, rki, rkd);
+      } else if(c=='d'){
+        lkd=gv/10.;
+        rkd=gv/10.;
+        lPID.SetTunings(lkp, lki, lkd);
+        rPID.SetTunings(rkp, rki, rkd);
+      } else if(c=='s'){
+        dump();
+      } else {
+        Serial.println("Tunning command not recognized. Use l NNN, r NNN, p NNN, i NNN, d NNN with NNN=n*10, s to dump variables");
+      }
+      while (Serial.available()) Serial.read();
+      c=0;
+    }
+  }
+  if(DEBUG){
+    Serial.print(lSet);
+    Serial.print(",");
+    Serial.print(rSet);
+    Serial.print(",");
+    Serial.print(lIn);
+    Serial.print(",");
+    Serial.print(rIn);
+    Serial.print(",");
+    Serial.print(lvt);
+    Serial.print(",");
+    Serial.print(rvt);
+    Serial.print(",");
+    Serial.print(lOut);
+    Serial.print(",");
+    Serial.println(rOut);
+  }
   delay(1000);
 }


Identificazione dell'URL corretto (http:// https:// ...)

--- naochallenge2020/NAO_LEGGI_URL_Ntag213.ino
+++ naochallenge2020/NAO_LEGGI_URL_Ntag213.ino
@@ -70,9 +70,29 @@
   }

   Serial.println("-- HO LETTO I DATI NEL TAG RFID NTAG213 --");
-  //TODO: Print URL type, by interpretation of the first byte
+  //Print URL type
+  switch (nfc_data[27]) {
+    case 1:
+      Serial.print("http://www.");
+      break;
+    case 2:
+      Serial.print("https://www.");
+      break;
+    case 3:
+      Serial.print("http://");
+      break;
+    case 4:
+      Serial.print("https://www.");
+      break;
+    case 5:
+      Serial.print("tel:");
+      break;
+    case 6:
+      Serial.print("mailto:");
+      break;
+  }

-  for (i=27; i<255; i++) {
+  for (i=28; i<255; i++) {
     if (nfc_data[i] == 0xFE) // End of string
       break;


Remove dead Arduino code

Remove dead Arduino code

--- sous_vide_arduino/sous_vide_arduino.ino
+++ sous_vide_arduino/sous_vide_arduino.ino
@@ -19,11 +19,6 @@
 {
     Serial.begin(57600);
     sensors.begin();
-}
-
-float temperature()
-{
-    return DallasTemperature::toFahrenheit(sensors.getTempC(thermometer));
 }

 void loop()


Update Stabilisator.ino

Update Stabilisator.ino

--- Firmware/Ball/Stabilisator/Stabilisator.ino
+++ Firmware/Ball/Stabilisator/Stabilisator.ino
@@ -1,4 +1,4 @@
-String version = "0.1.2";
+String version = "0.1.3";
 /*

  >      FIRMWARE ONLY FOR AN ARDUINO NANO !!    <


Baud select fix

Baud select fix

--- MicroView/WiFiModem-Menu/WiFiModem-Menu.ino
+++ MicroView/WiFiModem-Menu/WiFiModem-Menu.ino
@@ -2207,7 +2207,7 @@

                     newBaudRate = Modem_CommandBuffer[i++];

-                    if (newBaudRate >= '0' && newBaudRate <= '4')
+                    if (newBaudRate >= '0' && newBaudRate <= '3')
                     {
                         BAUD_RATE_FORCED = newBaudRate;
                     }


Update ESP_chip_id.ino

Update ESP_chip_id.ino

--- sample/ESP_chip_id.ino
+++ sample/ESP_chip_id.ino
@@ -1 +1,15 @@
+#include <ESP8266WiFi.h>
+void setup() {
+  // put your setup code here, to run once:
+  Serial.begin(115200);
+  Serial.println("Starting \n");
+  int chipId = 0;
+  chipId = ESP.getChipId();
+  Serial.print("Chip ID: " );
+  Serial.println(chipId);
+}

+void loop() {
+  // put your main code here, to run repeatedly:
+
+}


cmd_vel and pan/tilt all in one

cmd_vel and pan/tilt all in one

--- controller/controller.ino
+++ controller/controller.ino
@@ -1,8 +1,14 @@
-#include <ros.h>
+#include <ros.h> // Timer.h seems to bugger it up, so nope.
+#include <rosserial_arduino/pan_tilt.h> // {pan:uint8,tilt:uint8} ros msg
+
 #include <ZumoMotors.h>
-#include "Timer.h"
 #include <geometry_msgs/Twist.h>
 #include <std_msgs/Float32.h>
+
+// Nice Servo Library that uses Timer 2 (since Timer1 used by ZumoMotors.h)
+// Unfortunately Buzzer also uses Timer 2 so can't be used at the same time.
+// Library : https://github.com/DerekK19/Arduino/tree/master/libraries/ServoTimer2
+#include <ServoTimer2.h>

 // Distance between both wheels
 #define WHEEL_OFFSET_M 0.1 // 10cm
@@ -15,6 +21,8 @@
 #define USER_PUSHBUTTON_PIN 12
 #define LED_PIN 13

+#define BATTERY_VOLTAGE_PUBLISH_RATE 1000 // ms (publish voltage every second)
+
 // Encoders
 #define ENCODER_LEFT_PIN_A 2
 #define ENCODER_LEFT_PIN_B 11
@@ -23,14 +31,52 @@
 #define ENCODER_RIGHT_PIN_B 2 // (SPECIAL) Analog pin A2
 #define ENCODER_RIGHT_PIN_B_THRESHOLD 450 // Read value threshold crossing

+// Pan Tilt Servo pins
+#define SERVO_PAN_PIN 5 // Pan
+#define SERVO_TILT_PIN 6 // Tilt
+
+// Pan servo center min/max range (0-180 degrees with 90 degrees centred)
+#define SERVO_PAN_MIN 40
+#define SERVO_PAN_MAX 140
+
+// Tilt servo center min/max range (0-180 degrees with 90 degrees centred)
+#define SERVO_TILT_MIN 50
+#define SERVO_TILT_MAX 130
+// ServoTimer2 min/max microsecond delays 544us - 2400us ~ 0 - 180 degrees
+#define ST2_MIN 544
+#define ST2_MAX 2400
+
+#define PAN_TILT_MOVE_DELAY 2 // ms delay for smooth movement

 // ROS
 ros::NodeHandle nh;
 geometry_msgs::Twist twist_msg;

 ZumoMotors motors; // Motor controller
-Timer t;
-
+// Timer t;
+
+// Pan Tilt variables
+uint8_t pan, tilt;
+
+void set_position_callback(const rosserial_arduino::pan_tilt& msg)
+{
+  digitalWrite(13, HIGH-digitalRead(13));   // blink the led
+  pan = msg.pan;
+  tilt = msg.tilt;
+
+  moveTo(int(pan), int(tilt));
+}
+
+// Set up pan/tilt subscriber
+ros::Subscriber<rosserial_arduino::pan_tilt> pan_tilt_sub("pantilt/set_position", set_position_callback);
+
+// Servo objects
+ServoTimer2 servo_pan;
+ServoTimer2 servo_tilt;
+
+// Servo positions (0-180 degrees with 90 degrees centred)
+int pan_pos = 0;
+int tilt_pos = 0;

 /// Left Encoder
 int encoder_left_pos = 0;
@@ -44,11 +90,11 @@

 // Battery Voltage Publisher
 std_msgs::Float32 voltage_msg;
-ros::Publisher battery_topic("battery_voltage", &voltage_msg);
+ros::Publisher battery_pub("battery_voltage", &voltage_msg);

 void publishBatteryVoltage() {
   voltage_msg.data = getBatteryVoltage();
-  battery_topic.publish( &voltage_msg );
+  battery_pub.publish( &voltage_msg );
 }

@@ -60,16 +106,11 @@
 // Command Velocity Subscriber
 ros::Subscriber<geometry_msgs::Twist> cmd_vel_topic("cmd_vel", &cmd_vel_callback);

-
+unsigned long last_battery_published = 0;
 ////////////////////////////////////////////////////////////////////////////////

 void setup()
-{
-  // initialize serial:
-  // Serial.begin(9600);
-  // reserve 200 bytes for the inputString:
-  // inputString.reserve(200);
-
+{
   pinMode(LED_PIN, OUTPUT);

   // Initialize Encoders
@@ -80,9 +121,6 @@

   // Only Right encoder works with interrupts (left pinB doesn't pass interrupt threshold of ~3.3V)
   attachInterrupt(0, measureRightEncoder, CHANGE); // 0 = pin 2 interrupt
-
-  // Publish battery voltage every second
-  t.every(1000, publishBatteryVoltage);

   // Left motor power wiring is reversed.
   motors.flipLeftMotor(true);
@@ -90,8 +128,21 @@
   // Initial speed is zero
   drive_stop();

+  // Attach Pan Tilt Servos
+  servo_pan.attach(SERVO_PAN_PIN);
+  servo_tilt.attach(SERVO_TILT_PIN);
+
+  // Init pan/tilt to center
+  setZero();
+
   nh.initNode();
-  nh.subscribe(cmd_vel_topic);
+  nh.advertise(battery_pub); // Battery Voltage Publisher
+
+  nh.subscribe(cmd_vel_topic); // Command Velocity Subscriber
+  nh.subscribe(pan_tilt_sub); // Pan/Tilt Subscriber
+
+
+  last_battery_published = millis();
 }

 void loop()
@@ -99,33 +150,39 @@
   // Measure left encoder manually
   measureLeftEncoder();

-  // Timer updates
-  t.update();
+  // Publish battery voltage every second
+  if (millis() - last_battery_published > BATTERY_VOLTAGE_PUBLISH_RATE)
+  {
+    publishBatteryVoltage();
+    last_battery_published = millis();
+  }

   nh.spinOnce();
 }

 ////////////////////////////////////////////////////////////////////////////////
+// Motor drive speeds
+int vl = 0, vr = 0;

 // cmd_x  : linear x velocity (forward velocity)
 // cmd_th : angular z velocity (rotation of heading)
 void diff_drive(double cmd_x, double cmd_th) {
-  int vl = (cmd_x - cmd_th * WHEEL_OFFSET_M / 2.0) * MAX_MOTOR_SPEED / MAX_REAL_SPEED;
-  int vr = (cmd_x + cmd_th * WHEEL_OFFSET_M / 2.0) * MAX_MOTOR_SPEED / MAX_REAL_SPEED;
+  vl = (cmd_x - cmd_th * WHEEL_OFFSET_M / 2.0) * MAX_MOTOR_SPEED / MAX_REAL_SPEED;
+  vr = (cmd_x + cmd_th * WHEEL_OFFSET_M / 2.0) * MAX_MOTOR_SPEED / MAX_REAL_SPEED;
+  drive();
+}
+
+// Drive left and right wheel motors vased on vl and vr
+void drive() {
   motors.setLeftSpeed(vl);
   motors.setRightSpeed(vr);
 }

-// Drive left and right wheel motors for dt milliseconds, blocking
-void drive(int vl, int vr) {
-  motors.setLeftSpeed(vl);
-  motors.setRightSpeed(vr);
-}
-
 // Stops motors
 void drive_stop() {
-  motors.setLeftSpeed(0);
-  motors.setRightSpeed(0);
+  vl = 0;
+  vr = 0;
+  drive();
 }

 // Battery Voltage
@@ -155,4 +212,48 @@
         else {encoder_left_pos++;}
     }
     encoder_left_pin_A_last = encoder_right_val;
+}
+
+
+// Smoothly move to pan tilt pos 0-100 range for both (50 centered)
+void moveTo(int pan, int tilt)
+{
+  if (vl != 0 || vr != 0) {
+    // WARNING
+    // Left Encoder will miss steps due to the delay in this while loop!
+  }
+  while (abs(pan_pos - pan) + abs(tilt_pos - tilt) > 0) {
+    pan_pos += pan_pos > pan ? -1 : pan_pos < pan ? 1 : 0;
+    tilt_pos += tilt_pos > tilt ? -1 : tilt_pos < tilt ? 1 : 0;
+    setPan( map(pan, 0, 100, SERVO_PAN_MIN, SERVO_PAN_MAX) );
+    setTilt( map(tilt, 0, 100, SERVO_TILT_MIN, SERVO_TILT_MAX) );
+    delay(PAN_TILT_MOVE_DELAY); // ms
+  }
+}
+
+
+// Moves to pan and tilt in range 0 to 100, where 50 is centered
+void setPanTilt(int pan, int tilt)
+{
+  setPan( map(pan, 0, 100, SERVO_PAN_MIN, SERVO_PAN_MAX) );
+  setTilt( map(tilt, 0, 100, SERVO_TILT_MIN, SERVO_TILT_MAX) );
+}
+
+// Center Pan/Tilt servos
+void setZero()
+{
+  moveTo(50,50);
+}
+
+// Given degree, constrain to 0-180, then convert to microsecond delay
+void setPan(int pan_deg)
+{
+  pan_deg = constrain(pan_deg, SERVO_PAN_MIN, SERVO_PAN_MAX);
+  servo_pan.write(map(pan_deg, 0, 180, ST2_MIN, ST2_MAX));
+}
+
+void setTilt(int tilt_deg)
+{
+  tilt_deg = constrain(tilt_deg, SERVO_TILT_MIN, SERVO_TILT_MAX);
+  servo_tilt.write(map(tilt_deg, 0, 180, ST2_MIN, ST2_MAX));
 }


on/off ac using nest bridge

on/off ac using nest bridge

--- _71-nest-bridgetest/_71-nest-bridgetest.ino
+++ _71-nest-bridgetest/_71-nest-bridgetest.ino
@@ -3,6 +3,7 @@
 #include <ESP8266mDNS.h>
 #include <WiFiUdp.h>
 #include <ArduinoOTA.h>
+#include <WiFiClientSecure.h>
 #include <PubSubClient.h>
 #include <TimeLib.h>
 #include <ArduinoJson.h>
@@ -10,8 +11,10 @@
 #define COOL_PIN 5
 #define HEAT_PIN 4

-#include "/usr/local/src/ap_setting.h"
+#include "/usr/local/src/aptls_setting.h"
 const char* reporting_topic = "esp8266/nestbridge";
+const char* topic_ac_cmd    = "esp8266/cmd/ac";
+const char* hellotopic      = "HELLO";

 IPAddress mqtt_server = MQTT_SERVER;

@@ -22,15 +25,24 @@
 const int timeZone = 9;
 time_t prevDisplay = 0;

+// send reset info
+String getResetInfo;
+int ResetInfo = LOW;
+
 void ICACHE_RAM_ATTR callback(char* intopic, byte* inpayload, unsigned int length);
-WiFiClient wifiClient;
-PubSubClient client(mqtt_server, 1883, callback, wifiClient);
+WiFiClientSecure sslclient;
+PubSubClient client(mqtt_server, 8883, callback, sslclient);
 WiFiUDP udp;

-volatile bool bnest_isr = false;
-
-void ICACHE_RAM_ATTR nest_isr() {
-  bnest_isr = true;
+volatile bool bnest_isr_cool = false;
+volatile bool bnest_isr_heat = false;
+
+void ICACHE_RAM_ATTR nest_isr_cool() {
+  bnest_isr_cool = true;
+}
+
+void ICACHE_RAM_ATTR nest_isr_heat() {
+  bnest_isr_heat = true;
 }

 bool ICACHE_RAM_ATTR sendmqttMsg(const char* topictosend, String payloadtosend, bool retain = false)
@@ -79,23 +91,63 @@
   sendmqttMsg(reporting_topic, json, false);
 }

+void ICACHE_RAM_ATTR send_ac_cmd()
+{
+  DynamicJsonBuffer jsonBuffer;
+  JsonObject& root = jsonBuffer.createObject();
+  root["AC"] = !digitalRead(COOL_PIN);
+  String json;
+  root.printTo(json);
+
+  sendmqttMsg(topic_ac_cmd, json, true);
+}
+
 void ICACHE_RAM_ATTR callback(char* intopic, byte* inpayload, unsigned int length)
 {
 }

+bool verifytls()
+{
+
+  if (!sslclient.connect(mqtt_server, 8883))
+  {
+    return false;
+  }
+
+  if (sslclient.verify(MQTT_FINGERPRINT, MQTT_SERVER_CN))
+  {
+    sslclient.stop();
+    return true;
+  }
+  else
+  {
+    sslclient.stop();
+    return false;
+  }
+}
+
 boolean reconnect()
 {
   if (!client.connected())
   {
-    if (client.connect((char*) clientName.c_str()))
-    {
-      Serial.println("[MQTT] mqtt connected");
-    }
-    else
-    {
-      Serial.print("[MQTT] mqtt failed, rc=");
-      Serial.println(client.state());
-    }
+   if (verifytls())
+   {
+      if (client.connect((char*) clientName.c_str(), MQTT_USER, MQTT_PASS))
+      {
+         if ( ResetInfo == LOW) {
+            client.publish(hellotopic, (char*) getResetInfo.c_str());
+            ResetInfo = HIGH;
+         } else {
+            client.publish(hellotopic, "hello again 1 from nestbridge");
+         }
+         Serial.println("[MQTT] mqtt connected");
+      }
+      else
+      {
+         Serial.print("[MQTT] mqtt failed, rc=");
+         Serial.println(client.state());
+      }
+   }
   }
   return client.connected();
 }
@@ -256,8 +308,8 @@
    pinMode(COOL_PIN, INPUT);
    pinMode(HEAT_PIN, INPUT);

-   attachInterrupt(COOL_PIN, nest_isr, CHANGE);
-   attachInterrupt(HEAT_PIN, nest_isr, CHANGE);
+   attachInterrupt(COOL_PIN, nest_isr_cool, CHANGE);
+   attachInterrupt(HEAT_PIN, nest_isr_heat, CHANGE);

 	wifi_connect();

@@ -267,6 +319,9 @@
 	clientName += macToStr(mac);
 	clientName += "-";
 	clientName += String(micros() & 0xff, 16);
+
+   getResetInfo = "hello from nestbridge ";
+   getResetInfo += ESP.getResetInfo().substring(0, 50);

 	configTime(9 * 3600, 0, "pool.ntp.org", "time.nist.gov");

@@ -317,11 +372,19 @@
     }
     else
     {
-      if (bnest_isr)
+      if (bnest_isr_cool)
       {
          sendCheck();
-         bnest_isr = false;
+         send_ac_cmd();
+         bnest_isr_cool = false;
       }
+
+      if (bnest_isr_heat)
+      {
+         sendCheck();
+         bnest_isr_heat = false;
+      }
+
       client.loop();
     }
     ArduinoOTA.handle();


Factor handling of queued remote commands better

Split this out into a separate function, to make the main loop easier to
read.

--- Arduino/LightPlayer/LightPlayer.ino
+++ Arduino/LightPlayer/LightPlayer.ino
@@ -649,6 +649,18 @@
   }
 }

+void handleQueuedCommands()
+{
+  PendingOperations pending_operations_snapshot;
+  noInterrupts();
+  auto globals = &GlobalPendingOperations;
+  memcpy(&pending_operations_snapshot, globals, sizeof(*globals));
+  memset(globals, 0, sizeof(*globals));
+  interrupts();
+
+  performPendingOperations(pending_operations_snapshot);
+}
+
 void loop()
 {
   if (!readFrame()) {
@@ -657,14 +669,7 @@
     return;
   }

-  PendingOperations pending_operations;
-  noInterrupts();
-  memcpy(&pending_operations, &GlobalPendingOperations, sizeof(pending_operations));
-  memset(&GlobalPendingOperations, 0, sizeof(GlobalPendingOperations));
-  interrupts();
-
-  performPendingOperations(pending_operations);
-
+  handleQueuedCommands();
   adjustFrameColors();

   unsigned long frame_time = 50 + frame_len * 25UL;


Update 1fan.ino

Update 1fan.ino

--- examples/1fan/1fan.ino
+++ examples/1fan/1fan.ino
@@ -1,6 +1,6 @@
 #include "Dimmer.h"

-Dimmer fan(6);
+Dimmer fan(6); //pwn pin connected to arduino

 void setup()
 {
@@ -9,6 +9,7 @@

 void loop()
 {
-	fan.setIntensity(85);
-	int fanIntensity = fan.getIntensity();
+	fan.setIntensity(85); //sets the exit intensity in %(0 - 100)
+
+	int fanIntensity = fan.getIntensity(); //returns the intensity in %
 }


Added in swapping between 4 different options

--- examples/ping/ping.ino
+++ examples/ping/ping.ino
@@ -54,6 +54,9 @@
   // Setup SnowPlow Arduino tracker
   snowplow.initCf(snowplowCfSubdomain);
   snowplow.setUserId("my-arduino");
+
+  // Seed our random number generator
+  randomSeed(analogRead(0));
 }

 /*
@@ -71,8 +74,29 @@

   if (millis() - prevTime >= (15000))
   {
-    // Track via SnowPlow: category, action (label, property, value - all NULL)
-    snowplow.trackStructEvent("examples", "a ping");
+    // Between 0 and 3
+    switch (random(4)) {
+
+    case 0:
+      // Basic ping: label, property, value all NULL
+      snowplow.trackStructEvent("example", "basic ping");
+      break;
+
+    case 1:
+      // String ping: all fields set
+      snowplow.trackStructEvent("example", "string ping", "regular", "ascii", "a string");
+      break;
+
+    case 2:
+      // Int ping: all fields but property set
+      snowplow.trackStructEvent("example", "int ping", "age", NULL, 22);
+      break;
+
+    default: // Aka case 3
+      // Float ping: all fields but label set
+      snowplow.trackStructEvent("example", "float ping", NULL, "celsius", 15.3, 1);
+      break;
+    }

     prevTime = millis();
   }


preparations to do state machine based async sending

--- IBusCDC.ino
+++ IBusCDC.ino
@@ -1,15 +1,13 @@
 #ifdef CDC_IBUS
+
+// http://github.com/timotto/IBUS_Protocol
+#include <IBUS_Protocol.h>
+// http://pjrc.com/
+#include <AltSoftSerial.h>
+#include <EEPROM.h>

 //#define DEBUG_CDC(x) Serial.print(x)
 #define DEBUG_CDC
-
-// SoftwareSerial
-#define CDC_BUS_TX  12
-#define CDC_BUS_RX  11
-
-#include <EEPROM.h>
-#include <IBUS_Protocol.h>
-#include <AltSoftSerial.h>

 //Ignition status, Off:
 //80 04 BF 11 00 2A
@@ -22,8 +20,18 @@
 // Display on
 // 46 05 FF D5 01 00 68
 //
+
+// Wait for IBUS_TX_WAIT milliseconds after receiving the last frame before sending
+#define IBUS_TX_WAIT     50
+
+#define IBUS_GT          0x3b
 #define IBUS_CID         0x46
+#define IBUS_MFL         0x50
+#define IBUS_IKE         0x80
+#define IBUS_GLO         0xBF
+#define IBUS_BMBT        0xF0
 #define IBUS_LOC         0xFF
+
 #define BTN_BMBT_LEFT    0x4810
 #define BTN_BMBT_RIGHT   0x4800
 #define BTN_BMBT_CD1     0x4811
@@ -54,13 +62,17 @@
   ibus_serial.begin(9600, SERIAL_8E1);
 }

+uint32_t lastRx = 0;
 void cdc_loop() {
+  uint32_t now = millis();
   while(ibus_serial.available()) {
-    uint8_t c = ibus_serial.read();
-    infotainmentBus.feed(c);
+    lastRx = now;
+    infotainmentBus.feed(ibus_serial.read());
     if ( (rxFrame = infotainmentBus.getFrame()) != NULL) {
       _ibus_handleFrame();
     }
+  }
+  if (lastRx + 50 >= now) {
   }
 }

@@ -191,7 +203,7 @@
   }

   switch(to){
-    case 0x3b: // GT
+    case IBUS_GT: // GT
 //      DEBUG_CDC("to GT\n");
       switch(frameData[0]) {
         case 0x23: // display text
@@ -221,10 +233,10 @@
   }

   switch(from) {
-    case 0x80: //IKE
+    case IBUS_IKE: //IKE
       DEBUG_CDC("from IKE\n");
       switch(to) {
-        case 0xBF: //GLO
+        case IBUS_GLO: //GLO
 //          DEBUG_CDC("to GLO, len=");
 //          DEBUG_CDC(rxFrame->len());
 //          DEBUG_CDC("\n");
@@ -251,14 +263,14 @@
           break;
       }
       break;
-    case 0xF0: //BMBT
+    case IBUS_BMBT:
       switch(frameData[0]) {
         case 0x48: // Button
           _ibus_handleButton(0x4800 | frameData[1]);
           return;
       }
       break;
-    case 0x50: //MFL
+    case IBUS_MFL: //MFL
       switch(frameData[0]) {
         case 0x3B: // Button
           _ibus_handleButton(0x3B00 | frameData[1]);


Shrink the loop time by not multisampling the ramp pot, which doesn't need it

--- code/MotorController/MotorController.ino
+++ code/MotorController/MotorController.ino
@@ -30,9 +30,10 @@
 const int serialPin = 1;
 const int clockResetInPin = 14;
 const int debugDisplayInPin = 15;
+const int exp1Pin = 18;

 // Settings and limits
-const int switchDebounceTime = 30;
+const int switchDebounceTime = 20;
 const int minimumDelay = 10;
 const int maximumDelay = 46;
 const int minimumSpeed = 26;
@@ -91,6 +92,7 @@
   pinMode(speedOutPin, OUTPUT);
   pinMode(clockResetInPin, INPUT_PULLUP);
   pinMode(debugDisplayInPin, INPUT_PULLUP);
+  pinMode(exp1Pin, OUTPUT);
   // We don't have to set pin mode for analog inputs

   onOffSwitch.attach(onOffSwitchInPin);
@@ -178,7 +180,12 @@

   if (powerEnabled)
   {
-    targetSpeed = ReadPotentiometer(speedInPin);
+    // Motor speed is actually pretty sensitive to the exact value that we read
+    // here.  It's pretty easy to hear it wander up and down by a few steps.
+    // We do a multisampled read here (even though it takes a while) to reduce
+    // the jitter that is often present.  If we want to tighten the loop time
+    // we could instead do a rolling window average of single readings over time.
+    targetSpeed = analogReadMultisampled(speedInPin);
     targetSpeed = map(targetSpeed, 0, potentiometerCeiling, minimumSpeed, 255);
     if (targetDirection == COUNTER_CLOCKWISE)
     {
@@ -190,7 +197,7 @@
     targetSpeed = 0;
   }

-  int newDelayBetweenMotorUpdates = ReadPotentiometer(rateOfSpeedChangeInPin);
+  int newDelayBetweenMotorUpdates = analogRead(rateOfSpeedChangeInPin);
   newDelayBetweenMotorUpdates = map(newDelayBetweenMotorUpdates, 0, potentiometerCeiling, minimumDelay, maximumDelay);
   int absoluteCurrentSpeed = abs(currentSpeed);
   if (absoluteCurrentSpeed > abs(targetSpeed) && absoluteCurrentSpeed < startOfStopDamping)
@@ -234,7 +241,7 @@
     return powerEnabled || (!powerEnabled && currentSpeed == 0);
 }

-int ReadPotentiometer(int pin)
+int analogReadMultisampled(int pin)
 {
   const int numberOfSamples = 5;


Adding more dynamic data comparison for shutdown save

--- MID/MID.ino
+++ MID/MID.ino
@@ -244,7 +244,8 @@
 }

 int long saveProtectInit = 0;
-
+int long curProtectValue = 0;
+int long lastProtectRead = 0;

 void loop() {

@@ -256,30 +257,48 @@
     //
     ampInt.listener();

+
+    //
+    // Save protect pin
+    curProtectValue = analogRead(SAVE_PROTECT);
+    //
+    // Trigger data save at shutdown (used 3000uF capacitor)
     if (ampInt.isBig()) {
         Serial.print("\n Detected save pin value: ");
-        Serial.println(analogRead(SAVE_PROTECT));
+        Serial.println(curProtectValue);
     }
-
-    //
-    // last 515
-    if (analogRead(SAVE_PROTECT) < 820 && saveProtectInit == 0 || /* Only first initialization will run */
-        analogRead(SAVE_PROTECT) < 820 && saveProtectInit + MILLIS_PER_MN < millis()) { /* next record after a minute */
+    //
+    // Compare data to detect shutdown and protect multi-records from loop
+    if (curProtectValue < lastProtectRead - 20 && saveProtectInit == 0 || /* Only first initialization will run */
+        curProtectValue < lastProtectRead - 20 &&
+        saveProtectInit + MILLIS_PER_MN < millis()) { /* next record after a minute */
+        //
+        // Save data to eep rom
 //        eepRom.saveCurrentData();
+
         //
         // Show message
-
-        Serial.print("\n\n");
-        Serial.print("Data was recorded in EepRom !!! ********************************* ");
-        Serial.print("\n\n");
+        Serial.print("\n\n  ");
+
+        Serial.print(curProtectValue);
+        Serial.print("  ||  ");
+        Serial.print(lastProtectRead - 20);
+        Serial.print("  <~~~~~~~~~~~~~~~~~~~~~~~~~~~~ Data was RECORDED in EepRom !!!  ");
+        Serial.print("\n\n  ");

         //
         // Close first initialization
-        saveProtectInit = millis();
+
     } else {
         // TODO
     }
+
+    saveProtectInit = millis();
+    //
+    // Move value to last read
+    lastProtectRead = curProtectValue;
+

     //
     // Check recorded consumption


First pass turning both parts on

First pass turning both parts on

--- Monitor.ino
+++ Monitor.ino
@@ -3,7 +3,7 @@
 #include <Wire.h>
 #include <Adafruit_SSD1306.h>
 #include <Adafruit_GFX.h>
-//#include <SD.h>
+#include <SD.h>
 #include <RTClib.h>

 /*
@@ -31,12 +31,12 @@
 #else

 /* Solo use */
-#define OLED_DC 11
-#define OLED_CS 12
-#define OLED_CLK 10
-#define OLED_MOSI 9
-#define OLED_RESET 13
-
+/*#define OLED_DC 11
+ #define OLED_CS 12
+ #define OLED_CLK 10
+ #define OLED_MOSI 9
+ #define OLED_RESET 13
+ */
 #endif

 #define VOLT_ONE A1
@@ -44,7 +44,7 @@
 #define TEMP_TWO A3

 Adafruit_SSD1306 display(OLED_MOSI, OLED_CLK, OLED_DC, OLED_RESET, OLED_CS);
-//RTC_Millis rtc;
+RTC_DS1307 RTC;

 #if (SSD1306_LCDHEIGHT != 64)
 #error("Height incorrect, please fix Adafruit_SSD1306.h!");
@@ -74,10 +74,10 @@
 {
   analogRead(VOLT_ONE); // Discard the first read
   sensorVoltOneI = analogRead(VOLT_ONE);
-
+
   // fake it
   sensorVoltOneI = (millis()/10)%1023; // fake fake TODO
-
+
   sensorVoltOne = sensorVoltOneI * (28.0 / 1024.0);

   addBarGraphDataPoint(sensorVoltOneI);
@@ -85,11 +85,37 @@

 void setup()
 {
+  // Open serial communications and wait for port to open:
+  Serial.begin(9600);
+
+  Wire.begin();
+  RTC.begin();
+
+  if (! RTC.isrunning()) {
+    Serial.println("RTC is NOT running!");
+    // following line sets the RTC to the date & time this sketch was compiled
+    // uncomment it & upload to set the time, date and start run the RTC!
+//    RTC.adjust(DateTime(__DATE__, __TIME__));
+  }
+  else {
+    DateTime now = RTC.now();
+    Serial.print("RTC operating acceptably. Date is ");
+    Serial.print(now.year(), DEC);
+    Serial.print('/');
+    Serial.print(now.month(), DEC);
+    Serial.print('/');
+    Serial.print(now.day(), DEC);
+    Serial.print(' ');
+    Serial.print(now.hour(), DEC);
+    Serial.print(':');
+    Serial.print(now.minute(), DEC);
+    Serial.print(':');
+    Serial.print(now.second(), DEC);
+    Serial.println();
+  }
+
   barGraphIndex = 0;
   memset(barGraphData, 0, sizeof(barGraphData));
-
-  // Open serial communications and wait for port to open:
-  Serial.begin(9600);

   // by default, we'll generate the high voltage from the 3.3v line internally! (neat!)
   display.begin(SSD1306_SWITCHCAPVCC);
@@ -108,26 +134,31 @@
   delay(500);
   display.clearDisplay();   // clears the screen and buffer

-  Serial.print("Initializing SD card...");
+  Serial.println("Initializing SD card...");
   // make sure that the default chip select pin is set to
   // output, even if you don't use it:
-  /*  pinMode(SS, OUTPUT);
-
-   // see if the card is present and can be initialized:
-   if (!SD.begin(SD_CS)) {
-   Serial.println("Card failed, or not present");
-   // don't do anything more:
-   while (1) ;
-   }
-   Serial.println("card initialized.");
-
-   // Open up the file we're going to log to!
-   dataFile = SD.open("datalog.txt", FILE_WRITE);
-   if (! dataFile) {
-   Serial.println("error opening datalog.txt");
-   // Wait forever since we cant write data
-   while (1) ;
-   }*/
+//  pinMode(SS, OUTPUT);
+
+  // see if the card is present and can be initialized:
+  if (!SD.begin(SD_CS, SD_MOSI, SD_MISO, SD_CLK)) {
+    Serial.println("Card failed, or not present");
+    // don't do anything more:
+    while (1) ;
+  }
+  Serial.println("Card initialized.");
+
+  // Open up the file we're going to log to!
+//  char buf[12];
+//  DateTime now = RTC.now();
+//  itoa(now.unixtime(), buf, 10);
+//  Serial.print("Opening datalog at ");
+//  Serial.println(buf);
+  /*dataFile = SD.open(buf, FILE_WRITE);
+  if (! dataFile) {
+    Serial.println("error opening datalog");
+    // Wait forever since we cant write data
+    while (1) ;
+  }*/
 }

@@ -159,9 +190,9 @@

   updateBoostDuration();
-
+
   display.clearDisplay();
-
+
   display.fillRect(0, 0, display.width(), 16, WHITE);
   display.setTextSize(1);
   display.setTextColor(WHITE);
@@ -178,7 +209,7 @@
   display.println("s");

   drawBars();
-
+
   display.setCursor(15, 45);
   display.setTextSize(2);
   display.setTextColor(BLACK, WHITE); // 'inverted' text
@@ -201,3 +232,5 @@

+
+


Update cross-connect sketch with some links and special commands

--- tests/SerialXconnect/SerialXconnect.ino
+++ tests/SerialXconnect/SerialXconnect.ino
@@ -1,9 +1,17 @@
 /*
- * This utility allows you to cross-connect
- * 2 different serials.
+ * This utility allows you to cross-connect two serial channels
+ * using any Arduino-compatible hardware.
  *
- * This is usefull for checking wiring
- * or to convert baud rate, etc.
+ * This is usefull for:
+ *   Checking wiring
+ *   Converting baud rate
+ *   Sending AT commands
+ *   etc.
+ *
+ * Popular AT command sets:
+ *   ESP8266: http://www.espressif.com/sites/default/files/4a-esp8266_at_instruction_set_en_v1.5.4_0.pdf
+ *   SIM800L: https://www.itead.cc/wiki/images/6/6f/SIM800_Series_AT_Command_Manual_V1.05.pdf
+ *   XBee:    https://cdn.sparkfun.com/learn/materials/29/22AT%20Commands.pdf
  */

 #define ser1 Serial
@@ -27,10 +35,39 @@

 void loop() {
   if (ser1.available()) {
-    ser2.write(ser1.read());
+    int c = ser1.read();
+    if (!parseCommands(c)) {
+      ser2.write(c);
+    }
   }
   if (ser2.available()) {
     ser1.write(ser2.read());
   }
 }

+/*
+ * Special commands:
+ *   !speed=1000000 (after ESP8266 command: AT+UART_CUR=1000000,8,1,0,0)
+ */
+
+char cmd_prefix[] = "!speed=";
+uint8_t cmd_prefix_idx = 0;
+
+bool parseCommands(int c) {
+  if (c == cmd_prefix[cmd_prefix_idx]) {
+    cmd_prefix_idx++;
+    if (cmd_prefix_idx >= sizeof(cmd_prefix)-1) {
+      String cmd = ser1.readStringUntil('\n');
+      long baud = cmd.toInt();
+      ser1.print("Speed:"); ser1.println(baud);
+      ser2.begin(baud);
+      cmd_prefix_idx = 0;
+    }
+    return true;
+  } else if (cmd_prefix_idx > 0) {
+    ser2.write(cmd_prefix, cmd_prefix_idx);
+    cmd_prefix_idx = 0;
+  }
+  return false;
+}
+


increase IR return threshold

increase IR return threshold

--- glass/glass.ino
+++ glass/glass.ino
@@ -47,7 +47,7 @@
 boolean ir_bcast_mode = true;
 unsigned long ir_time;
 unsigned int ir_cycle = 200;  // broadcat IR signal every X ms
-unsigned int ir_response_threshold = 600;
+unsigned int ir_response_threshold = 800;

 // EXPERIMENT
 const int MODE_IR = 1;


Fixed code

Fixed code

--- examples/knight_rider3/knight_rider3.ino
+++ examples/knight_rider3/knight_rider3.ino
@@ -8,8 +8,8 @@

 void setup() {
   factory
-    .add( sweep.begin( 4, 5, 6, 7, 8, 9 ).speed( 50 ) );
-    .add( button.begin( 2 ).onPress( sweep, sweep.EVT_TOGGLE ) )
+    .add( sweep.begin( 4, 5, 6, 7, 8, 9 ).speed( 50 ) )
+    .add( button.begin( 2 ).onPress( sweep, sweep.EVT_TOGGLE ) );
 }

 void loop() {


Work in progress: -add output for debug -correct syntax -use external interrupts -rename pin

--- Arduino/Electronic_rule/src/sketch.ino
+++ Arduino/Electronic_rule/src/sketch.ino
@@ -39,12 +39,25 @@
 uint8_t latest_interrupted_pin;
 uint8_t interrupt_count[20]={0}; // 20 possible arduino pins

+int pinA = 2;
+int pinB = 3;
+int pinReset = 4;
+
+// These constants won't change.  They're used to give names
+// to the pins used:
+const int analogInPin = 0;  // Analog input pin that the potentiometer is attached to
+const int analogOutPin = 9; // Analog output pin that the LED is attached to
+
+int sensorValue = 0;        // value read from the pot
+int outputValue = 0;        // value output to the PWM (analog out)
+
+
 void int0()
 	{
 	if ( micros() - int0time < threshold )
 		return;
 	int0history = int0signal;
-	int0signal = bitRead(PIND,2);
+	int0signal = bitRead(PIND,pinA);
 	if ( int0history==int0signal )
 		return;
 	int0time = micros();
@@ -59,28 +72,30 @@
 	if ( micros() - int1time < threshold )
 		return;
 	int1history = int1signal;
-	int1signal = bitRead(PIND,3);
+	int1signal = bitRead(PIND,pinB);
 	if ( int1history==int1signal )
 		return;
 	int1time = micros();
 	}
 void reset()
 {
- rotaryHaflSteps = 0;
+ rotaryHalfSteps = 0;
  }

 void setup() {
-  pinMode(2, INPUT);
-  digitalWrite(2, HIGH);
-  PCintPort::attachInterrupt(2, &int0, CHANGE);
-  pinMode(3, INPUT);
-  digitalWrite(3, HIGH);
-  PCintPort::attachInterrupt(3, &int1, CHANGE);
+  pinMode(pinA, INPUT);
+  digitalWrite(pinA, HIGH);
+  attachInterrupt(0, int0, CHANGE);
+  //PCintPort::attachInterrupt(pinA, &int0, CHANGE);
+  pinMode(pinB, INPUT);
+  digitalWrite(pinB, HIGH);
+  attachInterrupt(1, int1, CHANGE);
+  //PCintPort::attachInterrupt(pinB, &int1, CHANGE);

   // Pin used to get absolute position
-  pinMode(4, INPUT);
-  digitalWrite(4, HIGH);
-  PCintPort::attachInterrupt(4, &reset, CHANGE);
+  pinMode(pinReset, INPUT);
+  digitalWrite(pinReset, HIGH);
+  PCintPort::attachInterrupt(pinReset, &reset, CHANGE);
   Serial.begin(115200);
   Serial.println("---------------------------------------");
 }
@@ -89,7 +104,29 @@

 void loop() {
   long actualRotaryTicks = (rotaryHalfSteps / 2);
-  Serial.println(actualRotaryTicks, DEC);
+    // read the analog in value:
+  Serial.print(rotaryHalfSteps*32+512);
+  Serial.print(",");
+  //Serial.print("\t output = ");
+  //Serial.println(outputValue);
+  delay(2);
+
+  for (int thisPin = 1; thisPin < 6; thisPin++) {
+  sensorValue = analogRead(thisPin);
+
+  // print the results to the serial monitor:
+  //Serial.print("sensor = " );
+  Serial.print(sensorValue);
+  Serial.print(",");
+  //Serial.print("\t output = ");
+  //Serial.println(outputValue);
+  delay(2);
+  }
+   Serial.println("");
+  // wait 2 milliseconds before the next loop
+  // for the analog-to-digital converter to settle
+  // after the last reading:
+  delay(2);
 }


add photon-live-update.ino implementation

--- firmware/examples/photon-live-update.ino
+++ firmware/examples/photon-live-update.ino
@@ -1 +1,49 @@
-#include "SmartMeterReader/SmartMeterReader.h"+#include "application.h"
+#include "SmartMeterReader/SmartMeterReader.h"
+
+const int MIN_READING_GAP = 30; // upload a reading at most every 30 seconds.
+const int photoresistorPin = D3;
+const int pulseLedPin = D6;
+
+SmartMeterReader smartMeterReader(photoresistorPin);
+float reading;
+String stringReading;
+int lastUploadTime = 0;
+
+void recordFlashISR() {
+  smartMeterReader.recordFlash();
+}
+
+void uploadReading() {
+    int now = Time.now();
+    if (now - lastUploadTime > MIN_READING_GAP) {
+        Spark.publish("power-usage", stringReading);
+        lastUploadTime = now;
+    }
+}
+
+void setup() {
+  Serial.begin(115200);
+  pinMode(pulseLedPin, OUTPUT);
+  attachInterrupt(photoresistorPin, recordFlashISR, RISING);
+}
+
+void loop() {
+  if (smartMeterReader.hasReading()) {
+    reading = smartMeterReader.reading();
+
+    Serial.print("Latest reading is ");
+    Serial.print(reading, 2);
+    Serial.println(" kW");
+
+    // flash the led to indicate a meter flash has been recorded
+    digitalWrite(pulseLedPin, HIGH);
+    delay(10);
+    digitalWrite(pulseLedPin, LOW);
+
+    stringReading = String(reading, 2);
+    uploadReading();
+  } else {
+    delay(10);
+  }
+}


working sockets

working sockets

--- firmware/http-neopixel-freddy/freddy.ino
+++ firmware/http-neopixel-freddy/freddy.ino
@@ -29,6 +29,16 @@
 //the neopixel chip type
 #define PIXEL_TYPE WS2812B

+#define STOP "stop"
+#define HEARTEYES "hearteyes"
+#define SPIRALEYES "spiraleyes"
+#define SPARKLEEYES "sparkleeyes"
+#define STATICHEARTEYES "statichearteyes"
+#define RAINBOWEYES "rainboweyes"
+#define WAKEUPEYES "wakeupeyes"
+#define GLOWEYES "gloweyes"
+#define ALLOFF "alloff"
+
 Adafruit_NeoPixel strip = Adafruit_NeoPixel(PIXEL_COUNT, PIXEL_PIN, PIXEL_TYPE);

 TCPServer server = TCPServer(TCP_PORT);
@@ -41,29 +51,7 @@
 char ip[64];
 char tcpstate[64];

-//program and action names
-#define STOP "stop"
-#define SHUTDOWN "shutdown"
-#define PRESTOP "prestop"
-#define RAINBOW "rainbow"
-#define ALTERNATE "alternate"
-#define BLOCKS "blocks"
-#define FADECOLOR "fadeColor"
-#define ALLOFF "allOff"
-#define SETALL "setAll"
-#define LOOPALTERNATE "loopAlternate"
-#define LOOPBLOCKS "loopBlocks"
-#define LATCHPIXEL "latchPixel"
-#define SETPIXEL "setPixel"
-#define LATCH "latch"
-#define ENDRUN "endrun"
-#define SNOW "snow"
-#define WEBSOCKET "websocket" //<- finish this
-#define SETBRIGHTNESS "setBrightness"
-#define USA "usa"
-#define FREDDYMAD "freddymad"
-
-String loopRun = FREDDYMAD;
+String loopRun = STOP;
 String *loopArgs = new String[20];
 String *strArr = new String[20];

@@ -73,12 +61,9 @@
   server.begin();
   strip.begin();
   strip.show(); // Initialize all pixels to 'off'
-  //register the run command as an API endpoint
-  Spark.function("run", run);
   //register the action variable as a GET parameter
   Spark.variable("action", &action, STRING);
   Spark.variable("tcpstate", &tcpstate, STRING);
-  //retister the parameters variable as a GET parameter
   Spark.variable("parameters", &parameters, STRING);
   Spark.variable("ip", &ip, STRING);
   (String(WiFi.localIP()[0]) + "." + String(WiFi.localIP()[1]) + "." +  String(WiFi.localIP()[2]) + "." +  String(WiFi.localIP()[3])).toCharArray(ip, 64);
@@ -86,289 +71,124 @@

 void loop()
 {
+    //TCPServer/Client connections
     if (client.connected()) {
         String("CONNECTED").toCharArray(tcpstate, 64);
-        String dStr = "data:";
+        String dStr = "";
         char data;
         while (client.available())
         {
             data = client.read();
             dStr += String(data);
         }
-        client.println("OK: " + dStr);
+        client.println("OK:" + dStr);
         client.flush();
         dStr.toCharArray(action, 64);
+        loopRun = action;
     }
     else
     {
         // if no client is yet connected, check for a new connection
         String("DISCONNECTED").toCharArray(tcpstate, 64);
         client = server.available();
-    }
+        if(client.connected())
+            return;
+    }
+
+    //////////command processing////////////////////

-    // if(loopRun.equals(STOP))
-    // {
-    //     delay(1000);
-    // }
-    // else if(loopRun.equals(SHUTDOWN))
-    // { //stop all programs and set all pixels to off
-    //     loopRun = PRESTOP;
-    //     delay(1000); //give a program time to stop
-    // }
-    // else if(loopRun.equals(PRESTOP))
-    // {
-    //     loopRun = STOP;
-    //     allOff();
-    // }
-    // else if(loopRun.equals(RAINBOW))
-    // {
-    //     rainbow(20);
-    // }
-    // else if(loopRun.equals(ALTERNATE))
-    // {
-    //     int r1 = stringToInt(loopArgs[0]);
-    //     int g1 = stringToInt(loopArgs[1]);
-    //     int b1 = stringToInt(loopArgs[2]);
-    //     int r2 = stringToInt(loopArgs[3]);
-    //     int g2 = stringToInt(loopArgs[4]);
-    //     int b2 = stringToInt(loopArgs[5]);
-    //     int d = stringToInt(loopArgs[6]);
-
-    //     staticAlternate(r1, g1, b1, r2, g2, b2);
-    //     delay(d);
-    //     staticAlternate(r2, g2, b2, r1, g1, b1);
-    //     delay(d);
-    // }
-    // else if(loopRun.equals(BLOCKS))
-    // {
-    //     int r1 = stringToInt(loopArgs[0]);
-    //     int g1 = stringToInt(loopArgs[1]);
-    //     int b1 = stringToInt(loopArgs[2]);
-    //     int r2 = stringToInt(loopArgs[3]);
-    //     int g2 = stringToInt(loopArgs[4]);
-    //     int b2 = stringToInt(loopArgs[5]);
-    //     int d = stringToInt(loopArgs[6]);
-    //     int blockSize = stringToInt(loopArgs[7]);
-
-    //     animateBlocks(r2, g2, b2, r1, g1, b1, blockSize, d, true);
-    //     animateBlocks(r2, g2, b2, r1, g1, b1, blockSize, d, false);
-    // }
-    // else if(loopRun.equals(FADECOLOR))
-    // {
-    //     int r1 = stringToInt(loopArgs[0]);
-    //     int g1 = stringToInt(loopArgs[1]);
-    //     int b1 = stringToInt(loopArgs[2]);
-    //     int r2 = stringToInt(loopArgs[3]);
-    //     int g2 = stringToInt(loopArgs[4]);
-    //     int b2 = stringToInt(loopArgs[5]);
-    //     int d = stringToInt(loopArgs[6]);
-    //     int duration = stringToInt(loopArgs[7]);
-
-    //     fadeColor(r1, g1, b1, r2, g2, b2, d, duration);
-    //     delay(d);
-    //     fadeColor(r2, g2, b2, r1, g1, b1, d, duration);
-    //     delay(d);
-    // }
-    // else if(loopRun.equals(ENDRUN))
-    // {
-    //     int r1 = stringToInt(loopArgs[0]);
-    //     int g1 = stringToInt(loopArgs[1]);
-    //     int b1 = stringToInt(loopArgs[2]);
-    //     int r2 = stringToInt(loopArgs[3]);
-    //     int g2 = stringToInt(loopArgs[4]);
-    //     int b2 = stringToInt(loopArgs[5]);
-    //     int d = stringToInt(loopArgs[6]);
-    //     endRun(r1, g1, b1, r2, g2, b2, d);
-    // }
-    // else if(loopRun.equals(SNOW))
-    // {
-    //     snow();
-    // }
-    // else if(loopRun.equals(USA))
-    // {
-    //     runUSA();
-    // }
-    // else if(loopRun.equals(FREDDYMAD))
-    // {
-        // runFreddyMad();
-    // }
+    if(loopRun.equals(STOP))
+    {
+        delay(100);
+    }
+    else if(loopRun.equals(ALLOFF))
+    {
+        allOff();
+        loopRun = STOP;
+    }
+    else if(loopRun.equals(HEARTEYES))
+    {
+        heartEyes();
+    }
+    else if(loopRun.equals(SPIRALEYES))
+    {
+        spiralEyes();
+    }
+    else if(loopRun.equals(SPARKLEEYES))
+    {
+        sparkleEyes();
+    }
+    else if(loopRun.equals(STATICHEARTEYES))
+    {
+        staticHeartEyes();
+    }
+    else if(loopRun.equals(RAINBOWEYES))
+    {
+        rainbowEyes();
+    }
+    else
+    {
+        String("INVALID_ACTION").toCharArray(action, 64);
+    }
+}
+
+int heartEyes()
+{
+    drawHeartEye(35, 0, 60);
+    strip.show();
+    delay(100);
+    return 1;
+}
+
+int spiralEyes()
+{
+    for(int i=0; i<50; i++)
+        spiralFreddy(random(128), random(128), random(255), random(50), random(50), random(50));
+    return 1;
+}
+
+int sparkleEyes()
+{
+    sparkleFreddy();
+    delay(100);
+    return 1;
+}
+
+int staticHeartEyes()
+{
+    heartEyeFreddy(75, 0, 130);
+    delay(100);
+    return 1;
+}
+
+int rainbowEyes()
+{
+    rainbow(20);
+    delay(100);
+    return 1;
+}
+
+int wakeUpEyes()
+{
+    wakeUpFreddy();
+    delay(1000);
+    return 1;
+}
+
+int glowEyes()
+{
+    glowEyeFreddy(20);
+    delay(1000);
+    return 1;
 }

 int allOff()
 {
-    setAll(0,0,0);
-    return 1;
-}
-
-/*
-    This function handles the API requests to /run.  The params are a
-    comma separated list.
-    params format is <command>,<param0>,<param1>,...,<paramN>
-    where <command> is the action to be run and <paramN> are the parameters that an individual
-    action needs.
-
-    Actions can be divided into two categories: one where the loop() function is used to animate pixel
-    values and one where pixel values are set a single time.
-    Looped programs can be run using the loopRun variable.  If loopRun is set to STOP the loop will
-    run with no program selected.
-*/
-int run(String params)
-{
-    String* args = stringSplit(params, ',');
-    String command = args[0];
-    strcpy(parameters, params.c_str());
-    strcpy(action, command.c_str());
-
-    if(command.equals(ALLOFF))
-    {
-        loopRun = SHUTDOWN;
-    }
-    else if(command.equals(SETALL))
-    {
-        int r = stringToInt(args[1]);
-        int g = stringToInt(args[2]);
-        int b = stringToInt(args[3]);
-        return setAll(r, g, b);
-    }
-    else if(command.equals(ALTERNATE))
-    {
-        int r1 = stringToInt(args[1]);
-        int g1 = stringToInt(args[2]);
-        int b1 = stringToInt(args[3]);
-        int r2 = stringToInt(args[4]);
-        int g2 = stringToInt(args[5]);
-        int b2 = stringToInt(args[6]);
-        return staticAlternate(r1, g1, b1, r2, g2, b2);
-    }
-    else if(command.equals(LOOPALTERNATE))
-    {
-        loopRun = ALTERNATE;
-        loopArgs[0] = args[1]; //r1
-        loopArgs[1] = args[2]; //g1
-        loopArgs[2] = args[3]; //b1
-        loopArgs[3] = args[4]; //r2
-        loopArgs[4] = args[5]; //g2
-        loopArgs[5] = args[6]; //b2
-        loopArgs[6] = args[7]; //delay
-        return 1;
-    }
-    else if(command.equals(LOOPBLOCKS))
-    {
-        loopRun = BLOCKS;
-        loopArgs[0] = args[1]; //r1
-        loopArgs[1] = args[2]; //g1
-        loopArgs[2] = args[3]; //b1
-        loopArgs[3] = args[4]; //r2
-        loopArgs[4] = args[5]; //g2
-        loopArgs[5] = args[6]; //b2
-        loopArgs[6] = args[7]; //delay
-        loopArgs[7] = args[8]; //block size
-        return 1;
-    }
-    else if(command.equals(BLOCKS))
-    {
-        int r1 = stringToInt(args[1]);
-        int g1 = stringToInt(args[2]);
-        int b1 = stringToInt(args[3]);
-        int r2 = stringToInt(args[4]);
-        int g2 = stringToInt(args[5]);
-        int b2 = stringToInt(args[6]);
-        int blockSize = stringToInt(args[7]);
-        buildBlocks(r1, g1, b1, r2, g2, b2, blockSize);
-        return 1;
-    }
-    else if(command.equals(FADECOLOR))
-    {
-        //possible commands: stop, rainbow, alternate
-        loopRun = FADECOLOR;
-        loopArgs[0] = args[1]; //r1
-        loopArgs[1] = args[2]; //g1
-        loopArgs[2] = args[3]; //b1
-        loopArgs[3] = args[4]; //r2
-        loopArgs[4] = args[5]; //g2
-        loopArgs[5] = args[6]; //b2
-        loopArgs[6] = args[7]; //delay
-        loopArgs[7] = args[8]; //duration
-        return 1;
-    }
-    else if(command.equals(RAINBOW))
-    {
-        loopRun = RAINBOW;
-        return 1;
-    }
-    else if(command.equals(LATCHPIXEL))
-    {
-        int pixel = stringToInt(args[0]);
-        int r1 = stringToInt(args[1]);
-        int g1 = stringToInt(args[2]);
-        int b1 = stringToInt(args[3]);
-        strip.setPixelColor(pixel, strip.Color(r1, g1, b1));
-        strip.show();
-        return 1;
-    }
-    else if(command.equals(SETPIXEL))
-    {
-        int pixel = stringToInt(args[0]);
-        int r1 = stringToInt(args[1]);
-        int g1 = stringToInt(args[2]);
-        int b1 = stringToInt(args[3]);
-        strip.setPixelColor(pixel, strip.Color(r1, g1, b1));
-        return 1;
-    }
-    else if(command.equals(LATCH))
-    {
-        strip.show();
-        return 1;
-    }
-    else if(command.equals(STOP))
-    {
-        loopRun = STOP;
-        return 1;
-    }
-    else if(command.equals(SHUTDOWN))
-    {
-        loopRun = SHUTDOWN;
-        return 1;
-    }
-    else if(command.equals(ENDRUN))
-    {
-        loopRun = ENDRUN;
-        loopArgs[0] = args[1]; //r1
-        loopArgs[1] = args[2]; //g1
-        loopArgs[2] = args[3]; //b1
-        loopArgs[3] = args[4]; //r2
-        loopArgs[4] = args[5]; //g2
-        loopArgs[5] = args[6]; //b2
-        loopArgs[6] = args[7]; //delay
-        return 1;
-    }
-    else if(command.equals(SNOW))
-    {
-        loopRun = SNOW;
-        return 1;
-    }
-    else if(command.equals(SETBRIGHTNESS))
-    {
-        int brightness = stringToInt(args[1]);
-        strip.setBrightness(brightness);
-        strip.show();
-        return 1;
-    }
-    else if(command.equals(USA))
-    {
-        loopRun = USA;
-        return 1;
-    }
-    else if(command.equals(FREDDYMAD))
-    {
-        loopRun = FREDDYMAD;
-        return 1;
-    }
-    else
-    { //command not found
-        return 0;
-    }
-}
+    return setAll(0,0,0);
+}
+
+
+///////////////////////////////////////IMP///////////////////////////////////////

 int setRow(int row, int eye, uint8_t r, uint8_t g, uint8_t b)
 {
@@ -779,199 +599,6 @@
     delay(del);
 }

-int runFreddyMad()
-{
-    // drawHeartEye(35, 0, 60);
-    // strip.show();
-    // delay(5000);
-
-    // for(int i=0; i<50; i++)
-    //     spiralFreddy(random(128), random(128), random(255), random(50), random(50), random(50));
-
-    // blink(100);
-    // delay(1000);
-
-    // drawHeartEye(75, 0, 130);
-    // strip.show();
-    // delay(5000);
-
-    // sparkleFreddy();
-    // delay(1000);
-
-    heartEyeFreddy(75, 0, 130);
-    delay(1000);
-
-    // rainbow(20);
-    // delay(1000);
-
-    // wakeUpFreddy();
-    // delay(1000);
-
-    // glowEyeFreddy(20);
-    // delay(1000);
-
-    return 1;
-}
-
-int runUSA()
-{
-    int blockSize = 5;
-
-    // for(int j=0; j<blockSize; j++)
-    int j = 0;
-    {
-        int count = -1;
-        for(int i=0; i<strip.numPixels(); i++) {
-            if(i % blockSize == 0)
-            {
-                count++;
-                if(count > 2)
-                    count = 0;
-            }
-
-
-            int pix = 0;
-            if( (i + j) >= strip.numPixels())
-            {
-                pix = (i + j) - strip.numPixels();
-            }
-            else
-            {
-                pix = i + j;
-            }
-
-            if(count == 0)
-            {
-                strip.setPixelColor(pix, strip.Color(255, 0, 0));
-            }
-            else if(count == 1)
-            {
-                strip.setPixelColor(pix, strip.Color(255, 255, 255));
-            }
-            else if(count == 2)
-            {
-                strip.setPixelColor(pix, strip.Color(0, 0, 255));
-            }
-
-        }
-        strip.show();
-        delay(500);
-    }
-    return 1;
-}
-
-int snow()
-{
-    for(int i=0; i<strip.numPixels() / 10; i++)
-    { //pick the random pixels
-        int pix = random(strip.numPixels());
-        strip.setPixelColor(pix, strip.Color(0, 0, 0));
-        strip.show();
-        delay(random(50));
-    }
-
-    for(int i=0; i<strip.numPixels() / 10; i++)
-    { //pick the random pixels
-        int pix = random(strip.numPixels());
-        int brightness = random(255);
-        strip.setPixelColor(pix, strip.Color(brightness, brightness, brightness * .20)); //poor mans white balance
-        strip.show();
-        delay(random(50));
-    }
-}
-
-int endRun(uint8_t r1, uint8_t g1, uint8_t b1,
-    uint8_t r2, uint8_t g2, uint8_t b2,
-    uint8_t d)
-{
-    for(int i=0; i<strip.numPixels(); i++)
-    {
-        strip.setPixelColor(i, strip.Color(r1, g1, b1));
-        strip.setPixelColor(strip.numPixels() - i, strip.Color(r2, g2, b2));
-        strip.show();
-        delay(d);
-    }
-}
-
-int animateBlocks(uint8_t r1, uint8_t g1, uint8_t b1,
-    uint8_t r2, uint8_t g2, uint8_t b2, uint8_t blockSize, int d, bool inBlock)
-{
-    for(int j=0; j<blockSize; j++)
-    {
-        for(int i=0; i<strip.numPixels(); i++) {
-            if(i % blockSize == 0)
-            {
-                inBlock = !inBlock;
-            }
-
-            int pix = 0;
-            if( (i + j) >= strip.numPixels())
-            {
-                pix = (i + j) - strip.numPixels();
-            }
-            else
-            {
-                pix = i + j;
-            }
-
-            if(inBlock)
-            {
-                strip.setPixelColor(pix, strip.Color(r1, g1, b1));
-            }
-            else
-            {
-                strip.setPixelColor(pix, strip.Color(r2, g2, b2));
-            }
-        }
-        strip.show();
-        delay(d);
-    }
-
-    return 1;
-}
-
-int buildBlocks(uint8_t r1, uint8_t g1, uint8_t b1,
-    uint8_t r2, uint8_t g2, uint8_t b2,
-    uint8_t blockSize)
-{
-    bool inBlock = true;
-
-    for(int i=0; i<strip.numPixels(); i++) {
-        if(i % blockSize == 0)
-        {
-            inBlock = !inBlock;
-        }
-
-        if(inBlock)
-        {
-            strip.setPixelColor(i, strip.Color(r1, g1, b1));
-        }
-        else
-        {
-            strip.setPixelColor(i, strip.Color(r2, g2, b2));
-        }
-    }
-    strip.show();
-    return 1;
-}
-
-int staticAlternate(uint8_t r1, uint8_t g1, uint8_t b1,
-    uint8_t r2, uint8_t g2, uint8_t b2)
-{
-    for(int i=0; i<strip.numPixels(); i++) {
-        if(i % 2 == 0)
-        {
-            strip.setPixelColor(i, strip.Color(r1, g1, b1));
-        }
-        else
-        {
-            strip.setPixelColor(i, strip.Color(r2, g2, b2));
-        }
-    }
-    strip.show();
-    return 1;
-}
-
 int setRGB(String rgb)
 {
     String r = rgb.substring(0,3);


Using explicit states instead

Using explicit states instead

--- control_board/firmware/vasttrapi.ino
+++ control_board/firmware/vasttrapi.ino
@@ -10,6 +10,8 @@
    - Sleep state where the microcontroller is in deep sleep and the power to the RPi is OFF.
    - Operation state where the microcontroller is triggering the relay to power on the RPi and
    can communication to it via UART.
+   - Shutdown state where the microcontroller sends a UART instruction to the RPi to begin its
+   shutdown sequence, in order to avoid damaging the SD card by abruptly turning the power off.

    ==== CURRENT FUNCTIONALITY ====
    Upon starting up, the microcontroller goes in deep sleep which can be interrupted by a HIGH
@@ -28,14 +30,22 @@

 volatile unsigned long timeToSleep = 0;
 const unsigned long awakePeriod = 600000; // Time in milliseconds to remain awake on every new touch
-const unsigned long shutdownTime = 15000; // Time in milliseconds to wait for the RPi to shutdown
+const unsigned long shutdownTime = 12000; // Time in milliseconds to wait for the RPi to shutdown
+
+enum PowerState {
+  SLEEP,
+  OPERATION,
+  SHUTDOWN
+};
+PowerState currentState = SLEEP; // Begin in a deep sleep state

 /**
    The change interrupt callback
 */
 ISR (PCINT0_vect) {
   // We register a touch event only when the signal from the touchSensor is rising
-  if (digitalRead(touchSensorPin) == HIGH) {
+  // Ignore touch events while in shutdown state
+  if (currentState != SHUTDOWN && digitalRead(touchSensorPin) == HIGH) {
     timeToSleep = millis() + awakePeriod;
   }
 }
@@ -70,20 +80,16 @@
 }

 /**
-   Wait for the RPi to shutdown properly, while disabling interrupts so to
-   avoid new touch events from being registered.
+   Wait for the RPi to shutdown properly. In the future more logic might be added here.
 */
 void waitForRPiShutdown() {
-  noInterrupts();
   delay(shutdownTime);
-  interrupts();
 }

 void setup() {
   Serial.begin(9600); // The Universal ATtinyCore library by Spence Konde uses PB0 as TX and PB1 as RX
   pinMode(rpiPwrPin, OUTPUT);
   pinMode(touchSensorPin, INPUT);
-  turnRPiPowerOff(); // When starting up, make sure the power to the RPi is off
   // Setup pin change interrupt for D2
   PCMSK |= bit (PCINT2); // want pin D2 (PB2)
   GIFR |= bit (PCIF); // clear any outstanding interrupts
@@ -91,12 +97,26 @@
 }

 void loop() {
-  if (millis() >= timeToSleep) { // Check if it is currently time to be asleep
-    signalShutdown(); // Send a command via UART to the RPi which will make it initiate a shutdown sequence
-    waitForRPiShutdown(); // Wait for the RPi to shutdown, while disabling interrupts so new touch events are not logged
-    turnRPiPowerOff(); // Cut off the power to the RPi
-    goToSleep(); // Deep sleep until a change interrupt at the specified pin is triggered
-  } else { // If we should not be sleeping, then we should be awake and doing stuff
-    turnRPiPowerOn(); // Turn on the power to the RPi (if this is already on, it won't make any difference)
+  switch (currentState) {
+    case SLEEP:
+      turnRPiPowerOff(); // Cut off the power to the RPi
+      goToSleep(); // Deep sleep until a change interrupt at the specified pin is triggered
+      currentState = OPERATION; // If we reach this, it means that a touch was registered so we should be operating
+      break;
+    case OPERATION:
+      turnRPiPowerOn(); // Turn on the power to the RPi (if this is already on, it won't make any difference)
+      if (millis() >= timeToSleep) { // Check if it is currently time to be asleep
+        // If we were operational but it's time to sleep, then we should move to the shutdown state
+        currentState = SHUTDOWN;
+      }
+      break;
+    case SHUTDOWN:
+      signalShutdown(); // Send a command via UART to the RPi which will make it initiate a shutdown sequence
+      waitForRPiShutdown(); // Wait for the RPi to shutdown, while disabling interrupts so new touch events are not logged
+      // Now that we should be certain that the RPi has shut down, we can put our state to SLEEP
+      currentState = SLEEP;
+      break;
+    default:
+      break;
   }
 }


replace delay with while loop in WiFiClient.ino

--- libraries/ESP8266WiFi/examples/WiFiClient/WiFiClient.ino
+++ libraries/ESP8266WiFi/examples/WiFiClient/WiFiClient.ino
@@ -71,7 +71,13 @@
   client.print(String("GET ") + url + " HTTP/1.1\r\n" +
                "Host: " + host + "\r\n" +
                "Connection: close\r\n\r\n");
-  delay(10);
+  while (client.available() == 0) {
+    if (timeout - millis() < 0) {
+      Serial.println(">>> Client Timeout !");
+      client.stop();
+      return;
+    }
+  }

   // Read all the lines of the reply from server and print them to Serial
   while(client.available()){


Splitting RGB

Splitting RGB

--- knot/arduino/bath.ino
+++ knot/arduino/bath.ino
@@ -31,12 +31,12 @@
 enum{
   kAcknowledge,     // 0
   kError,           // 1
-  kSetRgb,          // 2
-  kGetTemp,         // 3
-  kGetHumidity,     // 4
-  kGetLight,        // 5
-  knix6,
-  knix7,
+  kSetR,            // 2
+  kSetG,            // 3
+  kSetB,            // 4
+  kGetTemp,         // 5
+  kGetHumidity,     // 6
+  kGetLight,        // 7
   knix8,
   knix9,
   kTemp,            // 10
@@ -47,7 +47,9 @@

 void attachCommandCallbacks(){
   cmdMessenger.attach(              OnUnknownCommand);
-  cmdMessenger.attach(kSetRgb,      OnSetRgb        );
+  cmdMessenger.attach(kSetR,        OnSetR          );
+  cmdMessenger.attach(kSetG,        OnSetG          );
+  cmdMessenger.attach(kSetB,        OnSetB          );
   cmdMessenger.attach(kGetTemp,     OnGetTemp       );
   cmdMessenger.attach(kGetHumidity, OnGetHumidity   );
   cmdMessenger.attach(kGetLight,    OnGetLight      );
@@ -57,15 +59,21 @@
   cmdMessenger.sendCmd(kError,"Command without attached callback");
 }

-void OnSetRgb(){
+void OnSetR(){
   int16_t r = cmdMessenger.readInt16Arg();
+  analogWrite(PIN_LED_R, r);
+  cmdMessenger.sendCmdStart(kAcknowledge);
+}
+
+void OnSetG(){
   int16_t g = cmdMessenger.readInt16Arg();
+  analogWrite(PIN_LED_G, g);
+  cmdMessenger.sendCmdStart(kAcknowledge);
+}
+
+void OnSetB(){
   int16_t b = cmdMessenger.readInt16Arg();
-
-  analogWrite(PIN_LED_R, r);
-  analogWrite(PIN_LED_G, g);
   analogWrite(PIN_LED_B, b);
-
   cmdMessenger.sendCmdStart(kAcknowledge);
 }


working with answer to web

working with answer to web

--- esp8266_tmp/test_sketch/test_sketch.ino
+++ esp8266_tmp/test_sketch/test_sketch.ino
@@ -15,7 +15,7 @@
 ESP8266WebServer server(80); // on instancie un serveur ecoutant sur le port 80
 float t, h;
 //const int average_loop = 300;
-//char answerBuffer[5000];
+char answerBuffer[5000];

 void setup(void){
   Serial.println("Initializing...");
@@ -39,20 +39,20 @@

    //on commence a ecouter les requetes venant de l'exterieur
   server.on("/all", [](){
-  //PString answer(answerBuffer, sizeof(answerBuffer));
+  PString answer(answerBuffer, sizeof(answerBuffer));
     h = dht.readHumidity();          // Read humidity (percent)
     t = dht.readTemperature(false);     // Read temperature
-  //  answer.print("T:");
-  //  answer.print(t);
-  //  answer.print(",H:");
-  //  answer.print(h);
-  //  answer.print("\n");
+    answer.print("T:");
+    answer.print(t);
+    answer.print(",H:");
+    answer.print(h);
+    answer.print("\n");
   //  server.send(200, "text/plain", answerBuffer);
-    server.send(200, "text/plain", "Data read sent to serial");
+    server.send(200, "text/plain", answerBuffer);
     Serial.print("T:");
+    Serial.print(t);
+    Serial.print(",H:");
     Serial.print(h);
-    Serial.print(",H:");
-    Serial.print(t);
     Serial.println(";");
   });
   server.begin();


Added battery voltage from divider to reading.

--- freezer_node_v0_2/freezer_node_v0_2.ino
+++ freezer_node_v0_2/freezer_node_v0_2.ino
@@ -26,11 +26,13 @@
 #define DEBUG      1     // set to 1 to display each loop() run
 #define BAUD_RATE  57600

+#define APIN_BATTERY    0  // data connection for battery
 #define APIN_LDR        1  // data connection for photocell
 #define DPIN_ONEWIRE    3  // data connection for the Dallas OneWire bus
 #define DPIN_HALL       7  // data connection for hall effect
 #define DPIN_RF_LED     9  // led indicating rf traffic
 #define LED_DELAY       500
+#define VDD_RATIO       1.622

 #define MEASURE_PERIOD  100 // how often to measure, in tenths of seconds
 #define RETRY_PERIOD    10  // how soon to retry if ACK didn't come in
@@ -69,6 +71,7 @@
             byte door;    // door sensor: 0..1
             int tempIn;   // temperature: -500..+500 (tenths)
             int tempOut;  // temperature: -500..+500 (tenths)
+            int battery;  // battery voltage
         };
     };
 };
@@ -191,6 +194,11 @@
     sensorData.tempIn = smoothedAverage(sensorData.tempIn, tempIn, firstTime);
     int tempOut = int(oneWireSensors.getTempC(thermometerOutside) * 10);
     sensorData.tempOut = smoothedAverage(sensorData.tempOut, tempOut, firstTime);
+
+    // read battery voltage
+    int val = analogRead(APIN_BATTERY);
+    int battery = int(val * 0.00488 * VDD_RATIO * 10);
+    sensorData.battery = smoothedAverage(sensorData.battery, battery, firstTime);

 }

@@ -215,6 +223,8 @@
         Serial.print((int) sensorData.tempIn);
         Serial.print(' ');
         Serial.print((int) sensorData.tempOut);
+        Serial.print(' ');
+        Serial.print((int) sensorData.battery);
         Serial.println();
         serialFlush();
     #endif


renamed NoteManager

renamed NoteManager

--- chaise2.ino
+++ chaise2.ino
@@ -32,7 +32,6 @@
 #endif

 Heartbeat heartbeat(LED_BUILTIN,250,2000);
-NoteManager noteManager = NoteManager();
 uint16_t loop_count = 0;

 CRGB leds[NUM_LEDS];
@@ -73,6 +72,7 @@
 	}

 	FastLED.addLeds<CHIPSET, DATA_PIN, COLOR_ORDER>(leds, NUM_LEDS).setCorrection( TypicalLEDStrip );
+	memset8( leds, 0, NUM_LEDS * sizeof(CRGB));
 }

 void loop() {
@@ -83,7 +83,7 @@
 		for(uint16_t i = 0; i <= MAX_TOUCH_IDX; i++) {
 			if( b_n.test(i) ) {
 				//Serial.print("will play "); Serial.println(i);
-				noteManager.play(i);
+				Conductor.play(i);
 			}
 		}
 	}
@@ -93,7 +93,7 @@
 		std::bitset<10> b_r (r);
 		for(uint16_t i = 0; i <= MAX_TOUCH_IDX; i++) {
 			if( b_r.test(i) ) {
-				noteManager.release(i);
+				Conductor.release(i);
 			}
 		}
 	}
@@ -175,7 +175,7 @@
 	//	clear the buffer
 	memset8( leds, 0, NUM_LEDS * sizeof(CRGB));
 	//	update the note manager *before* showing leds
-	noteManager.update(leds);
+	Conductor.update(leds);

 	// if( loop_count++ % 1000 == 0 ) {
 	// 	for(uint16_t i = 0; i < NUM_LEDS; i++ ) {


Updated ground station pin

Updated ground station pin

--- GroundStationCode/GroundStationCode.ino
+++ GroundStationCode/GroundStationCode.ino
@@ -68,12 +68,12 @@
 int flightState;

 //I/O pins
-const int masterEnablePin = A0;
+const int masterEnablePin = A5;
 const int finOverridePin = A1;
 //const int servoPowerPin = A2; //Digital inputs for important flags
 const int buttonPin = A3;//Input to toggle display modes
 const int packetLED = A2; //Output pins for display LEDs
-const int mysteryLED = A5;
+const int mysteryLED = A0;
 const int finLLED = 5;
 const int finRLED = 20;
 const int finCLED = 21;


encryption check

encryption check

not working

--- _11-mqtt-lwt-test/_11-mqtt-lwt-test.ino
+++ _11-mqtt-lwt-test/_11-mqtt-lwt-test.ino
@@ -7,7 +7,7 @@
 #define _IS_MY_HOME
 // wifi
 #ifdef _IS_MY_HOME
-#include "/usr/local/src/ap_settingii.h"
+#include "/usr/local/src/ap_setting.h"
 #else
 #include "ap_setting.h"
 #endif
@@ -21,6 +21,10 @@

 String clientName;
 String payload;
+
+// send reset info
+String getResetInfo ;
+int ResetInfo = LOW;

 WiFiClient wifiClient;
 IPAddress server(192, 168, 10, 10);
@@ -72,37 +76,18 @@
   Serial.print("---------------------------------> IP address: ");
   Serial.println(WiFi.localIP());

-  /*
-    //
-    //Serial.println("Starting UDP");
-    udp.begin(localPort);
-    //Serial.print("Local port: ");
-    //Serial.println(udp.localPort());
-    delay(5000);
-    setSyncProvider(getNtpTime);
-
-    if (timeStatus() == timeNotSet) {
-      Serial.println("waiting for sync message");
-    }
-  */
-
-  /*
-    //startMills = millis();
-
-    if (WiFi.status() == WL_CONNECTED) {
-      if (!client.connected()) {
-        if (client.connect((char*) clientName.c_str(), willTopic, 0, true, willMessage)) {
-          client.publish(willTopic, "1", true);
-          //client.publish(hellotopic, "hello again wifi and mqtt from ESP8266 s20");
-          Serial.println("reconnecting wifi and mqtt");
-        } else {
-          Serial.println("mqtt publish fail after wifi reconnect");
-        }
-      } else {
-        client.publish(hellotopic, "hello again wifi from ESP8266 s20");
-      }
-    }
-  */
+
+
+
+//  Serial.println(WiFi.psk());
+
+
+/*
+  byte encryption = WiFi.encryptionType();
+  Serial.print("Encryption Type:");
+  Serial.println(encryption, HEX);
+*/
+
 }

 boolean reconnect() {
@@ -110,8 +95,13 @@
   delay(100);
   if (client.connect((char*) clientName.c_str(), willTopic, 0, true, willMessage)) {
     Serial.println("-----> mqtt connected");
-    //client.publish(hellotopic, "hello again 1 from ESP8266 s20");
     client.publish(willTopic, "1", true);
+    if ( ResetInfo == LOW) {
+      client.publish(hellotopic, (char*) getResetInfo.c_str());
+      ResetInfo = HIGH;
+    } else {
+      client.publish(hellotopic, "hello again 1 from ESP8266 s20");
+    }
   } else {
     Serial.print("-----------------> failed, rc=");
     Serial.println(client.state());
@@ -121,7 +111,7 @@
 }

 void setup() {
-  Serial.begin(74880);
+  Serial.begin(115200);
   Serial.println();
   //Serial.println("lwt test");
   //Serial.print("ESP.getFlashChipSize() : ");
@@ -144,24 +134,8 @@
   lastReconnectAttempt = 0;

-  String getResetInfo = "hello from ESP8266 s20 ";
+  getResetInfo = "hello from ESP8266 s20 ";
   getResetInfo += ESP.getResetInfo().substring(0, 30);
-
-  if (WiFi.status() == WL_CONNECTED) {
-    if (!client.connected()) {
-      if (client.connect((char*) clientName.c_str(), willTopic, 0, true, willMessage)) {
-        //client.publish(hellotopic, (char*) getResetInfo.c_str());
-        client.publish(willTopic, "1", true);
-        //Serial.print("Sending payload: ");
-        //Serial.println(getResetInfo);
-      }
-    } else {
-      //client.publish(hellotopic, (char*) getResetInfo.c_str());
-      client.publish(willTopic, "1", true);
-      //Serial.print("Sending payload: ");
-      //Serial.println(getResetInfo);
-    }
-  }

 }


Small update on texts and documentation

Small update on texts and documentation

--- OLED-Wifi-Scanner/OLED-Wifi-Scanner.ino
+++ OLED-Wifi-Scanner/OLED-Wifi-Scanner.ino
@@ -6,7 +6,7 @@
 // History : V1.00 2014-04-21 - First release
 //         : V1.11 2015-09-23 - rewrite for ESP8266 target
 //         : V1.20 2016-07-13 - Added new OLED Library and NeoPixelBus
-//         : V1.3  2016-09-16 - Rewrote everything, just a plain Wifi-Scanner showing all available AP on OLED.
+//         : V1.3  2016-09-16 - Rewrote everything, just a plain Wifi-Scanner showing all available AP on OLED. Millenseer.
 //
 // **********************************************************************************

@@ -195,6 +195,8 @@
   display->setTextAlignment(TEXT_ALIGN_LEFT);
   display->setFont(Roboto_Condensed_12);

+  // As the display has only space for 4 lines of text (WIFI_DISPLAY_NET), I am rotating the list
+  // The timer increases currentNumberOfNetwork with WIFI_DISPLAY_NET items

   for (int i = 0; i < WIFI_DISPLAY_NET; i++) {
     // Print SSID and RSSI for each network found
@@ -249,7 +251,7 @@
   Purpose : Called by ticker to tell main loop we need to update data
   Input   : -
   Output  : -
-  Comments: -
+  Comments: Timer to update the list and trigger the Wifi-Rescan
   ====================================================================== */
 void setReadyForUpdate() {
   Serial.println("Setting readyForUpdate to true");
@@ -336,9 +338,10 @@
   Serial.println(F("Setup done"));
   drawProgress(&display, 100, F("Setup Done"));

-
+  // setup the OLED-display UI
   if (has_display) {
     ui.setTargetFPS(30);
+    // Dont use the famous frame slider here
     //ui.setFrameAnimation(SLIDE_LEFT);
     ui.disableAutoTransition();
     ui.setFrames(frames, numberOfFrames);
@@ -346,7 +349,9 @@
     display.flipScreenVertically();
   }

+  // Setting Timer for updating the WIfi-list display
   ticker.attach(5, setReadyForUpdate);
+  // Setting Timer to rescan Wifi-list
   tickerWifi.attach(60, setReadyForWifiUpdate);
 }


Update main loop & state machine to better handle the car as built

--- VehicleController/VehicleController.ino
+++ VehicleController/VehicleController.ino
@@ -129,35 +129,61 @@
     // Start communication to the DAC & zero the outputs
     myDAC.begin();
     myDAC.analogWrite(0, 0);
-
-    digitalWriteFast(PIN_SHUTDOWN_CTRL, HIGH);
-    digitalWriteFast(PIN_CLOSE_AIR, HIGH);
 }

 void loop(){

+    // Check for bytes waiting on the Serial connection (Primarily for debug purposes)
     checkIncomingBytes();
-    if (state == VC_INIT_STATE) {
-        if (CANBus.available()) {
-            // Beep the beeper
-            digitalWriteFast(PIN_5V_0, HIGH);
-            delay(1500);
-            digitalWriteFast(PIN_5V_0, LOW);
-
-            msTimer.begin(msTimerISR, 1000); // Starts a 1ms timer interrupt
-            state = VC_RUNNING_STATE;
-        }
-    }

     if (CANBus.available()) {
         CANBus.read(rxmsg);
         handleCANMessage(&rxmsg);
     }
-
+
     gpsTask();

+    if (state == VC_INIT_STATE) {
+
+        // Start the car!
+        if(digitalRead(PIN_START_CAR) == LOW){
+
+            // Beep the beeper
+            //digitalWriteFast(PIN_5V_0, HIGH);
+            //delay(1500);
+            //digitalWriteFast(PIN_5V_0, LOW);
+
+            // Close the shutdown circuit, and precharge for 100ms
+            digitalWriteFast(PIN_SHUTDOWN_CTRL, HIGH);
+            digitalWriteFast(PIN_PRECHARGE, HIGH);
+            delay(100);
+
+            // Close AIR+
+            digitalWriteFast(PIN_CLOSE_AIR, HIGH);
+            digitalWriteFast(PIN_PRECHARGE, LOW);
+            delay(100);
+
+            msTimer.begin(msTimerISR, 1000); // Starts a 1ms timer interrupt
+            state = VC_RUNNING_STATE;
+        }
+    }
+
     if (state == VC_RUNNING_STATE) {
+
+        if (digitalRead(PIN_START_CAR) == HIGH) {
+            digitalWriteFast(PIN_CLOSE_AIR, LOW);
+            delay(10);
+            digitalWriteFast(PIN_SHUTDOWN_CTRL, LOW);
+            msTimer.end();
+
+            state = VC_INIT_STATE;
+        }
+
         uint16_t tempThrottle = getThrottle();
+        if (tempThrottle > 4095) {
+            tempThrottle = 0;
+            state = VC_ABORT_STATE;
+        }
         myDAC.analogWrite(tempThrottle, tempThrottle);

         if (!throttleTimer) {
@@ -194,6 +220,8 @@
     }
 }

+// Begins transmission for all available on a given i2c_t3 bus
+// If a device reports back, this function will alert the user
 void scanI2CBus(i2c_t3* buspt){
     int nDevices = 0;
     for (uint8_t i = 1; i < 127; i++){


Moving code to a class

Moving code to a class

--- moisture/moisture.ino
+++ moisture/moisture.ino
@@ -23,9 +23,25 @@
 // See guide for details on sensor wiring and usage:
 //   https://learn.adafruit.com/dht/overview

+
+SensorGroup *myGroup;
+
+
 DHT_Unified *dht_array[N_SENSORS];

 uint32_t delayMS;
+
+/**@brief Creating a class for the group of sensors */
+class SensorGroup
+{
+public:
+  void print_measurement();
+};
+
+void SensorGroup::test()
+{
+Serial.println("Test in the class");
+}

 void setup() {
   int i;
@@ -46,7 +62,11 @@
   }

   // Set delay between sensor readings based on sensor details.
+  dht_array[0]->humidity().getSensor(&sensor);
   delayMS = sensor.min_delay / 1000;
+
+
+  myGroup.print_measurement();
 }

 void loop() {
@@ -56,7 +76,7 @@
 }

 /** @brief Print data from all sensors */
-void print_measurement()
+void SensorGroup::print_measurement()
 {
   uint8_t i;
   sensors_event_t event;


Update OnewireKeypad_EventKey.ino

Update OnewireKeypad_EventKey.ino

--- Examples/OnewireKeypad_EventKey/OnewireKeypad_EventKey.ino
+++ Examples/OnewireKeypad_EventKey/OnewireKeypad_EventKey.ino
@@ -1,3 +1,5 @@
+//Original Creator: Andrew Mascolo
+
 #include <OnewireKeypad.h>

 char KEYS[]= {


ardubreakout should use new separate print class

--- examples/ArduBreakout/ArduBreakout.ino
+++ examples/ArduBreakout/ArduBreakout.ino
@@ -16,6 +16,7 @@

 Arduboy arduboy;
 ArduboyPlaytune tunes;
+AbPrinter text(arduboy);

 const unsigned int COLUMNS = 13; //Columns of bricks
 const unsigned int ROWS = 4;     //Rows of bricks
@@ -34,7 +35,7 @@
 unsigned int brickCount;  //Amount of bricks hit
 byte pad,pad2,pad3;     //Button press buffer used to stop pause repeating
 byte oldpad,oldpad2,oldpad3;
-char text[16];      //General string buffer
+char text_buffer[16];      //General string buffer
 boolean start=false;    //If in menu or in game
 boolean initialDraw=false;//If the inital draw has happened
 char initials[3];     //Initials used in high score
@@ -313,9 +314,9 @@

 void drawBall()
 {
-  // arduboy.setCursor(0,0);
-  // arduboy.print(arduboy.cpuLoad());
-  // arduboy.print("  ");
+  // text.setCursor(0,0);
+  // text.print(arduboy.cpuLoad());
+  // text.print("  ");
   arduboy.drawPixel(xb,   yb,   0);
   arduboy.drawPixel(xb+1, yb,   0);
   arduboy.drawPixel(xb,   yb+1, 0);
@@ -338,9 +339,9 @@

 void drawLives()
 {
-  sprintf(text, "LIVES:%u", lives);
-  arduboy.setCursor(0, 90);
-  arduboy.print(text);
+  sprintf(text_buffer, "LIVES:%u", lives);
+  text.setCursor(0, 90);
+  text.print(text_buffer);
 }

 void drawGameOver()
@@ -349,10 +350,10 @@
   arduboy.drawPixel(xb+1, yb,   0);
   arduboy.drawPixel(xb,   yb+1, 0);
   arduboy.drawPixel(xb+1, yb+1, 0);
-  arduboy.setCursor(52, 42);
-  arduboy.print( "Game");
-  arduboy.setCursor(52, 54);
-  arduboy.print("Over");
+  text.setCursor(52, 42);
+  text.print( "Game");
+  text.setCursor(52, 54);
+  text.print("Over");
   arduboy.display();
   delay(4000);
 }
@@ -361,8 +362,8 @@
 {
   paused = true;
   //Draw pause to the screen
-  arduboy.setCursor(52, 45);
-  arduboy.print("PAUSE");
+  text.setCursor(52, 45);
+  text.print("PAUSE");
   arduboy.display();
   while (paused)
   {
@@ -382,9 +383,9 @@
 void Score()
 {
   score += (level*10);
-  sprintf(text, "SCORE:%u", score);
-  arduboy.setCursor(80, 90);
-  arduboy.print(text);
+  sprintf(text_buffer, "SCORE:%u", score);
+  text.setCursor(80, 90);
+  text.print(text_buffer);
 }

 void newLevel(){
@@ -416,9 +417,9 @@
   drawLives();

   //Draws the initial score
-  sprintf(text, "SCORE:%u", score);
-  arduboy.setCursor(80, 90);
-  arduboy.print(text);
+  sprintf(text_buffer, "SCORE:%u", score);
+  text.setCursor(80, 90);
+  text.print(text_buffer);
 }

 //Used to delay images while reading button input
@@ -448,15 +449,15 @@
   int address = file*10*5;
   byte hi, lo;
   arduboy.clear();
-  arduboy.setCursor(32, 0);
-  arduboy.print("HIGH SCORES");
+  text.setCursor(32, 0);
+  text.print("HIGH SCORES");
   arduboy.display();

   for(int i = 0; i < 10; i++)
   {
-    sprintf(text, "%2d", i+1);
-    arduboy.setCursor(x,y+(i*8));
-    arduboy.print( text);
+    sprintf(text_buffer, "%2d", i+1);
+    text.setCursor(x,y+(i*8));
+    text.print(text_buffer);
     arduboy.display();
     hi = EEPROM.read(address + (5*i));
     lo = EEPROM.read(address + (5*i) + 1);
@@ -476,9 +477,9 @@

     if (score > 0)
     {
-      sprintf(text, "%c%c%c %u", initials[0], initials[1], initials[2], score);
-      arduboy.setCursor(x + 24, y + (i*8));
-      arduboy.print(text);
+      sprintf(text_buffer, "%c%c%c %u", initials[0], initials[1], initials[2], score);
+      text.setCursor(x + 24, y + (i*8));
+      text.print(text_buffer);
       arduboy.display();
     }
   }
@@ -494,10 +495,10 @@
 {
   //Clears the screen
   arduboy.clear();
-  arduboy.setCursor(16,22);
-  arduboy.setTextSize(2);
-  arduboy.print("ARAKNOID");
-  arduboy.setTextSize(1);
+  text.setCursor(16,22);
+  text.setSize(2);
+  text.print("ARAKNOID");
+  text.setSize(1);
   arduboy.display();
   if (pollFireButton(25))
   {
@@ -509,8 +510,8 @@
   {
     //Draws "Press FIRE"
     //arduboy.bitmap(31, 53, fire);  arduboy.display();
-    arduboy.setCursor(31, 53);
-    arduboy.print("PRESS FIRE!");
+    text.setCursor(31, 53);
+    text.print("PRESS FIRE!");
     arduboy.display();

     if (pollFireButton(50))
@@ -519,10 +520,10 @@
     }
     //Removes "Press FIRE"
     arduboy.clear();
-    arduboy.setCursor(16,22);
-    arduboy.setTextSize(2);
-    arduboy.print("ARAKNOID");
-    arduboy.setTextSize(1);
+    text.setCursor(16,22);
+    text.setSize(2);
+    text.print("ARAKNOID");
+    text.setSize(1);
     arduboy.display();

     arduboy.display();
@@ -551,17 +552,17 @@
     arduboy.display();
     arduboy.clear();

-    arduboy.setCursor(16,0);
-    arduboy.print("HIGH SCORE");
-    sprintf(text, "%u", score);
-    arduboy.setCursor(88, 0);
-    arduboy.print(text);
-    arduboy.setCursor(56, 20);
-    arduboy.print(initials[0]);
-    arduboy.setCursor(64, 20);
-    arduboy.print(initials[1]);
-    arduboy.setCursor(72, 20);
-    arduboy.print(initials[2]);
+    text.setCursor(16,0);
+    text.print("HIGH SCORE");
+    sprintf(text_buffer, "%u", score);
+    text.setCursor(88, 0);
+    text.print(text_buffer);
+    text.setCursor(56, 20);
+    text.print(initials[0]);
+    text.setCursor(64, 20);
+    text.print(initials[1]);
+    text.setCursor(72, 20);
+    text.print(initials[2]);
     for(byte i = 0; i < 3; i++)
     {
       arduboy.drawLine(56 + (i*8), 27, 56 + (i*8) + 6, 27, 1);


Adding more comments to Ping example.

Adding more comments to Ping example.

--- examples/ESP8266_Ping/ESP8266_Ping.ino
+++ examples/ESP8266_Ping/ESP8266_Ping.ino
@@ -1,23 +1,54 @@
+/************************************************************
+ESP8266_Ping.h
+SparkFun ESP8266 AT library - Ping Demo
+Jim Lindblom @ SparkFun Electronics
+Original Creation Date: July 16, 2015
+https://github.com/sparkfun/SparkFun_ESP8266_AT_Arduino_Library
+
+This example pings a destination server over and over and over.
+It'll print the response time (in ms) to the serial monitor.
+
+Development environment specifics:
+  IDE: Arduino 1.6.5
+  Hardware Platform: Arduino Uno
+  ESP8266 WiFi Shield Version: 1.0
+
+This code is released under the MIT license.
+
+Distributed as-is; no warranty is given.
+************************************************************/
+
 #include <SoftwareSerial.h>
 #include <SparkFunESP8266WiFi.h>

-IPAddress ip(204, 144, 132, 37);
+// Replace these two character strings with the name and
+// password of your WiFi network.
+const char mySSID[] = "yourSSIDhere";
+const char myPSK[] = "yourPWDhere";
+
+char destServer[] = "sparkfun.com";
+
 void setup()
 {
   Serial.begin(9600);
-  while (!Serial.available()) ;
-  while (esp8266.begin() != true) ;
+  while (esp8266.begin() != true)
+  {
+    Serial.print("Error connecting to ESP8266.");
+	delay(1000);
+  }
+
   if (esp8266.status() <= 0)
   {
-    while (esp8266.connect("sparkfun-guest", "sparkfun6333") < 0)
+    while (esp8266.connect(mySSID, myPSK) < 0)
       delay(1000);
   }
   delay(1000);
-  Serial.print("Pinging 204.144.132.37: ");
+  Serial.print("Pinging ");
+  Serial.println(destServer);
 }

 void loop()
 {
-  Serial.println(esp8266.ping(ip));
+  Serial.println(esp8266.ping(destServer));
   delay(1000);
 }


Added ATmega48 and ATmega88

Added ATmega48 and ATmega88

--- examples/IRremoteInfo/IRremoteInfo.ino
+++ examples/IRremoteInfo/IRremoteInfo.ino
@@ -117,8 +117,12 @@
   Serial.println(F("ATmega164"));
 #elif defined(__AVR_ATmega128__)
   Serial.println(F("ATmega128"));
+#elif defined(__AVR_ATmega88__) || defined(__AVR_ATmega88P__)
+  Serial.println(F("ATmega88"));
 #elif defined(__AVR_ATmega64__)
   Serial.println(F("ATmega64"));
+#elif defined(__AVR_ATmega48__) || defined(__AVR_ATmega48P__)
+  Serial.println(F("ATmega48"));
 #elif defined(__AVR_ATmega32__)
   Serial.println(F("ATmega32"));
 #elif defined(__AVR_ATmega16__)


Cleaning up code

Cleaning up code

--- examples/RGBCalibrate/RGBCalibrate.ino
+++ examples/RGBCalibrate/RGBCalibrate.ino
@@ -41,7 +41,7 @@
    	LEDS.setBrightness(255);

       // Uncomment one of the following lines for your leds arrangement.
-      // LEDS.addLeds<TM1803, DATA_PIN, RGB>(leds, NUM_LEDS);
+      LEDS.addLeds<TM1803, DATA_PIN, RGB>(leds, NUM_LEDS);
       // LEDS.addLeds<TM1804, DATA_PIN, RGB>(leds, NUM_LEDS);
       // LEDS.addLeds<TM1809, DATA_PIN, RGB>(leds, NUM_LEDS);
       // LEDS.addLeds<WS2811, DATA_PIN, RGB>(leds, NUM_LEDS);


improved comment

improved comment

--- examples/Tlc59711Test/Tlc59711Test.ino
+++ examples/Tlc59711Test/Tlc59711Test.ino
@@ -6,8 +6,7 @@
 // open source (see LICENSE file)
 //
 // notes:
-// * for "flicker" tests, values written at ~30 Hz to make possible flickering
-//  visible
+// * see page "Running Tlc59711Test" of the library's Wiki on GitHub
 //

 #include <Tlc59711.h>


Update Keypad.ino

Update Keypad.ino

--- ComboKeypad/Keypad.ino
+++ ComboKeypad/Keypad.ino
@@ -1,5 +1,5 @@
 //USER VARIABLES, Variables that YOU change for YOUR preferences
-const int buttons[] {7, 6, 5, 4};   //The PIN of all of the buttons
+const int buttons[] {7, 6, 5, 4};   //The PIN of all of the buttons {FIRST, SECOND, etc...}

 const int combination[] = {3, 1, 2, 4};  //what the combination is, to add just add a "," and a number

@@ -31,12 +31,14 @@

 //Function setup
 void setup() {
+    //Used to be able to add as many buttons as you want
     for(int setb = 0; setb < numOfButtons; setb++){
       pinMode(buttons[setb], INPUT); // sets All Input pin
      }

-    pinMode(wrongLight, OUTPUT);   //Wrong Light
-    pinMode(rightLight, OUTPUT);   //Right Light
+    pinMode(wrongLight, OUTPUT);   //Wrong Light, "Red" Light
+    pinMode(rightLight, OUTPUT);   //Right Light, "Green" Light
+
   if(!useFiveVoltpin){
   pinMode(buttonStream, OUTPUT);   //Button Stream
   digitalWrite(buttonStream, 1);   //Starts the Electricity for button pull down resistor
@@ -59,6 +61,7 @@

     //If timer has run out, reset all arrays the count variable
     if(count != 0 && millis() - time > del) {   //Resets if timer runs out
+      Serial.println("runns resety");
       reset();   //Runs the Reset function
     }

@@ -70,7 +73,7 @@
 }

  //////////////////////////////////////////////////////////////////////////////
- /// Checks if what button user presses is correct                          ///
+ /// Checks if what button the user presses is correct                          ///
  //////////////////////////////////////////////////////////////////////////////
  if(value == numOfCombos) { // Correction number
    digitalWrite(9, 1); //Corrections Light
@@ -82,7 +85,7 @@
 ///////////////////////////////////////////////////////////////////////////////
 /// If the combo number limit is reached                                    ///
 /// and some or all are wrong                                               ///
-/// \                                                                        ///
+/// \                                                                       ///
 /// this for loop is here to be able to customize this code                 ///
 /// to add any amount of combinations and buttons                           ///
 ///////////////////////////////////////////////////////////////////////////////
@@ -95,17 +98,16 @@
   }
 }

-// Which number i have input
+// Which number I have input
 if (count < numOfCombos) { // Restricts the variable to not go over 4

-  //Start of Combo,(Badger and Skinny Pete)
+  //Start of Combo,('(Badger and Skinny Pete)')
   for(int a = 0; a < numOfButtons; a++){
     pressButton(a, buttonsRead[a]);   //Runs the function pressButton
 ////////////////////////////////////////to save the button press and
 ////////////////////////////////////////add to the counter
   }
 }
-// Which number i have input end

 }   //Function Loop end

@@ -139,12 +141,16 @@
 // Functions "Reset"
 void reset() {
   // Reset everything
+ Serial.println("Reset");
+
   for (int t = 0; t < numOfCombos; t++) {   //You could aparently declare an int in a for loop... C++ Style?
     input[t] = 0;   //Zeros the input array
   }
-   digitalWrite(rightLight, 0);   //Turns the "Green" light off
-    digitalWrite(wrongLight, 0);   //Turns the "Red" light off
-     count = 0;  //Sets the counter to 0
+
+    time = millis();   //Sets this to 0 because it might be a bugg there
+     digitalWrite(rightLight, 0);   //Turns the "Green" light off
+      digitalWrite(wrongLight, 0);   //Turns the "Red" light off
+       count = 0;  //Sets the counter to 0

 }//Function Reset end

@@ -153,8 +159,8 @@
   Serial.print("Count = ");
    Serial.print(count);
     Serial.print(", |");
-    for(int a = 0; a < numOfCombos; a++){
-     Serial.print(input[a]);   //Prints which number has been pressed
-   }
-   Serial.println();
+     for(int a = 0; a < numOfCombos; a++){
+      Serial.print(input[a]);   //Prints which number has been pressed
+    }
+       Serial.println();
 }


Fix compile errors (undefined vars and case issue with var name)

--- Arduino/coopController/coopController.ino
+++ Arduino/coopController/coopController.ino
@@ -94,9 +94,11 @@
 int           doorTopVal      = 0;
 int           doorTopVal2     = 0;
 int           doorTopState    = 0;
+int           doorTopPrev     = 0;
 int           doorBottomVal   = 0;
 int           doorBottomVal2  = 0;
 int           doorBottomState = 0;
+int           doorBottomPrev  = 0;

 RTC_DS1307 rtc;
 OneWire ds(tempSense);
@@ -466,7 +468,7 @@
   // ---------------------------

   // Ensure fan is on if temperature is at or above fan threshold.
-  if (TempF >= fanThreshold) {
+  if (tempF >= fanThreshold) {
     if (!fanState) {
       if (Debugging) {
         debugger.println("Turning on fan.");
@@ -485,7 +487,7 @@
   }

   // Ensure water heater is on if temperature is at or below heater threshold.
-  if (TempF <= heaterThreshold) {
+  if (tempF <= heaterThreshold) {
     if (!heaterState) {
       if (Debugging) {
         debugger.println("Turning on water heater.");


Update mqtt.ino

Update mqtt.ino

Debugging flag activated

--- DroidMain/mqtt.ino
+++ DroidMain/mqtt.ino
@@ -1,55 +1,50 @@
-// Callback made from esp-link to notify of wifi status changes
-// Here we just print something out for grins
-
-void wifiCb(void* response) {
-  ELClientResponse *res = (ELClientResponse*)response;
-  if (res->argc() == 1) {
-    uint8_t status;
-    res->popArg(&status, 1);
-
-    if(status == STATION_GOT_IP) {
-      Serial.println("WIFI CONNECTED");
-    } else {
-      Serial.print("WIFI NOT READY: ");
-      Serial.println(status);
-    }
-  }
-}
-
-
-// Callback when MQTT is connected
-void mqttConnected(void* response) {
-  Serial.println("MQTT connected!");
-  mqtt.subscribe("iot-downlink");
-
-  connected = true;
-}
-
-// Callback when MQTT is disconnected
-void mqttDisconnected(void* response) {
-  Serial.println("MQTT disconnected");
-  connected = false;
-}
-
-// Callback when an MQTT message arrives for one of our subscriptions
-void mqttData(void* response) {
-  ELClientResponse *res = (ELClientResponse *)response;
-
-  Serial.print("Received: topic=");
-  String topic = res->popString();
-  Serial.println(topic);
-
-
-  String data = res->popString();
-  inputString = data.c_str();
-  stringComplete = true;
-  Serial.print("data=");
-  Serial.println(data);
-}
-
-void mqttPublished(void* response) {
-  Serial.println("MQTT published");
-}
-
-
+// Callback made from esp-link to notify of wifi status changes
+// Here we just print something out for grins

+void wifiCb(void* response) {
+  ELClientResponse *res = (ELClientResponse*)response;
+  if (res->argc() == 1) {
+    uint8_t status;
+    res->popArg(&status, 1);
+
+    if(status == STATION_GOT_IP) {
+      if (debugging == true) { Serial.println("WIFI CONNECTED");}
+    } else {
+      if (debugging == true) {
+        Serial.print("WIFI NOT READY: ");
+        Serial.println(status); }
+    }
+  }
+}
+
+// Callback when MQTT is connected
+void mqttConnected(void* response) {
+  if (debugging == true) { Serial.println("MQTT connected!"); }
+  mqtt.subscribe("iot-downlink");
+  connected = true;
+}
+
+// Callback when MQTT is disconnected
+void mqttDisconnected(void* response) {
+  if (debugging == true) { Serial.println("MQTT disconnected!"); }
+  connected = false;
+}
+
+// Callback when an MQTT message arrives for one of our subscriptions
+void mqttData(void* response) {
+  ELClientResponse *res = (ELClientResponse *)response;
+  if (debugging == true) { Serial.print("Received: topic=");}
+  String topic = res->popString();
+  if (debugging == true) { Serial.println(topic);}
+
+  String data = res->popString();
+  inputString = data.c_str();
+  stringComplete = true;
+  if (debugging == true) {
+    Serial.print("data=");
+    Serial.println(data); }
+}
+
+void mqttPublished(void* response) {
+  if (debugging == true) { Serial.println("MQTT published");}
+}


COH-72: POST 'buttons' check must be right

Door/window switch can be legit on or off.

We can also not try to do the checks for
non-user-facing boards where the button GPIOs
are redeployed for other purposes.

--- Arduino/V0p2_Main/V0p2_Main.ino
+++ Arduino/V0p2_Main/V0p2_Main.ino
@@ -281,23 +281,25 @@

 //  posPOST(1, F("Radio OK, checking buttons/sensors and xtal"));

-// Buttons should not be activated DURING boot; activated button implies fault.
-//#if (9 != V0p2_REV) || !defined(CONFIG_REV9_cut1) // Usual tests for stuck control buttons.
-//  // Check buttons not stuck in the activated position.
-//  if((fastDigitalRead(BUTTON_MODE_L) == LOW)
-//#if defined(BUTTON_LEARN_L)
-//     || (fastDigitalRead(BUTTON_LEARN_L) == LOW)
-//#endif
-//#if defined(BUTTON_LEARN2_L) && (9 != V0p2_REV) // This input is not momentary with REV9.
-//     || (fastDigitalRead(BUTTON_LEARN2_L) == LOW)
-//#endif
-//    )
-//    { panic(F("button stuck")); }
+// Buttons should not be activated DURING boot for user-facing boards; an activated button implies a fault.
+#if ((V0p2_REV >= 1) && (V0p2_REV <= 4)) || ((V0p2_REV >= 7) && (V0p2_REV <= 8))
+#if (9 != V0p2_REV) || !defined(CONFIG_REV9_cut1) // Usual tests for stuck control buttons.
+  // Check buttons not stuck in the activated position.
+  if((fastDigitalRead(BUTTON_MODE_L) == LOW)
+#if defined(BUTTON_LEARN_L)
+     || (fastDigitalRead(BUTTON_LEARN_L) == LOW)
+#endif
+#if defined(BUTTON_LEARN2_L) && (9 != V0p2_REV) // This input is not momentary with REV9.
+     || (fastDigitalRead(BUTTON_LEARN2_L) == LOW)
+#endif
+    )
+    { panic(F("button stuck")); }
 //#else
 //    DEBUG_SERIAL_PRINT(fastDigitalRead(BUTTON_MODE_L)); DEBUG_SERIAL_PRINTLN(); // Should be BOOSTSWITCH_L for REV9.
 //    DEBUG_SERIAL_PRINT(fastDigitalRead(BUTTON_LEARN_L)); DEBUG_SERIAL_PRINTLN();
 //    DEBUG_SERIAL_PRINT(fastDigitalRead(BUTTON_LEARN2_L)); DEBUG_SERIAL_PRINTLN(); // AKA WINDOW SWITCH
-//#endif
+#endif
+#endif // select user-facing boards.

 #if defined(WAKEUP_32768HZ_XTAL)
   // Check that the 32768Hz async clock is actually running having done significant CPU-intensive work.


randomised sleep

randomised sleep

--- examples/atmega328p/Philosophers.ino
+++ examples/atmega328p/Philosophers.ino
@@ -8,19 +8,19 @@
 static byte leds[] = { 5, 6, 7, 8, 9, 10, 11, 12 };

 void eating(byte id, byte weight) {
-	Serial.print("Philosopher ");
+	Serial.print(F("Philosopher "));
 	Serial.print(id);
-	Serial.print(" eats: ");
+	Serial.print(F(" eats: "));
 	Serial.println(weight);

 	digitalWrite(leds[id], HIGH);

-	Tasks::delay(500);
+	Tasks::delay(1 + random(MAX * 100));

 	digitalWrite(leds[id], LOW);
 }

-class Philosopher: public Task<100> {
+class Philosopher: public Task<50> {
 public:
 	void setup() {
 		_id = ids++;
@@ -43,8 +43,11 @@
 Philosopher philosophers[MAX-1];

 void setup() {
-	Serial.begin(9600);
+	Serial.begin(115200);
+	randomSeed(analogRead(0));
+
 	Tasks::init();
+	Tasks::set_idle_handler(timer_sleep);
 	for (int i = 0; i < MAX; i++) {
 		forks[i].signal();
 		pinMode(leds[i], OUTPUT);