eddy beedy eeddy, hey buck!

eddy beedy eeddy, hey buck!

--- Lifter/Lifter.ino
+++ Lifter/Lifter.ino
@@ -41,16 +41,16 @@
 const byte CARD_PIN = A1;           // Analog prox. for 'card on-board'
 const int cardThickness = 52;       // calculated 141 steps to lift a card. 608steps/turn
                                      // (20 turns per 86 cards, 141.3953 ...
-const int proxSense2 = 600;         // threshold for OPB606A riding on fan housing
-const int liftSenseTop = 810;        // above threshold nothing is close to face of OPB606A
-const long int hoverArmPos = 5;      // pick up postion after zeroing against armLimit
-const long int firstArmPos = 142;    // experimentally determined drop-off position
-const long int secondArmPos = 280;   // 2nd drop and max Arm travel
-const byte lowAng = 120;              // servo position: closest approach to card-stack
-const byte highAng = 157;              // servo postion:
+const int proxSense2 = 750;         // threshold for OPB606A riding on fan housing
+const int liftSenseTop = 700;        // above threshold nothing is close to face of OPB606A
+const long int hoverArmPos = 18;      // pick up postion after zeroing against armLimit
+const long int firstArmPos = 148;    // experimentally determined drop-off position
+const long int secondArmPos = 300;   // 2nd drop and max Arm travel
+const byte closeAng = 117;              // servo position: closest approach to card-stack
+const byte openAng = 165;              // servo postion:
 const byte bumpBinSteps = 36;        // for jiggle when grabTryCo17unt goes up.
-const byte servoPosition = 145;      // initial setup() safe servo position
-const byte extraServoBump = 3;      // travel either way a little further then settle back to low or high
+const byte servoPosition = 137;      // initial setup() safe servo position & middle return
+const byte extraServoBump = 8;      // travel either way a little further then settle back to low or high
 int newAnalog1 = 0;                 // hold value from the PROX_PIN sensor
 int newAnalog2 = 0;                 // hold value from the CARD_PIN sensor
 int oldAnalog1 = 0;                 // discover changes in the PROX_PIN sensor
@@ -66,13 +66,15 @@
 boolean stressedServo = false;       // flag for above
 unsigned long timeStart = 0;
 unsigned long timeCurrent = 0;
-boolean UPDATE = true;              // flag for printing updated info to serial monitor
+boolean UPDATE = true;                  // flag for printing updated info to serial monitor
+unsigned long currentTime = millis();  // I can't seem to declare local variables
+byte currentServoPos = 0;

 AccelStepper stepperArm(AccelStepper::DRIVER, PINST1_ST, PINST1_DIR);
 AccelStepper stepperLift(AccelStepper::DRIVER, PINST2_ST, PINST2_DIR);

 const long int liftUpToTop = -200000;     // arbitrary rise until limit switch hit.
-const int liftBackOff = 500;              // back off the switch; zero is limit-switch position
+long int liftBackOff = 500;              // back off the switch; zero is limit-switch position

 Servo myserv;

@@ -116,34 +118,32 @@
 }

 void loop() {
+    /*
     if (DEBUG) {
       digitalWrite(GREENLED, digitalState(LIMIT_SW));     // glow when free. in loop
       digitalWrite(REDLED, digitalState(LIMIT_ARM));      // glow when free. in loop
     }
+    */

     // only handles limiting if bin is mostly empty
-    if ((liftState == HIGH) && (stepperLift.targetPosition() < 0)) {
-      delay(5);                                    // de-bounce the switch hopefully
+    if ((liftState == HIGH) && !BACKINGOFF) {
+      delay(3);                             // de-bounce the switch hopefully
       if (digitalState(LIMIT_SW)) {
         stepperLift.setCurrentPosition(0);
-        delay(3);                                 // deceleration
         stepperLift.moveTo(liftBackOff);
         BACKINGOFF = true;
-        timeStart = millis();
         UPDATE = true;
         liftState = LOW;
       }
     }
-    else if ((!liftState) && ((timeStart - millis()) > 1900))    // deals with limit-switch hysterysis
+    else if (BACKINGOFF && !liftState) {   // deals with limit-switch hysterysis
       BACKINGOFF = false;
-    else if ((liftState == HIGH) && (!BACKINGOFF)) {          // stopping for unforseen reasons
-      delay(4);                                               // de-bounce
-      if (digitalState(LIMIT_SW)) {
-        stepperLift.stop();                                  // stop at maximum deceleration
-        UPDATE = true;                                      // report position
-        liftState = LOW;
-      }
-    }
+      liftBackOff = stepperLift.currentPosition();
+      if (liftBackOff < 1)
+        Serial.println("WARNING  WARNING  error with liftBackOff");
+      stepperLift.setCurrentPosition(0);
+    }
+

     // arm starts off moving towards limit switch in setup(), hits it, moves to ready-to-load
     if ((armState == HIGH) && (stepperArm.targetPosition() < 0)){
@@ -161,23 +161,19 @@
     newAnalog2 = analogRead(CARD_PIN);

     // auto-servo position based on bin and sensor threshold
-    fanDown(lowAng, highAng, destinationArmPos);
+    fanDown(closeAng, openAng, destinationArmPos);

     // loading by default, so moving down, one card at a time
+    // newAnalog1 < senseTop means 'covered'  newAnalog1 >... is 'uncovered'
     if (!LOADED){
       if ((newAnalog1 < liftSenseTop) && (stepperLift.distanceToGo() < cardThickness)) {
         stepperLift.moveTo(stepperLift.currentPosition() + cardThickness);
       }
     }
     // loaded? Then move upwards a little bit
-    else if ((newAnalog1 > liftSenseTop) && (stepperLift.distanceToGo() < 1)) {
+    else if ((newAnalog1 > liftSenseTop) && (stepperLift.distanceToGo() < 1))
         stepperLift.moveTo(stepperLift.currentPosition() - cardThickness);
-    }
-    else if ((grabTryCount % 5) == 2)
-        stepperLift.moveTo(stepperLift.currentPosition() - cardThickness);
-    else if ((grabTryCount % 5) == 4)
-        stepperLift.moveTo(stepperLift.currentPosition() + cardThickness);
-
+
     // TRACKING via SERIAL MONITOR without flooding it
     // analog sensors avoiding flutter values
    // comment out once everything is working perfectly
@@ -185,32 +181,25 @@
       UPDATE = true;
       oldAnalog1 = newAnalog1;
     }
-    else if (abs(oldAnalog2 - newAnalog2) > 30)
-
+    else if (abs(oldAnalog2 - newAnalog2) > 30) {
+      UPDATE = true;
+      oldAnalog2 = newAnalog2;
+    }
+
+    if (abs(myserv.read() - oldServoPos) > 1) {
+      UPDATE = true;
+      oldServoPos = myserv.read();
+    }
+
     if (UPDATE) {
         Serial.print("Liftpos: " + String(stepperLift.currentPosition()) + " Armpos: " + String(stepperArm.currentPosition()));
-        Serial.println("  A0: " + String(newAnalog1) + "  A1: " + String(newAnalog2) + " srvo: " + String(myserv.read()));
+        Serial.println("  A0: " + String(newAnalog1) + "  A1: " + String(newAnalog2) + " srvo: " + String(oldServoPos) + " tm:" + String(millis()));
         UPDATE = false;
     }

-    stepperLift.run();
-    stepperArm.run(); {
-      UPDATE = true;
-      oldAnalog2 = newAnalog2;
-    }
-    else if (abs(myserv.read() - oldServoPos) > 2) {
-      UPDATE = true;
-      oldServoPos = myserv.read();
-    }
-
-    if (UPDATE) {
-        Serial.print("Liftpos: " + String(stepperLift.currentPosition()) + " Armpos: " + String(stepperArm.currentPosition()));
-        Serial.println("  A0: " + String(newAnalog1) + "  A1: " + String(newAnalog2) + " srvo: " + String(myserv.read()));
-        UPDATE = false;
-    }
-
-    stepperLift.run();
-    stepperArm.run();
+    if (!digitalState(LIMIT_SW) || BACKINGOFF)
+      stepperLift.run();
+    stepperArm.run();

     // first character sent switches us into LOADED mode
     // 97="a", 98="b", 99="c", 100="d"
@@ -230,7 +219,7 @@
       }
       else if (inputString == "99") {        // 'c' unidentified pile
         stepperArm.moveTo(secondArmPos);
-        destinationArmPos = firstArmPos;
+        destinationArmPos = secondArmPos;
       }
       else if (inputString == "100") {       // 'd' Reset into loading mode until another character sent
         stepperArm.moveTo(firstArmPos);
@@ -251,31 +240,44 @@
   armState = digitalState(LIMIT_ARM);
 }

-// trying for non-blocking servo with delay between actuation attempts...
-void fanDown(byte down, byte drop, long int dropZone) {
+// trying for non-blocking non-repetitive servo with delay between actuation attempts...
+void fanDown(byte suck, byte drop, long int dropZone) {
   // go down to get card only if stopped in hover position over bin
-
-  if (!stressedServo && ((millis() - timeStart) > 700)){
-    if ((stepperArm.currentPosition() == hoverArmPos) && (newAnalog2 > proxSense2)) {
-      myserv.write(down - extraServoBump);
-      restServoPos = down;
+  currentTime = millis();
+  currentServoPos = myserv.read();
+
+  // after allowing time for travel, check stress levels...
+  if (((timeStart - currentTime) > 900)) {
+    if (currentServoPos == (drop + extraServoBump)) {
       stressedServo = true;
-      timeStart = millis();
-      grabTryCount += 1;
-    }
-    else if ((stepperArm.currentPosition() == dropZone) && (newAnalog2 < proxSense2)) {
-      myserv.write(drop + extraServoBump);
       restServoPos = drop;
+    }
+    else if (currentServoPos == (suck - extraServoBump)) {
+      restServoPos = suck;
       stressedServo = true;
-      timeStart = millis();
-      grabTryCount = 0;
-    }
+    }
+    else if ((currentServoPos == suck) || (currentServoPos == drop))
+      stressedServo = false;
+  }
+
+  if ((stepperArm.currentPosition() == hoverArmPos) &&
+      (newAnalog2 > proxSense2) &&
+      !stressedServo) {
+        myserv.write(drop + extraServoBump);
+        timeStart = currentTime;
+    }
+  else if ((stepperArm.currentPosition() == dropZone) &&
+            (newAnalog2 < proxSense2) &&
+            !stressedServo) {
+              myserv.write(suck - extraServoBump);
+              timeStart = currentTime;
+   }
+  else if (stressedServo && ((timeStart - currentTime) > 900)) {
+    myserv.write(restServoPos);
+    if (DEBUG)
+      Serial.println("de-stressed to position: " + String(restServoPos));
   }
-  else if (stressedServo && ((millis() - timeStart) > 600)) {
-    myserv.write(restServoPos);
-    stressedServo = false;
-  }
-}
-
-
-
+}
+
+
+


updated LCD display

updated LCD display

--- mwsLCD/mwsLCD.ino
+++ mwsLCD/mwsLCD.ino
@@ -203,7 +203,10 @@
   // set up the LCD's number of columns and rows:
   lcd.begin(16, 2);
   // Print a message to the LCD.
-  lcd.print("Mobile Weather Station is up");
+  lcd.clear();
+  lcd.print("Mobile Weather");
+  lcd.setCursor(0, 2);
+  lcd.print("Station is up");

   Serial.begin(9600);

@@ -511,32 +514,38 @@
   Serial.print(",");
   Serial.print(gps.satellites.value());

-  lcd.setCursor(0, 1);
-  lcd.print("lon=");
+  lcd.clear();
+//  lcd.setCursor(0, 1);
+  lcd.println("lon=");
   lcd.print(gps.location.lng(), 6);
-  lcd.setCursor(0, 2);
-  lcd.print(",lat=");
+  delay(1500);
+//  lcd.setCursor(0, 2);
+  lcd.clear();
+  lcd.println("lat=");
   lcd.print(gps.location.lat(), 6);
-  delay(1000);
+  delay(1500);

   char sz[32];
   Serial.print(",");
   sprintf(sz, "%02d-%02d-%02d", gps.date.year(), gps.date.month(), gps.date.day());
   Serial.print(sz);

-  lcd.setCursor(0, 1);
-  lcd.print(",date=");
+  lcd.clear();
+  //lcd.setCursor(0, 1);
+  lcd.println(",date=");
   lcd.print(sz);
+  delay(1500);

   //Serial.print(",time=");
   Serial.print(",");
   sprintf(sz, "%02d:%02d:%02d", gps.time.hour(), gps.time.minute(), gps.time.second());
   Serial.print(sz);

-  lcd.setCursor(0, 2);
-  lcd.print(",time=");
+  lcd.clear();
+  //lcd.setCursor(0, 2);
+  lcd.println(",time=");
   lcd.print(sz);
-  delay(1000);
+  delay(1500);

   //Serial.print(",winddir=");
   Serial.print(",");


add progress

add progress

--- _56-gopro-control/_56-gopro-control.ino
+++ _56-gopro-control/_56-gopro-control.ino
@@ -158,7 +158,7 @@
 uint32_t value_timestamp;
 uint32_t value_nonce;
 /* ---- */
-String value_status  = "esp-01 / ";
+String value_status;
 /* ---- */
 //
 char* hellotopic  = "HELLO";
@@ -220,10 +220,10 @@
 void rtc_boot_check() {
   system_rtc_mem_read(100, &rtc_boot_mode, sizeof(rtc_boot_mode));
   if (rtc_boot_mode.magic != RTC_MAGIC) {
-    rtc_boot_mode.magic = RTC_MAGIC;
-    rtc_boot_mode.gopro_mode = false;
+    rtc_boot_mode.magic        = RTC_MAGIC;
+    rtc_boot_mode.gopro_mode   = false;
     rtc_boot_mode.formatspiffs = false;
-    rtc_boot_mode.Temperature = 0;
+    rtc_boot_mode.Temperature  = 0;
   }
 }

@@ -612,10 +612,6 @@
   WiFi.mode(WIFI_OFF);
   rtc_boot_check();

-  value_status += rtc_boot_mode.Temperature;
-  value_status += (char)223;
-
-
   Wire.begin(0, 2);
   delay(100);

@@ -634,7 +630,8 @@
   getResetInfo += ESP.getResetInfo().substring(0, 80);

   //
-  solar_data.Temperature1 = solar_data.Temperature2 = solar_data.Humidity = solar_data.data1 = solar_data.data2 =  solar_data.data3 =  solar_data.data4 = solar_data.powerAvg = 0 ;
+  solar_data.Temperature1 = solar_data.Temperature2 = solar_data.Humidity = 0;
+  solar_data.data1 = solar_data.data2 = solar_data.data3 = solar_data.data4 = solar_data.powerAvg = 0;
   lastTime = lastTime2 = millis();

   // lcd
@@ -695,7 +692,8 @@
     } else {
       lcd.print("[CONFIG] loaded");
       lcd.setCursor(0, 2);
-      lcd.print("[CONFIG] [PH] : " + twitter_phase);
+      lcd.print("[CONFIG] [PH] : ");
+      lcd.print(twitter_phase);
     }
     delay(1000);

@@ -883,6 +881,7 @@
     pinMode(SquareWavePin, INPUT_PULLUP);
     attachInterrupt(1, alm_isr, FALLING);
   }
+
   x = true;
 }

@@ -906,7 +905,7 @@
         rtc_boot_mode.gopro_mode  = true;
         rtc_boot_mode.Temperature = solar_data.Temperature2 ;
         system_rtc_mem_write(100, &rtc_boot_mode, sizeof(rtc_boot_mode));
-
+
         attempt_this  = 0;
         twitter_phase = 0;
         saveConfig_helper();
@@ -995,13 +994,17 @@
         value_timestamp  = now();
         value_nonce      = *(volatile uint32_t *)0x3FF20E44;

+        value_status  = "esp-01 / ";
+        value_status += rtc_boot_mode.Temperature;
+        value_status += "C / ";
+        value_status += hour();
+        value_status += ":";
+        value_status += minute();
+
         switch (twitter_phase) {

           case 0:
-            if (get_gpro_list()) {
-              delay(200);
-              ESP.reset();
-            }
+            get_gpro_list();
             break;

           case 1:
@@ -1276,6 +1279,9 @@

     lcd.setCursor(0, 3);
     lcd.print("[P:3] put : ");
+
+    int pre_progress = 0;
+
     while (f.available()) {
       int c = f.readBytes(buff, ((len > sizeof(buff)) ? sizeof(buff) : len));
       if ( c > 0 ) {
@@ -1283,13 +1289,16 @@
       }

       float progress = ((get_size - len) / (get_size / 100));
-      lcd.setCursor(13, 3);
-      if (progress < 10) {
-        lcd.print(" ");
-      }
-
-      lcd.print(progress, 0);
-      lcd.print(" %");
+      if (int(progress) != pre_progress ) {
+        lcd.setCursor(13, 3);
+        if (progress < 10) {
+          lcd.print(" ");
+        }
+
+        lcd.print(progress, 0);
+        lcd.print(" % ");
+        pre_progress = int(progress);
+      }

       if (len > 0) {
         len -= c;
@@ -1316,13 +1325,16 @@
   if (!sslclient.connect(UPLOAD_BASE_HOST, HTTPSPORT)) {
     return false;
   }
-  sslclient.setNoDelay(true);
+

   if (!sslclient.verify(upload_fingerprint, UPLOAD_BASE_HOST)) {
     lcd.setCursor(0, 2);
     lcd.print("[P:3] ssl fail");
     return false;
   }
+
+  wifiClient.setNoDelay(true);
+  sslclient.setNoDelay(true);

   sslclient.print(content_header);
   get_hash_str(content_more, content_last, positionofchunk, get_size, true);
@@ -1884,6 +1896,7 @@
       lcd.setCursor(0, 1);
       lcd.print("[P:1] get : ");

+      int pre_progress = 0;
       while (http.connected() && (len > 0 || len == -1)) {
         size_t size = stream->available();
         if (size) {
@@ -1891,13 +1904,16 @@
           f.write(buff, c);

           float progress = ((gopro_size - len) / (gopro_size / 100));
-          lcd.setCursor(13, 1);
-          if (progress < 10) {
-            lcd.print(" ");
+          if (int(progress) != pre_progress ) {
+            lcd.setCursor(13, 1);
+            if (progress < 10) {
+              lcd.print(" ");
+            }
+
+            lcd.print(progress, 0);
+            lcd.print(" %");
+            pre_progress = int(progress);
           }
-
-          lcd.print(progress, 0);
-          lcd.print(" %");

           if (len > 0) {
             len -= c;
@@ -1924,6 +1940,7 @@
       }

       lcd.print("OK");
+      delay(1000);

       attempt_this  = 0;
       twitter_phase = 2;


Added heater subscriber.

Added heater subscriber.

--- Temperature/Temperature.ino
+++ Temperature/Temperature.ino
@@ -1,19 +1,10 @@
-/*
- * rosserial Temperature Sensor Example
- *
- * This tutorial demonstrates the usage of the
- * Sparkfun TMP102 Digital Temperature Breakout board
- * http://www.sparkfun.com/products/9418
- *
- * Source Code Based off of:
- * http://wiring.org.co/learning/libraries/tmp102sparkfun.html
- */
-
+//TODO: Create "library" for each component
 #include <Wire.h>
 #include <ros.h>
 #include <std_msgs/String.h>
 #include <std_msgs/UInt8.h>
 #include <std_msgs/Empty.h>
+#include <std_msgs/Bool.h>
 #include <OneWire.h>
 #include <DallasTemperature.h>

@@ -33,6 +24,8 @@
 #define MAX_SAMPLE_RATE 10
 #define MAX_SAMPLE_COUNT 10
 #define MAX_DELTA 0.5
+
+#define HEATER_PIN 22

 typedef struct one_wire_data {
   OneWire one_wire;
@@ -76,17 +69,22 @@
   send_message(sensor);
 }

-static void send_count(void) {
+static void count_callback(const std_msgs::Empty& empty) {
   count_msg.data = (uint8_t)sizeof(sensors) / sizeof(sensors[0]);
   pub_temp.publish(&temp_msg);
 }

-static void count_callback(const std_msgs::Empty& empty) {
-  send_count();
+static void heater_callback(const std_msgs::Bool& state) {
+  if(state.data) {
+    digitalWrite(HEATER_PIN, HIGH);
+  } else {
+    digitalWrite(HEATER_PIN, LOW);
+  }
 }

 static ros::Subscriber<std_msgs::UInt8> sub_temp("req_temperature", &temperature_callback);
 static ros::Subscriber<std_msgs::Empty> sub_count("req_count", &count_callback);
+static ros::Subscriber<std_msgs::Bool> sub_heater("heater", &heater_callback);

 static void increment_sample_rate(TemperatureSensor* sensor) {
   if(sensor->sample_rate == MAX_SAMPLE_RATE) {
@@ -176,13 +174,14 @@
   }
 }

-void setup()
+void setup(void)
 {
   nh.initNode();
   nh.advertise(pub_temp);
   nh.advertise(pub_count);
   nh.subscribe(sub_temp);
   nh.subscribe(sub_count);
+  nh.subscribe(sub_heater);

   uint32_t sensor_count = 0;
   // Create analog temperature sensor
@@ -190,16 +189,21 @@
   create_sensor(sensor_count, ANALOG_PIN, TYPE_ANALOG, &analog_sensor);
   sensors[sensor_count++] = analog_sensor;

+  // Create one wire temperature sensor
   TemperatureSensor one_wire_sensor;
   create_sensor(sensor_count, ONE_WIRE_PIN, TYPE_ONE_WIRE, &one_wire_sensor);
   sensors[sensor_count++] = one_wire_sensor;

+  // Create I2C temperature sensors
   TemperatureSensor i2c_sensor0;
   create_sensor(sensor_count, TMP102_ADDR_0, TYPE_I2C, &i2c_sensor0);
   sensors[sensor_count++] = i2c_sensor0;
-}
-
-void loop()
+
+  // Set heater output pin
+  pinMode(HEATER_PIN, OUTPUT);
+}
+
+void loop(void)
 {
   TemperatureSensor* sensor;
   for(uint32_t c = 0; c < SENSOR_COUNT; c++) {


Added temp_sensor_count publisher and subscriber

--- Temperature/Temperature.ino
+++ Temperature/Temperature.ino
@@ -13,6 +13,7 @@
 #include <ros.h>
 #include <std_msgs/String.h>
 #include <std_msgs/UInt8.h>
+#include <std_msgs/Empty.h>
 #include <OneWire.h>
 #include <DallasTemperature.h>

@@ -39,13 +40,13 @@
 } OneWireData;

 typedef struct temperature_sensor {
-  unsigned int id;
+  uint32_t id;
   float prev_temp;
   float curr_temp;
-  unsigned int type;
-  unsigned int pin_addr;
-  unsigned int sample_rate;
-  unsigned int sample_count;
+  uint32_t type;
+  uint32_t pin_addr;
+  uint32_t sample_rate;
+  uint32_t sample_count;
   unsigned long publisher_timer;
   OneWireData* one_wire_data;
 } TemperatureSensor;
@@ -63,9 +64,11 @@
 // ROS variables
 static ros::NodeHandle  nh;
 static std_msgs::String temp_msg;
+static std_msgs::UInt8 count_msg;
 static ros::Publisher pub_temp("temperature", &temp_msg);
-
-static void message_callback(const std_msgs::UInt8& id){
+static ros::Publisher pub_count("temp_sensor_count", &count_msg);
+
+static void temperature_callback(const std_msgs::UInt8& id) {
   if(id.data > SENSOR_COUNT) {
     return;
   }
@@ -73,7 +76,17 @@
   send_message(sensor);
 }

-static ros::Subscriber<std_msgs::UInt8> sub_temp("req_temperature", &message_callback);
+static void send_count(void) {
+  count_msg.data = (uint8_t)sizeof(sensors) / sizeof(sensors[0]);
+  pub_temp.publish(&temp_msg);
+}
+
+static void count_callback(const std_msgs::Empty& empty) {
+  send_count();
+}
+
+static ros::Subscriber<std_msgs::UInt8> sub_temp("req_temperature", &temperature_callback);
+static ros::Subscriber<std_msgs::Empty> sub_count("req_count", &count_callback);

 static void increment_sample_rate(TemperatureSensor* sensor) {
   if(sensor->sample_rate == MAX_SAMPLE_RATE) {
@@ -121,7 +134,7 @@
 }

 static void handle_analog(TemperatureSensor* sensor) {
-  unsigned int raw_voltage = analogRead(sensor->pin_addr);
+  uint32_t raw_voltage = analogRead(sensor->pin_addr);
   float volts = raw_voltage / 205.0f;
   float celsius = 100.0 * volts - 50;
   sensor->curr_temp = celsius;
@@ -139,7 +152,7 @@
   if (Wire.available() >= byte_req) {
     byte msb;
     byte lsb;
-    unsigned int temperature;
+    uint32_t temperature;

     msb = Wire.read(); // receive high byte (full degrees)
     lsb = Wire.read(); // receive low byte (fraction degrees)
@@ -150,7 +163,7 @@
   }
 }

-static void create_sensor(unsigned int id, unsigned int pin_addr, unsigned int type, TemperatureSensor* sensor) {
+static void create_sensor(uint32_t id, uint32_t pin_addr, uint32_t type, TemperatureSensor* sensor) {
   *sensor = default_sensor;
   sensor->id = id;
   sensor->pin_addr = pin_addr;
@@ -167,9 +180,11 @@
 {
   nh.initNode();
   nh.advertise(pub_temp);
+  nh.advertise(pub_count);
   nh.subscribe(sub_temp);
-
-  unsigned int sensor_count = 0;
+  nh.subscribe(sub_count);
+
+  uint32_t sensor_count = 0;
   // Create analog temperature sensor
   TemperatureSensor analog_sensor;
   create_sensor(sensor_count, ANALOG_PIN, TYPE_ANALOG, &analog_sensor);
@@ -187,7 +202,7 @@
 void loop()
 {
   TemperatureSensor* sensor;
-  for(unsigned int c = 0; c < SENSOR_COUNT; c++) {
+  for(uint32_t c = 0; c < SENSOR_COUNT; c++) {
     sensor = &sensors[c];
     if(millis() > sensor->publisher_timer) {
       switch(sensor->type) {


fix timer issue

fix timer issue

--- arduino/control_power/control_power.ino
+++ arduino/control_power/control_power.ino
@@ -11,6 +11,7 @@
   //I2C
   Wire.begin(i2c_slave_addr);
   Wire.onReceive(callback_i2c_receive);
+  Wire.onRequest(callback_i2c_request);

   //GPIO
   pinMode(pin_LED,OUTPUT);
@@ -161,6 +162,7 @@
       }
       break;
     case RPI_STAT_RUNNING:
+      if(loop_count % 20 == 0){ check_expired_timer(); }
       break;
     case RPI_STAT_WAIT_SHUTDOWN:
       static int shtdwn_delay_count=0;
@@ -185,7 +187,7 @@
             digitalWrite(pin_shutdown,HIGH);
           }
         }else{
-          if(shtdwn_delay_count>20*30){ //50*20 * 30 msec (30sec)
+          if(shtdwn_delay_count>20*20){ //50*20 * 20 msec (20sec)
             raspi_stat = RPI_STAT_SHUTDOWN;
             Serial.println("*** TURN OFF power successfully ***");
             turn_off();
@@ -201,8 +203,10 @@
 }

-const int  CMD_SET_WAKUP_TIMER01    = 0x11;
-const int  CMD_SET_WAKUP_TIMER02    = 0x12;
+const int  CMD_SET_WAKUP_TIMER01A    = 0x11;
+const int  CMD_SET_WAKUP_TIMER01B    = 0x12;
+const int  CMD_SET_WAKUP_TIMER02A    = 0x21;
+const int  CMD_SET_WAKUP_TIMER02B    = 0x22;
 const int  CMD_CLEAR_TIMER          = 0x40;
 const int  CMD_SHUTDOWN_NOW         = 0xFF;

@@ -223,6 +227,8 @@

 void check_timer(){
   unsigned long now = millis();
+  Serial.println(now);
+  Serial.println(raspy_timer[0]);
   if(raspy_timer[0] > 0 && now > raspy_timer[0]){
       Serial.println("Timer1 ignition");
       wakeup_by_timer();
@@ -232,6 +238,23 @@
       wakeup_by_timer();
   }
 }
+
+void check_expired_timer(){
+  unsigned long now = millis();
+  Serial.println(now);
+  Serial.println(raspy_timer[0]);
+  if(raspy_timer[0] > 0 && now > raspy_timer[0]){
+      Serial.println("Timer1 expired");
+      raspy_timer[0]=0;
+  }
+  if(raspy_timer[1] > 0 && now > raspy_timer[1]){
+      Serial.println("Timer2 expired");
+      raspy_timer[1]=0;
+  }
+}
+
+unsigned long timer_data_com1 = 0;
+unsigned long timer_data_com2 = 0;

 void callback_i2c_receive(int length){
   unsigned long now = millis();
@@ -241,26 +264,60 @@
   Serial.println(cmd);
   Serial.print("data_len = ");
   Serial.println(data_len);
-  unsigned long data=0;
-  if(data_len==4){
+
+  if(cmd==CMD_SET_WAKUP_TIMER01A){
+    timer_data_com1=0;
     int count=3;
     while (0 < Wire.available()) {
       int d = Wire.read();
-      data += d << (8*count);
-      count -= 1;
+      Serial.print(d);
+      if(count>=2){
+        if(d>0 && count==3){
+          timer_data_com1 += (unsigned long)(d * 0x1000000);
+        }
+        if(d>0 && count==2){
+          timer_data_com1 += (unsigned long)(d * 0x10000);
+        }
+        count -= 1;
+      }
     }
-    Serial.print("\ndata=");
-    Serial.println(data);
-  }
+  }
+  if(cmd==CMD_SET_WAKUP_TIMER01B){
+    int count=1;
+    while (0 < Wire.available()) {
+      int d = Wire.read();
+      Serial.print(d);
+      if(count>=0){
+        if(d>0){
+          timer_data_com1 += (unsigned long)(d << (8*count));
+        }
+        count -= 1;
+      }
+    }
+  }
+  if(cmd==CMD_SET_WAKUP_TIMER01A || cmd==CMD_SET_WAKUP_TIMER01B){
+    Serial.print("\ntimer_data_com1=");
+    Serial.println(timer_data_com1);
+  }
+  if(cmd!=CMD_SET_WAKUP_TIMER01A && cmd!=CMD_SET_WAKUP_TIMER01B){
+    while (0 < Wire.available()) {
+      int d = Wire.read();
+    }
+  }
+

+  Serial.print("now=");
+  Serial.println(now);
   switch(cmd){
-    case CMD_SET_WAKUP_TIMER01:
+    case CMD_SET_WAKUP_TIMER01B:
       Serial.println("CMD_SET_WAKUP_TIMER01");
-      raspy_timer[0]=millis()+data*1000 + now;
-      break;
-    case CMD_SET_WAKUP_TIMER02:
+      raspy_timer[0]=timer_data_com1*1000 + now;
+      Serial.print("raspy_timer[0]=");
+      Serial.println(raspy_timer[0]);
+      break;
+    case CMD_SET_WAKUP_TIMER02B:
       Serial.println("CMD_SET_WAKUP_TIMER02");
-      raspy_timer[1]=millis()+data*1000 + now;
+      raspy_timer[1]=timer_data_com2*1000 + now;
       break;
     case CMD_CLEAR_TIMER:
       Serial.println("CMD_CLEAR_TIMER");
@@ -278,6 +335,9 @@

 }

+void callback_i2c_request(){
+  Serial.println("callback_i2c_request");
+}

 //************************************************************
 void loop() {


Faster vcc read

Faster vcc read

--- battery_indicator/battery_indicator.ino
+++ battery_indicator/battery_indicator.ino
@@ -8,6 +8,8 @@
 int value_old;

 void setup() {
+  Serial.begin(57600);
+
   // initialize the robot
   Robot.begin();

@@ -22,8 +24,10 @@
 }
 void loop()
 {
+
   batteryUpdate();
-  delay(100);
+
+  delay(2000);
 }

 void batteryDraw()
@@ -45,6 +49,11 @@
   Robot.noStroke();
   value_old = value;
   value = batteryVcc();
+
+  if (value == -1) {
+    // Not got a value yet
+    value = value_old;
+  }

   if (value == value_old) {
     // No need to redraw the same value to the screen.
@@ -75,10 +84,9 @@
   Robot.textSize(2);
   Robot.text("mV", 92, 58);

-
-
   return value;
 }
+

 int batteryVcc()
 {
@@ -98,13 +106,19 @@
     ADMUX = _BV(REFS0) | _BV(MUX3) | _BV(MUX2) | _BV(MUX1);
   #endif

-  delay(2); // Wait for Vref to settle
+  // prescaler of 32, speed's better than accuracy.
+  ADCSRA |= _BV(ADPS2) | _BV(ADPS0);
+
+  // Here's the blocking part,
+  // but it's not a bad idea as you don't want analogRead() messing the readings
+
+  // Wait for Vref to settle
+  delayMicroseconds(500);
   ADCSRA |= _BV(ADSC); // Start conversion
   while (bit_is_set(ADCSRA,ADSC)); // measuring

   uint8_t low  = ADCL; // must read ADCL first - it then locks ADCH
   uint8_t high = ADCH; // unlocks both
-
   long result = (high<<8) | low;

   // return registries to previous settings, just in case.


deleted old files

deleted old files

--- oldfiles/laserDriverArduino_new.ino
+++ oldfiles/laserDriverArduino_new.ino
@@ -1,117 +0,0 @@
-#include <laserDriver.h>
-
-const int button_UP = 19,
-          button_DOWN = 18,
-          button_SEL = 17;
-
-unsigned char wait = 0,
-     l_paddle = 128,
-     r_paddle = 128,
-     S_paddle = 3,
-     SETTING = 0;
-
-int  A_ball = 0,
-      heightAdjust = 0;
-
-
-float  SX_ball = 1.5,
-       SY_ball = 2.5,
-       X_ball = 128.0,
-       Y_ball = 128.0;
-
-
-laserDriver LD;
-
-void setup()
-{
-
-  pinMode(13, OUTPUT);
-  pinMode(button_UP, INPUT);
-  pinMode(button_DOWN, INPUT);
-  pinMode(button_SEL, OUTPUT);
-  digitalWrite(13,HIGH);
-
-}
-
-void loop() {
-
-  /* sets the paddle's y positions to the value read from pods */
- l_paddle = analogRead(4)/4;
- r_paddle = analogRead(5)/4;
-
-
-
-/*  //GET PLAYER 1
-  digitalWrite(button_SEL, HIGH);
-
-  if ( !digitalRead(button_UP) ) {
-
-    if (l_paddle>11)
-      l_paddle-=S_paddle;
-    else
-      l_paddle=11;
-    //Y_paddle-=3;
-
-  } else if ( !digitalRead(button_DOWN) ) {
-
-    if (l_paddle<244)
-      l_paddle+=S_paddle;
-    else
-      l_paddle=244;
-
-    //Y_paddle+=3;
-
-  } else;
-
-  //GET PLAYER 2
-  digitalWrite(button_SEL, LOW);
-
-  if ( !digitalRead(button_UP) ) {
-
-    if (r_paddle>11)
-      r_paddle-=S_paddle;
-    else
-      r_paddle=11;
-    //Y_paddle-=3;
-
-  } else if ( !digitalRead(button_DOWN) ) {
-
-    if (r_paddle<244)
-      r_paddle+=S_paddle;
-    else
-      r_paddle=244;
-
-    //Y_paddle+=3;
-
-  } else;
- */
-
-  LD.lSet(0,heightAdjust);
-  delayMicroseconds(1000);
-  LD.lSet(255,heightAdjust);
-  delayMicroseconds(1000);
-  LD.lSet(128, heightAdjust);
-  delayMicroseconds(1000);
-  LD.lSet(128, 255-heightAdjust);
-  delayMicroseconds(1000);
-  LD.lSet(255,255-heightAdjust);
-  delayMicroseconds(1000);
-  LD.lSet(0,255-heightAdjust);
-  delayMicroseconds(1000);
-
-  LD.lRect(10, l_paddle, 8, 20);
-  LD.lRect(245, r_paddle, 8, 20);
-
-  if (X_ball>250 || X_ball<14)
-    SX_ball *= -1;
-  else;
-
-  if (Y_ball>250 || Y_ball<4)
-    SY_ball *= -1;
-  else;
-
-  X_ball += SX_ball;
-  Y_ball += SY_ball;
-
-  LD.lCircle(X_ball, Y_ball, 3);
-}


Move display.begin() after expand.begin()

In case of using pin expander, it has to be initialized for performing
LCD reset on display.begin().

--- src/main.ino
+++ src/main.ino
@@ -73,14 +73,16 @@
 {
     bool clear = true;

-    display.begin();
-#ifndef ESP8266
+#ifdef ESP8266
+    expand.begin();
+#else
     mySerial.begin(9600);
 #endif
     Serial.begin(9600);

+    display.begin();
+
 #ifdef ESP8266
-    expand.begin();

     set_press = (expand.readByte() & 0b10 ) != 0b10;
     if (set_press) {


Update ArduCAM_Mini_Video_Streaming.ino

Update ArduCAM_Mini_Video_Streaming.ino

--- ArduCAM/examples/mini/ArduCAM_Mini_Video_Streaming/ArduCAM_Mini_Video_Streaming.ino
+++ ArduCAM/examples/mini/ArduCAM_Mini_Video_Streaming/ArduCAM_Mini_Video_Streaming.ino
@@ -61,8 +61,14 @@
 Serial.println(F("ACK CMD ArduCAM Start! END"));
 // set the CS as an output:
 pinMode(CS, OUTPUT);
+digitalWrite(CS, HIGH);
 // initialize SPI:
 SPI.begin();
+//Reset the CPLD
+myCAM.write_reg(0x07, 0x80);
+delay(100);
+myCAM.write_reg(0x07, 0x00);
+delay(100);
 while(1){
   //Check if the ArduCAM SPI bus is OK
   myCAM.write_reg(ARDUCHIP_TEST1, 0x55);


i2c twi_setClock

i2c twi_setClock

--- _45-esp-atmega328p-i2c/_01-esp-i2c-master/_01-esp-i2c-master.ino
+++ _45-esp-atmega328p-i2c/_01-esp-i2c-master/_01-esp-i2c-master.ino
@@ -37,6 +37,11 @@
   delay(20);
   Serial.begin(115200);
   Wire.begin(4, 5);
+  // default
+  //Wire.setClock(100000);
+  //twi_setClock(100000);
+  twi_setClock(400000);
+
   delay(200);

   sensor_data._salt = 0;
@@ -53,7 +58,7 @@
 void loop ()
 {
   count++;
-
+
   sensor_data._salt++;
   sensor_data.pls++;
   sensor_data.ct1++;
@@ -65,16 +70,16 @@
   Wire.beginTransmission(SLAVE_ADDRESS);
   I2C_writeAnything(sensor_data);
   Wire.endTransmission();
-  wtime += ( wtime + (micros() - now));
+  wtime = wtime + (micros() - now);

-  delay(1);
+  delay(2);

-  now = micros();
+  unsigned long now2 = micros();
   if (Wire.requestFrom(SLAVE_ADDRESS, sizeof(sensor_data_copy)))
   {
     I2C_readAnything(sensor_data_copy);
   }
-  rtime += ( rtime + (micros() - now));
+  rtime = rtime + (micros() - now2);

   if ( sensor_data._salt != sensor_data_copy._salt ||
        sensor_data.pls   != sensor_data_copy.pls ||
@@ -86,11 +91,11 @@
     error++;
   }

-  if ( error != old_error || count % 100 == 0 ) {
+  if ( error != old_error || count % 1000 == 0 ) {
     Serial.print("wtime/us : ");
-    Serial.print(wtime/count);
+    Serial.print(wtime / count);
     Serial.print(" - rtime/us : ");
-    Serial.print(rtime/count);
+    Serial.print(rtime / count);
     Serial.print(" - pad1 : ");
     Serial.print(sensor_data.pad);
     Serial.print(" - pad2 : ");
@@ -102,5 +107,5 @@
     old_error = error;
   }

-  delay(1);
+  delay(5);
 }


Change stg key mode layout

Change stg key mode layout

--- arduino/dudrack/dudrack.ino
+++ arduino/dudrack/dudrack.ino
@@ -35,21 +35,21 @@
 #define MAPPING_COUNT 2

 #define STICK_NEUTRAL 0
-#define STICK_DOWN 0x7FFF
-#define STICK_UP -0x7FFF
-#define STICK_LEFT -0x7FFF
-#define STICK_RIGHT 0x7FFF
-
-#define STICK_DOWN_KEY  KEY_Z
-#define STICK_UP_KEY    KEY_X
-#define STICK_LEFT_KEY  KEY_AT
-#define STICK_RIGHT_KEY KEY_LEFT_BRACKET
-#define BUTTON_1_KEY    KEY_ENTER
-#define BUTTON_2_KEY    KEY_RIGHT_ALT
-#define BUTTON_3_KEY    KEY_PRINTSCREEN
-#define BUTTON_4_KEY    KEY_LEFT_SHIFT
-#define BUTTON_5_KEY    KEY_CAPS_LOCK
-#define BUTTON_6_KEY    KEY_A
+#define STICK_DOWN 0x7000
+#define STICK_UP -0x7000
+#define STICK_LEFT -0x7000
+#define STICK_RIGHT 0x7000
+
+#define STICK_DOWN_KEY  KEY_K
+#define STICK_UP_KEY    KEY_I
+#define STICK_LEFT_KEY  KEY_J
+#define STICK_RIGHT_KEY KEY_L
+#define BUTTON_1_KEY    KEY_D
+#define BUTTON_2_KEY    KEY_F
+#define BUTTON_3_KEY    KEY_G
+#define BUTTON_4_KEY    KEY_S
+#define BUTTON_5_KEY    KEY_MUHENKAN
+#define BUTTON_6_KEY    KEY_HENKAN
 #define BUTTON_7_KEY    KEY_SPACE

 USB    Usb;


Initlize random display at start up after the display is cleared after bootup text

--- padawan360_dome/padawan360_dome.ino
+++ padawan360_dome/padawan360_dome.ino
@@ -341,6 +341,7 @@

   // Scrolling is done, switch to random mode
   resetDisplays();
+  displayEffect = domeData.dsp;

 }///end setup


update new setup

update new setup

--- arduino/opencr_arduino/opencr/libraries/OpenManipulator/example/OPM_for_Arduino/test_manager/test_manager.ino
+++ arduino/opencr_arduino/opencr/libraries/OpenManipulator/example/OPM_for_Arduino/test_manager/test_manager.ino
@@ -1,6 +1,34 @@
 #include <OMManager.h>
-#include <OMMath.h>

+#define WORLD     0
+#define BASE      1
+#define SHOULDER  2
+#define UPPER_ARM 3
+#define LOWER_ARM 4
+#define WRIST     5
+#define GRIPPER   6
+
+#define NONE      -1
+
+void setup()
+{
+  Manipulator manipulator;
+  manipulator.addComponent(WORLD, NONE, BASE, mass, inertia_tensor, relative_position, relative_orientation, axis_of_rotation);
+  manipulator.addComponent(WORLD, NONE, BASE, mass, inertia_tensor, relative_position, relative_orientation, axis_of_rotation);
+  manipulator.addComponent(WORLD, NONE, BASE, mass, inertia_tensor, relative_position, relative_orientation, axis_of_rotation);
+  manipulator.addComponent(WORLD, NONE, BASE, mass, inertia_tensor, relative_position, relative_orientation, axis_of_rotation);
+  manipulator.addComponent(WORLD, NONE, BASE, mass, inertia_tensor, relative_position, relative_orientation, axis_of_rotation);
+
+}
+
+void loop()
+{
+
+}
+
+
+
+#if 0
 void setup()
 {
   OMMath math_;
@@ -75,4 +103,5 @@
 void loop()
 {

-}+}
+#endif


Update for SdFat 2.x support

Update for SdFat 2.x support

--- teensy/teensy.ino
+++ teensy/teensy.ino
@@ -26,8 +26,6 @@
 #include <SdFatConfig.h>
 #include <MinimumSerial.h>
 #include <SdFat.h>
-#include <BlockDriver.h>
-#include <SysCall.h>
 #include <DMAChannel.h>
 #include <EEPROM.h>

@@ -91,7 +89,7 @@
 static bool hold = false;
 static bool finished = false;

-static FatFile tasFile;
+static SdFile tasFile;

 //static unsigned int progressPos = 0;
 static unsigned long numFrames = 0, curFrame = 0;
@@ -99,7 +97,7 @@
 static int incompleteCommand = 0;
 static volatile unsigned long viCount = 0;

-static SdFatSdioEX sd;
+static SdFs sd;

 static uint16_t currentSnesFrame;

@@ -243,13 +241,13 @@

 static void emitList(const String& path)
 {
-  FatFile dir;
+  SdFile dir;
   if (!dir.open(&sd, path.c_str(), O_READ)) {
     Serial.println(F("E:Failed to open requested directory"));
     return;
   }
   dir.rewind();
-  FatFile listFile;
+  SdFile listFile;
   while (listFile.openNext(&dir)) {
     char name[256];
     listFile.getName(name, sizeof(name));
@@ -398,10 +396,10 @@
   return ret;
 }

-static FatFile writeFile;
+static SdFile writeFile;

 static void appendData(const String& data) {
-  if (writeFile.write(data.c_str(), data.length()) == (int)data.length())
+  if (writeFile.write(data.c_str(), data.length()) == data.length())
     Serial.println("AP:OK");
   else
     Serial.println("AP:NAK");
@@ -1085,4 +1083,3 @@
   if (doLoop)
     runEEPROM();
 }
-


LpgSerial test with simple manual

LpgSerial test with simple manual

--- tests/LpgSerial/LpgSerial.ino
+++ tests/LpgSerial/LpgSerial.ino
@@ -82,32 +82,33 @@
 */
 void serialEvent2() {

-    uint16_t width = pulseIn(LPG_INPUT, HIGH, LPG_TIMEOUT);
+    if (Serial2.available()) {
+        uint16_t width = pulseIn(LPG_INPUT, HIGH, LPG_TIMEOUT);
+
 #ifdef LPG_TIME_SENS
-    Serial.println(width);
-    return;
+        Serial.println(width);
+        return;
 #endif
-    if (width == 0) {
-        if (lpg_dataBuffer) {
-            lpg_dataOffset = 0;
-            lpg_recData = lpg_dataBuffer;
-            lpg_dataBuffer = '\0';
-            lpg_isReceive = true;
+        if (width == 0) {
+            if (lpg_dataBuffer) {
+                lpg_dataOffset = 0;
+                lpg_recData = lpg_dataBuffer;
+                lpg_dataBuffer = '\0';
+                lpg_isReceive = true;
+            } else {
+                lpg_isReceive = false;
+            }
+            return;
+        }
+
+        if (width > LPG_BYTE_HIGH_MIN && width < LPG_BYTE_HIGH_MAX) {
+            lpg_dataBuffer |= 1 << lpg_dataOffset;
+            lpg_dataOffset++;
         } else {
-            lpg_recData = '\0';
-            lpg_isReceive = false;
+            lpg_dataBuffer |= 0 << lpg_dataOffset;
+            lpg_dataOffset++;
         }
-        return;
     }
-
-    if (width > LPG_BYTE_HIGH_MIN && width < LPG_BYTE_HIGH_MAX) {
-        lpg_dataBuffer |= 1 << lpg_dataOffset;
-        lpg_dataOffset++;
-    } else {
-        lpg_dataBuffer |= 0 << lpg_dataOffset;
-        lpg_dataOffset++;
-    }
-
 }

@@ -139,16 +140,24 @@
     lpg.begin();
 }

+unsigned long loopCounter;
+void loop() {

-void loop() {
+    if (loopCounter % 500 == 0) {
+        Serial.print("Loop offset ");
+        Serial.print(loopCounter);
+        Serial.println();
+    }
+

     if (lpg_isReceive) {
         //
         // NOTE: original send 10000100100011 will be inverted in receive
         Serial.println();
+        Serial.print(" Data output ");
         Serial.println(lpg_recData, BIN);
-        Serial.print("13 bit is: ");
+        Serial.print(" && bit 13 is: ");
         Serial.println(bitRead(lpg_recData, 13));
-
     }
+    loopCounter++;
 }


Refactored PIRSketch

Refactored PIRSketch

--- ProofOfConceptNesh/PIRSketch.ino
+++ ProofOfConceptNesh/PIRSketch.ino
@@ -1,22 +1,22 @@
 /*
-This code connects to Azure IoT Hub and blinks the onboard LED on the MKR1000
-when there is a message for the particular device.
-
-Written by Mohan Palanisamy (http://mohanp.com)
-
-Instructions are here to properly set up the MKR1000 for SSL connections.
-http://mohanp.com/mkr1000-azure-iot-hub-how-to/
-Feb 19, 2016
+This code connects to Azure IoT Hub.
+Some logic has been adapted from Mohan Palanisamy (http://mohanp.com)
 */

 #include <SPI.h>
 #include <WiFi101.h>

+///*** PINs Config ***///
 const int MKR1000_LED = 6 ;
 const int  MKR1000_PINPIR1 = 14;               // choose the input pin (for PIR sensor)
-int pirState = LOW;             // we start, assuming no motion detected
+
+
 int val = 0;                    // variable for reading the pin status
-
+long unsigned int lowIn;         //the time when the sensor outputs a low impulse
+long unsigned int pause = 5000;  //the amount of milliseconds the sensor has to be low before we assume all motion has stopped
+boolean lockLow = true;
+boolean takeLowTime;
+String duration ="0";

 ///*** WiFi Network Config ***///
 char ssid[] = "YourWifiSSID"; //  your network SSID (name)
@@ -34,7 +34,6 @@

 unsigned long lastConnectionTime = 0;
 const unsigned long pollingInterval = 5L * 1000L; // 5 sec polling delay, in milliseconds
-

 int status = WL_IDLE_STATUS;

@@ -55,11 +54,11 @@
   // attempt to connect to Wifi network:
   while (status != WL_CONNECTED) {
     status = WiFi.begin(ssid, pass);
+    Serial.println("wait 10 seconds for wifi connection:");
     // wait 10 seconds for connection:
-	Serial.println("wait 10 seconds for connection");
     delay(10000);
   }
-  Serial.println("connection succeeded");
+  Serial.println("wifi connection succeeded:");
 }

 void azureMessageloop()
@@ -89,8 +88,7 @@

   // polling..if pollingInterval has passed
   if (millis() - lastConnectionTime > pollingInterval) {
-    digitalWrite(MKR1000_LED, LOW);
-    //detectMotion();
+    digitalWrite(MKR1000_LED, LOW);
   }
 }

@@ -119,7 +117,7 @@
   }
   else {
     // if you couldn't make a connection:
-    Serial.println("connection failed");
+    Serial.println("connection to azure webservice failed");
   }
 }

@@ -153,32 +151,48 @@
   }
   else {
     // if you couldn't make a connection:
-    Serial.println("connection failed");
+    Serial.println("connection to azure webservice failed");
   }
 }

 void loop(){
-  val = digitalRead(MKR1000_PINPIR1);  // read input value
-  if (val == HIGH) {            // check if the input is HIGH
-    digitalWrite(MKR1000_LED, HIGH);  // turn LED ON
-    delay(150);
+  val = digitalRead(MKR1000_PINPIR1);   // read input value
+  if (val == HIGH) {                    // check if the input is HIGH
+    digitalWrite(MKR1000_LED, HIGH);    // turn LED ON
+    //delay(150);
+
+    if (lockLow) {
+         lockLow = false;               //makes sure we wait for a transition to LOW before any further output is made:
+         duration = millis()/1000;
+         Serial.println("---");
+         Serial.print("motion detected at ");
+         Serial.print(duration);
+         Serial.println(" sec");
+
+         azureHttpPost("{deviceId:NeshMKR100Dev1, motion:1,elapsed:"+ duration + "}");
+    }

-    if (pirState == LOW) {
-      // we have just turned on
-      azureHttpPost("{deviceId:NeshMKR100Dev1, motion:1}");
-      Serial.println("Motion detected!");
-      // We only want to print on the output change, not state
-      pirState = HIGH;
-    }
-  } else {
-      digitalWrite(MKR1000_LED, LOW); // turn LED OFF
-      delay(300);
-      if (pirState == HIGH){
-      // we have just turned off
-      azureHttpPost("{deviceId:NeshMKR100Dev1, motion:0}");
-      Serial.println("Motion ended!");
-      // We only want to print on the output change, not state
-      pirState = LOW;
+    takeLowTime = true;
+  }
+  else {
+      digitalWrite(MKR1000_LED, LOW);   // turn LED OFF
+      //delay(150);
+
+       if(takeLowTime){
+          lowIn = millis();             //save the time of the transition from high to LOW
+          takeLowTime = false;          //make sure this is only done at the start of a LOW phase
+        }
+
+       //if the sensor is low for more than the given pause, we assume that no more motion is going to happen
+       if(!lockLow && millis() - lowIn > pause){
+           //makes sure this block of code is only executed again after a new motion sequence has been detected
+           lockLow = true;
+           duration = (millis() - pause)/1000;
+           Serial.print("motion ended at ");      //output
+           Serial.print(duration);
+           Serial.println(" sec");
+
+          azureHttpPost("{deviceId:NeshMKR100Dev1, motion:0,elapsed:"+ duration + "}");
     }
   }
 }


Made software serial object non-static, made format ptr const

--- Software/gridMeter/gridMeter.ino
+++ Software/gridMeter/gridMeter.ino
@@ -67,7 +67,7 @@
 static const uint32_t IDEAL_F_CLK_COUNTS = IDEAL_SECONDS * IDEAL_F_CLK;  // If mains is exactly 50Hz, should count exactly this many clocks in time period

 // Software serial is used for debugging - outputs frequency every second
-static SoftwareSerial s_serial(RX_PIN, TX_PIN); // RX, TX (physical pins 11, 12)
+SoftwareSerial s_serial(RX_PIN, TX_PIN); // RX, TX (physical pins 11, 12)

 /*
  * Module private functions
@@ -76,7 +76,7 @@
 /* output_to_serial
  * Print "output" wth the given printf format, with or without newline
  */
-static void output_to_serial(uint32_t output, char * fmt, bool newline = false)
+static void output_to_serial(uint32_t output, char const * const fmt, bool newline = false)
 {
 	char buf[16];
 	sprintf(buf, fmt, output);


Update mech.ino

Update mech.ino

--- mech/mech.ino
+++ mech/mech.ino
@@ -143,7 +143,7 @@
       stepperC2.run();
   }
   adcCnt = 0;
-  while (adcCnt < 128) {
+  while (adcCnt < 16) {
     busLoop();
     adcLoop();
     sendStatusUpdates();
@@ -178,7 +178,7 @@
   isAutoTune = 1;
   stepperC1.moveTo(10);
   stepperC2.moveTo(10);
-  stepperL.setAcceleration(20000);
+  stepperL.setAcceleration(800);
   optimize(&stepperL, 1000, 0);
   optimize(&stepperC1, 20, 0);
   optimize(&stepperC2, 20, 0);


Fix tx example.

Fix tx example.

--- examples/tx/tx.ino
+++ examples/tx/tx.ino
@@ -29,7 +29,9 @@
     if (millis() < next)
         return;

+    next = millis() + 1000;
     on = !on;
+
     nRF24L01Message msg;

     if (on) {


add door check callback

add door check callback

--- _06-power_meter/_06-power_meter.ino
+++ _06-power_meter/_06-power_meter.ino
@@ -28,6 +28,8 @@
 char* willTopic = "clients/power";
 char* willMessage = "0";

+char* subtopic = "esp8266/check";
+
 IPAddress server(192, 168, 10, 10);

 // pin : using line tracker
@@ -69,7 +71,7 @@
 int average = 0;

 WiFiClient wifiClient;
-PubSubClient client(wifiClient);
+PubSubClient client(server, 1883, callback, wifiClient);

 long lastReconnectAttempt = 0;

@@ -119,6 +121,7 @@
       } else {
         client.publish(hellotopic, "hello again 1 from ESP8266 s07");
       }
+      client.subscribe(subtopic);
       if (EVENT_PRINT) {
         Serial.println("---------------> connected");
       }
@@ -131,6 +134,36 @@
   }
   //timemillis = millis();
   return client.connected();
+}
+
+void callback(char* intopic, byte* inpayload, unsigned int length)
+{
+  String receivedtopic = intopic;
+  String receivedpayload ;
+
+  for (int i = 0; i < length; i++) {
+    receivedpayload += (char)inpayload[i];
+  }
+
+  if (EVENT_PRINT) {
+    Serial.print(intopic);
+    Serial.print(" => ");
+    Serial.println(receivedpayload);
+  }
+
+  if ( receivedpayload == "{\"DOOR\":\"CHECKING\"}") {
+
+    String check_doorpayload = "{\"DOOR\":";
+    if ( doorStatus == 0 ) {
+      check_doorpayload += "\"CHECK_CLOSED\"";
+    }
+    else {
+      check_doorpayload += "\"CHECK_OPEN\"";
+    }
+    check_doorpayload += "}";
+    sendmqttMsg(doortopic, check_doorpayload);
+  }
+
 }

 void setup() {
@@ -223,7 +256,7 @@
   } else {
     wifi_connect();
   }
-
+
   VIrms = emon1.calcIrms(1480) * 220.0;
   ave.push(VIrms);
   average = ave.mean();


checking pulse counter of power

checking pulse counter of power

--- _06-power_meter/_06-power_meter.ino
+++ _06-power_meter/_06-power_meter.ino
@@ -252,23 +252,23 @@
   ArduinoOTA.onError([](ota_error_t error) {
     //ESP.restart();
     /*
-    if (error == OTA_AUTH_ERROR) abort();
-    else if (error == OTA_BEGIN_ERROR) abort();
-    else if (error == OTA_CONNECT_ERROR) abort();
-    else if (error == OTA_RECEIVE_ERROR) abort();
-    else if (error == OTA_END_ERROR) abort();
+      if (error == OTA_AUTH_ERROR) abort();
+      else if (error == OTA_BEGIN_ERROR) abort();
+      else if (error == OTA_CONNECT_ERROR) abort();
+      else if (error == OTA_RECEIVE_ERROR) abort();
+      else if (error == OTA_END_ERROR) abort();
     */
   });

   ArduinoOTA.begin();

-  pinMode(IRPIN, INPUT);
+  pinMode(IRPIN, INPUT_PULLUP);
   pinMode(DOORPIN, INPUT_PULLUP);

   doorStatus = digitalRead(DOORPIN);
   olddoorStatus = doorStatus;

-  attachInterrupt(4, IRCHECKING_START, FALLING);
+  attachInterrupt(4, IRCHECKING_START, RISING);
   attachInterrupt(5, DOORCHECKING, CHANGE);

   //emon1.current(A0, 60.6);
@@ -282,7 +282,7 @@

 void IRCHECKING_START() {
   detachInterrupt(4);
-  attachInterrupt(4, count_powermeter, FALLING);
+  attachInterrupt(4, count_powermeter, RISING);
   startMills = millis();
   oldirStatus = HIGH ;
 }
@@ -302,86 +302,90 @@
           lastReconnectAttempt = 0;
         }
       }
+    } else {
+
+      if ((millis() - sentMills) > ( 700) ) {
+        unsigned long emonmillis = millis();
+        //VIrms = emon1.calcIrms(1480) * 220.0;
+        VIrms = emon1.calcIrms(2960) * 220.0;
+        calcIrmsmillis = millis() - emonmillis;
+
+        ave.push(VIrms);
+        average = ave.mean();
+      }
+
+      //if ( revMills > 600 ) {
+      if ( irStatus == oldirStatus ) {
+        revValue = (float(( 3600  * 1000 ) / ( 600 * float(revMills) ) ) * 1000);
+      }
+      //}
+
+      if ( oldrevValue == 0 ) {
+        oldrevValue = revValue;
+      }
+
+      if ( oldrevMills == 0 ) {
+        oldrevMills = revMills;
+      }
+
+      payload = "{\"VIrms\":";
+      payload += average;
+      payload += ",\"revValue\":";
+      payload += revValue;
+      payload += ",\"revMills\":";
+      payload += revMills;
+      payload += ",\"powerAvg\":";
+      payload += (( average + revValue ) / 2) ;
+      payload += ",\"Stddev\":";
+      payload += ave.stddev();
+      payload += ",\"calcIrmsmillis\":";
+      payload += calcIrmsmillis;
+      payload += ",\"revCounts\":";
+      payload += revCounts;
+      payload += ",\"FreeHeap\":";
+      payload += ESP.getFreeHeap();
+      payload += ",\"RSSI\":";
+      payload += WiFi.RSSI();
+      payload += ",\"millis\":";
+      payload += (millis() - timemillis);
+      payload += "}";
+
+      if ( doorStatus != olddoorStatus ) {
+
+        doorpayload = "{\"DOOR\":";
+
+        if ( doorStatus == 0 ) {
+          doorpayload += "\"CLOSED\"";
+        }
+        else {
+          doorpayload += "\"OPEN\"";
+        }
+        doorpayload += "}";
+
+        sendmqttMsg(doortopic, doorpayload);
+        olddoorStatus = doorStatus ;
+      }
+
+      if (((millis() - sentMills) > REPORT_INTERVAL ) && ( irStatus == oldirStatus )) {
+        sendmqttMsg(topic, payload);
+        sentMills = millis();
+      }
+
+      if ( irStatus != oldirStatus ) {
+        sendmqttMsg(topic, payload);
+        sentMills = millis();
+        oldirStatus = irStatus ;
+        oldrevValue = revValue ;
+        oldrevMills = revMills ;
+      }
+
+      client.loop();
+      ArduinoOTA.handle();
+
     }
   } else {
     wifi_connect();
   }
-
-  if ((millis() - sentMills) > ( 700) ) {
-    unsigned long emonmillis = millis();
-    //VIrms = emon1.calcIrms(1480) * 220.0;
-    VIrms = emon1.calcIrms(2960) * 220.0;
-    calcIrmsmillis = millis() - emonmillis;
-
-    ave.push(VIrms);
-    average = ave.mean();
-  }
-
-  if ( revMills > 600 ) {
-    revValue = (float(( 3600  * 1000 ) / ( 600 * float(revMills) ) ) * 1000);
-  }
-
-  if ( oldrevValue == 0 ) {
-    oldrevValue = revValue;
-  }
-
-  if ( oldrevMills == 0 ) {
-    oldrevMills = revMills;
-  }
-
-  payload = "{\"VIrms\":";
-  payload += average;
-  payload += ",\"revValue\":";
-  payload += revValue;
-  payload += ",\"revMills\":";
-  payload += revMills;
-  payload += ",\"powerAvg\":";
-  payload += (( average + revValue ) / 2) ;
-  payload += ",\"Stddev\":";
-  payload += ave.stddev();
-  payload += ",\"calcIrmsmillis\":";
-  payload += calcIrmsmillis;
-  payload += ",\"revCounts\":";
-  payload += revCounts;
-  payload += ",\"FreeHeap\":";
-  payload += ESP.getFreeHeap();
-  payload += ",\"RSSI\":";
-  payload += WiFi.RSSI();
-  payload += ",\"millis\":";
-  payload += (millis() - timemillis);
-  payload += "}";
-
-  if ( doorStatus != olddoorStatus ) {
-
-    doorpayload = "{\"DOOR\":";
-
-    if ( doorStatus == 0 ) {
-      doorpayload += "\"CLOSED\"";
-    }
-    else {
-      doorpayload += "\"OPEN\"";
-    }
-    doorpayload += "}";
-
-    sendmqttMsg(doortopic, doorpayload);
-    olddoorStatus = doorStatus ;
-  }
-
-  if (((millis() - sentMills) > REPORT_INTERVAL ) && ( irStatus == oldirStatus )) {
-    sendmqttMsg(topic, payload);
-    sentMills = millis();
-  }
-
-  if ( irStatus != oldirStatus ) {
-    sendmqttMsg(topic, payload);
-    sentMills = millis();
-    oldirStatus = irStatus ;
-    oldrevValue = revValue ;
-    oldrevMills = revMills ;
-  }
-
-  client.loop();
-  ArduinoOTA.handle();
 }

 void sendmqttMsg(char* topictosend, String payloadtosend)
@@ -425,17 +429,18 @@

   if (( millis() - startMills ) < 600 ) {
     return;
-  }
-
-  if (( millis() - startMills ) < ( revMills / 3 )) {
-    return;
+    /*
+      }
+
+      if (( millis() - startMills ) < ( revMills / 3 )) {
+       return;
+    */
   } else {
     revMills   = (millis() - startMills)  ;
     startMills = millis();
     irStatus   = !irStatus ;
     revCounts++;
   }
-
 }

 String macToStr(const uint8_t* mac)


Reduce SRAM usage.

Reduce SRAM usage.

--- sketch/arduino-golem/arduino-golem.ino
+++ sketch/arduino-golem/arduino-golem.ino
@@ -6,8 +6,9 @@
 #include <Ethernet.h>
 #include <EthernetServer.h>
 #include <string.h>
-
-//#define DEBUG
+#include <avr/pgmspace.h>
+
+#define DEBUG

 #define MAX_ROUTE_LENGTH 20
 #define MAX_HEADER_NAME_LENGTH 20
@@ -103,7 +104,7 @@
             SetState(STATE_FAIL);
           } else if (character == ' ') {
             #ifdef DEBUG
-              Serial.print("Request Method: ");
+              Serial.print(F("Request Method: "));
               Serial.println(method);
             #endif

@@ -118,7 +119,7 @@
             SetState(STATE_FAIL);
           } else if (character == ' ') {
             #ifdef DEBUG
-              Serial.print("Request Route: ");
+              Serial.print(F("Request Route: "));
               Serial.println(route);
             #endif

@@ -131,7 +132,7 @@
         case STATE_REQUEST_PROTOCOL:
           if (isTerminator) {
             #ifdef DEBUG
-              Serial.print("Request Protocol: ");
+              Serial.print(F("Request Protocol: "));
               Serial.println(protocol);
             #endif

@@ -146,7 +147,7 @@
             SetState(header_name.Length() == 0 ? STATE_SUCCESS : STATE_FAIL);
           } else if (character == ':') {
             #ifdef DEBUG
-              Serial.print("Header Name: ");
+              Serial.print(F("Header Name: "));
               Serial.println(header_name);
             #endif

@@ -159,7 +160,7 @@
         case STATE_HEADER_VALUE:
           if (isTerminator) {
             #ifdef DEBUG
-              Serial.print("Header Value: ");
+              Serial.print(F("Header Value: "));
               Serial.println(header_value);
             #endif

@@ -269,7 +270,7 @@
       pos = current_pos;

       #ifdef DEBUG
-        Serial.print("Path fragment: ");
+        Serial.print(F("Path fragment: "));
         Serial.println(element);
       #endif

@@ -327,12 +328,13 @@
   if (switch_index > 3) return false;

   #ifdef DEBUG
-    Serial.print("Toggle switch ");
+    Serial.print(F("Toggle switch "));
     Serial.print(switch_index);
-    Serial.println(toggle ? " on" : " off");
+    Serial.println(toggle ? F(" on") : F(" off"));
   #endif

-  char code[14] = "000FFFF0FFFFS";
+  char code[14];
+  strcpy_P(code, PSTR("000FFFF0FFFFS"));

   switch (switch_index) {
     case 3:
@@ -355,7 +357,7 @@
   if (!toggle) code[11] = '0';

   #ifdef DEBUG
-    Serial.print("Sending code ");
+    Serial.print(F("Sending code "));
     Serial.print(code);
   #endif

@@ -381,7 +383,7 @@
   char buffer[URL_PARSE_BUFFER_SIZE];

   if (!url_parser.NextPathElement(buffer, URL_PARSE_BUFFER_SIZE)) return response_not_found;
-  if (strcmp(buffer, "socket") != 0) return response_not_found;
+  if (strcmp_P(buffer, PSTR("socket")) != 0) return response_not_found;

   if (!url_parser.NextPathElement(buffer, URL_PARSE_BUFFER_SIZE)) return response_not_found;
   if (strlen(buffer) > 2 ) return response_not_found;
@@ -392,9 +394,9 @@
   if (!url_parser.NextPathElement(buffer, URL_PARSE_BUFFER_SIZE)) return response_not_found;
   if (!url_parser.AtEnd()) return response_not_found;

-  if (strcmp(buffer, "on") == 0) {
+  if (strcmp_P(buffer, PSTR("on")) == 0) {
     if (!toggle_switch(switch_index, true, rc_switch)) return response_not_found;
-  } else if (strcmp(buffer, "off") == 0) {
+  } else if (strcmp_P(buffer, PSTR("off")) == 0) {
     if (!toggle_switch(switch_index, false, rc_switch)) return response_not_found;
   } else {
     return response_not_found;
@@ -425,7 +427,7 @@
   Ethernet.begin(macAddress, ip);
   server.begin();

-  Serial.print("Server listening at ");
+  Serial.print(F("Server listening at "));
   Serial.println(Ethernet.localIP());
 }

@@ -434,7 +436,7 @@

   if (client) {
     #ifdef DEBUG
-      Serial.println("Incoming connection...");
+      Serial.println(F("Incoming connection..."));
     #endif

     HttpParser parser;
@@ -458,7 +460,7 @@

     if ((abs(millis() - start_timestamp)) > REQUEST_TIMEOUT) {
       #ifdef DEBUG
-        Serial.println("Request timeout");
+        Serial.println(F("Request timeout"));
       #endif

       parser.Abort();


removed example

removed example

--- examples/BoardsAndShields/Arduino_M0_Serial/Arduino_M0_Serial.ino
+++ examples/BoardsAndShields/Arduino_M0_Serial/Arduino_M0_Serial.ino
@@ -1,78 +0,0 @@
-/**************************************************************
- * Blynk is a platform with iOS and Android apps to control
- * Arduino, Raspberry Pi and the likes over the Internet.
- * You can easily build graphic interfaces for all your
- * projects by simply dragging and dropping widgets.
- *
- *   Downloads, docs, tutorials: http://www.blynk.cc
- *   Blynk community:            http://community.blynk.cc
- *   Social networks:            http://www.fb.com/blynkapp
- *                               http://twitter.com/blynk_app
- *
- * Blynk library is licensed under MIT license
- * This example code is in public domain.
- *
- **************************************************************
- * This example shows how to use ordinary Arduino Serial
- * to connect your project to Blynk.
- * Feel free to apply it to any other example. It's simple!
- *
- * 1. Optional, but recommended.
- *    Connect additional USB-serial adapter to see the prints.
- *
- * 2. Edit auth token and upload this sketch.
- *
- * 3. Run the script (script located in "scripts" folder of library root,
- *    e.g. 'blynk-library/scripts') for redirecting traffic to server:
- *
- *      for Windows:
- *                     1. Open cmd.exe
- *                     2. write : (your way to blynk-ser.bat folder) example: "cd C:\blynk-library-0.3.1\blynk-library-0.3.1\scripts"
- *                     3. write : "blynk-ser.bat -c COM4" (where COM4 is port with your Arduino)
- *                     4. And press "Enter" , press "Enter" and press "Enter"
- *
- *      for Linux and OSX:
- *
- *                    ./blynk-ser.sh (may need to run with sudo)
- *
- *    You can specify port, baud rate, and server endpoint like this:
- *      ./blynk-ser.sh -c <serial port> -b <baud rate> -s <server address> -p <server port>
- *
- *    For instance :
- *      ./blynk-ser.sh -c /dev/ttyACM0 -b 9600 -s cloud.blynk.cc -p 8442
- *
- *    Run blynk-ser.sh -h for more information
- *
- *    Be sure to select the right serial port (there may be multiple).
- *
- *    Attention!
- *        Arduino IDE may complain with "programmer is not responding".
- *        You need to terminate script before uploading new sketch.
- *
- * 4. Start blynking! :)
- *
- **************************************************************/
-
-#define BLYNK_PRINT SerialUSB
-#include <BlynkSimpleSerial.h>
-
-// You should get Auth Token in the Blynk App.
-// Go to the Project Settings (nut icon).
-char auth[] = "YourAuthToken";
-
-void setup()
-{
-  // Debug console to SerialUSB
-  SerialUSB.begin(9600);
-
-  // Blynk will work through Serial
-  Blynk.begin(auth);
-  // Default baud rate is 9600. You could specify it like this:
-  //Blynk.begin(auth, 57600);
-}
-
-void loop()
-{
-  Blynk.run();
-}
-


Ginsing support and other stuff

Ginsing support and other stuff

--- laserharp.ino
+++ laserharp.ino
@@ -5,6 +5,8 @@

 #include <Adafruit_MotorShield.h>
 #include "utility/Adafruit_PWMServoDriver.h"
+
+#include <GinSing.h>

 #define BAUD             115200
 #define LIGHT_SENSOR_PIN      0
@@ -13,8 +15,15 @@
 #define MIDICMD_NOTEON     0x90 // MIDI command (Note On, Channel 0)
 #define MIDICMD_NOTEOFF    0x80 // MIDI command (Note On, Channel 0)

-#define NOTE_COUNT_MAX      100 // kinda a hack to allow static initialization in waitForNote
-
+#define NOTE_COUNT_MAX      10 // kinda a hack to allow static initialization in waitForNote
+
+GinSing  gGS;            // this creates the class library from which all methods and data are accessed
+GinSingPoly * gGSPoly =     NULL;
+
+GSNote gGSNote[NOTE_COUNT_MAX] = {C_6, CS_6, D_6, DS_6, E_6, F_6, FS_6, G_6, GS_6, A_6};
+
+bool gMidi             =   false;
+bool gGinsing          =   true;
 int  gNoteCount        =   10;
 bool gMute             =   false;

@@ -98,15 +107,16 @@
   myMotor->step(steps, directionToStep, DOUBLE);
 }

-void setupMotor() {
-  AFMS.begin();  // create with the default frequency 1.6KHz
-  myMotor->setSpeed(250);
-
+void autoPositionMirror() {
   int maxLight = 0;
   int maxLightStep = 0;
   for (int i = 0; i < gMotorStepsPerRev; i++) {
+    if (i % (gMotorStepsPerRev / 10) == 0)
+    {
+      Serial.print(F("."));
+    }
     stepMotor(FORWARD, 1);
-    int sample = sampleLight(10);
+    int sample = sampleLight(30);
     logMeter(Log, sample, 600, LOG_LEVEL_INFOS);
     if (sample > maxLight)
     {
@@ -114,13 +124,23 @@
       maxLightStep = i;
     }
   }
-  Log.Error("Max light value (%d) at motor step %d\n", maxLight, maxLightStep);
+  Log.Info("Max light value (%d) at motor step %d\n", maxLight, maxLightStep);
   stepMotor(FORWARD, maxLightStep + (gMotorStepsPerRev / 8));
 }

+void setupMotor() {
+  Serial.print(F("Setting up motor..."));
+  AFMS.begin();  // create with the default frequency 1.6KHz
+  myMotor->setSpeed(250);
+  autoPositionMirror();
+  Serial.println(F("done"));
+
+}
+
 void sampleLightCmd()
 {
-  Serial.println(F("Running sampleLightCmd"));
+  Serial.print(F("Running ")); Serial.println(__FUNCTION__);
+
   Serial.print(F("Before: ")); Serial.println(gLightAverage);
   gLightAverage = sampleLight(50);
   Serial.print(F("After:  ")); Serial.println(gLightAverage);
@@ -128,7 +148,8 @@

 void setLightSensitivityCmd()
 {
-  Serial.println(F("Running setLightSensitivityCmd"));
+  Serial.print(F("Running ")); Serial.println(__FUNCTION__);
+
   char * str = sCmd.next();
   if (str && *str)
   {
@@ -156,12 +177,13 @@

 void setNoteCountCmd()
 {
-  Serial.println(F("Running setNoteCountCmd"));
+  Serial.print(F("Running ")); Serial.println(__FUNCTION__);
+
   char * str = sCmd.next();
   if (str && *str)
   {
     int val = atoi(str);
-    if (val > 1)
+    if (val > 1 && val <= NOTE_COUNT_MAX)
     {
       Serial.print(F("Before: ")); Serial.println(gNoteCount);
       gNoteCount = val;
@@ -187,28 +209,114 @@
   Serial.println(cmd);
 }

+void playMidiNote(bool on, int note)
+{
+  if (gMidi == false)
+  {
+    return;
+  }
+  char cmd = on ? MIDICMD_NOTEON : MIDICMD_NOTEOFF;
+  char data1 = 0x4a + note;
+  char data2 = 0x49;
+  Serial.print(cmd);
+  Serial.print(data1);
+  Serial.print(data2);
+}
+
+void playGinsingNote(bool on, int note)
+{
+  if (gGinsing == false)
+  {
+    return;
+  }
+
+  if (on == true)
+  {
+    gGSPoly->setNote(1, gGSNote[note]);
+    gGSPoly->trigger(1);
+  }
+  else
+  {
+    gGSPoly->release(1);
+  }
+}
+
+
+void playNote(bool on, int note)
+{
+  if (on == true && gMute == true)
+  {
+    return;
+  }
+
+  playMidiNote(on, note);
+
+  playGinsingNote(on, note);
+}
+
+
+void playNotesCmd()
+{
+  Serial.println(F("Running playNoteCmd"));
+  Serial.print(F("Playing notes: "));
+  for (int iNote = 0; iNote < NOTE_COUNT_MAX; iNote++)
+  {
+    Serial.print(iNote); Serial.print(F(" "));
+    playNote(true, iNote);
+    delay(250);
+    playNote(false, iNote);
+  }
+  Serial.println();
+}
+
 void setupSerialCommands()
 {
   sCmd.addCommand("SampleLight", sampleLightCmd);
   sCmd.addCommand("SetLightSensitivity", setLightSensitivityCmd);
   sCmd.addCommand("SetNoteCount", setNoteCountCmd);
-  //sCmd.addCommand("PlayNote")
+  sCmd.addCommand("AutoPosition", autoPositionMirror);
+  sCmd.addCommand("PlayNotes", playNotesCmd);
   sCmd.setDefaultHandler(unrecognizedSerialCmd);
 }

+void setupGinsing()
+{
+  if (gGinsing == false)
+  {
+    return;
+  }
+
+  Serial.println(F("Setting up ginsing"));
+
+#define rcvPin  4       // this is the pin used for receiving    ( can be either 4 or 12 )
+#define sndPin  3       // this is the pin used for transmitting ( can be either 3 or 11 )
+#define ovfPin  2       // this is the pin used for overflow control ( can be either 2 or 10 )
+  gGS.begin( rcvPin , sndPin , ovfPin );
+
+//  GinSingVoice *voice = gGS.getVoice();                    // get the interface for voice mode
+//  voice->begin();                                         // enter voice mode
+//  voice->preview();                                       // preview the mode
+
+  gGSPoly = gGS.getPoly();                           // get the poly mode interface
+  gGSPoly->begin ();  // enter poly mode
+}
+
 void setup()
 {
+  setupSerialCommands();
+
   Log.Init(gLogLevel, BAUD);

   //For the light sensor
   analogReference(EXTERNAL);

+  setupGinsing();
+
   setupMotor();

   //Get some initial values for each light string
   gLightAverage = sampleLight(50);

-  setupSerialCommands();
 }

 //Read the sonar unit and figure out if the
@@ -221,24 +329,12 @@

 }

-
-void SendMIDI(char cmd, char data1, char data2)
-{
-  if (gMute == false)
-  {
-    Serial.print(cmd);
-    Serial.print(data1);
-    Serial.print(data2);
-  }
-}
-
-
-void waitForNote(int note)
+void waitForNote(int note, int delay)
 {
   static bool noteStates[NOTE_COUNT_MAX] = {0};
   bool detected = false;
   bool currentlyOn = noteStates[note];
-  unsigned long duration = millis() + gMotorStepDelay;
+  unsigned long duration = millis() + delay;
   while (millis() < duration)
   {
     int light = analogRead(LIGHT_SENSOR_PIN);
@@ -249,11 +345,7 @@
     if (currentlyOn != detected)
     {
       Log.Info("Note %d %s!\n", note, detected ? "on" : "off");
-
-      SendMIDI(
-        currentlyOn ? MIDICMD_NOTEOFF : MIDICMD_NOTEON,
-        0x4a + note,
-        0x49);
+      playNote(detected, note);
     }

   }
@@ -327,25 +419,40 @@

 void loop()
 {
-
-  for (int i = 1; i < gNoteCount; i++)
-  {
-    if (gMotorStepDelay > 0) {
-      stepMotor(FORWARD);
-      waitForNote(i);
-    }
-  }
-
+  static int iNote = 0;
+  static int motorDirection = FORWARD;
+
+  waitForNote(iNote, gMotorStepDelay);
   checkSonar();
-
-  for (int i = gNoteCount - 2; i >= 0; i--)
-  {
-    if (gMotorStepDelay > 0) {
-      stepMotor(BACKWARD);
-      waitForNote(i);
-    }
-  }
-
   checkButtons();
-  checkSonar();
-}
+
+  if (gMotorStepDelay > 0)
+  {
+    stepMotor(motorDirection);
+    if (motorDirection == FORWARD)
+    {
+      iNote++;
+      if (iNote == (gNoteCount-1))
+      {
+        motorDirection = BACKWARD;
+      }
+    }
+    else
+    {
+      iNote--;
+      if (iNote == 0)
+      {
+        motorDirection = FORWARD;
+      }
+    }
+  }
+}
+
+void shutdown ()
+{
+  if (gGinsing == true)
+  {
+     gGS.end();
+  }
+}
+


-Close request on no auth.

-Close request on no auth.

--- webservertask.ino
+++ webservertask.ino
@@ -68,7 +68,8 @@
       else
       {
         Serial.println( "Unauthorized access." );
-        request->send( 401, "text/plain", "Not logged in." );
+        xSemaphoreGive( x_SPI_Mutex );
+        return request->send( 401, "text/plain", "Not logged in." );
       }
     }


Add parser for talkback

Add parser for talkback

- add (simple) parsing functionalit
- add shield outputs

--- examples/03.ThingSpeak/ExecuteCommand/ExecuteCommand.ino
+++ examples/03.ThingSpeak/ExecuteCommand/ExecuteCommand.ino
@@ -11,19 +11,77 @@
 // CHANGE THE TALKBACK ID HERE:
 static const unsigned int talkbackId = 3092;

-SoftwareSerial espSerial(2,3);
+ParkingShield shield;
+SoftwareSerial espSerial(2, 3);
 Esp8266<SoftwareSerial> esp(espSerial);
-ParkingShield shield;

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

   // Setup module
   esp.configureBaud();
   esp.setBaud(9600);
-  esp.joinAccessPoint("ti_iot","ti_iot42!");
+  esp.joinAccessPoint("ti_iot", "ti_iot42!");
   esp.setMultipleConnections(1);
+}
+
+void executeCommand(const String &str)
+{
+  if (str == F("LED_1_ON"))
+    shield.setLed(ParkingShield::RED_LED, true);
+
+  else if (str == F("LED_1_OFF"))
+    shield.setLed(ParkingShield::RED_LED, false);
+
+  else if (str == F("LED_2_ON"))
+    shield.setLed(ParkingShield::YELLOW_LED, true);
+
+  else if (str == F("LED_2_OFF"))
+    shield.setLed(ParkingShield::YELLOW_LED, false);
+
+  else if (str == F("LED_3_ON"))
+    shield.setLed(ParkingShield::GREEN_LED, true);
+
+  else if (str == F("LED_3_OFF"))
+    shield.setLed(ParkingShield::GREEN_LED, false);
+
+  else if (str == F("BUZZER_1_MARCH"))
+    shield.playMarch();
+
+  else if (str == F("7SEG_1_0"))
+    shield.showNumber(0);
+
+  else if (str == F("7SEG_1_1"))
+    shield.showNumber(1);
+
+  else if (str == F("7SEG_1_2"))
+    shield.showNumber(2);
+
+  else if (str == F("7SEG_1_3"))
+    shield.showNumber(3);
+
+  else if (str == F("7SEG_1_4"))
+    shield.showNumber(4);
+
+  else if (str == F("7SEG_1_5"))
+    shield.showNumber(5);
+
+  else if (str == F("7SEG_1_6"))
+    shield.showNumber(6);
+
+  else if (str == F("7SEG_1_7"))
+    shield.showNumber(7);
+
+  else if (str == F("7SEG_1_8"))
+    shield.showNumber(8);
+
+  else if (str == F("7SEG_1_9"))
+    shield.showNumber(9);
+
+  else if (str == F("7SEG_1_DOWN"))
+    shield.countDown();
+
 }

 void loop()
@@ -35,10 +93,10 @@

   // Build the request
   HttpRequest req(path);
-  req.addParameter(F("api_key"), api_key);
+  req.addParameter(F("api_key"), api_key);

   // Print the request
-  String reqStr = req.get();
+  String reqStr = req.get();
   Serial.print("Send request: ");
   Serial.println(reqStr);

@@ -49,12 +107,14 @@
   // Parse answer
   IPDParser parser(espSerial);
   if (parser.parse()) {
+    String payload = parser.getPayload();
     Serial.print("Received talkback: ");
-    Serial.println(parser.getPayload());
+    Serial.println(payload);
+    executeCommand(payload);
   }
   else
     Serial.println("No or invalid ansewer.");
-
-  // Thingspeak requires 15 s delay between requests
+
+  // Thingspeak requires 15 s delay between requests
   delay (16000);
 }


Update RTC.ino

Update RTC.ino

Fix #105

--- examples/Widgets/RTC/RTC.ino
+++ examples/Widgets/RTC/RTC.ino
@@ -60,6 +60,10 @@

   // Begin synchronizing time
   rtc.begin();
+
+  // Other Time library functions can be used, like:
+  //   timeStatus(), setSyncInterval(interval)...
+  // Read more: http://www.pjrc.com/teensy/td_libs_Time.html

   // Display digital clock every 10 seconds
   timer.setInterval(10000L, clockDisplay);


A mostly-working OctoTemp

A mostly-working OctoTemp

--- octotemp/code/OctoTemp/OctoTemp/OctoTemp.ino
+++ octotemp/code/OctoTemp/OctoTemp/OctoTemp.ino
@@ -1,3 +1,15 @@
+#include <ESP8266WiFi.h>
+#include <ESP8266WiFiAP.h>
+#include <ESP8266WiFiGeneric.h>
+#include <ESP8266WiFiMulti.h>
+#include <ESP8266WiFiScan.h>
+#include <ESP8266WiFiSTA.h>
+#include <ESP8266WiFiType.h>
+#include <WiFiClient.h>
+#include <WiFiClientSecure.h>
+#include <WiFiServer.h>
+#include <WiFiUdp.h>
+
 #include <Math.h>
 #include <Wire.h>
 #include <prometheus.h>
@@ -16,11 +28,16 @@
 #define ADC_ADDR 0x37
 #define NUM_CHANNELS 4

+
+#define WIFI_SSID           "Embedded Pie"
+#define WIFI_PASSWORD       "embedded"
+
+
 const String channels[NUM_CHANNELS] = {
   "hot_water_out",
   "recirc_return",
   "cold_water_in",
-  "recirc_pump_in",
+  "ambient",
 };

 // TODO(z2amiller):  Cut this out into a separate library.
@@ -125,6 +142,18 @@
 {
   Serial.begin(115200);
   adc.Init(0x1);
+  WiFi.begin(WIFI_SSID, WIFI_PASSWORD);
+    Serial.print("\n\r \n\rConnecting to WiFi.");
+  // Wait for connection
+  while (WiFi.status() != WL_CONNECTED) {
+    delay(100);
+    Serial.print(".");
+  }
+  Serial.println("");
+  Serial.print("Connected to ");
+  Serial.println(WIFI_SSID);
+  Serial.print("IP address: ");
+  Serial.println(WiFi.localIP());
 }

 float TempC(const uint8_t channel) {
@@ -154,5 +183,5 @@
     Serial.println(channels[ch] + "(" + ch + ") = " + TempF(ch));
   }
   prom.Send();
-  delay(5000);
+  delay(60000);
 }


Enable/disable functionality added

Enable/disable functionality added

--- examples/DWEasyFlipFlop_Basics/DWEasyFlipFlop_Basics.ino
+++ examples/DWEasyFlipFlop_Basics/DWEasyFlipFlop_Basics.ino
@@ -16,7 +16,7 @@
 // 				dejaWorks
 //
 // Date			06/03/15 17:10
-// Version		0.1
+// Version		0.2
 //
 // Copyright	Trevor D. BEYDAG 2015
 // License	    MIT
@@ -43,6 +43,8 @@
 	myFlipFlop.setFlopDelay(800);
 // Set Flop call back function (the function will be called after desigred ms delay)
 	myFlipFlop.setFlopHandler(flop);
+// Start flip flop
+	myFlipFlop.start();

 }
 void loop()


Tweaks

Tweaks

--- examples/mqtt_arbitrary_buffer/mqtt_arbitrary_buffer.ino
+++ examples/mqtt_arbitrary_buffer/mqtt_arbitrary_buffer.ino
@@ -28,8 +28,8 @@

 #define ARB_SERVER      "...host computer ip address..."
 #define ARB_SERVERPORT  1883                   // use 8883 for SSL
-#define ARB_USERNAME    "testUser"
-#define ARB_PW         "testPassword"
+#define ARB_USERNAME    "TestUser"
+#define ARB_PW         "TestUser"

 /************ Global State (you don't need to change this!) ******************/


successfully connected to wifi

successfully connected to wifi

--- module/module.ino
+++ module/module.ino
@@ -25,7 +25,7 @@
 	pinMode(ledPin, OUTPUT);
 	pinMode(signalPin, INPUT);
 	pinMode(speakerPin, OUTPUT);
-	Serial.println("Done.");
+	Serial.print("Done.\n");
 }

 void loop() {


Update mech.ino

Update mech.ino

--- mech/mech.ino
+++ mech/mech.ino
@@ -178,7 +178,7 @@
   isAutoTune = 1;
   stepperC1.moveTo(10);
   stepperC2.moveTo(10);
-  stepperL.setAcceleration(800);
+  stepperL.setAcceleration(1600);
   optimize(&stepperL, 1000, 0);
   optimize(&stepperC1, 20, 0);
   optimize(&stepperC2, 20, 0);


Revert "Fix for serialEvent example"

Revert "Fix for serialEvent example"

This reverts commit 4648330a7febbd7b7f4d28b75a0256b25b751532.

--- build/shared/examples/04.Communication/SerialEvent/SerialEvent.ino
+++ build/shared/examples/04.Communication/SerialEvent/SerialEvent.ino
@@ -28,7 +28,6 @@
 }

 void loop() {
-  serialEvent(); //call the function
   // print the string when a newline arrives:
   if (stringComplete) {
     Serial.println(inputString);


Cleaning up a bit.

Cleaning up a bit.

--- messenger.ino
+++ messenger.ino
@@ -58,7 +58,7 @@
 }

 void loop() {
-  // Update teh bouncer states
+  // Update the bouncer states
   bDIT.update();
   bDAH.update();
   bBRK.update();
@@ -94,25 +94,6 @@
     clearMessage();
     nBrk = 0;
   }
-
-}
-
-void addSeparators() {
-  if (nBrk == 1) {
-    addCharacter(readMorse());
-    clearMorse();
-  } else if (nBrk == 2) {
-    addCharacter(readMorse());
-    addCharacter(' ');
-    clearMorse();
-  } else if (nBrk == 3) {
-    addCharacter(readMorse());
-    addCharacter('.');
-    addCharacter(' ');
-    clearMorse();
-  }
-  printMessage();
-  nBrk = 0;
 }

 void addCharacter(char c) {


firmware updated for cc3200

firmware updated for cc3200


error handling for max servo moves; individual servo feed rates

--- uArm.ino
+++ uArm.ino
@@ -184,8 +184,8 @@
 	if (*buf[0] == '\0' || *buf[0] == '\n' || *buf[0] == '\r')
 		return false;

-	// should this display an error?
 	if (servoMoveCount == MAX_CMD_SERVO_MOVES) {
+		sendMsg(String(F("ERROR: servo command has too many simultaneous moves, max = ")) + String(MAX_CMD_SERVO_MOVES, DEC) + String(F("\n")));
 		return false;
 	}

@@ -210,6 +210,19 @@
 		case 'H': case 'h':
 			moveServoFuncPtr = &moveServoH;
 			servoShortName = 'H';
+			break;
+		case 'F': case 'f':
+			(*buf)++;
+			pos = strtoul(*buf, &endptr, 10);
+			if (pos > 0 && pos <= 255) {
+				servoSpeed = pos;
+				servoSpeedLocal = pos;
+			} else {
+				sendMsg(String(F("ERROR: invalid feed rate\n")));
+				return false;
+			}
+			*buf = endptr;
+			return true;
 			break;
 	};


expose api

expose api

--- status.ino
+++ status.ino
@@ -1,23 +1,51 @@
 #include "SparkButton.h"

+#define OFF 0
+#define GREEN 1
+#define RED 2
+
+
 SparkButton strip = SparkButton();
+
+int current[12];
+int desired[12];

 void setup() {
     strip.begin();
     strip.allLedsOff();
+    for(int i=0; i<12; i++) {
+        current[i] = OFF;
+        desired[i] = OFF;
+    }
+    Spark.function("update", handleUpdate);
 }

 void loop() {
     for(int i=0; i<12; i++) {
-        if (rand() % 2 == 0) {
-            strip.ledOff(i);
-        }
-        else {
-            int r = rand() % 255;
-            int g = rand() % 255;
-            int b = rand() % 255;
-            strip.ledOn(i, r, g, b);
+        if (current[i] != desired[i]) {
+            updateColor(i, desired[i]);
+            current[i] = desired[i];
         }
     }
-    delay(50);
 }
+
+void updateColor(int i, int state) {
+    switch(state) {
+        case OFF:
+            strip.ledOff(i);
+            break;
+        case GREEN:
+            strip.ledOn(i, 0, 10, 0);
+            break;
+        case RED:
+            strip.ledOn(i, 10, 0, 0);
+            break;
+    }
+}
+
+int handleUpdate(String command) {
+    int n = atoi(command.c_str());
+    desired[n] = GREEN;
+    desired[n+1] = RED;
+    return 1;
+}


Better collision handling

Better collision handling

proper collision handler...  inserts appropriate recovery actions onto cmdQ

--- software/firmware/LogoBotWifiScribbler/LogoBotWifiScribbler.ino
+++ software/firmware/LogoBotWifiScribbler/LogoBotWifiScribbler.ino
@@ -43,13 +43,14 @@
 #define MAX_CMD_LENGTH 10
 #define QUEUE_LENGTH 20

-// position state info
-struct POSITION {
+// logobot state info
+struct STATE {
   float x;
   float y;
   float ang;
+  byte colliding;  // 0 = not colliding, 1=left, 2=right, 3=both
 };
-POSITION position;
+STATE state;

 Servo penliftServo;

@@ -105,8 +106,6 @@
   } else
     return false;
 }
-
-

 String popCmd() {
   // pops head of queue
@@ -129,6 +128,8 @@
   return qSize == 0;
 }

+
+
 void printCommandQ()
 {
   Serial.print("cmdQ:");
@@ -147,9 +148,9 @@

 // position calcs
 void resetPosition() {
-  position.x = 0;
-  position.y = 0;
-  position.ang = 0;
+  state.x = 0;
+  state.y = 0;
+  state.ang = 0;
 }

@@ -206,12 +207,7 @@
     }
   }

-  // Check bump switches
-  if (!digitalRead(switchFL) || !digitalRead(switchFR)) {
-    buzz(250);
-    stepperL.setCurrentPosition(stepperL.currentPosition());
-    stepperR.setCurrentPosition(stepperR.currentPosition());
-  }
+  handleCollisions();

   // Do buzzer
   if (millis() < buzzEnd)
@@ -254,7 +250,47 @@
   }
 }

-void doLogoCommand(String c)
+
+static void handleCollisions() {
+  byte nowColliding = 0;
+  if (!digitalRead(switchFL)) nowColliding = 1;
+  if (!digitalRead(switchFR)) nowColliding += 2;
+
+  if (nowColliding != state.colliding) {
+    // collision state has changed, do something sensible
+
+    if (nowColliding == 1) {
+      // abort current command
+      abort();
+      buzz(500);
+
+      // insert some recovery steps
+      insertCmd("RT 45");
+      insertCmd("BK 20");
+    } else if (nowColliding == 2) {
+      // abort current command
+      abort();
+      buzz(500);
+
+      // insert some recovery steps
+      insertCmd("LT 45");
+      insertCmd("BK 20");
+    } else if (nowColliding == 3) {
+      // abort current command
+      abort();
+      buzz(500);
+
+      // insert some recovery steps
+      insertCmd("RT 120");
+      insertCmd("BK 20");
+    }
+
+    state.colliding = nowColliding;
+  }
+}
+
+
+static void doLogoCommand(String c)
 {
   /* Official Logo Commands
        Implemented
@@ -305,6 +341,11 @@
   }
 }

+void abort() {
+    stepperL.setCurrentPosition(stepperL.currentPosition());
+    stepperR.setCurrentPosition(stepperR.currentPosition());
+}
+
 void pushTo(float x, float y)
 {
   String s = "TO ";
@@ -316,13 +357,13 @@

 static void driveTo(float x, float y) {
   // calc angle
-  float ang = atan2(y-position.y, x-position.x) * 180 / PI;
+  float ang = atan2(y-state.y, x-state.x) * 180 / PI;
   // now angle delta
-  ang = ang - position.ang;
+  ang = ang - state.ang;
   turn(ang);

   // and distance
-  float dist = sqrt(sqr(y-position.y) + sqr(x-position.x));
+  float dist = sqrt(sqr(y-state.y) + sqr(x-state.x));
   String s = "FD ";
   s += dist;
   insertCmd(s);
@@ -331,8 +372,8 @@
 void drive(float distance)
 {
   // update state
-  position.x += distance * cos(position.ang * PI / 180);
-  position.y += distance * sin(position.ang * PI / 180);
+  state.x += distance * cos(state.ang * PI / 180);
+  state.y += distance * sin(state.ang * PI / 180);

   // prime the move
   int steps = distance * STEPS_PER_MM;
@@ -343,11 +384,11 @@
 void turn(float ang)
 {
   // update state
-  position.ang += ang;
+  state.ang += ang;

   // correct wrap around
-  if (position.ang > 360) position.ang -= 360;
-  if (position.ang < -360) position.ang += 360;
+  if (state.ang > 360) state.ang -= 360;
+  if (state.ang < -360) state.ang += 360;

   // prime the move
   int steps = ang * STEPS_PER_DEG;
@@ -480,8 +521,8 @@

 static void writeA()
 {
-  float x = position.x;
-  float y = position.y;
+  float x = state.x;
+  float y = state.y;
   float w = fontSize * 0.5;

   pushCmd("PD");
@@ -496,8 +537,8 @@

 static void writeB()
 {
-  float x = position.x;
-  float y = position.y;
+  float x = state.x;
+  float y = state.y;
   float w = fontSize * 0.5;

   pushCmd("PD");
@@ -513,8 +554,8 @@

 static void writeC()
 {
-  float x = position.x;
-  float y = position.y;
+  float x = state.x;
+  float y = state.y;
   float w = fontSize * 0.5;

   pushTo(x + w, y + capHeight);
@@ -527,8 +568,8 @@

 static void writeD()
 {
-  float x = position.x;
-  float y = position.y;
+  float x = state.x;
+  float y = state.y;
   float w = fontSize * 0.5;

   pushCmd("PD");
@@ -543,8 +584,8 @@

 static void writeE()
 {
-  float x = position.x;
-  float y = position.y;
+  float x = state.x;
+  float y = state.y;
   float w = fontSize * 0.5;

   pushCmd("PD");
@@ -561,8 +602,8 @@

 static void writeF()
 {
-  float x = position.x;
-  float y = position.y;
+  float x = state.x;
+  float y = state.y;
   float w = fontSize * 0.5;

   pushCmd("PD");
@@ -577,8 +618,8 @@

 static void writeG()
 {
-  float x = position.x;
-  float y = position.y;
+  float x = state.x;
+  float y = state.y;
   float w = fontSize * 0.5;

   pushTo(x + w, y + capHeight);
@@ -593,8 +634,8 @@

 static void writeH()
 {
-  float x = position.x;
-  float y = position.y;
+  float x = state.x;
+  float y = state.y;
   float w = fontSize * 0.5;

   pushCmd("PD");
@@ -608,8 +649,8 @@

 static void writeI()
 {
-  float x = position.x;
-  float y = position.y;
+  float x = state.x;
+  float y = state.y;
   float w = fontSize * 0.5;

   pushTo(x + w / 2, y);
@@ -620,8 +661,8 @@

 static void writeJ()
 {
-  float x = position.x;
-  float y = position.y;
+  float x = state.x;
+  float y = state.y;
   float w = fontSize * 0.5;

   pushTo(x, y + capHeight / 4);
@@ -634,8 +675,8 @@

 static void writeK()
 {
-  float x = position.x;
-  float y = position.y;
+  float x = state.x;
+  float y = state.y;
   float w = fontSize * 0.5;

   pushCmd("PD");
@@ -650,8 +691,8 @@

 static void writeL()
 {
-  float x = position.x;
-  float y = position.y;
+  float x = state.x;
+  float y = state.y;
   float w = fontSize * 0.5;

   pushCmd("PD");
@@ -663,8 +704,8 @@

 static void writeM()
 {
-  float x = position.x;
-  float y = position.y;
+  float x = state.x;
+  float y = state.y;
   float w = fontSize * 0.5;

   pushCmd("PD");
@@ -677,8 +718,8 @@

 static void writeN()
 {
-  float x = position.x;
-  float y = position.y;
+  float x = state.x;
+  float y = state.y;
   float w = fontSize * 0.5;

   pushCmd("PD");
@@ -690,8 +731,8 @@

 static void writeO()
 {
-  float x = position.x;
-  float y = position.y;
+  float x = state.x;
+  float y = state.y;
   float w = fontSize * 0.5;

   pushCmd("PD");
@@ -704,8 +745,8 @@

 static void writeP()
 {
-  float x = position.x;
-  float y = position.y;
+  float x = state.x;
+  float y = state.y;
   float w = fontSize * 0.5;

   pushCmd("PD");
@@ -718,8 +759,8 @@

 static void writeQ()
 {
-  float x = position.x;
-  float y = position.y;
+  float x = state.x;
+  float y = state.y;
   float w = fontSize * 0.5;

   pushCmd("PD");
@@ -737,8 +778,8 @@

 static void writeR()
 {
-  float x = position.x;
-  float y = position.y;
+  float x = state.x;
+  float y = state.y;
   float w = fontSize * 0.5;

   pushCmd("PD");
@@ -752,8 +793,8 @@

 static void writeS()
 {
-  float x = position.x;
-  float y = position.y;
+  float x = state.x;
+  float y = state.y;
   float w = fontSize * 0.5;

   pushCmd("PD");
@@ -767,8 +808,8 @@

 static void writeT()
 {
-  float x = position.x;
-  float y = position.y;
+  float x = state.x;
+  float y = state.y;
   float w = fontSize * 0.5;
   pushTo(x + w/2, y);
   pushCmd("PD");
@@ -780,8 +821,8 @@

 static void writeU()
 {
-  float x = position.x;
-  float y = position.y;
+  float x = state.x;
+  float y = state.y;
   float w = fontSize * 0.5;

   pushTo(x, y + capHeight);
@@ -794,8 +835,8 @@

 static void writeV()
 {
-  float x = position.x;
-  float y = position.y;
+  float x = state.x;
+  float y = state.y;
   float w = fontSize * 0.5;

   pushTo(x, y + capHeight);
@@ -807,8 +848,8 @@

 static void writeW()
 {
-  float x = position.x;
-  float y = position.y;
+  float x = state.x;
+  float y = state.y;
   float w = fontSize * 0.5;

   pushTo(x, y + capHeight);
@@ -822,8 +863,8 @@

 static void writeX()
 {
-  float x = position.x;
-  float y = position.y;
+  float x = state.x;
+  float y = state.y;
   float w = fontSize * 0.5;

   pushCmd("PD");
@@ -837,8 +878,8 @@

 static void writeY()
 {
-  float x = position.x;
-  float y = position.y;
+  float x = state.x;
+  float y = state.y;
   float w = fontSize * 0.5;

   pushCmd("PD");
@@ -853,8 +894,8 @@

 static void writeZ()
 {
-  float x = position.x;
-  float y = position.y;
+  float x = state.x;
+  float y = state.y;
   float w = fontSize * 0.5;

   pushTo(x, y + capHeight);