Adding interrupts and ATMega compatibility.

--- attiny/attiny.ino
+++ attiny/attiny.ino
@@ -6,6 +6,9 @@
 #include <nRF24L01.h>
 #include <RF24.h>
 #include <printf.h>
+
+void sleepNow(void);
+void setup_watchdog(uint8_t prescalar);

 #if defined(__AVR_ATtiny84__) || defined(__AVR_ATtiny85__)
 RF24 radio(3,7);
@@ -14,11 +17,11 @@
 const int led_pin = 1;
 const int sleep_pin = 8;
 #else
-RF24 radio(3,7);
-const int role_pin = 10;
+RF24 radio(9, 10);
+const int role_pin = 8;
 const int sensor_pin = 2;
-const int led_pin = 1;
-const int sleep_pin = 8;
+const int led_pin = 7;
+const int sleep_pin = 5;
 #endif

 const uint64_t pipe = 0xE8E8F0F0F1LL;
@@ -33,9 +36,11 @@
 role_e role;
 const char* role_friendly_name[] = { "invalid", "Remote", "LED Board"};

-uint8_t led_state;
-uint8_t sensor_state;
+bool led_state;
+bool sensor_state;
 volatile int awakems = 0;
+int send_tries = 0;
+bool send_ok = true;

 void setup(void) {
     // set up the role pin
@@ -45,7 +50,7 @@

     // read the address pin, establish our role
     role = digitalRead(role_pin) ? role_remote : role_led;
-    digitalWrite(role_pin, HIGH);
+    digitalWrite(role_pin, LOW);

     Serial.begin(9600);
     printf_begin();
@@ -56,7 +61,7 @@
     radio.setChannel(38);
     radio.setDataRate(RF24_250KBPS);
     radio.setAutoAck(pipe, true);
-//    radio.setRetries(15, 15);
+    radio.setRetries(15, 15);

     if (role == role_remote) {
         radio.openWritingPipe(pipe);
@@ -72,7 +77,7 @@
         pinMode(sensor_pin,INPUT);
         digitalWrite(sensor_pin,HIGH);
     }
-
+
     if (role == role_led) {
         setup_watchdog(wdt_2s);
     }
@@ -100,44 +105,42 @@
     if (role == role_remote) {
         // Get the current state of buttons, and
         // Test if the current state is different from the last state we sent
-        uint8_t state = ! digitalRead(sensor_pin);
+        delay(5);
+        bool state = !digitalRead(sensor_pin);
         printf("Sensor state: %d\n", state);
         if (state != sensor_state) {
             different = true;
+            send_tries = 500;
             sensor_state = state;
+            led_state = sensor_state;
         }

         // Send the state of the buttons to the LED board
-        if (different) {
+        if (send_tries && (different || !send_ok)) {
             printf("Now sending...");
-            led_state = sensor_state;
             digitalWrite(led_pin, led_state);
             radio.powerUp();
-            delay(5);
-            int tries = 50;
-            bool ok = false;
-            while (!ok && tries) {
-                ok = radio.write( &sensor_state, sizeof(uint8_t) );
-                if (ok) {
-                    printf("ok\n\r");
-                } else {
-                    printf("failed\n\r");
-                    digitalWrite(sleep_pin, LOW);
-                    digitalWrite(led_pin, LOW);
-                    delay(50);
-                    digitalWrite(sleep_pin, HIGH);
-                    digitalWrite(led_pin, led_state);
-                }
-                tries--;
+            delay(10);
+            send_ok = radio.write( &sensor_state, sizeof(bool), false );
+            if (send_ok) {
+                printf("ok\n\r");
+            } else {
+                printf("failed\n\r");
+                send_tries--;
+                digitalWrite(sleep_pin, LOW);
+                digitalWrite(led_pin, LOW);
+                delay(50);
+                digitalWrite(sleep_pin, HIGH);
+                digitalWrite(led_pin, led_state);
             }
             radio.powerDown();
             awakems = 0;
         }

         awakems += 1;
-        if (awakems > 100) {
-          sleepNow();
-          awakems = 0;
+        if (awakems > 10) {
+            sleepNow();
+            awakems = 0;
         }
     }

@@ -147,15 +150,15 @@
             bool done = false;
             awakems = 0;
             while (!done) {
-                done = radio.read( &sensor_state, sizeof(uint8_t) );
+                done = radio.read( &sensor_state, sizeof(bool) );
             }
-            if (led_state != sensor_state) {
-                different = true;
-                printf("Got buttons\n\r");
+//            if (led_state != sensor_state) {
+//                different = true;
+                printf("Got buttons: %d\n\r", sensor_state);
                 led_state = sensor_state;
                 digitalWrite(led_pin, led_state);
                 awakems = -1000;
-            }
+//            }
         }

         uint8_t incomingByte;
@@ -174,7 +177,7 @@
 	}

         awakems += 1;
-        if (awakems > 300) {
+        if (awakems > 400) {
             sleepNow();
             awakems = 0;
         }
@@ -183,7 +186,6 @@
 #define BODS 7                   //BOD Sleep bit in MCUCR
 #define BODSE 2                  //BOD Sleep enable bit in MCUCR
 uint8_t mcucr1, mcucr2;
-

 void setup_watchdog(uint8_t prescalar)
 {
@@ -211,7 +213,7 @@
         GIMSK |= _BV(INT0);                       //enable INT0
         MCUCR &= ~(_BV(ISC01) | _BV(ISC00));      //INT0 on low level
 #else
-
+        attachInterrupt(0, wakeATMega, CHANGE);
 #endif
     }
     ACSR |= _BV(ACD);                         //disable the analog comparator
@@ -246,9 +248,18 @@
     delay(5);
 }

+#if defined(__AVR_ATtiny84__) || defined(__AVR_ATtiny85__)
 ISR(INT0_vect) {
     awakems = 0;
 }
+ISR(PCINT18_vect) {
+    awakems = 0;
+}
+#else
+void wakeATMega() {
+    awakems = 0;
+}
+#endif

 ISR(WDT_vect) {


Final changes before defense

Final changes before defense

--- arduinoApp/gardenSketch/gardenSketch.ino
+++ arduinoApp/gardenSketch/gardenSketch.ino
@@ -104,13 +104,13 @@
     int data = bluetooth.parseInt();
     setGoodAirTemperature(data);
   }
+  if (bluetooth.find("l")) {
+    int data = bluetooth.parseInt();
+    setGoodLDRValue(data);
+  }
   if (bluetooth.find("w")) {
     int data = bluetooth.parseInt();
     setGoodSoilMoisture(data);
-  }
-  if (bluetooth.find("l")) {
-    int data = bluetooth.parseInt();
-    setGoodLDRValue(data);
   }

   if (bluetooth.find("m")) {


fix #143

fix #143

--- examples/Widgets/Email/Email.ino
+++ examples/Widgets/Email/Email.ino
@@ -72,6 +72,8 @@
     Serial.println("Button is pressed."); // This can be seen in the Serial Monitor
     Blynk.email("your_email@mail.com", "Subject: Button Logger", "You just pushed the button...");

+    // Or, if you want to use the email specified in the App (like for App Export):
+    //Blynk.email("Subject: Button Logger", "You just pushed the button...");
   }
 }


Updating Basic example

Updating Basic example

- No loger using .data atribute
- Add all compatible boards options

--- examples/CS5490_Basics/CS5490_Basics.ino
+++ examples/CS5490_Basics/CS5490_Basics.ino
@@ -1,8 +1,16 @@

 #include<CS5490.h>

+#define rx 14
+#define tx 12

-CS5490 line(MCLK_default,14,12);
+/* Choose your board */
+
+/* Arduino UNO and ESP8622 */
+CS5490 line(MCLK_default,rx,tx);
+
+/* ESP and MEGA  (Uses Serial2)*/
+//CS5490 line(MCLK_default);

 void setup() {
@@ -11,35 +19,19 @@
   line.begin(600);
   //Initializing communication arduino/PC to show results in Monitor Serial
   Serial.begin(115200);
-
-
-  //Turns Continous conversion ON. Necessary for some measurments
-  line.CC();
 }

 void loop() {

-  //Get instant voltage number from CS5490
-  line.getInstV();
+  double foo = line.getFreq();
+  double bar = line.getTime();

-  //Prints last "get" method in Serial Monitor
-  Serial.println("The instant voltage value is: ");
-  Serial.println(line.data[0],HEX);
-  Serial.println(line.data[1],HEX);
-  Serial.println(line.data[2],HEX);
+  Serial.print("The Line to Sample Frequency Ratio is: ");
+  Serial.println( foo , 10 ); //10 is the number of decimal places
+
+  Serial.print("The System Time is: ");
+  Serial.println( bar );
+
   Serial.println("");
-
-  //Get the current peak information from CS5490
-  line.getPeakI();
-
-  //Prints last "get" method in Serial Monitor
-  Serial.println("The peak current value is: ");
-  Serial.println(line.data[0],HEX);
-  Serial.println(line.data[1],HEX);
-  Serial.println(line.data[2],HEX);
-  Serial.println("");
-
-
-
   delay(1000);
 }


adding change interrupts for the rest of the pins

--- examples/CaroloCar/CaroloCar.ino
+++ examples/CaroloCar/CaroloCar.ino
@@ -56,7 +56,8 @@
   pinMode(OVERRIDE_THROTTLE_PIN, INPUT);
   pinMode(OVERRIDE_SERVO_PIN, INPUT);
   setupChangeInterrupt(OVERRIDE_SIGNAL_PIN);
-  //  setupChangeInterrupt(RIGHT_IR_ARRAY);
+  setupChangeInterrupt(OVERRIDE_THROTTLE_PIN);
+  setupChangeInterrupt(OVERRIDE_SERVO_PIN);
   Serial.begin(9600); //to HLB
   Serial3.begin(9600); //to LED driver
 }


Update to v0.6 - Add READ/WRITE an array of 8-bits or 16-bits values.

--- examples/MB85RS1MT/MB85RS1MT.ino
+++ examples/MB85RS1MT/MB85RS1MT.ino
@@ -5,16 +5,16 @@
     @license  BSD (see license.txt)

     This sketch connects the FRAM chips.
-    Once ok, it read/write Byte, Short, Long at different addresses.
-    Dump the full memory
-    Erase the complete chip (if ERASE_FRAM is defined)
+    Reads and Writes differents kinds of data type into F-RAM
+    Dump the full memory (optional with define)
+    Erase the complete chip (optional with define)

-    All the operations are visible on Serial if SER_OUT is defined
-    and the execution time of all of them is indicated
+    All the operations are visible on Serial if DEBUG_TRACE is defined in .h
+    The execution time of all the operations is indicated in microseconds or seconds

     @section  HISTORY

-    v1.0.0 - First release
+    v0.6 - See ReadMe for more informations

  */
 /**************************************************************************/
@@ -23,7 +23,7 @@
 #include <FRAM_MB85RS_SPI.h>

 // Defines
-//#define ERASE_FRAM  // Erase FRAM at the end of setup if defined
+//#define ERASE_FRAM  // Erase FRAM at the end of setup
 //#define DUMP_FRAM   // Full dump of the memory

 // Prototypes


New Transition States, SAFE_SWITCH, Serial Output

Added ACC->OFF (press button for less than 1sec) and RUN->ACC (press and
hold for more than 1sec before release) transitions. Toggled state
changes to button release with the exception of ACC->START (press and
hold for more than 1sec). SAFE_SWITCH must be open for ACC->START.
Extracted relay setting to setRelayState() and added printState(state)
to print the system state to the console.

--- push_start.ino
+++ push_start.ino
@@ -17,49 +17,51 @@
  * * START the RELAY_START and RELAY_IGN are energized/ON
  * * RUN the RELAY_IGN is energized/ON
  *
- * If the kill switch circuit is open then the whole system is disabled and the relays are
- * immediately deenergized and the button no longer can transition states.
+ * If the KILL_SWITCH circuit is grounded then the whole system is DISABLED and the relays are
+ * immediately deenergized and the button no longer can transition states. If the circuit is
+ * opened the system transitons to the OFF state.
  *
  * When the kill switch is closed the system is enabeled and has the basic flow of:
- * ACC -> (START) -> RUN -> OFF
+ * OFF -> ACC -> (OFF | START) -> RUN -> (OFF | ACC)
  * * To transition from OFF -> ACC depress and release the push button
+ * * To transition from ACC -> OFF depress and release the push button under HOLD_MS (1sec)
  * * To transition from ACC -> (START) -> RUN depress and hold the push button in until
- * * vehicle is started and then release the button. The initial press puts it in START
- * * mode and the release of the button once the vehicle is started transitions to RUN mode.
+ * * vehicle is started and then release the button. The initial depress starts a timer that
+ * * once held for over HOLD_MS (1sec) puts the system in START mode and then the release
+ * * of the button once the vehicle is started transitions to RUN mode. Note, if the
+ * * SAFE_SWITCH is grounded the this transition will not be conducted.
  * * To transition from RUN -> OFF depress and release the push button.
+ * * To transition from RUN -> ACC depress and hold the push button longer than HOLD_MS
+ * * (1sec) then release.
  *
  * Because the timing to kick over the motor can be different for various vehicles and you
  * do not want not run the starter too long which may grind the flywheel/flexplate teeth the
  * I decided to keep the amount of time the starter is engaged to the actual press, just like
  * turning a key. The system could be modified to do it based on time in the future.
  *
- * Future enhancements:
- * * Secondary Killswitch (prox sensor? nfc/rfid?)
- * * Brake Input?
- * * OFF->RUN?
- * * RUN->ACC?
- *
  * @author Chris Fitzpatrick
- * @version 0.6 01/01/2017
+ * @version 1.0 02/11/2017
  * @license MIT License
  */

 // Pin Definitions

 // LEDs
-const int LED_BUTTON = 9;    // Push button LED
+const int LED_BUTTON   = 9;  // Push button LED
 const int LED_ON_BOARD = 13; // Onboard will not fade because there is no PWM attached,
                              // but can at least give indication of state when not
                              // using 12v input for testing/debug
 // Switches
 const int PUSH_BUTTON = 2;   // Momentary push button
 const int KILL_SWITCH = 3;   // This is any input to enable/disable the system, could be NFC
-                             // trigger/physical swtich
+                             // trigger/physical switch, if grounded system is disabled.
+const int SAFE_SWITCH = 4;   // Brake/Clutch/Neutral safety switch, if grounded cannot start.
+
 // Relays
-const int RELAY_ACC = 5;
-const int RELAY_IGN = 6;
+const int RELAY_ACC   = 5;
+const int RELAY_IGN   = 6;
 const int RELAY_START = 7;
-const int RELAY_4 = 8;        // Not Used
+const int RELAY_4     = 8;   // Not Used

 // System state
 enum sysState {
@@ -71,18 +73,23 @@
 };

 // Globals
-const int FLASH_DELAY = 10;     // How many ticks to pass through before turning on/off LED
-                                // when in ACC state. Increasing this number makes the blink
-                                // slower. Since the main loop sleeps 30ms a value of 10 here
-                                // waits 300ms in ON then 300ms in OFF.
+const int FLASH_DELAY = 10;    // How many ticks to pass through before turning on/off LED
+                               // when in ACC state. Increasing this number makes the blink
+                               // slower. Since the main loop sleeps 30ms a value of 10 here
+                               // waits 300ms in ON then 300ms in OFF.
+
+const int HOLD_MS = 1000;      // Milliseconds to hold button to transition from ACC->START
+                               // or from RUN->ACC

-unsigned int tick = 0;          // Count cycles for LED flash mode (unsigned so when it rolls
-                                // over it restarts at 0
-int brightness = 0;             // How bright the LED is (usable range 0-255)
-int fadeAmount = 5;             // How many points to fade the LED by when in OFF state
-
-int previousButtonState = HIGH; // Stores the previous button state so we can see if it changes
-sysState runState = OFF;        // Stores current system run state
+unsigned int tick = 0;         // Count cycles for LED flash mode (unsigned so when it rolls
+                               // over it restarts at 0
+int brightness = 0;            // How bright the LED is (usable range 0-255)
+int fadeAmount = 5;            // How many points to fade the LED by when in OFF state
+
+int previousButtonState = LOW; // Stores the previous button state so we can see if it changes
+long pressTime;                // When the button was pressed
+
+sysState runState = OFF;       // Stores current system run state

 /**
  * Setup runs once when system is reset, Setup pins and default states
@@ -97,6 +104,7 @@

   pinMode(PUSH_BUTTON, INPUT_PULLUP);
   pinMode(KILL_SWITCH, INPUT_PULLUP);
+  pinMode(SAFE_SWITCH, INPUT_PULLUP);

   pinMode(RELAY_ACC, OUTPUT);
   pinMode(RELAY_IGN, OUTPUT);
@@ -107,6 +115,13 @@
   digitalWrite(RELAY_ACC, HIGH);
   digitalWrite(RELAY_IGN, HIGH);
   digitalWrite(RELAY_START, HIGH);
+
+  Serial.println("+------ Push Button Start System v1.0 ------+");
+  Serial.println("| MIT License                               |");
+  Serial.println("| Copyright (c) 2016-2017 Chris Fitzpatrick |");
+  Serial.println("| https://github.com/synthtc/push_start     |");
+  Serial.println("+-------------------------------------------+");
+  printState(runState);
 }

 /**
@@ -116,18 +131,20 @@
   // Set the brightness of LEDs:
   analogWrite(LED_BUTTON, brightness);
   analogWrite(LED_ON_BOARD, brightness);
-
+
   // System is enabled, process as normal
-  if (digitalRead(KILL_SWITCH) == HIGH) { // HIGH = System Enabled, LOW = Disabled
+  if (digitalRead(KILL_SWITCH) == HIGH) { // HIGH = System Enabled LOW = Disabled (grounded)
     // If we were disabled move to OFF
     if (runState == DISABLED) {
       runState = OFF;
+      printState(runState);
     }
     // Read in the button state to see if it has been pressed
     int buttonState = digitalRead(PUSH_BUTTON);
     if (buttonState != previousButtonState) {
-      // Only transition on HIGH state so we do not bounce
-      if (buttonState == HIGH) {
+      // Transition on LOW (released) state for most states
+      if (buttonState == LOW) { // Released
+        Serial.println("Released");
         switch (runState){
           case DISABLED: // Disabled -> Off
             // This state should never be hit, but is included for completeness.
@@ -135,57 +152,95 @@
             break;
           case OFF: // Off -> Acc
             runState = ACC;
-            digitalWrite(RELAY_ACC, LOW);
-            digitalWrite(RELAY_IGN, HIGH);
-            digitalWrite(RELAY_START, HIGH);
-            break;
-          case ACC: // Acc -> Start
-            runState = START;
-            digitalWrite(RELAY_ACC, HIGH);
-            digitalWrite(RELAY_IGN, LOW);
-            digitalWrite(RELAY_START, LOW);
+            break;
+          case ACC: // Acc -> Off (Acc -> Start handled below)
+            runState = OFF;
             break;
           case START: // Start -> Run
-            // This state should never really be hit since we bump from START->RUN when
-            // we release the push button switch during the START sequence
             runState = RUN;
-            digitalWrite(RELAY_ACC, HIGH);
-            digitalWrite(RELAY_IGN, LOW);
-            digitalWrite(RELAY_START, HIGH);
-            break;
-          case RUN: // Run -> Off
-            runState = OFF;
-            digitalWrite(RELAY_ACC, HIGH);
-            digitalWrite(RELAY_IGN, HIGH);
-            digitalWrite(RELAY_START, HIGH);
+            break;
+          case RUN: // Run -> Off or ACC
+            //Serial.println(millis() - pressTime);
+            // Transition back to ACC if button was held longer than HOLD_MS otherwise
+            // go to OFF
+            if (millis() - pressTime > HOLD_MS) {
+              runState = ACC;
+            } else {
+              runState = OFF;
+            }
             break;
         }
-
-        Serial.println("System State:");
-        Serial.println(runState);
-      } else {
-        // Special case for START
-        // When we release the push button in the START state we want to immediately
-        // transition to RUN
-        if (runState == START) {
-          // Turn off starter solenoid and move to RUN
-          digitalWrite(RELAY_START, HIGH);
-          runState = RUN;
+        printState(runState);
+        setRelayState();
+      } else { // Pressed
+        pressTime = millis();
+        Serial.println("Pressed");
+      }
+    } else if (buttonState == HIGH) { // Pressed
+      // Special case for START
+      // When we release the push button in the ACC state we want to transition to
+      // START if held longer than HOLD_MS and the SAFE_SWITCH is open
+      if (runState == ACC) {
+        bool safe = digitalRead(SAFE_SWITCH) == HIGH; // HIGH = Safe LOW = Disabled (grounded)
+        if (safe && millis() - pressTime > HOLD_MS) {
+          runState = START;
+          printState(runState);
+          setRelayState();
+        } else {
+          Serial.println("WARNING: Unsafe to Start");
         }
       }
     }
     // Store button state for next cycle
     previousButtonState = buttonState;
   } else {
+    if (runState != DISABLED) {
+      printState(DISABLED);
+    }
     runState = DISABLED;
-    digitalWrite(RELAY_ACC, HIGH);
-    digitalWrite(RELAY_IGN, HIGH);
-    digitalWrite(RELAY_START, HIGH);
+    setRelayState();
   }
   // Set brightness for next cycle
   setLedBrigtness();
   // Wait for 30 milliseconds
   delay(30);
+}
+
+/**
+ * Sets the relays depending on the current system run state
+ *
+ * DISABLED - All Off
+ * OFF      - All Off
+ * ACC      - ACC On
+ * START    - ACC On IGN On
+ * RUN      - IGN On
+ *
+ * @return none
+ */
+void setRelayState() {
+  switch (runState){
+    case DISABLED:
+    case OFF:
+      digitalWrite(RELAY_ACC, HIGH);
+      digitalWrite(RELAY_IGN, HIGH);
+      digitalWrite(RELAY_START, HIGH);
+      break;
+    case ACC:
+      digitalWrite(RELAY_ACC, LOW);
+      digitalWrite(RELAY_IGN, HIGH);
+      digitalWrite(RELAY_START, HIGH);
+      break;
+    case START:
+      digitalWrite(RELAY_ACC, HIGH);
+      digitalWrite(RELAY_IGN, LOW);
+      digitalWrite(RELAY_START, LOW);
+      break;
+    case RUN:
+      digitalWrite(RELAY_ACC, HIGH);
+      digitalWrite(RELAY_IGN, LOW);
+      digitalWrite(RELAY_START, HIGH);
+      break;
+  }
 }

 /**
@@ -246,3 +301,32 @@
       break;
   }
 }
+
+/**
+ * Prints the current system state
+ *
+ * @param  state Current system state
+ * @return none
+ */
+void printState(sysState state) {
+  String strState;
+  switch (state) {
+     case DISABLED:
+        strState = "DISABLED";
+        break;
+     case OFF:
+        strState = "OFF";
+        break;
+     case ACC:
+        strState = "ACCESSORY";
+        break;
+     case START:
+        strState = "STARTING";
+        break;
+     case RUN:
+        strState = "RUNNING";
+        break;
+  }
+  Serial.println("System State: " + strState);
+}
+


Accidentally kept the old version of OpenStage.ino replacing with new version.

--- OpenStage/OpenStage.ino
+++ OpenStage/OpenStage.ino
@@ -22,666 +22,10 @@
   along with this program.  If not, see <http://www.gnu.org/licenses/>.

-
-* Citing
   This work has been published under the title: "Openstage: A Low-Cost
   Motorized Microscope Stage with Sub-Micron Positioning Accuracy" by
   Campbell, Eifert, and Turner in PLoS ONE, 2014, DOI: 10.1371/journal.pone.0088977
   http://www.plosone.org/article/info%3Adoi%2F10.1371%2Fjournal.pone.0088977
   Please cite us if you publish using our methods.

-
-* Purpose
-  OpenStage is a sub-micron positioning system for microscope stages.
-  It drives stepper motors coupled to micrometers that push translation stages.
-  It has been tested with three axes, but in theory can drive more.
-
-
-* Necessary Hardware
-  - The microcontroller: the easiest way to get up and running is to use an Arduino
-  Mega 2560. This unit has enough IO pins to handle multiple axes, an LCD display,
-  etc. An Arduino Due is not suitable since it is not currently compatible with the
-  USB Host Shield we use to read the PS3 gamepad, which is our input device. The same
-  goes for ChipKit boards. So unless you want to write your own game-pad driver
-  (contact me if you do), you're stuck with the Mega.
-
-  - Input device: A PlayStation DualShock 3 controller that plugs into a USB
-  Host Shield. I used the SparkFun version of the USB shield. If you don't stack the
-  shield you will have access to more of the Mega's pins. To wire the devices in this
-  way you will need to do the following:
-    a. Connect pin 7 to reset on the shield.
-    b. Connect reset on the shield to reset on the Mega.
-    c. Connect GND and VIN on the shield to GND and VIN on the Mega.
-    d. Connect pin 13 on the shield to pin 52 on the Mega.
-    e. Connect pin 12 on the shield to pin 50 on the Mega.
-    f. Connect pin 11 on the shield to pin 51 on the Mega.
-    g. Connect pin 10 on the shield to pin 53 on the Mega.
-    h. Connect pin 10 on the Mega to pin 53 on the Mega
-
-  The libraries to interface with the DualShock are found here:
-  http://www.circuitsathome.com/arduino_usb_host_shield_projects (see link to the
-  GitHub repository). You will note that there are drivers for XBox and Wii
-  controllers also. However, the code below assumes a DualShock. You can plug the
-  controller directly into the USB shield with a mini USB cable or you can use
-  Bluetooth if you can find a compatible dongle.
-
-  - Per axis hardware:
-      a. one Big Easy Driver (or similar, see Sparkfun). The motors have two pairs of
-        leads called A and B. The letters A and B are also marked on the Easy Driver.
-        Inverting the connections of the motor to the driver (i.e. connecting the A
-        lead pair to B and vice versa) will invert the direction of rotation of the
-        motor. Connect as required to get the stage moving in the correct direction
-        according to button presses. The micro-controller software knows only stage
-        direction, not how it maps onto left and right. You determine that according
-        to how the motors are wired to the controllers. The micro-stepping pins on all
-        axes are wired together.
-      b. one micrometer. We use regular Thor 50 TPI for X and Y and a Newport
-        HR-13 (100 TPI) for Z. Obviously a translation stage is needed too.
-        Choose a stage from Newport or Thor according your needs.
-      c. one flexible coupler. (https://sdp-si.com/eStore/Catalog/Group/484)
-        Choose operating torque over about 6 lb-in to minimise back-lash.
-        We use 8" couplers for X and Y and a 10" coupler for Z.
-      d. one stepper motor. We used Vexta motors sourced from orientalmotor.com
-        We use Vexta PK243M-02BA for XY and PK243M-01BA for Z.
-      e. Machined male/female adapters to attach the flexible couplers to the micrometer
-        head and stepper motor shaft (if shaft is not 1/4").
-
-  - Misc: You will also need a power supply for the motors (24V), a power supply for the
-   Arduino and associated electronics, a 20x4 character LCD display, LEDs,
-   power switches, etc. If you don't want to bother with the display, then you
-   can just skip those items and comment out those code lines. Finally, a Sparkfun
-   RS232 Serial Shifter is needed if you want to interface the controller with a PC
-   via the serial port.
-
-
-
-* Wiring tips: it should be obvious which pins do what from the global definitions, below.
-  Check that the Big Easy Driver output pins behave the way they should before you hook up
-  the hardware to your stage. A cheap stepper motor from Sparkfun can be used to sanity
-  check everything. Check the step size, direction, and enable behavor of the Big Easy
-  Driver. Check that the stepper motor revolves the number of times you expect, etc. If not,
-  look over the values for step size, gear ratio, etc, in the global definitions. It's
-  also helpful to visualise the motor pulses with an oscilscope, as triggering on the
-  step pulses will provide an exact measure of the pulse rate driving the motor. Again:
-  * * Do Not Connect Motors To Your Stage Until You Have Tested The Assembled Controller * *
-
-
-* Usage instructions:
-  The DualShock controls the stage in the following ways:
-  1. Left hat-stick for X and Y. Right hat-stick up/down for Z. Right hat-stick left/right
-     does not do anything.
-  2. D-pad executes single motion steps in X and Y motions. D-pad plus Triangle performs
-     fixed-step motions in Z.
-  3. Shoulder buttons (L1 and R1) cycle through four different speed modes. Selected speed
-     mode indicated by LEDs on the DualShock. 1 is slow and 4 is fast. See global variables
-     below for speed values these select. Speed modes influence hat-stick motions and D-pad
-     fixed speed motions.
-  4. Pressing one of the four right-hand buttons stores the current stage location. Storage
-     is signalled by two beeps. Double-clicking the button will cause the stage to move to the
-     stored location. All four buttons default to the position of the stage on reboot.
-
-
- * Other files included in this distribution:
-   - OS_pollPS3.ino contains the function that polls the PS3 controller and initiates moves.
-   - OS_moveToTarget.ino contains the function the performs moves following button double-clicks
-   - OS_HelperFunctions.ino contains other (more peripheral) functions
-   - OS_SerialFunctions.ino contains functions required for the serial port interface
-*/
-
-
-
-//------------------------------------------------------------------------------------------------
-// * Load libraries
-//
-//PS3 DualShock3 driver libraries
-// Load the libraries necessary to interface with the DualShock3 via the USB Host Shield.
-#include <PS3USB.h>
-USB Usb;
-// The PS3USB class is used read the state of the DualShock. You can create an instance
-// of this class in one of two ways:
-PS3USB PS3(&Usb); // This will just create the instance
-// This will also store the bluetooth address - this can be obtained from the dongle when running the sketch
-// PS3upStickB PS3(&Usb,0x00,0x15,0x83,0x3D,0x0A,0x57);
-
-
-#include <AccelStepper.h>  //Control of stepper motors
-#include <LiquidCrystal.h> //Write to LCD display (https://bitbucket.org/fmalpartida/new-liquidcrystal/wiki/Home)
-#include <Wire.h> //Seems to be needed on some systems
-
-
-//------------------------------------------------------------------------------------------------
-// * Enable/disable major OpenStage functions
-//
-bool doSerialInterface=1; //Set to 1 to communicate with the stage via a PC serial port.
-bool controlViaUSB=0; //Optional bool to control via USB. See setup() for serial port IDs.
-bool doGamePad=1; //Set to 1 to enable PS3 DualShock as an input device
-bool doLCD=1; //Set to 1 to enable LCD character display
-
-
-
-//------------------------------------------------------------------------------------------------
-// * Microscope axis hardware definitions.
-//
-//                                   === WARNING ===
-//   ******************************************************************************
-//  ==> This section must be filled out correctly or you may damage your hardware <==
-//   ******************************************************************************
-//
-//
-// The properties of each axis are defined as separate variables (mostly arrays with a length
-// equal to the number of axes).
-//
-// The elements in the arrays define the properties of X, Y, and Z in that order. Further
-// axes can be added. A Z-only stage can also be set up by altering the code below.
-
-
-// numAxes
-const byte numAxes=3; //The number of motorised axes
-
-// axisPresent
-// Allows particular axes to be skipped. Useful for testing. 1 means present. 0 means absent.
-bool axisPresent[numAxes]={1,1,1};
-
-// gearRatio
-// Micrometer gear ratios on X,Y,Z in microns per revolution.
-unsigned short gearRatio[numAxes]={635,635,250};
-
-
-// fullStep
-// Stepper motor full step size (in degrees) for X,Y,Z. We have tested 1.8 degree and 0.9
-// degree step sizes. Motors with finer step sizes are available but driving them in
-// quickly using sub-micron steps is a limiting factor. If you want to get up and running
-// in the shortest time, 0.9 degree motors are suggested.
-float fullStep[numAxes]={0.9,0.9,0.9}; //In degrees
-
-// disableWhenStationary
-// bool to tell the system whether or not a motor should be disabled when the stage isn't moving.
-// Disabling will reduce noise but can cause the motors to move to the nearest full step when the
-// power is switched off. Perhaps it makes make sense to do this in X and Y but not Z.
-bool disableWhenStationary[numAxes]={0,0,0};
-
-
-//------------------------------------------------------------------------------------------------
-// * Speed modes (hat-stick)
-//
-// There will be four (coarse to fine) speeds which may be selected via the two shoulder buttons
-// (L1 and R1). The currently selected speed will be inidicated by the 4 LEDs on the DualShock.
-// 1 is fine and slow and 4 is coarse and fast. Here we define the step size and max speed for those
-// 4 speed settings. If you change these, you should verify with an osciloscope and the serial
-// monitor that the right values are being produced. You will also need to verify that you are not
-// over-driving you motor and causing it to miss steps. Missing steps means the controller will lose
-// its absolute position (there is no feedback from the motors). Note that the selection of speed
-// values and step sizes are chosen based on the resulting step frequencies the controller must
-// produce and on resonances the motors might exhibit.
-byte coarseFine=2; //boot up in a fine mode
-unsigned short maxSpeed[4]={3.5,25,100,750}; //defined in microns per second
-
-
-// stepSize
-// The microstep sizes for each speed mode.
-float stepSize[4]={1/16.0, 1/8.0, 1/4.0, 1/2.0}; //Defined in fractions of a full step
-
-
-// curve
-// Curve is the non-linear mapping value to convert analog stick position to speed. The idea
-// is to make the conversion from analog stick value to motor pulse rate logarithmic.
-// 0 is linear. See the fscale function for details.
-float curve[4]={-7,-6,-5,-4};
-
-
-
-//------------------------------------------------------------------------------------------------
-// * Speed mode (D-pad)
-//
-// The D-pad will be used for making fixed-distance motions of a high speed. The size of the motions
-// depends on the coarseFine setting and is defined by the DPadStep array. There's a trade-off between
-// speed and accuracy. For these fast motions, I'd like to be hit about 1000 um/s but the AccelStepper
-// moveTo function can only churn out about 4.3 kHz on an Arduino Mega. At 1/4 steps we get reliable
-// motions and about 700 um/s. A 1/4 step gives us a 0.156 micron resolution in Z (0.9 degree stepper
-// and 250 um per rev micrometer). The motors MUST be enabled throughout or they will slip and become
-// hopelessly lost. To get increased accuracy *and* higher speeds we would need a faster micro-controller,
-// or write our own hardware-timer based routines, or slave comercial controllers.
-float DPadStep[4]={3,5,10,50};
-float DPadStepSize=1/2.0;
-// Acceleration in X, Y, and Z
-unsigned long DPadAccel[numAxes]={1.0E4, 1.0E4, 1.0E4};
-
-
-
-//------------------------------------------------------------------------------------------------
-// * moveTo speeds
-//
-// The moveToTarget() function is executed when the user travels to a right-button set point
-// or responds to a serial command. It does this using the settings described below. The minimum
-// step size and motor RPM are reported to the serial terminal on bootup.
-float moveToStepSize=1.0/2.0;
-unsigned int moveToSpeed[numAxes]={1600,1600,1200};
-unsigned int moveToAccel[numAxes]={1.0E4,1.0E4,1.0E4};
-
-
-//------------------------------------------------------------------------------------------------
-// * Stage Position
-// The stage controller unit keeps track of how far the stage has moved along each axis. This
-// allows the unit to do handy things such as moving to a pre-defined absolute location. When
-// the controller boots up it assumes it is at [0,0,0]. Note that there are no encoders:
-// if you manually move the stage, it loses it's position and needs to be reset.
-// **BE CAREFUL** Manually moving the stage and forgetting to reset might cause a
-// dangerous stage motion.
-//
-// The absolute positioning abilities of the stage can be accessed most diectly using the right
-// hand buttons on the DualShock. Pressing down a button hard for 1 second stores the current
-// location of the stage. The stage will return to this location when the button is double-clicked.
-// The return motion is a straight line. It's up to the user to ensure that making this motion
-// won't cause the stage to hit anything.
-//
-// The following global variables are used by the controller code. They aren't user settings.
-
-// stagePosition
-// The current stage position in microns.
-float stagePosition[numAxes]={0,0,0};
-
-
-// stepperPreviousPos
-// The previous position of the steppers. We need to keep track of this in a counter in order to
-// figure out how far we've pushed the stage each pass through the main loop. The stage position
-// will be updated whenever pollPS3 is called. Note that stepperPreviousPos relates to stepper
-// motor counts (which are integers) not the actual stage position (which a float and measured
-// in microns).
-long stepperPreviousPos[3]={0,0,0};
-
-
-
-// thisStep
-// How far the last step has pushed the stage in microns. This is used to update the stage postion.
-float thisStep[numAxes][4];
-
-
-// SPEEDMAT
-// This matrix stores the motor speed for each hat-stick value at each speed mode. These numbers
-// are calculated once in the setup function and never change during execution. Pre-calculating
-// them is a good way of improving performance during hat-stick motions.
-float SPEEDMAT[128][4];
-
-// hatStickThresh
-//Ensure we don't get motion for stick values smaller than the following threshold
-short hatStickThresh=40;
-
-
-
-
-
-
-//------------------------------------------------------------------------------------------------
-// * DualShock controller variables
-//
-// The inputs to the PlayStation controller modify the following global variables which
-// are used to move the stage. These are not user settings.
-
-// buttonStageLocations
-// The buttons will be used to store 4 different stage locations. We store these in a 2-D
-// array, where the first dimension is button and the second is axis:
-float buttonStageLocations[4][numAxes] = {{0,0,0},
-                                          {0,0,0},
-                                          {0,0,0},
-                                          {0,0,0}};
-
-// locationStored
-// zero indicates that no position was stored. As positions are stored we update these to 1.
-// This is important, as it minimises the possibility of the user double-clicking a button
-// unbound to a location as it may make the stage perform a large motion to back to zero.
-bool locationStored[4]={0,0,0,0};
-
-
-
-//------------------------------------------------------------------------------------------------
-// * Motor control DIO lines
-//
-
-// stepOut
-// One pulse at these pins moves the motor by one step (or one micro-step)
-byte stepOut[numAxes]={22,24,26}; //Ordered X, Y, and Z
-
-// stepDir
-// These pins tell the Big Easy Driver to which they connect which direction to rotate the motor
-byte stepDir[numAxes]={23,25,27}; //Ordered X, Y, and Z
-
-// enable
-// If these pins are low, the motor is enabled. If high it's disabled. Disabling might decrease
-// electrical noise but will lead to errors in absolute positioning.
-byte enable[numAxes]={28,29,30}; //Ordered X, Y, and Z
-
-// The microstep pins.
-// These pins define the microstep size. The MS pins on all axes are wired together.
-byte MS1=45;
-byte MS2=47;
-byte MS3=49;
-
-
-
-//------------------------------------------------------------------------------------------------
-// * AccelStepper
-// Set up three AccelStepper instances for managing the three axes of motion. There are are a
-// couple of other ways to issue steps and keep track of the stage position.
-// 1. Software pulse generation and software stage position counters
-// 2. Hardware timer pulse generation and hardware counter for step pulses.
-// AccelStepper does a good job and makes the code more compact so we've gone with it.
-AccelStepper stepperX(1, stepOut[0], stepDir[0]);
-AccelStepper stepperY(1, stepOut[1], stepDir[1]);
-AccelStepper stepperZ(1, stepOut[2], stepDir[2]);
-
-//Make an array of pointers to the AccelStepper instances to make loops possible
-AccelStepper *mySteppers[3]={&stepperX, &stepperY, &stepperZ};
-
-
-
-//------------------------------------------------------------------------------------------------
-// * Outputs
-// The following are pin definitions of controller outputs. These signal information to the user
-
-//Misc
-byte beepPin=9; //This is the pin to which the Piezo buzzer is connected
-
-// stageLEDs
-// LEDs will light when the stage moves or an axis is reset,
-// *NOTE: Updating the stage LEDs for hat-stick motions requires fast digital writes as motor speed
-//        is set in a closed-loop based on hat-stick position. So we set the stage LEDs using
-//        direct port writes. The code expects the LEDS to be on the first 3 pins of port C of the
-//        Mega. You can use a different port (or even different pins on that port), but then you will
-//        have to change the code in pollPS3. Direct port writes on these pins are only implemented
-//        for the closed-loop hat-stick control code. Elsewhere we use conventional Arduino
-//        digitalWrites, as these are adequate.
-//
-// PC0: 37 (X axis)
-// PC1: 36 (Y axis)
-// PC2: 35 (Z axis)
-// PC3: 34 (a good idea to reserve this for a 4th axis, such as a PIFOC)
-byte stageLEDs[4]={37,36,35,35};
-
-
-
-// Define pins for LCD display (http://learn.adafruit.com/character-lcds/wiring-a-character-lcd)
-LiquidCrystal lcd(7, 6, 5, 4, 3, 2 );
-
-
-//------------------------------------------------------------------------------------------------
-// * Serial communiciation via serial shifter (Sparkfun) to allow the PC to interface with the
-// the stage. We use the serial shifter rather than the virtual serial port because this makes
-// debugging easier.
-long values[numAxes]; // array holding values for all the received fields from the seria1 port
-                     // see serialMove(). For some reason this must be a global.
-
-
-
-
-
-
-//------------------------------------------------------------------------------------------------
-// * setup function
-// The setup function is run once when the microcontroller is powered on, reset, or programmed.
-// Opening the serial terminal in the Arduino IDE will cause the controller to re-boot if it's
-// connected to the PC.
-//
-// The setup function performs basic operations such as defining the DIO direction of each pin,
-// connecting to a serial device, etc.
-
-HardwareSerial* SerialComms;
-
-void setup() {
-
-  //Initialise loop counters
-  byte ii;
-  byte jj;
-
-
-  // Connect to the PC's serial port via the Arduino programming USB connection.
-  // This used mainly for printing de-bugging information to the PC's serial terminal
-  // during testing. [In future we will add the option for controlling the stage through
-  // the USB port]
-  Serial.begin(115200);
-  if (doSerialInterface){
-    if (!controlViaUSB){
-       Serial1.begin(115200);
-       SerialComms = &Serial1;
-     } else {
-        SerialComms = &Serial;
-     }
-  } //if doSerialInterface
-
-
-  //Set the micro-step pins as outputs
-  pinMode(MS1,OUTPUT);
-  pinMode(MS2,OUTPUT);
-  pinMode(MS3,OUTPUT);
-
-
-  //Set up motor control pins, LED pins, etc, as output lines
-  for (ii=0; ii<numAxes; ii++){
-    if (!axisPresent[ii]) //Skip axes that aren't present
-      continue;
-
-    pinMode(stepDir[ii],OUTPUT);
-
-    pinMode(stepOut[ii],OUTPUT);
-    digitalWrite(stepOut[ii],LOW);
-
-    pinMode(enable[ii],OUTPUT);
-    digitalWrite(enable[ii],LOW);//power to motors
-  }
-
-  for (ii=0; ii<4; ii++){
-    pinMode(stageLEDs[ii],OUTPUT);
-    digitalWrite(stageLEDs[ii],LOW);
-  }
-
-
-
-
-  //Initialise the 20 by 4 LCD display
-  if (doLCD){
-   lcd.begin(20,4);
-   lcd.home ();
-   lcd.clear();
-  }
-
-  // Connect to the USB Shield
-  if (doGamePad){
-    if (Usb.Init() == -1) {
-      Serial.print(F("\r\nConnection to USB shield failed"));
-
-      //halt and flash warning
-      if (doLCD){
-        while(1){ //infinite while loop
-           lcd.setCursor (0, 1);
-           lcd.print (" No USB connection!");
-           delay(1000);
-           lcd.clear();
-           delay(1000);
-         }// while
-      }
-    }//if USB.init
-
-     //Pre-calculate the speeds for different hat-stick values. This moves these
-     //calculations out of the main loop, and allows for smoother closed-loop hat-stick motions.
-     for (ii=0; ii<128; ii++){
-       for (jj=0; jj<4; jj++){
-          //SPEEDMAT[ii][jj]=(ii/127.5)*maxSpeed[jj]; //Plain linear
-          SPEEDMAT[ii][jj]=fscale(hatStickThresh, 127.5, 0.04, maxSpeed[jj], ii, curve[jj]); //non-linear mapping
-       }
-     }
-
-  }//if doGamePad
-
-
-  //Display boot message on LCD screen
-  if (doLCD){
-   lcd.setCursor (0,0);
-   lcd.print ("Booting OpenStage");
-   lcd.setCursor (0,1);
-  }
-
-
-
-
-
-  //the variable thisStep can take on one of four values for each axis
-  //Calculate all of these here
-  for (ii=0; ii<numAxes; ii++){
-    for (jj=0; jj<4; jj++){
-      if (axisPresent[ii]){
-           thisStep[ii][jj] = (fullStep[ii]/360) * stepSize[jj] * gearRatio[ii];
-      } //if axisPresent
-    } // jj for loop
-  } //ii for loop
-
-
-  if (doGamePad){
-    // Poll the USB interface a few times. Failing to do this causes the motors to move during
-    // following a rest. I don't know why the following code fixes this, but it does.
-    for (ii=1; ii<10; ii++){
-      Usb.Task();
-      delay(100);
-      if (doLCD){
-        lcd.print(".");
-      } //if doLCD
-     } //for loop
-    setPSLEDS(); //Set the LEDs on the DualShock to the correct states
-  } //if doGamePad
-
-
-  //Set default values for the AccelStepper instances
-  for (ii=0; ii<numAxes; ii++){
-    (*mySteppers[ii]).setMaxSpeed(4.0E3); //The max the Arduino Mega is capable of
-    (*mySteppers[ii]).setAcceleration(0); //Must be zero to allow hat stick speed motions
-  }
-
-
-  pinMode(13,OUTPUT); //PIN 13 is optionally used for testing and debugging with an osciliscope
-  pinMode(beepPin,OUTPUT); //Produce sound on this pin
-
-  //An analog stick value of zero likely means that the controller is not connected.
-  //If the game pad is enabled, don't proceed until a contoller is found, or the
-  //stage will move by itself.
-  if (doGamePad){
-    while (PS3.getAnalogHat(LeftHatX)==0){
-      if (doLCD){
-        lcd.setCursor(0,1);
-        lcd.print("Connect DualShock");
-        lcd.setCursor(0,2);
-        lcd.print("And Re-Boot");
-     } //if doLCD
-    } //while PS3
-  } //if doGamePad
-
-  if (doLCD){
-    lcd.clear();
-    lcd.home();
-    setupLCD();//Print axis names to LCD
-  } //if doLCD
-
-  if (doSerialInterface){
-     Serial1.begin(115200);
-  } //if doSerialInterface
-}//End of setup function
-
-
-
-
-
-
-
-
-
-
-
-//------------------------------------------------------------------------------------------------
-// * main loop
-// This is the microcontroller's main loop, which cycles continuously following successful
-// completion of the setup function.
-float currentSpeed[3]; //An array defining the speed of each axis
-
-void loop() {
-  //Define main loop static variables
-  static bool moving=0; //0 if stationary moving; 1 more than one axis is moving (this isn't a user setting)
-
-  // Polling the USB Host Shield to which the PS3 controller is connected takes time, so we don't
-  // do it on every pass through the loop. About 30 to 50 times per second is adequate. In other words,
-  // we read the positions of the analog sticks, the button states, etc, at about these rates.
-  static unsigned short n=0;          //Counter to implement the periodic polling of the DualShock
-  static unsigned short nCycles=3000; //The DualShock is polled on every "nCycles" passses through the loop.
-
-  //LCD updating is slow, so we do it even more rarely than polling the PS3 controller, and also we
-  //do it in different cycles by making sure it's an odd number.
-  static unsigned short lcdCounter=0;
-  static unsigned short lcdCycles=3301; //10k works out as roughly 6 Hz
-  static unsigned short lcdAxis=0;      //counter to update axes on different cycles
-  static unsigned short lcdAxisTimer=0; //counter to update axes on different cycles
-
-
-
-
-  //Poll DualShock
-  if (doGamePad && ++n == nCycles){
-    moving=pollPS3();
-    n=0;
-  }
-
-  //Updating the LCD creates some motor choppiness at the faster speeds.
-  //With the current parameters, the motor stalls or is not smooth at
-  //faster motions if the LCD display is being updated. So no updates
-  //at this speed.
-  if (doLCD && lcdCounter++ == lcdCycles+lcdAxisTimer) {
-
-      if (coarseFine<4 || moving==0){
-          lcdStagePos(lcdAxis,stagePosition[lcdAxis],currentSpeed[lcdAxis]);
-      }
-
-      //update counters
-      lcdAxis++;
-      lcdAxisTimer+=500;
-      if (lcdAxis==numAxes){
-        lcdAxis=0;
-        lcdAxisTimer=0;
-        lcdCounter=0;
-      }
-  } //if lcdCounter
-
-
-  if (doGamePad){
-    //Move motors based on hat-stick positions
-    for (byte ii=0; ii<numAxes; ii++){
-       (*mySteppers[ii]).runSpeed();
-    }
-  } //if doGamePad
-
-
-  //Move based on serial commands
-  if (doSerialInterface){
-
-    if (SerialComms->available()){
-        char ch=SerialComms->read(); //read first character
-        if (ch=='g') //Absolute and relative motion
-          serialMove();
-        if (ch=='m') //Set speed mode on DualShock
-          serialSetMode();
-        if (ch=='z') //Zero stage position counter
-          zeroStage();
-        if (ch=='p') //Report stage position to PC
-          tellPosition();
-        if (ch=='s') //Report or change step size
-          serial_moveToStepSize();
-        if (ch=='v') //Report or change motion speed
-          serial_moveToSpeed();
-        if (ch=='a') //Report or change motion acceleration
-          serial_moveToAccel();
-        if (ch=='i') //Report various settings to PC
-          reportInfo();
-        if (ch=='b') //Issue beep from controller
-          serialBeep();
-
-       SerialComms->flush();
-    }
-  }
-
-}//End loop()
-
-
+*/


Just removed some indentation

Just removed some indentation

--- RGB_lamps/RGB_lamps.ino
+++ RGB_lamps/RGB_lamps.ino
@@ -13,7 +13,7 @@
   for (int pin = 2; pin < 14; pin++)  {
     pinMode(pin, OUTPUT);
   }
-
+
   lamps[0].create(2,3,4);
   lamps[1].create(5,6,7);
   lamps[2].create(8,9,10);
@@ -24,7 +24,7 @@
     int col[] = {random(0, 255),random(0, 255),random(0, 255)};
     lamps[lamp].setColor(col);
   }
-
+
   // Sleeps for 2 seconds to test the output before moving on
   delay(2000);
 }
@@ -32,13 +32,13 @@
 // This will carry out the fades and so on. These must be run each loop! (!!!)
 void work() {
   boolean finish = true;
-
+
   for (int lamp = 0; lamp < 4; lamp++) {
     if(lamps[lamp].work()) {
       finish = false;
     }
   }
-
+
   if(finish) {
     // Sets all lamps to fade to a random color
     for (int lamp = 0; lamp < 4; lamp++) {
@@ -50,8 +50,8 @@

 // This is our main loop
 void loop() {
-
+
   // This is where the fun begins
   work();
-
-}
+
+}


v19.16 Correct fraction of sunrise and sunset

--- GPSLCD.ino
+++ GPSLCD.ino
@@ -286,10 +286,6 @@
       // Compute fraction.  UTC is the best I can do. "sun_rise_set" dose not return minutes and seconds.
       double riseF = rise - (double)riseI;
       double setF = set - (double)setI;
-      String riseFS(abs(riseF));
-      String setFS(abs(setF));
-      riseFS = riseFS.substring(1, 6);
-      setFS = setFS.substring(1, 6);

       // Convert UTC "sunrise" time to local "sunset" time
       (void) convertToLocal(&riseI, &year, &month,
@@ -297,6 +293,18 @@
       // Convert UTC "sunset" time to local "sunset" time
       (void) convertToLocal(&setI, &year, &month,
                             &day, GPSData.lon, false); // false means no date and DST conversion.
+      // Convert UTC "sunrise" time to local "sunset" time
+      (void) convertToLocal((uint16_t)&riseF, &year, &month,
+                            &day, GPSData.lon, false); // false means no date and DST conversion.
+      // Convert UTC "sunset" time to local "sunset" time
+      (void) convertToLocal((uint16_t)&setF, &year, &month,
+                            &day, GPSData.lon, false); // false means no date and DST conversion.
+
+      String riseFS(abs(riseF));
+      String setFS(abs(setF));
+      riseFS = riseFS.substring(1, 6);
+      setFS = setFS.substring(1, 6);
+

       // Get day lenght hours in UTC.
       daylen = day_length(year, month, day, GPSData.lon, GPSData.lat);


improve title

improve title

--- wolke/fan1/fan1.ino
+++ wolke/fan1/fan1.ino
@@ -1,3 +1,5 @@
+// Test
+
 void setup() {
   pinMode(13, OUTPUT);
 }


Using my own library now

Using my own library now

--- current-test-program/servo_via_timer.ino
+++ current-test-program/servo_via_timer.ino
@@ -1,81 +1,23 @@
 #include <Servo.h>
-#include <inttypes.h>
-#include <signal.h>
+#include <servomover.h>

-Signal main_signal=Signal(1300, 1750, 2200, 11);
-Servo secondary_signal;
+LinearServoMover upper_arm = LinearServoMover(11, 1300, 1750, 1200);
+LinearServoMover lower_arm = LinearServoMover(12, 1150, 1750, 1200);

-// int MAIN_SIGNAL_MIN = 1300;
-// int MAIN_SIGNAL_MAX = 1750;
-// int MAIN_SIGNAL_DURATION_MS = 2200;
-// int main_signal_timestep_ms;
-// boolean main_signal_done=false;
-// unsigned int main_signal_next_time_ms;
-// int main_signal_value;
-
-int SECONDARY_SIGNAL_MIN = 1150;
-int SECONDARY_SIGNAL_MAX = 1750;
-int SECONDARY_SIGNAL_DURATION_MS = 1200;
-int secondary_signal_timestep_ms;
-boolean secondary_signal_done=false;
-unsigned int secondary_signal_next_time_ms;
-int secondary_signal_value;
-
-int INITIAL_DELAY_MS = 500;
+int INITIAL_DELAY_MS = 2000;

 void setup() {
-  pinMode(13, OUTPUT);
-
-  main_signal.toMaxPos();
-  // main_signal.attach(11);
-  // main_signal_timestep_ms = (MAIN_SIGNAL_DURATION_MS) / (MAIN_SIGNAL_MAX - MAIN_SIGNAL_MIN);
-  // main_signal_value = MAIN_SIGNAL_MIN;
-  // main_signal.writeMicroseconds(main_signal_value);
-  // main_signal_next_time_ms = millis() + INITIAL_DELAY_MS;
-  // main_signal.writeMicroseconds(main_signal_value);
-
-  secondary_signal.attach(12);
-  secondary_signal_timestep_ms = (SECONDARY_SIGNAL_DURATION_MS) / (SECONDARY_SIGNAL_MAX - SECONDARY_SIGNAL_MIN);
-  secondary_signal_value = SECONDARY_SIGNAL_MIN;
-  secondary_signal.writeMicroseconds(secondary_signal_value);
-  secondary_signal_next_time_ms = millis() + INITIAL_DELAY_MS + 50;
-  secondary_signal.writeMicroseconds(secondary_signal_value);
+  upper_arm.init();
+  lower_arm.init();
+  delay(INITIAL_DELAY_MS);
+  upper_arm.move_to_max();
+  lower_arm.move_to_max();

 }

-// void perhaps_update_main_signal() {
-//   if (millis() > main_signal_next_time_ms && !main_signal_done) {
-//     main_signal_value++;
-//     if (main_signal_value > MAIN_SIGNAL_MAX) {
-//       main_signal_done = true;
-//       main_signal.detach();
-//       return;
-//     }
-//     main_signal_next_time_ms += main_signal_timestep_ms;
-//     main_signal.writeMicroseconds(main_signal_value);
-//   }
-// }
-
-
-void perhaps_update_secondary_signal() {
-  if (millis() > secondary_signal_next_time_ms && !secondary_signal_done) {
-    secondary_signal_value++;
-    if (secondary_signal_value > SECONDARY_SIGNAL_MAX) {
-      secondary_signal_done = true;
-      secondary_signal.detach();
-      return;
-    }
-    secondary_signal_next_time_ms += secondary_signal_timestep_ms;
-    secondary_signal.writeMicroseconds(secondary_signal_value);
-  }
+void loop() {
+  upper_arm.perhaps_update();
+  lower_arm.perhaps_update();
 }
-
-
-void loop() {
-  uint64_t now=millis();
-  main_signal.update(now);
-  // perhaps_update_main_signal();
-  perhaps_update_secondary_signal();
-}


should be better reset behavior - but couldn't test it yet!

--- BuggyTracker/BuggyTracker.ino
+++ BuggyTracker/BuggyTracker.ino
@@ -85,6 +85,22 @@

 }

+void resetRun() {
+
+#if DEBUG
+  if (ble_connected()) {
+    ble_write_bytes( (unsigned char *)"reset\n",6);
+  }
+#endif
+  char result[37];
+  // length of output should be: 7 fixed, 10 begin, 10 time , 10 distance;
+  sprintf(result,"Run:%10lu:%10lu:%10lu\n",beginRun,time,curDistance);
+  runs.write(result,37);
+  runs.flush();
+  curDistance=distance;
+  beginRun=millis();
+
+}

 void stroller_ble_print() {
 #if NORMALPOW
@@ -104,6 +120,7 @@
 {

   if (hadRound== 1) {
+
 #if NORMALPOW
     Serial.println("had round");
 #endif
@@ -115,7 +132,22 @@
     if (lastMeasurement == 0 ){
       lastMeasurement = time;
     }
+    // actually increase the round
     curDistance = curDistance + distance;
+
+#if DEBUG
+    if (ble_connected()) {
+      char temp[32];
+      sprintf(temp,"resetting:%10lu:%10lu\n",lastMeasurement,time);
+      ble_write_bytes( (unsigned char *)temp,32);
+    }
+#endif
+    if ((time-lastMeasurement)>timeBetweenRounds) {
+      resetRun();
+    }
+#if DEBUG
+    stroller_ble_print();
+#endif
     //
     //      // write to SD card

@@ -126,32 +158,6 @@
     dataFile.write(output,25);
     dataFile.flush();

-    byte reset= 0;
-#if DEBUG
-    if (ble_connected()) {
-      char temp[32];
-      sprintf(temp,"resetting:%10lu:%10lu\n",lastMeasurement,time);
-      ble_write_bytes( (unsigned char *)temp,32);
-    }
-#endif
-    if ((time-lastMeasurement)>timeBetweenRounds) {
-#if DEBUG
-      if (ble_connected()) {
-        ble_write_bytes( (unsigned char *)"reset\n",6);
-      }
-#endif
-      reset=1;
-      char result[37];
-      // length of output should be: 7 fixed, 10 begin, 10 time , 10 distance;
-      sprintf(result,"Run:%10lu:%10lu:%10lu\n",beginRun,time,curDistance);
-      runs.write(result,37);
-      runs.flush();
-      curDistance=distance;
-      beginRun=millis();
-    }
-#if DEBUG
-    stroller_ble_print();
-#endif
     lastMeasurement = time;
     hadRound=0;

@@ -168,6 +174,7 @@
       else if ( 'c' == temp ) { // aCcept or commit command from smartphone, later used for resetting
         curDistance=0;
         ble_write('r');
+        resetRun();
         ble_write('\n');
       }
     }
@@ -192,3 +199,4 @@

+


adds watchdog timer to recall or shutdown mars

--- marsduino/marsduino.ino
+++ marsduino/marsduino.ino
@@ -55,7 +55,8 @@
 //Watchdog
 bool watchdogEnabled = false;
 unsigned long watchdogTimer;
-unsigned long timeoutTime = 30000;
+unsigned long recallTime = 30000;
+unsigned long shutdownTime = 1200000;
 String recallCode = "M1005";

 //Timing
@@ -63,6 +64,9 @@

 //Logging
 String logs = "marsduino initated";
+
+//Memcheck Mode
+bool memCheck = false;

@@ -150,7 +154,10 @@
 }

 void process_code(String input){
-
+  /*
+   * Processes Input Control codes
+   */
+
   char codeArray[8]; //input string turned into an array
   input.toCharArray(codeArray, 6);

@@ -159,7 +166,7 @@

   switch (first) {
     //Motor code
-    case 'M': {
+    case 'M': { /*Motor codes*/
         char enable = codeArray[1] == '0' ? LOW : HIGH;
         char reverse = codeArray[2] == '0' ? LOW : HIGH;
         char brake = codeArray[3] == '0' ? LOW : HIGH;
@@ -178,8 +185,8 @@
         logs = "motor code set to level to " + input.substring(1);
         break;
       }
-    //LED code
-    case 'L': {
+
+    case 'L': { /*LED codes*/
         char ledValue = codeArray[1];
         int ledDutyCycle = int(charToInt(ledValue) * 25.5);
         analogWrite(ledPin, ledDutyCycle); //sets up PWM on the speedPin
@@ -187,33 +194,46 @@
         break;
       }

-    case 'R': {
+    case 'R': {/*reference voltage reset*/
       useRef = true;
       realReference = input.substring(1).toInt();
       logs = "Voltage Reference set to " + input.substring(1);
       break;
     }
-    case 'E': {
+    case 'E': {/*reference voltage disabled*/
       useRef = false;
       logs = "Voltage Reference disabled";
     }
-    case 'W': {
+    case 'W': {/*watchdog timer reset*/
       watchdogEnabled = true;
       watchdogTimer = 0;
       logs = "Watchdog Timer Reset";
       break;
     }
-    case 'Q': {
+    case 'Q': {/*watchdog timer disabled*/
       watchdogEnabled = false;
       logs = "Watchdog Timer Disabled";
     }
-  }
-}
-
-/**
-   Generates a DaqTelemetry object
-*/
+    case 'C': { /*memory mode enabled*/
+      memCheck = true;
+      logs = "Memory Check enabled";
+      break;
+    }
+    case 'X':{ /*memory mode disabled*/
+      memCheck = false;
+      logs = "Memory Check disabled";
+      break;
+    }
+  }
+}
+
+
 DaqTelemetry* daq()
+  /*
+   * acquires values from sensors via input pins and dervies the values in standard units
+   *
+   */
+
 {
   daqTelemetry = new DaqTelemetry();
   int voltageOffset;
@@ -261,12 +281,11 @@
   return daqTelemetry;
 }

-
-/**
-   Send daqTelemtry data over the serial
-*/
-
 String distance_to_string(double distance){
+  /*
+   * converts doubles to a string type
+   */
+
   String outputDistance = (String)distance;

   if(outputDistance == "-1") {
@@ -277,6 +296,11 @@

 void save_and_send(DaqTelemetry *daqTelemetry)
+  /*
+   * compiles all the daqTelemetry, logs and runclock and forwards it along
+   * to the controlling computer
+   *
+   */
 {
   String outputDistance = distance_to_string(daqTelemetry->distance);

@@ -289,28 +313,65 @@
   Serial.println(daqString);
 }

-int update_watchdog_timer(){
+unsigned long update_watchdog_timer(){
+  /*
+   * updates the watchdog timer
+   */
   watchdogTimer = watchdogTimer + ( millis() - lastTime );
   lastTime = millis();
   return watchdogTimer;
 }

+void memory_check(){
+  /*
+   * This function just prints out the current amount of free memory possessed by the arduino
+   * used only in troubleshooting scenarios
+   *
+   * running this method with Goddard will effectively break the MARS controller
+   */
+
+  Serial.print("freeMemory()=");
+  Serial.println(freeMemory());
+}
+
+
+void emergency_shutdown(){
+  /*
+   * This function shuts down the watchdog and turns all pins off (to effectively disengage the motor)
+   *
+   * only used in the event that that the arduino has recieved no contact from MARS
+   * for a long duration. the arduino assumes that something catastrophic has happened
+   * and MARS is stuck in the tube without any controlling software.
+   *
+   */
+  watchdogEnabled = false;
+  memCheck = false;
+  digitalWrite(enablePin, LOW);
+  digitalWrite(revPin, LOW);
+  digitalWrite(brakePin, LOW);
+  digitalWrite(speedPin,LOW);
+  digitalWrite(ledPin,LOW);
+}
+
 void loop() {
-  Serial.println(watchdogTimer);
-  if (Serial.available() > 0) {
+ if (Serial.available() > 0) {
     process_code( retrieve_code() );
-  }
-  daqTelemetry = daq();
-  save_and_send(daqTelemetry);
+ }
+ daqTelemetry = daq();
+ save_and_send(daqTelemetry);

  update_watchdog_timer();
   if(watchdogEnabled == true){
-    if(watchdogTimer > timeoutTime){
+    if(watchdogTimer > recallTime){
       process_code( recallCode );
     }
-  }
-  Serial.print("freeMemory()=");
-  Serial.println(freeMemory());
+    else if(watchdogTimer > shutdownTime){
+      emergency_shutdown();
+    }
+  }
+  if(memCheck == true){
+    memory_check();
+  }
   logs = "Null";
   delete daqTelemetry;
 }


Added timer1 interrupt code

Added timer1 interrupt code

--- sensor_firmware/sensor_firmware.ino
+++ sensor_firmware/sensor_firmware.ino
@@ -1,22 +1,28 @@
 /*
-  AnalogReadSerial
-  Reads an analog input on pin 0, prints the result to the serial monitor.
-  Attach the center pin of a potentiometer to pin A0, and the outside pins to +5V and ground.
-
- This example code is in the public domain.
+ * Wind Sensor Firmware
+ *
  */

-// the setup routine runs once when you press reset:
+
+#include "TimerOne.h"
+
 void setup() {
-  // initialize serial communication at 9600 bits per second:
-  Serial.begin(9600);
+    int baud_rate = 115200;
+    Serial.begin(baud_rate);
+
+    // Set sample period in microseconds for 8kHz
+    long timer_delay_us = 125;
+    Timer.initialize(timer_delay_us);
 }

-// the loop routine runs over and over again forever:
 void loop() {
-  // read the input on analog pin 0:
-  int sensorValue = analogRead(A0);
-  // print out the value you read:
-  Serial.println(sensorValue);
-  delay(1);        // delay in between reads for stability
+    // We don't need to do anything for now
 }
+
+void interrupt_loop(){
+    // Sample sensor
+    int sensorValue = analogRead(A0);
+    Serial.println(sensorValue);
+}
+
+


update

update

--- src/Firmware.ino
+++ src/Firmware.ino
@@ -5,19 +5,12 @@
 OutputPin dirPinY(3);
 OutputPin stepPinY(2);

+
 long xPosition = 0;
 long yPosition = 0;

-long currentSpeed = 1000;
-long currentAcc = 1000;
-
-double pulsePerMM = 168.35;
-long feedRate = 1000;
-
-int xPulsePin = 10;
-int xDirPin = 11;
-int yPulsePin = 9;
-int yDirPin = 3;
+double pulsePerMM = 62.289;
+
 float curve_section = 0.5;
 bool isRelative = false;
 String gcode = "";
@@ -27,13 +20,15 @@
 long count = 0;
 int motionDir = 1;
 long targetDuringTime = 200;
-long currentDuringTime = 0;
+long currentDuringTime = 2000;
 int motionAcc = 1;
 bool isMoving = false;
+
+
 void updateMotion()
 {
     if(isMoving){
-        if(motionDir>0&&currentDuringTime>10){
+        if(motionDir>0&&currentDuringTime>targetDuringTime){
             if(motionDir>150){
                 motionAcc = -1;
                 motionDir=150;
@@ -47,7 +42,7 @@
                 currentDuringTime = targetDuringTime;
                 motionDir = 0;
             }
-        }else if(motionDir<0&&currentDuringTime<5000){
+        }else if(motionDir<0&&currentDuringTime<50000){

             if(motionDir<-150){
                 motionAcc = -1;
@@ -70,6 +65,7 @@
     pinMode(7,OUTPUT);
     analogWrite(7,0);
     Serial.print("start\n");
+
 }

 void loop(){
@@ -168,14 +164,14 @@
 void stepX(bool dir){
     dirPinX = dir;
     stepPinX = LOW;
-    delayMicroseconds(2);
+    delayMicroseconds(1);
     stepPinX = HIGH;
     xPosition+=dir?1:-1;
 }
 void stepY(bool dir){
     dirPinY = dir;
     stepPinY = LOW;
-    delayMicroseconds(2);
+    delayMicroseconds(1);
     stepPinY = HIGH;
     yPosition+=dir?1:-1;
 }
@@ -193,7 +189,7 @@
     long y0 = yPosition;
     long x1 = tx;
     long y1 = ty;
-    currentDuringTime = max(targetDuringTime+2000,2000);
+    currentDuringTime = max(targetDuringTime+500,1000);
     motionDir = 1;
     motionAcc = 1;
     long dx,dy,sx,sy;
@@ -230,7 +226,6 @@

             //     delayUs;delayUs;
         }
-        Serial.println(millis()-ttt);
     }else{
         motionDir = 1;
         while(true){


Small changes. Working on finalizing pins.  Finished mounting everything to board.

--- main_sketch/main_sketch.ino
+++ main_sketch/main_sketch.ino
@@ -20,7 +20,7 @@
 Photores setup:  power- 5v
                  gnd  - gnd
                  output- prPin1(10), prPin2(11)
-                 resistors - x ohms
+                 resistors - 10 kohms
 */

 #include <Servo.h>
@@ -99,6 +99,7 @@

   //measure distance from sharpIR
   dis = sharp.distance();
+  //Serial.println(dis);

   //do wheel things
   handleWheels();


fixed doorAngle bug

fixed doorAngle bug

--- Arduino/Turnstyle/Turnstyle.ino
+++ Arduino/Turnstyle/Turnstyle.ino
@@ -136,7 +136,7 @@
         baselineYaw = currentYaw;
         switchClosedLastIteration = false;
       }
-      float doorAngle = abs(currentYaw - baselineYaw);
+      doorAngle = abs(currentYaw - baselineYaw);
       // if the doorAngle is > 180, it must be due to the discontinuity, assuming doors open to an angle of max 180 degrees.
       if (doorAngle > 180) {
         doorAngle = 360 - doorAngle;


Changed the ExampleClient code so it works, now using Serial and Serial1 for debug

--- examples/ExampleClient/ExampleClient.ino
+++ examples/ExampleClient/ExampleClient.ino
@@ -1,5 +1,6 @@
-#include <SoftwareSerial.h>
 #include <SIM900.h>
+
+#define debug Serial1

 SIM900GPRS gsm;
 SIM900Client client(&gsm);
@@ -13,65 +14,69 @@
 char imeiStr[16];
 long _startTime;

-size_t freeRam ()
-  {
+size_t freeRam () {
   return RAMEND - size_t (__malloc_heap_start);
-  } // end of freeRam
+} // end of freeRam

 void setup(){
-  Serial.begin(9600);
-  Serial.println(F("Test of GSMGPRS_Shield"));
-  Serial.print(F("GSM lib "));
-  Serial.println(GSM_LIB_VERSION);
-  Serial.print(F("SIM900 lib "));
-  Serial.println(SIM900_GPRS_VERSION);
-  Serial.print(F("Free memory = "));
-  Serial.println(freeRam());
+  Serial.begin(57600);
+  debug.begin(115200);
+  debug.println(F("Test of GSMGPRS_Shield"));
+  debug.print(F("GSM lib "));
+  debug.println(GSM_LIB_VERSION);
+  debug.print(F("SIM900 lib "));
+  debug.println(SIM900_GPRS_VERSION);
+  debug.print(F("Free memory = "));
+  debug.println(freeRam());

   // try to turn on the GSM Shield, stop if we fail
   if(!gsm.turnOn()) {
+    debug.println(F("Failed to turn on!"));
     goto STOP;
   }
-  Serial.println(F("Module on"));
+  debug.println(F("Module on"));

   // initialize GSM
-  while(gsm.begin() != GSM_READY) {
-    Serial.println("gsm setup problem");
-    goto STOP;
+  for(ret=0; ret<15 && GSM_READY != gsm.begin(); ret ++ ) {
+    debug.println("gsm setup problem");
+    delay(1000);
   }
-  Serial.println(F("GSM ready"));
+  debug.println(F("GSM ready"));

-  Serial.print(F("Signal strength: "));
-  Serial.println(gsm.getSignalStrength());
+  debug.print(F("Signal strength: "));
+  debug.println(gsm.getSignalStrength());

   gsm.getIMEI(imeiStr, 16);
-  Serial.print(F("IMEI: "));
-  Serial.println(imeiStr);
+  debug.print(F("IMEI: "));
+  debug.println(imeiStr);

   // wait until GPRS is available
-  while(!gsm.isGPRSAvailable()) {
-    delay(500);
+  for(ret=0; ret<15 && !gsm.isGPRSAvailable(); ret++) {
+    debug.println("no gprs yet");
+    delay(1000);
   }
-  Serial.println(F("GPRS is available, attach!"));
+  if(ret == 15) goto STOP;
+  debug.println(F("GPRS is available, attach!"));

-  while(GPRS_READY != gsm.attachGPRS("online.telia.se", NULL, NULL)) {
-      Serial.println("gprs join network error");
+  for(ret=0; ret<15 && GPRS_READY != gsm.attachGPRS("online.telia.se", NULL, NULL); ret++) {
+      debug.println("gprs join network error");
+      delay(1000);
+  }
+  if(ret == 15) goto STOP;
+  debug.println(F("GPRS ready"));
+
+  gsm.getIP(ipStr, 17);
+  debug.print(F("IP Address is "));
+  debug.println(ipStr);
+
+  if(false == client.connect("www.yelloworb.com", 80)) {
+      debug.println(F("connect error"));
       goto STOP;
   }
-  Serial.println(F("GPRS ready"));
-
-  gsm.getIP(ipStr, 17);
-  Serial.print(F("IP Address is "));
-  Serial.println(ipStr);
-
-  if(false == client.connect("www.yelloworb.com", 3000)) {
-      Serial.println(F("connect error"));
-      goto STOP;
-  }
-  Serial.println(F("connect success"));
+  debug.println(F("connect success"));

-  Serial.println(F("waiting to fetch..."));
+  debug.println(F("waiting to fetch..."));
   client.beginWrite();
   client.print(http_cmd);
   client.endWrite();
@@ -90,17 +95,19 @@
     }
   }
   buffer[ret] = '\0';
-  Serial.print(F("Recv: "));
-  Serial.print(ret);
-  Serial.println(F(" bytes: "));
-  Serial.println(buffer);
-  Serial.println(F("fetch over..."));
+  debug.print(F("Recv: "));
+  debug.print(ret);
+  debug.println(F(" bytes: "));
+  debug.println(buffer);
+  debug.println(F("fetch over..."));

   STOP:
   client.stop();
   gsm.detachGPRS();
   gsm.shutdown();
-  Serial.println(F("All Done!"));
+  debug.print(F("Free memory = "));
+  debug.println(freeRam());
+  debug.println(F("All Done!"));
 }

 void loop(){


Removed some old cruft

Removed some old cruft

--- utils/src/eep_writer/eep_writer.ino
+++ utils/src/eep_writer/eep_writer.ino
@@ -1,27 +0,0 @@
-/**
-
-Name:       EEPROM Writer
-Author:     Andrew fisher
-version:    0.1
-Description:
-
-This application is used to set certain eeprom values on an arduino in order to
-override the defaults supplied by a particular firmware. In particular this allows
-a binary firmware to be shipped for a backpack without the end user having to
-compile things but allows the end user to configure an I2C address in the advent
-of a clash.
-
-**/
-
-
-/**
-
-* Establish comms with serial connection.
-* Read value reads the EEPROM and then outputs this value to the serial connection
-* write value takes a value from the serial connection and writes this to the eeprom
-
-* Keep this generic so that it basically reads and writes a given number of
-bytes to a specific address space and that's all it does and then leave the
-configuration aspect of this to the JS side.
-
-**/


fix eror

fix eror

--- robot/robot.ino
+++ robot/robot.ino
@@ -48,6 +48,7 @@
 uint8_t kakiD1 = 2;
 uint8_t kakiD2 = 3;

+/*
 //servo rumus kdua
 int h1 = 1;
 int l1 = 2;
@@ -71,6 +72,7 @@
 int h3h = 90 - frw;
 int h4h = 90 + frw;

+*/

 //ini motor pompa
 int motor = 7;


Adjust for modified/new APIs

Adjust for modified/new APIs

--- ESP8266HueEmulator/ESP8266HueEmulator.ino
+++ ESP8266HueEmulator/ESP8266HueEmulator.ino
@@ -35,8 +35,8 @@
 RgbColor black = RgbColor(0);
 unsigned int transitionTime = 800; // by default there is a transition time to the new state of 400 milliseconds

-NeoPixelBus<NeoRgbFeature, Neo800KbpsMethod> strip(pixelCount, pixelPin);
-NeoPixelAnimator animator(pixelCount); // NeoPixel animation management object
+NeoPixelBus<NeoGrbFeature, Neo800KbpsMethod> strip(pixelCount, pixelPin);
+NeoPixelAnimator animator(pixelCount, NEO_DECISECONDS); // NeoPixel animation management object

 RgbColor StripRgbColors[pixelCount]; // Holds all colors of the pixels on the strip even if they are off
 bool StripLightIsOn[pixelCount]; // Holds on/off information for all the pixels
@@ -295,7 +295,7 @@
   static unsigned long update_strip_time = 0;  //  keeps track of pixel refresh rate... limits updates to 33 Hz
   if (millis() - update_strip_time > 30)
   {
-    if ( animator.IsAnimating() ) animator.UpdateAnimations(100);
+    if ( animator.IsAnimating() ) animator.UpdateAnimations();
     strip.Show();
     update_strip_time = millis();
   }


Changed pause frequencies

Changed pause frequencies

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

   panTilt.updateAngles();

-  if(random(1001) < 8){
+  if(random(1001) < 12){
     delay(markovPause());

   }
@@ -97,7 +97,7 @@

   if(random(10001) < 2){
     laser.fire(0);
-    delay(random(1000, 5000));
+    delay(random(1000, 5000))

   }

@@ -197,7 +197,7 @@
 int val = random(101);

-  if(val < 20){
+  if(val < 30){
     return random(1000, 1500);
   }
   else if(val < 80){


alarm set working, with animations for wakeup and > 12 hrs

--- NeoPixelNightLight/NeoPixelNightLight.ino
+++ NeoPixelNightLight/NeoPixelNightLight.ino
@@ -1,4 +1,4 @@
-#define DEBUG
+//#define DEBUG
 #include <EEPROM.h>

 // RTC
@@ -56,9 +56,11 @@
 #ifdef DEBUG
   #define DEBUG_PRINT(n) Serial.print(n);
   #define DEBUG_PRINTLN(n) {Serial.println(n); delay(100); }
+  #define DEBUG_PRINTTIME(n) printTime(n);
 #else
   #define DEBUG_PRINT(n) {}
   #define DEBUG_PRINTLN(n) {}
+  #define DEBUG_PRINTTIME
 #endif

 void printTime( DateTime &dt )
@@ -112,10 +114,10 @@
   pinMode(MODE_SWITCH_PIN,INPUT_PULLUP);

   EEPROM.get(MODE_INDEX,mode);
+  if ( mode < 0 || mode >= sizeof(modes)/sizeof(char*))
+    mode = 0;
   Serial.print(F("Got mode from eeprom ") );
-  Serial.println(mode);
-  if ( mode < 0 )
-    mode = 0;
+  Serial.println(modes[mode]);

   int32_t wakeUnixTime;
   EEPROM.get(WAKE_INDEX,wakeUnixTime);
@@ -137,7 +139,7 @@
   if ( rtcRunning )
     return rtc.now();
   else
-    return compileTime.unixtime() + millis()/1000;
+    return compileTime.unixtime() + millis()/50;  // 1000 for close to real time
 }

 /*******************************************************************************
@@ -294,49 +296,84 @@
 }

 int prevHours = -1;
+int nextWake = 0;
+unsigned long lastWakeChange = 0;

 /*******************************************************************************
 *******************************************************************************/
 void nightlight(DateTime current, bool forceChange)
 {
-  // how many hours until wakey?
+  // how many minutes until wakey?
   double currentMin = 60.0*current.hour() + current.minute();
   double wakeyMin = 60.0*wakeTime.hour() + wakeTime.minute();

+  bool show = forceChange || checkColorChange();
+
   double diffMin = wakeyMin - currentMin;
-  if ( diffMin < 0 )
+  if ( diffMin <= 0 )
+  {
+    // for 15 minutes, animate
+    if ( diffMin > -15 )
+    {
+      if ( lastWakeChange == 0 || millis() - lastWakeChange > 100 )
+      {
+        lastWakeChange = millis();
+        for ( int i = 0; i < NEOPIXEL_LEDS; i++ )
+          strip.setPixelColor(i,Wheel(colorValue));
+        strip.setPixelColor(nextWake++ % NEOPIXEL_LEDS,0);
+        strip.show();
+        prevHours = -1;
+      }
+      DEBUG_PRINT("Wake UP! since diff min is ");
+      DEBUG_PRINTLN(diffMin);
+      return;
+    }
+
     diffMin = wakeyMin + (24.0*60)-currentMin; // remains of today + until wakey
-  int newHours = (diffMin / 60)+.5;
+  }
+  lastWakeChange = 0;
+
+  int newHours = 1.5 + (diffMin / 60); // last light 30 minutes
+
+
   if ( newHours > 12 )
-    newHours = 11; // so can tell difference between this and backlight
-
-  bool show = forceChange || checkColorChange();
-
-  if ( prevHours != newHours || show )
-  {
+  {
+    clearPixels();
+    for ( int i = 0; i < NEOPIXEL_LEDS; i+=4 )
+      strip.setPixelColor(i,Wheel(colorValue));
+
+    prevHours = newHours;
+    show = true;
+  }
+  else if ( prevHours != newHours || show )
+  {
+    clearPixels();
     show = true;
-    if ( prevHours >= 0 )
-      strip.setPixelColor(prevHours,0);
     for ( int i = 0; i < abs(newHours); i++ )
       strip.setPixelColor(i,Wheel(colorValue));
-    DEBUG_PRINT( F("PreHours "));
+    DEBUG_PRINT( F("PrevHours "));
     DEBUG_PRINT( prevHours );
     DEBUG_PRINT( F(" newHours "));
     DEBUG_PRINTLN( newHours );
     prevHours = newHours;
   }

-  if ( millis() % 1000 == 0 )
-  {
-    DEBUG_PRINT( F("Wakey - current: "));
+#ifdef DEBUG
+  if ( millis() % 1000 == 0 || show )
+  {
+    DEBUG_PRINTTIME printTime(current);
+    DEBUG_PRINT( F(" (WakeyMin - currentMin) =  ("));
     DEBUG_PRINT( (int)wakeyMin );
-    DEBUG_PRINT( F("min - "));
+    DEBUG_PRINT( F(" - "));
     DEBUG_PRINT( (int)currentMin );
-    DEBUG_PRINT( F("min and diff is "));
+    DEBUG_PRINT( F(") and diff is "));
     DEBUG_PRINT( (int)diffMin );
     DEBUG_PRINT( F("min and show is "));
-    DEBUG_PRINTLN( show );
-  }
+    DEBUG_PRINT( show );
+    DEBUG_PRINT( F(" and forceChange is "));
+    DEBUG_PRINTLN( forceChange );
+  }
+#endif

   if ( show )
     strip.show();


Dormitory 3 fully working

Dormitory 3 fully working

--- Margoulineur2000.ino
+++ Margoulineur2000.ino
@@ -166,8 +166,10 @@
         else
          {
           lcd.clear();
-          lcd.print("New Balance :");
+          lcd.print("New balance :");
+          lcd.setCursor(0,1);
           lcd.print(newPosition / 4);
+
           oldPosition = newPosition;
           Serial.println(newPosition / 4);
          }
@@ -186,16 +188,14 @@
   uint8_t currentblock;                     // Counter to keep track of which block we're on
   bool authenticated = false;               // Flag to indicate if the sector is authenticated
   uint8_t data[16] = {0x04, 0x0A, 0x52, 0x18, 0x7B, 0x2C, 0x10, 0x68, 0x00, 0x00, 0x00, 0x00, 0x00, 0x45, 0x55, 0x43};                         // Array to store block data during reads
-  uint8_t savedData[16];
-  int currentBalance = 0;
-
-  int value = encoderWrite() * 100;
-
-
-  Serial.print("New value = ");Serial.println(value);
+  uint8_t savedData[16];
+
+  int newBalance = encoderWrite() * 100;
+
+  Serial.print("New value = ");Serial.println(newBalance);
   uint8_t balance[] = {0, 0};
-  balance[0] = value / 256;
-  balance[1] = value - (balance[0] * 256);
+  balance[0] = newBalance / 256;
+  balance[1] = newBalance - (balance[0] * 256);
   Serial.print("Hex 1 = ");Serial.println(balance[0], HEX);
   Serial.print("Hex 2 = ");Serial.println(balance[1], HEX);
   digitalWrite(writeLedPin, HIGH);
@@ -206,8 +206,8 @@

   success = nfc.readPassiveTargetID(PN532_MIFARE_ISO14443A, uid, &uidLength);

-  if (success) {
-    // Display some basic information about the card
+  if (success)
+  {
     Serial.println("Found an ISO14443A card");
     lcd.clear();
     lcd.print("I Found a card !");
@@ -267,8 +267,11 @@
         }
         else
         {
-          if (currentblock == 24)
-          {
+          if (currentblock == 24 || currentblock == 26 )
+          {
+           nfc.mifareclassic_ReadDataBlock(currentblock, data);
+           data[6] = balance[0];
+           data[7] = balance[1];
             success = nfc.mifareclassic_WriteDataBlock(currentblock, data);
             if (success)
             {
@@ -285,6 +288,27 @@

             }
           }
+          else if (currentblock == 25)
+          {
+           nfc.mifareclassic_ReadDataBlock(currentblock, data);
+           data[5] = balance[0];
+           data[6] = balance[1];
+            success = nfc.mifareclassic_WriteDataBlock(currentblock, data);
+            if (success)
+            {
+              Serial.print("Block ");Serial.print(currentblock, DEC);
+              if (currentblock < 10)
+              {
+                Serial.print("  ");
+              }
+              else
+              {
+                Serial.print(" ");
+              }
+              nfc.PrintHexChar(data, 16);
+
+            }
+          }
           else
           {
             // Oops ... something happened
@@ -300,15 +324,12 @@
       Serial.println("Ooops ... this doesn't seem to be a Mifare Classic card!");
     }
   }
-  // Wait a bit before trying again
-//  Serial.println(savedData[0], HEX);
- // Serial.println(savedData[1], HEX);
-
-  lcd.clear();
-  lcd.print("Balance :");
-  lcd.setCursor(0,1);
-  lcd.print(currentBalance);
-  Serial.println(currentBalance, DEC);
+
+  lcd.clear();
+  lcd.print("New balance :");
+  lcd.setCursor(0,1);
+  lcd.print(newBalance / 100);
+  Serial.println(newBalance, DEC);
   Serial.println("\n\nDONE ! waiting 4 the button");
   digitalWrite(writeLedPin, LOW);
   wait4button();
@@ -439,14 +460,10 @@
       Serial.println("Ooops ... this doesn't seem to be a Mifare Classic card!");
     }
   }
-  // Wait a bit before trying again
-//  Serial.println(savedData[0], HEX);
- // Serial.println(savedData[1], HEX);
-
   lcd.clear();
   lcd.print("Balance :");
   lcd.setCursor(0,1);
-  lcd.print(currentBalance);
+  lcd.print(currentBalance / 100);
   Serial.println(currentBalance, DEC);
   Serial.println("\n\nDONE ! waiting 4 the button");
   digitalWrite(readLedPin, LOW);
@@ -454,7 +471,6 @@
   lcd.clear();
   Serial.print("end read = ");Serial.println(oldPosition);

-
   Serial.flush();
 }


removed unless lines

removed unless lines

--- src/piCar2.0.ino
+++ src/piCar2.0.ino
@@ -13,27 +13,6 @@
 int blueLight = 0;
 long TLC = 0;
 Adafruit_BLE_UART BTLEserial = Adafruit_BLE_UART(ADAFRUITBLE_REQ, ADAFRUITBLE_RDY, ADAFRUITBLE_RST);
-/*  MonsterMoto Shield Example Sketch
-  date: 5/24/11
-  code by: Jim Lindblom
-  hardware by: Nate Bernstein
-  SparkFun Electronics
-
-  License: CC-SA 3.0, feel free to use this code however you'd like.
-  Please improve upon it! Let me know how you've made it better.
-
-  This is really simple example code to get you some basic
-  functionality with the MonsterMoto Shield. The MonsterMote uses
-  two VNH2SP30 high-current full-bridge motor drivers.
-
-  Use the motorGo(uint8_t motor, uint8_t direct, uint8_t pwm)
-  function to get motors going in either CW, CCW, BRAKEVCC, or
-  BRAKEGND. Use motorOff(int motor) to turn a specific motor off.
-
-  The motor variable in each function should be either a 0 or a 1.M
-  pwm in the motorGo function should be a value between 0 and 255.
-*/
-
 int frontUltra = 0;
 int frontUltraPin = 0;


Print values for the serial plotter.

Print values for the serial plotter.

--- arduino/sensor_manager/sensor_manager.ino
+++ arduino/sensor_manager/sensor_manager.ino
@@ -22,10 +22,17 @@
 }

 void loop() {
-  send("sonar", sonar.get_range());
-  send("tach0", tach_0.get_rpm());
-  send("tach1", tach_1.get_rpm());
+  // send("sonar", sonar.get_range());
+  // send("tach0", tach_0.get_rpm());
+  // send("tach1", tach_1.get_rpm());
+  plot(tach_0.get_rpm(), tach_1.get_rpm());
   delay(1000/FREQ);
+}
+
+void plot(int v0, int v1){
+  Serial.print(v0);
+  Serial.print(",");
+  Serial.println(v1);
 }

 void send(const String& label, int value)


Update Arduino.ino

Update Arduino.ino

--- Arduino/Arduino.ino
+++ Arduino/Arduino.ino
@@ -37,7 +37,7 @@
       parseBuffer();
     }
   }
-  joystickUpdate();
+  //joystickUpdate();
 }
 void parseBuffer(){
   int startIndex = 0,endIndex = 0,index = 0,len = _buffer.length(),maxCmdLen = 0;


Terminate the cmd before exec

Terminate the cmd before exec

--- battlestation/arduino/arduino.ino
+++ battlestation/arduino/arduino.ino
@@ -29,9 +29,6 @@

 #define TEAMS 3
 static uint32_t team_colors[TEAMS];
-
-static char cmd[20];
-static byte cmd_idx = 0;

 void setup() {
   Serial.begin(115200);
@@ -44,7 +41,7 @@
     score_strips[i] = new Adafruit_NeoPixel(SCORE_STRIP_LEDS, score_pins[i], NEO_GRB + NEO_KHZ800);
     score_strips[i]->begin();
     for (byte l = 0; l < SCORE_STRIP_LEDS; l++) {
-      score_strips[i]->setBrightness(l, 255);
+      score_strips[i]->setBrightness(255);
       score_strips[i]->setPixelColor(l, 0, 0, 0);
     }
     score_strips[i]->show();
@@ -57,6 +54,9 @@
 }

 void read_and_exec_cmd() {
+  static char cmd[20];
+  static byte cmd_idx = 0;
+
   while (Serial.available()) {
     char c = Serial.read();
     boolean clear = false;
@@ -67,6 +67,7 @@
     }

     if (c == '\n') {
+      cmd[cmd_idx] = 0;
       exec_cmd();
     } else {
       Serial.println  ("command too long");
@@ -79,7 +80,7 @@
   }
 }

-void exec_cmd() {
+void exec_cmd(const char * cmd) {
   boolean ok = false;
   char * tok = NULL;
   const char * cmd_name = strtok_r(cmd, " ", &tok);


Adding button pushes

Adding button pushes

--- software/rectangle_rag/rectangle_rag.ino
+++ software/rectangle_rag/rectangle_rag.ino
@@ -7,6 +7,7 @@
 #define AMBER_PIN 3
 #define GREEN_PIN 4
 #define BUTTON_PIN 0
+#define MAX_LOOPS 7

 // Hello PVG - a perversion of your look-up.
 #define RED 1
@@ -80,13 +81,56 @@

 void loop() {
+
+  uint8_t presses = 0;
+  if(pressed())  {
+    presses = getPresses(1, 1, 4, MAX_LOOPS);
+    doSequence(presses-1);
+  }
+
+
+
 //  doSequence(4);
-  doSequence(3);
-  doSequence(2);
-  doSequence(1);
-  doSequence(0);
+//  doSequence(3);
+//  doSequence(2);
+//  doSequence(1);
+//  doSequence(0);

 }
+
+uint8_t getPresses(uint8_t presses, uint8_t min_press, uint8_t max_press, uint8_t max_loops) {
+  showNumber(presses);
+  if (!pressed()) {
+    return (presses);
+  }
+  else {
+    if (presses < max_press) {  // No overflow
+      getPresses(presses + 1, min_press, max_press, max_loops);
+    }
+    else {
+      if (max_loops<=0) {
+        // Heap overflow if we keep recursing.
+        return (min_press);
+      }
+      else {
+        // Start from min_touch and count up again
+        getPresses(presses, min_press, max_press, max_loops-1);
+      }
+    }
+  }
+}
+
+void showNumber(uint8_t presses) {
+  for (uint8_t i=1; i <= presses; i++)  {
+    delay(FLASH_INTERVAL_MILLIS/2);
+    digitalWrite(RED_PIN,   HIGH);
+    delay(FLASH_INTERVAL_MILLIS/2);
+    digitalWrite(RED_PIN,   LOW);
+    delay(FLASH_INTERVAL_MILLIS/2);
+  }
+  delay(FLASH_INTERVAL_MILLIS*2);
+}
+

 void doSequence(unsigned char s)  {
@@ -124,6 +168,11 @@
   digitalWrite(GREEN_PIN, LOW);
 }

+bool pressed() {
+   return !digitalRead(BUTTON_PIN);
+}
+
+
 void pinsToOutput()  {
   pinMode(RED_PIN,   OUTPUT);
   pinMode(AMBER_PIN, OUTPUT);


Compute positions of gears

Compute positions of gears

Lots of casework, but it should work fine.

--- crypt-gears/gear_arduino/gear_arduino.ino
+++ crypt-gears/gear_arduino/gear_arduino.ino
@@ -31,10 +31,13 @@
 // at selector position j.  Only meaningful in state 1, and then only for
 // 0 <= j < the current selector gear position.  When we transition to state 2
 // we use this to populate gear_types and gear_orientations.
+// NOTE: we assume the photoresistor is positioned "up".
+// TODO(benkraft): Confirm this is correct.
 boolean photoresistor_history[3][7];

-// The state of the ith gear, if we know it.  Only meaningful in state 2; set
-// from photoresistor_history when we transition there.
+// The state of the ith gear, if we know it.  This is not its current position,
+// but rather the position corresponding to selector gear 0!  Only meaningful
+// in state 2; set from photoresistor_history when we transition there.
 // Type is 0, 1, 2, in order of the correct solution.
 // Orientation is 0 in the correct solution, 1 if we are one step clockwise
 // from it, and so on.
@@ -150,17 +153,41 @@
       {
         state = 2;
         // This fills in gear_types and gear_orientations.
-        if (!computeGearPositions())
+        // We check that it passes each time, and that
+        // we see one of each gear type.
+        int failed = false;
+        int types_seen = 0;
+        for (int i=0; i<3; i++)
         {
-          // Or should we say you failed calibration?
+          if (!computeGearPositions(i))
+          {
+            failed = true;
+          }
+          else
+          {
+            types_seen |= 1 << gear_types[i]
+          }
+        }
+
+        if (types_seen != 7)
+        {
+          failed = true;
+        }
+
+
+        if (failed)
+        {
+          // Or should we say you failed calibration, not an error?
           sendCastleErrorMessage();
           state = 0;
           resetLights();
         }
-
-        for (int i=0; i<7; i++)
+        else
         {
-          correct_positions[i] = false;
+          for (int i=0; i<7; i++)
+          {
+            correct_positions[i] = false;
+          }
         }
       }
     }
@@ -216,12 +243,137 @@

 // LOGIC FOR GEAR STUFF

-// Takes in photoresistor_history, which must be filled in entirely, and sets
-// gear_orientations and gear_types.
-// Returns true for success, false if there was an issue.
-boolean computeGearPositions()
-{
-  // TODO(benkraft)
+// Reads photoresistor_history[i][], which must be filled in entirely, and sets
+// gear_types[i] and gear_orientations[i].
+// Returns true for success, false if there was an issue (in which case output
+// arrays may not be set).
+boolean computeGearPosition(int i)
+{
+  // Hold on tight; this is kinda bespoke and messy.
+  int positions_white = 0;
+  for (int j=0; j<7; j++)
+  {
+    positions_white += photoresistor_history[i][j]
+  }
+
+  // If we saw 2 white, they should be in 1, 4 or 2, 5, and that means we have
+  // gear 1, in positions 2 or 1 respectively.
+  if (positions_white == 2)
+  {
+    gear_types[i] = 1;
+    if (photoresistor_history[i][1] && photoresistor_history[i][4])
+    {
+      gear_orientations[i] = 2;
+      return true;
+    }
+    else if (photoresistor_history[i][2] && photoresistor_history[i][5])
+    {
+      gear_orientations[i] = 1;
+      return true;
+    }
+    else
+    {
+      return false;
+    }
+  }
+
+  // If we saw 3 white, they should be in 0, 3, 6, and that means we have gear
+  // 1, in position 0.
+  else if (positions_white == 3)
+  {
+    if (photoresistor_history[i][0] && photoresistor_history[i][3]
+        && photoresistor_history[i][6])
+    {
+      gear_types[i] = 1;
+      gear_orientations[i] = 0;
+      return true;
+    }
+    else
+    {
+      return false;
+    }
+  }
+
+  // If we saw 3 black, they should be in 0, 3, 6, and that means we have gear
+  // 0 in position 1.
+  else if (positions_white == 4)
+  {
+    if (!photoresistor_history[i][0] && !photoresistor_history[i][3]
+        && !photoresistor_history[i][6])
+    {
+      gear_types[i] = 0;
+      gear_orientations[i] = 1;
+      return true;
+    }
+    else
+    {
+      return false;
+    }
+  }
+
+  // If we saw 2 black, we could have them in 1, 4 or 2, 5, in which case we
+  // have gear 0 in positions 0 or 2 respectively; or they could be in 0, 4 or
+  // 1, 5 or 2, 6, in which case we have gear 2 in positions 2, 1, or 0
+  // respectively.
+  else if (positions_white == 5)
+  {
+    if (!photoresistor_history[i][1] && !photoresistor_history[i][4])
+    {
+      gear_types[i] = 0;
+      gear_orientations[i] = 0;
+      return true;
+    }
+    else if (!photoresistor_history[i][2] && !photoresistor_history[i][5])
+    {
+      gear_types[i] = 0;
+      gear_orientations[i] = 2;
+      return true;
+    }
+    else if (!photoresistor_history[i][0] && !photoresistor_history[i][4])
+    {
+      gear_types[i] = 2;
+      gear_orientations[i] = 2;
+      return true;
+    }
+    else if (!photoresistor_history[i][1] && !photoresistor_history[i][5])
+    {
+      gear_types[i] = 2;
+      gear_orientations[i] = 1;
+      return true;
+    }
+    else if (!photoresistor_history[i][2] && !photoresistor_history[i][6])
+    {
+      gear_types[i] = 2;
+      gear_orientations[i] = 0;
+      return true;
+    }
+    else
+    {
+      return false;
+    }
+  }
+
+  // If we saw 1 black, it should be in 3, and we have gear 2 in position 3.
+  else if (positions_white == 6)
+  {
+    if (!photoresistor_history[i][3])
+    {
+      gear_types[i] = 2;
+      gear_orientations[i] = 3;
+      return true;
+
+    }
+    else
+    {
+      return false;
+    }
+  }
+
+  // Otherwise, something is wrong.
+  else
+  {
+    return false;
+  }
 }

 // True if positions pos1 and pos2 are connected on gear_num.
@@ -354,6 +506,7 @@
   // TODO(bhomberg): close all solenoids (??)
 }

+// Tell the user they have won!
 void sendCastleSuccessMessage()
 {
   // 20's -- 2nd puzzle message
@@ -361,6 +514,8 @@
   Serial.println(20);
 }

+// Tell the user something has gone horribly wrong.
+// Caller likely wants to reset internal state here.
 void sendCastleErrorMessage()
 {
   // TODO(benkraft): May or may not need to wait a tick to be sure here.


subscribe from chatroom

subscribe from chatroom

--- src/neurite.ino
+++ src/neurite.ino
@@ -1065,8 +1065,8 @@
 			}

 			nd->mqtt_connected = true;
-			//mqtt_cli.subscribe(nd->cfg.topic_from);
-			//log_info("subscribe: %s\n\r", nd->cfg.topic_from);
+			mqtt_cli.subscribe(nd->cfg.topic_from);
+			log_info("subscribe: %s\n\r", nd->cfg.topic_from);
 			mqtt_cli.subscribe(nd->topic_private);
 			log_info("subscribe: %s\n\r", nd->topic_private);
 			char payload_buf[32];


Ajusting script

Ajusting script

--- pug.ino
+++ pug.ino
@@ -211,7 +211,7 @@
   delay(START_TIMER);

   // Forward
-  goForward(30, 850);
+  goForward(30, 900);

   // Break!
   goBackward(1);


Added license to the header of water-sensor.ino

--- water-sensor.ino
+++ water-sensor.ino
@@ -1,3 +1,27 @@
+/*
+The MIT License (MIT)
+
+Copyright (c) 2015 DEV Tecnologia, Rede Infoamazônia
+
+Permission is hereby granted, free of charge, to any person obtaining a copy
+of this software and associated documentation files (the "Software"), to deal
+in the Software without restriction, including without limitation the rights
+to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
+copies of the Software, and to permit persons to whom the Software is
+furnished to do so, subject to the following conditions:
+
+The above copyright notice and this permission notice shall be included in all
+copies or substantial portions of the Software.
+
+THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
+AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
+LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
+OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
+SOFTWARE.
+*/
+
 #include <SoftwareSerial.h>
 #include "Adafruit_FONA.h"
 #include <Wire.h> //I2C needed for sensors


Increase serial port speed from 9600 to 115200 (logging one frame at 9600 bps takes about 15 ms)

--- zg01/zg01.ino
+++ zg01/zg01.ino
@@ -24,7 +24,7 @@
     pinMode(PIN_DATA, INPUT);

     // initialize serial port
-    Serial.begin(9600);
+    Serial.begin(115200);
     Serial.println("Hello world!\n");

     // initialize ZG01 finite state machine


(unticketed) adding humidity sensor

(unticketed) adding humidity sensor

--- device_src/pull_alarm/pull_alarm.ino
+++ device_src/pull_alarm/pull_alarm.ino
@@ -107,8 +107,8 @@
         digitalWrite(RED_PIN,LOW);
     }
     else{
-        digitalWrite(GREEN_PIN,HIGH);
-        digitalWrite(RED_PIN,LOW);
+        digitalWrite(GREEN_PIN,LOW);
+        digitalWrite(RED_PIN,HIGH);
     }

   }


Fixed a bug in the setSSid function.

Fixed a bug in the setSSid function.

--- BackEnd/BackEnd.ino
+++ BackEnd/BackEnd.ino
@@ -1148,13 +1148,17 @@
 ///////////////////////////////
 void procSsidMsg( aJsonObject *_pJsonSsid )
 {
-  aJsonObject *poSsid = aJson.getObjectItem(_pJsonSsid, "ssid");
-  if ( poSsid && String(poSsid->valuestring).length() <= SSID_MAX_LENGTH )
-  {
-    if( strcmp(g_sSsid, poSsid->valuestring) )
-    {
-      sprintf(g_sSsid, "%s", poSsid->valuestring);
-      setSsidName(poSsid->valuestring);
+ // aJsonObject *poSsid = aJson.getObjectItem(_pJsonSsid, "ssid");
+ // Serial.println("HERE");
+ // Serial.print("here SSID size: ");Serial.println(String(_pJsonSsid->valuestring).length());
+  if ( String(_pJsonSsid->valuestring).length() <= SSID_MAX_LENGTH )
+  {
+   //  Serial.print("SSID size: ");Serial.println(String(_pJsonSsid->valuestring).length());
+    if( strcmp(g_sSsid, _pJsonSsid->valuestring) )
+    {
+     //     Serial.print("SSID: ");Serial.println(_pJsonSsid->valuestring);
+      sprintf(g_sSsid, "%s", _pJsonSsid->valuestring);
+      setSsidName(_pJsonSsid->valuestring);
     }
   }
  }
@@ -1396,7 +1400,7 @@
       int iSsidLen = strlen(Line)-strlen(Find);
       // Truncate Ssid if it too long
       int n = iSsidLen < SSID_MAX_LENGTH ? iSsidLen : SSID_MAX_LENGTH;
-      strncpy(_sSsidName, SubStr+strlen(Find), n);
+      strncpy(_sSsidName, SubStr+strlen(Find), n-1);
     }
   }

@@ -1473,7 +1477,7 @@
     // Test code
     ///////////////////////////////////////

-    getSerialCommand();
+ //   getSerialCommand();

 /*
     g_iCatNumber++;