Update firmware.ino

Update firmware.ino

Added cleaning servos function to avoid problems with servos on startup.
Added last rotation of 90 degrees to keep the servos on the zero position when are detached.

--- firmware/firmware.ino
+++ firmware/firmware.ino
@@ -87,6 +87,17 @@

  Serial.begin(57600);
  setupSerialCommands();
+ Serial.println("Cleaning servos, wait..");
+
+ for (int i=0; i<32; i++){
+   pinMode(servoPINS[i],OUTPUT);
+   servoarray[i].attach(servoPINS[i]);
+   Serial.println(servoarray[i].read());
+   servoarray[i].write(90);
+   delay(ROTATION_DELAY);
+   servoarray[i].detach();
+ }
+
  Serial.println("Ready.");

  pinMode(LED, OUTPUT);
@@ -230,9 +241,11 @@
     servoarray[channel-1].attach(servoPINS[channel-1]);
     for( int s = 0; s < SHAKE; s++)
     {
-      servoarray[channel-1].write(0);
+      servoarray[channel-1].write(2);
       delay(ROTATION_DELAY);
-      servoarray[channel-1].write(180);
+      servoarray[channel-1].write(178);
+      delay(ROTATION_DELAY);
+      servoarray[channel-1].write(90);
       delay(ROTATION_DELAY);
     }
     servoarray[channel-1].detach();
@@ -277,12 +290,16 @@
   for( int s = 0; s < SHAKE; s++)
   {
     for (int i = 0; i<GROUP_SIZE; i++) {
-      servoarray[bat[i]-1].write(0);
+      servoarray[bat[i]-1].write(2);
     }
     delay(ROTATION_DELAY);

     for (int i = 0; i<GROUP_SIZE; i++) {
-      servoarray[bat[i]-1].write(180);
+      servoarray[bat[i]-1].write(178);
+    }
+    delay(ROTATION_DELAY);
+    for (int i = 0; i<GROUP_SIZE; i++) {
+      servoarray[bat[i]-1].write(90);
     }
     delay(ROTATION_DELAY);
   }


Update arduino sketch to include all four encoders with normal pin assignments

--- arduino/arduino_nano328_node/arduino_nano328_node.ino
+++ arduino/arduino_nano328_node/arduino_nano328_node.ino
@@ -57,10 +57,10 @@
     void calcSteering();
   private:
     // Pin assignments
-    /* const int ENC_FR_PIN = X; */
     const int ENC_FL_PIN = 2;
-    const int ENC_BR_PIN = 3;
+    const int ENC_FR_PIN = 3;
     const int ENC_BL_PIN = 5;
+    const int ENC_BR_PIN = 6;
     const int THROTTLE_PIN = 7;
     const int STEERING_PIN = 8;
     const int MOTOR_PIN = 10;
@@ -275,11 +275,11 @@
 }

 void Car::initEncoders() {
-  /* pinMode(ENC_FR_PIN, INPUT_PULLUP); */
+  pinMode(ENC_FR_PIN, INPUT_PULLUP);
   pinMode(ENC_FL_PIN, INPUT_PULLUP);
   pinMode(ENC_BR_PIN, INPUT_PULLUP);
   pinMode(ENC_BL_PIN, INPUT_PULLUP);
-  /* enableInterrupt(ENC_FR_PIN, incFRCallback, CHANGE); */
+  enableInterrupt(ENC_FR_PIN, incFRCallback, CHANGE);
   enableInterrupt(ENC_FL_PIN, incFLCallback, CHANGE);
   enableInterrupt(ENC_BR_PIN, incBRCallback, CHANGE);
   enableInterrupt(ENC_BL_PIN, incBLCallback, CHANGE);


added insertTile()

added insertTile()

--- colors_arduino/colors_arduino.ino
+++ colors_arduino/colors_arduino.ino
@@ -19,6 +19,7 @@
 int board[4][4];
 int tempBoard[4][4];
 boolean gameInProgress = false;
+boolean gameResult = false;
 boolean buttonPressed = false;

 // Pins for inputs (push buttons)
@@ -28,9 +29,9 @@
 const int LEFT_PIN = A3;

 // Pins for outputs (shift registers / LEDs)
-const int LATCH_PIN = 8; // green
-const int CLOCK_PIN = 12; // yellow
-const int DATA_PIN = 11; // blue
+const int LATCH_PIN = 8; // Green wire
+const int CLOCK_PIN = 12; // Yellow wire
+const int DATA_PIN = 11; // Blue wire

 /* Initializes all connections and creates a new game. */
 void setup() {
@@ -47,7 +48,7 @@
     pinMode(CLOCK_PIN, OUTPUT);
     pinMode(DATA_PIN, OUTPUT);

-    // Seed the PRNG with the read from an unconnected pin
+    // Seed the PRNG with the reading from an unconnected pin
     randomSeed(analogRead(A4));

     // Begin game
@@ -58,6 +59,7 @@
 void loop() {
     // Make sure we have a game going on
     if (!gameInProgress) {
+        gameResult ? wonGame() : lostGame();
         return;
     }

@@ -199,12 +201,71 @@
         return false;
     }

-    // TODO ~ Insert new tile
+    // Add a new tile
+    insertTile();

     return true;
 }

-/* Checks whether the game is still winnable. Calls lostGame() if not. */
+/* Returns whether tile at (i, j) can be moved to (i2, j2).
+ * Updates |tempBoard| if a move is possible. */
+boolean attemptTileMove(int i, int j, int i2, int j2) {
+    // No tile in the original space
+    if (tempBoard[i][j] == 0) {
+        return false;
+    }
+
+    // No tile in the new space
+    if (tempBoard[i2][j2] == 0) {
+        tempBoard[i2][j2] = tempBoard[i][j];
+        tempBoard[i][j] = 0;
+        return true;
+    }
+
+    // Identical tiles, collapse them into the new location
+    if (tempBoard[i][j] == tempBoard[i2][j2]) {
+        tempBoard[i][j] = 0;
+        tempBoard[i2][j2]++;
+
+        // They won!
+        if (tempBoard[i2][j2] == 6) {
+            gameInProgress = false;
+            gameResult = true;
+        }
+
+        return true;
+    }
+
+    return false;
+}
+
+/* Inserts a tile into |tempBoard|. */
+void insertTile() {
+    // Keep track of empty locations
+    int numEmpty = 0;
+    int locations[16];
+    memset(locations, 0, sizeof(locations));
+
+    // Find empty locations
+    for (int i = 0; i <= 3; i++) {
+        for (int j = 0; j <= 3; j++) {
+            if (tempBoard[i][j] == 0) {
+                locations[numEmpty] = (i * 4) + j;
+                numEmpty++;
+            }
+        }
+    }
+
+    // Choose a random empty location to insert a tile
+    int insertLocation = random(0, numEmpty);
+    int i = insertLocation / 4;
+    int j = insertLocation % 4;
+    tempBoard[i][j] = randomTile();
+
+    return;
+}
+
+/* Checks whether the game is still playable. */
 void checkLost() {
     for (int i = 0; i < 4; i++) {
         if (attemptMove(i)) {
@@ -214,13 +275,14 @@

     // Whoops, we lost the game
     gameInProgress = false;
-    Serial.println("L");
+    gameResult = false;
 }

 /****************************************
  ********** DISPLAY  METHODS ************
  ****************************************/

+// (off, red, red-green, green, green-blue, blue, red-blue, white)
 byte colors[8] = {7, 6, 4, 5, 1, 3, 2, 0};

 byte color(int tileNum) {
@@ -274,12 +336,28 @@

 /* Prints board to serial. For debugging. */
 void printBoard() {
-    for (int i = 0; i < 4; i++) {
-        for (int j = 0; j < 4; j++) {
+    for (int i = 0; i <= 3; i++) {
+        for (int j = 0; j <= 3; j++) {
             Serial.print(board[i][j]);
         }
         Serial.println("");
     }
+ }
+
+ void wonGame() {
+    Serial.println("W");
+
+    // TODO ~ Show that they won (woohoo!)
+
+    return;
+ }
+
+ void lostGame() {
+    Serial.println("L");
+
+    // TODO ~ Show that they lost (womp womp)
+
+    return;
  }

 /****************************************
@@ -289,42 +367,9 @@
 /* Randomly returns either 1 or 2. */
 int randomTile() {
     return random(1, 3);
-
 }

 /* Randomly returns the index of a row or column. */
 int randomIndex() {
     return random(0, 4);
-}
-
-/* Returns whether tile at (i, j) can be moved to (i2, j2).
- * Updates |tempBoard| if a move is possible. */
-boolean attemptTileMove(int i, int j, int i2, int j2) {
-    // No tile in the original space
-    if (tempBoard[i][j] == 0) {
-        return false;
-    }
-
-    // No tile in the new space
-    if (tempBoard[i2][j2] == 0) {
-        tempBoard[i2][j2] = tempBoard[i][j];
-        tempBoard[i][j] = 0;
-        return true;
-    }
-
-    // Identical tiles, collapse them into the new location
-    if (tempBoard[i][j] == tempBoard[i2][j2]) {
-        tempBoard[i][j] = 0;
-        tempBoard[i2][j2]++;
-
-        // They won!
-        if (tempBoard[i2][j2] == 6) {
-            gameInProgress = false;
-            Serial.println("W");
-        }
-
-        return true;
-    }
-
-    return false;
 }


lcd.print

lcd.print


Added simple Button dimmer example

Added simple Button dimmer example

* Uses Button lib: https://github.com/virgildisgr4ce/Button
* Press dims by 25% until dark
* Hold (1s) resets to 100% brightness

--- examples/WearButton/WearButton.ino
+++ examples/WearButton/WearButton.ino
@@ -1,3 +1,4 @@
+#include <Button.h>
 #include <Adafruit_NeoPixel.h>

 #define LED_COUNT 60
@@ -8,6 +9,21 @@
 uint8_t pixel_index;

 long last_time;
+
+Button button = Button(13, BUTTON_PULLUP_INTERNAL, true, 50);
+
+float brightness = 1.0;
+
+void onPress(Button& b){
+  brightness = brightness - 0.25;
+  if(brightness < 0) brightness = 0;
+  Serial.println("Btn pressed");
+}
+
+void onHold(Button& b){
+  brightness = 1.0;
+  Serial.println("Btn held");
+}

 void setup()
 {
@@ -20,8 +36,10 @@
   strip.begin();
   strip.show();
   last_time = millis();
+
+  button.pressHandler(onPress);
+  button.holdHandler(onHold, 1000); // must be held for at least 1000 ms to trigger
 }
-

 uint8_t i = 0;
@@ -32,8 +50,6 @@
 int count;

 void color_loop() {
-  float brightness = random(100,100)/100.0;
-
   for (uint8_t i = 0; i < LED_COUNT; i++) {
     uint8_t red =   64*(1+sin(i/2.0 + j/4.0       ))*brightness;
     uint8_t green = 64*(1+sin(i/1.0 + f/9.0  + 2.1))*brightness;
@@ -101,6 +117,7 @@
   }

   color_loop();
+  button.process();
 }


updated intro comment

updated intro comment

--- examples/androidCar/androidCar.ino
+++ examples/androidCar/androidCar.ino
@@ -1,4 +1,5 @@
-/* The running sketch on the Android Autonomous Vehicle by Team Pegasus
+/* The running arduino sketch on the Android Autonomous Vehicle by Team Pegasus
+* Description: The vehicle is based on an Arduino Mega, that is connected to various sensors (infrared, ultrasound, speed encoder, gyroscope and 9DOF IMU) and receives driving instructions from an Android phone, via Bluetooth, that is attached on the top of the vehicle. The vehicle can follow street lanes, park and overtake obstacles, using image processing on the Android phone.
 *  Author: Dimitris Platis
 */
 #include <AndroidCar.h>


add fuse settings for frankenmeter

add fuse settings for frankenmeter

--- examples/attiny84/frankenmeter.ino
+++ examples/attiny84/frankenmeter.ino
@@ -1,5 +1,6 @@
 /*
  * Set IDE to "ATtiny84@1MHz, BOD disabled"
+ * fuses: H:FF, E:DF, L:62
  * (Can program with Arduino as ISP using one of these:
  * http://programmablehardware.blogspot.ie/2011/05/in-system-programming.html )
  */


Fix incorrect comment in toneMultiple example

The comment about the note duration didn't match the code.

--- build/shared/examples/02.Digital/toneMultiple/toneMultiple.ino
+++ build/shared/examples/02.Digital/toneMultiple/toneMultiple.ino
@@ -34,7 +34,7 @@

   // turn off tone function for pin 7:
   noTone(7);
-  // play a note on pin 8 for 500 ms:
+  // play a note on pin 8 for 300 ms:
   tone(8, 523, 300);
   delay(300);
 }


put all includes in .ino file, so the gui can compile it

--- firmware/Nanpy.ino
+++ firmware/Nanpy.ino
@@ -1,3 +1,11 @@
+#include <EEPROM.h>
+#include <Servo.h>
+#include <LiquidCrystal.h>
+#include <Stepper.h>
+#include <OneWire.h>
+#include <DallasTemperature.h>
+#include <CapacitiveSensor.h>
+
 #include "BaseClass.h"
 #include "ArduinoClass.h"
 #include "OneWireClass.h"
@@ -17,7 +25,7 @@

 void setup() {

-    REGISTER_CLASS(EEPROMClass);
+    REGISTER_CLASS(nanpy::EEPROMClass);
     REGISTER_CLASS(ArduinoClass);
     REGISTER_CLASS(LiquidCrystalClass);
     REGISTER_CLASS(OneWireClass);


Simple way to add a new sensor.

Simple way to add a new sensor.

--- arduino/sensor/sensor.ino
+++ arduino/sensor/sensor.ino
@@ -1,34 +1,43 @@
-int sensorId = 1;//Modify the id here
-int sensorValue = 0;
-int lastValue = 0;
+//Sensor 1
+const int idSensor1 = 1;
+const int pinSensor1 = A0;
+int lastValueSensor1 = 0;
+
+//Sensor 2
+const int idSensor2 = 2;
+const int pinSensor2 = A1;
+int lastValueSensor2 = 0;
+
 long waitingTime = 2000;//Time to wait between each reading
-unsigned long lastSending = 0;//Time when last sending occured
-long maxTime = 600000;//10 minutes max between each sending (milliseconds)
-long timePassed = 0;
-const int sensor = A0;

-void sendFrame(int numArduino, int numPin, long value);
+void sendFrame(int numArduino, long value);
+int readSendSensor(const int sensorId, const int pin, int lastValue);

 void setup() {
-  // initialize the digital pin as an output.
-  pinMode(sensor, INPUT);
+  pinMode(pinSensor1, INPUT);
+  pinMode(pinSensor2, INPUT);
   Serial.begin(9600);
 }

 void loop() {
-  //Read sensor value
-  sensorValue = analogRead(sensor);
+  lastValueSensor1 = readSendSensor(idSensor1, pinSensor1, lastValueSensor1);
+  lastValueSensor2 = readSendSensor(idSensor2, pinSensor2, lastValueSensor2);
+  delay(waitingTime);
+}
+
+//Read the value and send over serial
+int readSendSensor(const int sensorId, const int pin, int lastValue) {
+  int sensorValue = 0;
+
+  sensorValue = analogRead(pin);
   sensorValue = map(sensorValue, 0, 1023, 0, 255);
-  timePassed = millis() - lastSending;
-  //May occured when millis() will overflow, after approximately 50 days
-  timePassed = timePassed >= 0 ? timePassed : -timePassed;

-  if(sensorValue != lastValue || timePassed > maxTime) {
+  //Check if value has changed
+  if(sensorValue != lastValue) {
     sendFrame(sensorId, sensorValue);
-    lastValue = sensorValue;
-    lastSending = millis();
   }
-  delay(waitingTime);
+
+  return sensorValue;
 }

 void sendFrame(int numArduino, long value){


SGANT driven by small geared steppers

SGANT driven by small geared steppers

--- Arduino/SGANT_Steppers/SGANT_Steppers.ino
+++ Arduino/SGANT_Steppers/SGANT_Steppers.ino
@@ -2,9 +2,9 @@
 // Stepper library info: https://www.airspayce.com/mikem/arduino/AccelStepper/classAccelStepper.html

 /*
-Spec sheet notes:
-Speed Variation Ratio: 1/64
-Stride Angle:   5.625° /64
+  Spec sheet notes:
+  Speed Variation Ratio: 1/64
+  Stride Angle:   5.625° /64
 */

 /*
@@ -41,15 +41,15 @@
 String test;
 boolean AOS = false;

-double deg2StepperCounts=64/5.6; // To move 1 deg on output shaft, command 64/5.6 stepper counts.
+double deg2StepperCounts = 64 / 5.6; // To move 1 deg on output shaft, command 64/5.6 stepper counts.

-double SGANT_El_deg = -180; // SGANT antenna elevation angle, deg; From telemetry stream
-double SGANT_xEl_deg = 180; // SGANT "cross elevation" angle, deg; From telemetry stream
-double SGANT_Elev_PosCountsTarget =0;// -1*SGANT_El_deg*deg2StepperCounts;
+double SGANT_El_deg = -30; // SGANT antenna elevation angle, deg; From telemetry stream
+double SGANT_xEl_deg = 30; // SGANT "cross elevation" angle, deg; From telemetry stream
+double SGANT_Elev_PosCountsTarget = 0; // -1*SGANT_El_deg*deg2StepperCounts;
 double SGANT_xElev_PosCountsTarget = 0;//-1*SGANT_xEl_deg*deg2StepperCounts;

-int PosErrCount1=0;
-int PosErrCount2=0;
+int PosErrCount1 = 0;
+int PosErrCount2 = 0;

 #include <AccelStepper.h>
 #define HALFSTEP 8
@@ -69,69 +69,80 @@

 // Notice, I'm passing them as StepA1, StepC1, StepB1, StepD1 (coil ends order) not
 // StepA1, StepB1, StepC1, StepD1 (firing order).
-AccelStepper stepper1(HALFSTEP, StepA1, StepC1, StepB1, StepD1);
-AccelStepper stepper2(HALFSTEP, StepA2, StepC2, StepB2, StepD2);
+//AccelStepper stepper1(HALFSTEP, StepA1, StepC1, StepB1, StepD1);
+//AccelStepper stepper2(HALFSTEP, StepA2, StepC2, StepB2, StepD2);
+
+AccelStepper stepper1(FULLSTEP, StepA1, StepC1, StepB1, StepD1);
+AccelStepper stepper2(FULLSTEP, StepA2, StepC2, StepB2, StepD2);

 void setup() {
-  Serial.begin(115200);
+  Serial.begin(9600);
   //Serial3.begin(115200);          //Serial1 is connected to the RasPi
   Serial.setTimeout(50);

-//  //Set the initial speed (read the AccelStepper docs on what "speed" means
-////  stepper1.setSpeed(100.0);
-//  //Tell it how fast to accelerate
-stepper1.setAcceleration(100.0);
-//  //Set a maximum speed it should exceed
-stepper1.setMaxSpeed(4000.0);
-//  //Tell it to move to the target position
-//
-//
-//// Now for stepper2, for CrossElevation stepper
-stepper2.setAcceleration(100.0);
-stepper2.setSpeed(100.0);
-//  //Tell it how fast to accelerate
-//  stepper2.setAcceleration(100.0);
-//  //Set a maximum speed it should exceed
-stepper2.setMaxSpeed(4000.0);
-//  //Tell it to move to the target position
+  //  //Set the initial speed (read the AccelStepper docs on what "speed" means
+  ////  stepper1.setSpeed(100.0);
+  //  //Tell it how fast to accelerate
+  stepper1.setAcceleration(100.0);
+  //  //Set a maximum speed it should exceed
+  stepper1.setMaxSpeed(4000.0);
+  //  //Tell it to move to the target position
+  //
+  //
+  //// Now for stepper2, for CrossElevation stepper
+  stepper2.setAcceleration(100.0);
+  stepper2.setSpeed(100.0);
+  //  //Tell it how fast to accelerate
+  //  stepper2.setAcceleration(100.0);
+  //  //Set a maximum speed it should exceed
+  stepper2.setMaxSpeed(4000.0);
+  //  //Tell it to move to the target position

-//setPinsInverted (bool directionInvert=false, bool stepInvert=false, bool enableInvert=false)
-//stepper1.setPinsInverted(true,false,false); // Flips the sign, so our steppers move positive dir for pos cmd
-//stepper2.setPinsInverted(true,false,false); // Flips the sign, so our steppers move positive dir for pos cmd
+  //setPinsInverted (bool directionInvert=false, bool stepInvert=false, bool enableInvert=false)
+  //stepper1.setPinsInverted(true,false,false); // Flips the sign, so our steppers move positive dir for pos cmd
+  //stepper2.setPinsInverted(true,false,false); // Flips the sign, so our steppers move positive dir for pos cmd

 }

 void loop() {

-  SGANT_Elev_PosCountsTarget = -1*SGANT_El_deg*deg2StepperCounts;
-  SGANT_xElev_PosCountsTarget = -1*SGANT_xEl_deg*deg2StepperCounts;
-  stepper1.moveTo(SGANT_Elev_PosCountsTarget);
-  stepper2.moveTo(SGANT_xElev_PosCountsTarget);
+  if (Serial.available())
+  {
+    checkSerial();
+  }

-  stepper1.run();
-  stepper2.run();
+SGANT_Elev_PosCountsTarget = -1 * SGANT_El_deg * deg2StepperCounts;
+SGANT_xElev_PosCountsTarget = -1 * SGANT_xEl_deg * deg2StepperCounts;
+stepper1.moveTo(SGANT_Elev_PosCountsTarget);
+stepper2.moveTo(SGANT_xElev_PosCountsTarget);

- //--------------------------------------------------------
+stepper1.run();
+stepper2.run();

-  Serial.print(SGANT_El_deg );
-  Serial.print(",");
-  Serial.print(stepper1.targetPosition() );
-  Serial.print(",");
-  Serial.print(stepper1.currentPosition());
-  Serial.print(",");
-  Serial.print(stepper1.speed() );
-  Serial.print("  |  ");
-
-  Serial.print(SGANT_xEl_deg );
-  Serial.print(",");
-  Serial.print(stepper2.targetPosition() );
-  Serial.print(",");
-  Serial.print(stepper2.currentPosition());
-  Serial.print(",");
-  Serial.print(stepper2.speed() );
-
-  Serial.println("");
+delay(15);
+
+
+////--------------------------------------------------------
+//
+Serial.print(SGANT_El_deg );
+Serial.print(",");
+Serial.print(stepper1.targetPosition() );
+Serial.print(",");
+Serial.print(stepper1.currentPosition());
+Serial.print(",");
+Serial.print(stepper1.speed() );
+Serial.print("  |  ");
+
+Serial.print(SGANT_xEl_deg );
+Serial.print(",");
+Serial.print(stepper2.targetPosition() );
+Serial.print(",");
+Serial.print(stepper2.currentPosition());
+Serial.print(",");
+Serial.print(stepper2.speed() );
+
+Serial.println("");

 }


Swapped struct for typedef in for loop

Swapped struct for typedef in for loop

--- examples/PICooTest/PICooTest.ino
+++ examples/PICooTest/PICooTest.ino
@@ -33,7 +33,7 @@
 	    printf("\e[0;0H");
 	    printf("Uptime: %lums\n", Thread::Milliseconds());
 	    printf("Entry    Thread     Stack %%CPU S A\n");
-	    for (struct TCB *scan = ThreadList; scan; scan = scan->next) {
+	    for (thread scan = ThreadList; scan; scan = scan->next) {
 	        printf("%08X %-10s %-4d %4d%% %c %c\n",
 	            scan->entry,
 	            scan->name, (scan->stack_head - scan->sp) * 4,


RF working and display showing distance

RF working and display showing distance

--- arduino/v2/v2.ino
+++ arduino/v2/v2.ino
@@ -29,7 +29,7 @@

 int count = 0;
-String inputString = "";         // a string to hold incoming data
+
 boolean stringComplete = false;  // whether the string is complete

 // XBee's DOUT (TX) is connected to pin 2 (Arduino's Software RX)
@@ -39,7 +39,7 @@
 // The setup() method runs once, when the sketch starts
 void setup()   {
   Serial.begin(9600);
-  // Serial.println(freeRam());
+  Serial.println(freeRam());
   XBee.begin(9600);

   // turn on backlight
@@ -74,35 +74,38 @@
 {
    if (XBee.available())
     { // If data comes in from XBee, send it out to serial monitor
-
     // get the new byte:
+    String inputString1 = "";         // a string to hold incoming data
     char inChar = (char)XBee.read();
     // add it to the inputString:
-    inputString += inChar;
+    inputString1 += inChar;
     while (inChar != ',')
     {
       inChar = (char)XBee.read();
       // add it to the inputString:
-      inputString += inChar;
+      inputString1 += inChar;
     }
-    char floatbuf[32];
-    inputString.toCharArray(floatbuf, sizeof(floatbuf));
-    angle = atof(floatbuf);
+    char floatbuf1[32];
+    inputString1.toCharArray(floatbuf1, 32*sizeof(char));
+    angle = atof(floatbuf1);

-    inputString = "";
+
+
+    String inputString2 = "";         // a string to hold incoming data
     // get the new byte:
     inChar = (char)XBee.read();
     // add it to the inputString:
-    inputString += inChar;
+    inputString2 += inChar;
     while (inChar != '\n')
     {
       inChar = (char)XBee.read();
       // add it to the inputString:
-      inputString += inChar;
+      inputString2 += inChar;
     }

-    inputString.toCharArray(floatbuf, sizeof(floatbuf));
-    distance = atof(floatbuf);
+    char floatbuf2[32];
+    inputString2.toCharArray(floatbuf2, 32*sizeof(char));
+    distance = atof(floatbuf2);

       Serial.print("angle:");
       Serial.println(angle);
@@ -166,6 +169,11 @@
   glcd.drawline(topy, topx, lefty, leftx, BLACK);
   glcd.drawline(topy, topx, righty, rightx, BLACK);
   //glcd.drawline(altitude,32,29,35, BLACK);
+
+  char outstr[15];
+  dtostrf(distance,7, 3, outstr);
+  glcd.drawstring(altitude, 5, outstr);
+
   glcd.display();
 }


Da hardware update (#48)

Da hardware update (#48)

* hardware update

done did some fixes

* Hardware updated to communicate with Server

* Updated code with optimizations

--- hardware/SPOTS.ino
+++ hardware/SPOTS.ino
@@ -12,16 +12,12 @@

 #include <ESP8266WiFi.h>
 #include <SPI.h>
-#include <MFRC522.h>      // Library Downloaded from: https://github.com/miguelbalboa/rfid
-#include "RestClient.h"   // Library Downloaded from: https://github.com/DaKaZ/esp8266-restclient
-
-#define apiKey  "1234"    //  Key for interacting with server
-#define lotID  "NV"    //  The hardware's current lotID, must be changed for each post...
-#define spotID  "NV010"  //  The lot number the hardware is set up at, must be changed for each post...
+#include <MFRC522.h>        // Library Downloaded from: https://github.com/miguelbalboa/rfid
+#include "RestClient.h"   // Library Downloaded from: https://github.com/DaKaZ/esp8266-restclient

 // These two fields must be changed if a different access point is used.
-#define weefee_ID       "stuff"
-#define weefee_Password "stuffy"
+#define weefee_ID       "ChangeME"
+#define weefee_Password "ChangeMETOO"

 #define Green_Led   15
 #define Red_Led     0
@@ -33,51 +29,47 @@

 MFRC522 mfrc522(SELECTOR_PIN, RESET_PIN);
 MFRC522::MIFARE_Key key;
+//////////////////

 unsigned int UID = 0;
 unsigned long start_time = 0;
-unsigned long current_time = 0;
 unsigned long timer = 0;
 unsigned int timeLimit = 20000;  // Time in milliseconds for sign in
-
-RestClient client = RestClient("6cb06ef3.ngrok.io");
-String response;
-String path;
-
-bool cardPresent = false;
-bool authorized = false;
-bool flag;
+unsigned int success = 0;
+unsigned int failure = 0;
+
+// URL for server communications must be added here
+RestClient client = RestClient("unlv-spots.herokuapp.com");
+
+bool vacancyFlag;
+bool authorized;

 // List of all the beautiful functions used for this immaculate device
 void Wifi_connect();    // Setup code to connect the ESP8266 to the wifi_chip
 void get_UID();         // Function to read the data UID from a card
 void flash_LED();
 bool readCard();        // Convenience Function to read a card
-bool cheatAuthorization();  // Cheat function for testing until API is done
 bool checkAuthorization();  // Check if the user is authorized
 String createPath(String);  // Creates the path for rest calls
-bool updateVacancy(bool);    // Update the server of a spot vacancy
+bool updateVacancy(String);    // Update the server of a spot vacancy

 void setup() {
-  pinMode(Sensor_Pin, INPUT);
-  pinMode(Green_Led, OUTPUT);
-  pinMode(Red_Led, OUTPUT);
   Serial.begin(9600);
   Wifi_connect();
-  SPI.begin();
-  // Setup the RFID sensor
-  mfrc522.PCD_Init();           // Initialize the MFRC522 (rfid card)
+  SPI.begin();
+  mfrc522.PCD_Init();
   // Prepare key - all keys are set to FFFFFFFFFFFFh at chip delivery from the factory.
   for (byte i = 0; i < 6; i++) {
     key.keyByte[i] = 0xFF;
   }
-
-  // Setup the pins for LED
+
   pinMode(Green_Led, OUTPUT);
   pinMode(Red_Led, OUTPUT);
   pinMode(Sensor_Pin, INPUT);
-  digitalWrite(Green_Led, HIGH);
-  digitalWrite(Red_Led, LOW);
+  Serial.println("Welcome to SPOTS!");
+  Serial.println("Setting the lot to vacant as part of boot sequence...");
+  updateVacancy("true"); // Set the vacancy of the spot to true at startup
+  Serial.println("Waiting for spot to become occupied...");
 }

 void loop() {
@@ -85,50 +77,38 @@
   timer = 0;
   digitalWrite(Green_Led, HIGH);
   digitalWrite(Red_Led, LOW);
+  start_time = millis();
+  vacancyFlag = false;
   authorized = false;
-  start_time = millis();
-  flag = false;

   while(!digitalRead(Sensor_Pin)){
-    flag = true;
-    Serial.print("Updating spot vacancy to false...");
-    Serial.println();
-    while(!updateVacancy(false)) {
-      delay(100); // Continuously attempt to update Vacancy if the call fails....
-      start_time = millis();
-    }
-    Serial.print("Pwease Scan an ID Card (^.^)\n");
+    while(millis() - start_time < 3000) { // Wait three seconds to ensure object is still present
+      delay(100);
+    }
+    if(digitalRead(Sensor_Pin)){
+      break;
+    }
+    digitalWrite(Red_Led, HIGH);
+    digitalWrite(Green_Led, LOW);
+    vacancyFlag = true;
+    Serial.println("Vehicle Detected: Updating spot vacancy to false.");
+    updateVacancy("false");
+    start_time = millis();
+
+    Serial.println("Please Scan an ID Card.");
     while( !digitalRead(Sensor_Pin) && readCard() && timer < timeLimit) {
       delay(50);
       timer = millis() - start_time;
-      if(timer > 3000){ // 3 seconds to turn on Red LED
-        digitalWrite(Red_Led, HIGH);
-        digitalWrite(Green_Led, LOW);
-      }
     }
     // If the object left exit the loop
     if(digitalRead(Sensor_Pin))
       break;
-
-    if(timer > 3000){ // 3 seconds to turn on Red LED
-        digitalWrite(Red_Led, HIGH);
-        digitalWrite(Green_Led, LOW);
-      }
+
     // If the user timed out
     if(timer > timeLimit) {
-      Serial.print("Uh Oh darling, you ran out of time =(\n");
-      // ****************************************************************
-      //  Just so it can easily be seen...
-      //  Update database of timeOut
-      // ****************************************************************
-      // Kind of an odd workaround...
-      // Logic here is that they either didn't scan a card... or took too long
-      // Thus we send an authorization request with a UID that is guaranteed to not
-      // be valid, this updates the server of an invalid parking at that spot...
-      // At least... that's my thought process...
-//      UID = 0;
-//      authorized = checkAuthorization();
-//    ****** Note.... I'm not even sure this is needed... I highly doubt it but eh...
+      Serial.print("User time has expired...\n");
+      Serial.println("Alerting parking enforcement of unauthorized vehicle.");
+      Serial.println("Please scan a card or leave the spot.");

       bool flash = true;
       while(!digitalRead(Sensor_Pin) && readCard())
@@ -137,53 +117,57 @@
         flash = !flash;
         delay(250);   // Delay 250ms
       }
-      // If the object left exit the loop
+      digitalWrite(Red_Led, HIGH);
+      // If the object, left exit the loop
       if(digitalRead(Sensor_Pin))
         break;
     }
     get_UID();
-    // ****************************************************************
-    //  Just so it can easily be seen...
-    // Send UID to database to see if card is authorized
-    // ****************************************************************
-
-    //authorized = checkAuthorization();
-    authorized = cheatAuthorization2();
-
-    if(authorized) {
-      Serial.print("Maaa!!!!! I did it!!! (Authorized user) \n");
+    authorized = checkAuthorization();
+
+    if(authorized == false)
+    {
+      bool flash = true;
+      while(authorized == false)
+      {
+        Serial.println("Please try scanning again or Please leave the spot.");
+        while(!digitalRead(Sensor_Pin) && readCard())
+        {
+          digitalWrite(Red_Led, flash);
+          flash = !flash;
+          delay(250);
+        }
+        digitalWrite(Red_Led, HIGH);
+        // If the object, left exit the loop
+        if(digitalRead(Sensor_Pin))
+          break;
+        get_UID();
+        authorized = checkAuthorization();
+//        delay(200);
+//        break;
+      }
+    }
+    if(authorized == true) {
       digitalWrite(Red_Led, LOW); // Shutoff Red LED for flashing sequence
       flash_LED(Green_Led, 2000); // Flash LED for 2 seconds
-      digitalWrite(Green_Led, LOW); // Shutoff Green LED
       digitalWrite(Red_Led, HIGH);  // Turn on RED LED to signal occupied
-      Serial.print("Time to wait for Michael to move his car...\n");
+      Serial.print("Waiting for user to move their vehicle...\n");
       while(!digitalRead(Sensor_Pin))
       {
         delay(500); // check the pin every 500ms to avoid WDT reset
-      }
-    }
-    else // If they are not authorized...
-    {
-      Serial.print("Don't tell Maaa!!!! (Unauthorized user) \n");
-      bool flash = true;
-      while(!digitalRead(Sensor_Pin))
-      {
-        digitalWrite(Red_Led, flash);
-        flash = !flash;
-        delay(250);
-      }
-    }
-  }
-  if(flag == true) {
-    Serial.print("Guess they left... (Object no longer detected)\n");
-    Serial.print("Updating spot vacancy to true...");
+      }
+//      delay(200);
+//      break;
+    }
+
+  }
+  if(vacancyFlag == true) {
+    Serial.println("User has left the spot. Updating spot vacancy.");
+    updateVacancy("true");
     Serial.println();
-    while(!updateVacancy(true)) {
-      delay(100);
-    }
-    delay(500);  // Delay for 1/2 Second
-  }
-  delay(250); // Check for card every 250ms to avoid WDT resets
+    Serial.println("Waiting for spot to become occupied...");
+  }
+  delay(100); // Check for card every 100ms to avoid WDT resets
 }

 ////////////////////////////////////////////////////////////////////////////////////////////////
@@ -198,14 +182,14 @@
   // Code to setup esp8266 to connect to zee weefee
   delay(100);
   WiFi.begin(weefee_ID, weefee_Password);
-  Serial.print("Connecting to ze network...");
+  Serial.print("Connecting to the wifi network...");
   while (WiFi.status() != WL_CONNECTED) {
-    //Serial.print(".");
     delay(500);
   }
   Serial.println();
-  Serial.print("connected: ");
-  Serial.println(WiFi.localIP());
+  Serial.println("connected. ");
+  //Serial.println(WiFi.localIP());
+  delay(2000);  // Wait 2 seconds to stabilize connection...
 }

 // Reads the Unique ID from the card and stores it as a 32-bit unsigned integer
@@ -215,13 +199,9 @@
     UID = UID << 8;
     UID = UID + mfrc522.uid.uidByte[i];
   }
-  // This information is printed to serial monitor for debug purposes
-  Serial.print("Saved UID (DEC): ");
-  Serial.print(UID, DEC);
-  Serial.println();
-  Serial.print("Saved UID (HEX): ");
-  Serial.print(UID, HEX);
-  Serial.println();
+  Serial.print("User has scanned a card with ID: ");
+  Serial.println(UID);
+  return;
 }

 // Flashes a designated LED for a specified duration, the LED will always remain
@@ -247,74 +227,30 @@
   return ( (!mfrc522.PICC_IsNewCardPresent() || !mfrc522.PICC_ReadCardSerial()) );
 }

-// Cheating test function that tests authorization of current card
-bool cheatAuthorization() {
-  if(UID == 0x647B403B)
-    return true;
-  else
-    return false;
-}
-
-bool cheatAuthorization2() {
-  Serial.print("Attempting to cheat Authorization...\n");
-  if(UID == 0x647B403B){
-    UID = 12345678; // This is a staff ID#
-    Serial.print("Authorization should be set to True\n");
-    return (checkAuthorization());
-  }
-  else {
-    Serial.print("Authorization should be set to False\n");
-    return false;
-  }
-}
-
-// Generates a path to be used for the post and get API commands
-// The command field should either be the string "swipe" or "update"
-// A string containing the path to be updated is returned...
-// Returned string looks like the following
-// "/command/key/lotID/spotID/"
-String createPath(String command)
-{
-  String tempPath;
-  String spotsHW = "/spotsHW";
-  tempPath =  spotsHW + '/' + command + '/' + apiKey + '/' + lotID + '/' + spotID + '/';
-//  Serial.print("Generated path: ");
-//  Serial.print(tempPath);
-//  Serial.println();
-//  delay(100);
-  return tempPath;
-}
-
 // Updates the vacancy of the spot with the server
 // If the spot is not occupied, set vacant = true;
 // else, set it to false
-bool updateVacancy(bool vacant)
-{
-  String updatePath = createPath("update");
+bool updateVacancy(String vacant)
+{
+  String updatePath = "/spotsHW/update/1234/LB/0013/";
   const char * c;
-  int statusCode;
-  response = "";
-
-  if(vacant) {
-    updatePath = updatePath + "true";
+  String response = "";
+  int statusCode = 0;
+
+  updatePath += vacant;
+  c = updatePath.c_str();
+  statusCode = client.post(c, "POSTDATA", &response);
+
+  if(statusCode == 200) {
+    success++;
   }
   else {
-    updatePath = updatePath + "false";
-  }
-
-  c = updatePath.c_str();
-  Serial.print("Generated path: ");
-  Serial.print(c);
-  Serial.println();
-  delay(10);
-  // This is done in this way because client.post requires a const char* for the path...
-  // client.post(const char* path, const char* body, String* response)
-  statusCode = client.post(c, "POSTDATA", &response);
-  Serial.print("Status code from server: ");
-  Serial.println(statusCode);
-  Serial.print("Response body from server: ");
-  Serial.println(response);
-  delay(10);
+    failure++;
+  }
+  Serial.print("Successful requests: ");
+  Serial.println(success);
+  Serial.print("Failed requests:");
+  Serial.println(failure);
   if(statusCode == 200) // Status Code 200 means "OK"
     return true;
   else
@@ -326,31 +262,41 @@
 // false otherwise.
 bool checkAuthorization()
 {
-  String swipePath = createPath("swipe");
+  Serial.print("Checking for authorization of cardID: ");
+  Serial.println(UID);
+  String swipePath = "/spotsHW/swipe/1234/LB/0013/";
   // UID is a global variable that contains the integer representation of the card ID
   String cardID = String(UID);
-  swipePath = swipePath + cardID;
+  swipePath += cardID;
   const char * c;
-  int statusCode;
+  int statusCode = 0;
   int len;
+  String response = "";

   c = swipePath.c_str();
-  Serial.print("swipePath: ");
-  Serial.print(c);
-  Serial.println();
-  statusCode = client.post(c, "POSTDATA", &response);
-  Serial.print("Status code from server: ");
-  Serial.println(statusCode);
-  Serial.print("Response body from server: ");
-  Serial.println(response);
-  delay(10);
+
+  statusCode = client.post(c, "POSTDATA", &response);
+
+  if(statusCode == 200) {
+    success++;
+  }
+  else {
+    failure++;
+  }
+  Serial.print("Successful server requests: ");
+  Serial.println(success);
+  Serial.print("Failed requests:");
+  Serial.println(failure);

   // Search the response string for "true" to see if user is authorized
   len = response.length();
   for(int i = 0; i <= len; i++) {
-    if(response.substring(i, i + 4) == "true")
+    if(response.substring(i, i + 4) == "true") {
+      Serial.print("User is authorized. \n");
       return true;
+    }
   }
   // if we can't find "true" in the response string, user is not authorized...
+  Serial.print("User is unauthorized. \n");
   return false;
 }


[feat] proceeded with bypass valve turn algorithm (kind of simplified pid).

--- heater_control.ino
+++ heater_control.ino
@@ -99,6 +99,22 @@
   int method;
 };

+struct bypassValve {
+  char *name;
+  struct ad *actualTemp;
+  time_t changed;
+  int up;
+  int dn;
+  float targetAd;
+  int timeMultiplier;
+  int latency;         // seconds, how long does it take after up, or down op the realise change in targetAd.
+  float hysteresis;
+  int minTurntime;     // milliseconds
+  int maxTurntime;     // milliseconds
+};
+
+
+

 struct variable variables[]= {
   {"boilTemp",      0,24.5},
@@ -119,6 +135,9 @@
   {5,"radiator",     0,0,     0,0.0, 0,0.3, 7,  21.0, 539,  36.5,  0,-273.0,  0,0.0}
 };

+struct bypassValve bypasses[]= {
+  {"heating",&adArr[3],0,30,31,20.0,1000,30,0.3,800,10000}
+};

 // counters are kept in array, this for preparing to have more of them.

@@ -311,7 +330,6 @@
   }
 }

-
 void evaluateCondition(struct ad *source,time_t ts)
 {
   float value;
@@ -356,40 +374,44 @@
 	// calculate target
 	iTable=(struct convert *) conditions[i].target;
 	conditions[i].limit2->value=resolveConversion(value,conditions[i].limit->value,iTable);
-
-	// action, what to do when target has changed
-        // this should be separate function with selectable operands
-	// now its hard coded to handle io pins 30 and 31 and to compare target
-        // temperature against radiator.
 	float radReq=conditions[i].limit2->value;
-	float radiator=adArr[3].measured.analog;
-	float diff=radReq-radiator;
-
-	if (radiator==-273) // in startup this is -273 = 0 kelvin.
-	  return;
-
-	Serial.print("requested radiator temp is ");
-	Serial.print(radReq);
-	Serial.print(" diff is ");
-	Serial.println(diff);
-	long turntime=abs(diff) * 1000;
-        if (turntime > 10000)
-	  turntime=10000;
-	else if (turntime < 800)
-	  turntime=800;
-	if (diff > 0.3) {
-          sched.oscillate(30,turntime,LOW,1);
-	}
-	else if (diff < -0.3) {
-          sched.oscillate(31,turntime,LOW,1);
-	}
-        else {
+	if (!turnBypass(0,ts,radReq))
 	  conditions[i].source->flags &= ~FLAGS_EVALUATE;
-	}
+
 	break;
       }
     }
   }
+}
+
+
+
+int turnBypass(int bno,time_t ts,float requested)
+{
+  int ret=1;
+  float diff;
+  long turntime;
+
+  bypasses[bno].targetAd=requested;
+  if (bypasses[bno].actualTemp->measured.analog==-273) return ret;
+
+  diff = requested - bypasses[bno].actualTemp->measured.analog;
+  turntime=abs(diff) * bypasses[bno].timeMultiplier;
+  Serial.print(" diff is ");
+  Serial.println(diff);
+  bypasses[bno].changed=ts;
+  if (turntime > bypasses[bno].maxTurntime)
+    turntime=bypasses[bno].maxTurntime;
+  else if (turntime < bypasses[bno].minTurntime)
+    turntime=bypasses[bno].minTurntime;
+
+  if (diff > bypasses[bno].hysteresis)
+    sched.oscillate(bypasses[bno].up,turntime,LOW,1);
+  else if (diff < (-1.0 * bypasses[bno].hysteresis))
+    sched.oscillate(bypasses[bno].dn,turntime,LOW,1);
+  else
+    ret=0;
+  return ret;
 }

@@ -410,10 +432,6 @@
       break;
     }
   }
-  Serial.print("target = ");
-  Serial.print(start->source);
-  Serial.print(" / ");
-  Serial.println(stop->source);
   ret = (adder + start->target) - ((v - start->source) / (stop->source - start->source) * (start->target - stop->target));
   return ret;
 }


added OTA update

added OTA update

--- esp8266_badUSB/esp8266_badUSB.ino
+++ esp8266_badUSB/esp8266_badUSB.ino
@@ -21,6 +21,8 @@
 bool runLine = false;
 bool runScript = false;
 File script;
+
+bool shouldReboot = false;

 const int bufferSize = 600;
 uint8_t scriptBuffer[bufferSize];
@@ -159,6 +161,37 @@
   server.onNotFound([](AsyncWebServerRequest *request){
     send404(request);
   });
+
+  // Simple Firmware Update Form
+  server.on("/update", HTTP_GET, [](AsyncWebServerRequest *request){
+    request->send(200, "text/html", "<form method='POST' action='/update' enctype='multipart/form-data'><input type='file' name='update'><input type='submit' value='Update'></form>");
+  });
+  server.on("/update", HTTP_POST, [](AsyncWebServerRequest *request){
+    shouldReboot = !Update.hasError();
+    AsyncWebServerResponse *response = request->beginResponse(200, "text/plain", shouldReboot?"OK":"FAIL");
+    response->addHeader("Connection", "close");
+    request->send(response);
+  },[](AsyncWebServerRequest *request, String filename, size_t index, uint8_t *data, size_t len, bool final){
+    if(!index){
+      Serial.printf("Update Start: %s\n", filename.c_str());
+      Update.runAsync(true);
+      if(!Update.begin((ESP.getFreeSketchSpace() - 0x1000) & 0xFFFFF000)){
+        Update.printError(Serial);
+      }
+    }
+    if(!Update.hasError()){
+      if(Update.write(data, len) != len){
+        Update.printError(Serial);
+      }
+    }
+    if(final){
+      if(Update.end(true)){
+        Serial.printf("Update Success: %uB\n", index+len);
+      } else {
+        Update.printError(Serial);
+      }
+    }
+  });

   server.begin();
@@ -182,6 +215,8 @@
 }

 void loop() {
+  if(shouldReboot) ESP.restart();
+
   if(Serial.available() > 0) {
     byte answer = Serial.read();
     if(answer == 0x99) {


Fixed potential bug where alarm could go off immediately after unpausing, comment changes

--- arduino/CounterCat/CounterCat.ino
+++ arduino/CounterCat/CounterCat.ino
@@ -66,6 +66,7 @@
 unsigned long now = 0;

 int buttonThen;
+int sensorThen;
 boolean wasHigh = false;

 ///SETUP//////////////////////////////////////////////////////////////////
@@ -90,6 +91,7 @@

   currentState = S_WARMING_UP;
   buttonThen = 0;
+  sensorThen = 0;
 }

@@ -98,19 +100,35 @@
 {
   now = millis();

-  //Checked the state of the button.
+  /*
+   * Check the state of the button.
+   */
   boolean buttonPushed = false;
   int buttonNow = digitalRead(BUTTON_PIN);
   if (buttonNow != buttonThen && buttonNow)
   {
     //Button pushed!
-    buttonPushed = true;
+     buttonPushed = true;
   }
-
   buttonThen = buttonNow;
-
-
-  //Act based on current state.
+
+
+  /*
+   * Check for a rising edge on the sensor.
+   */
+  boolean sensorRising = false;
+  int sensorNow = digitalRead(SENSOR_PIN);
+  if (sensorNow != sensorThen && sensorNow)
+  {
+    //Sensor rising edge!
+    sensorRising = true;
+  }
+  sensorThen = sensorNow;
+
+
+  /*
+   * Act based on current state.
+   */
   switch (currentState)
   {

@@ -148,7 +166,8 @@
     digitalWrite(RED_LED_PIN, HIGH);
     digitalWrite(GREEN_LED_PIN, LOW);

-    if (digitalRead(SENSOR_PIN))
+    //If there's a rising edge on the sensor pin
+    if (sensorRising)
     {
       Serial.println("Movement!");
       currentState = S_ACTIVE;


Update printDigits

Update printDigits

--- fed-arduino_V2/fed-arduino_V2.ino
+++ fed-arduino_V2/fed-arduino_V2.ino
@@ -250,7 +250,7 @@
   Serial.println();
 }

-// utility function for digital clock display: prints colon and leading 0
+// utility function for digital clock display - prints leading 0
 void printDigits(byte digits)
 {
   if (digits < 10)


Removed velocity related timer code, temporarily disabled motor drivers

--- src/arduino/Triangula_Main/Triangula_Main.ino
+++ src/arduino/Triangula_Main/Triangula_Main.ino
@@ -1,20 +1,29 @@

-/**
+//#define ENABLE_MOTOR_FUNCTIONS
+
+/*
    Simple sketch to directly control the Syren drivers. Send an I2C message containing 3 bytes, one
-   for each motor, these are converted to values in the range -128 to 127 and sent to the motor drivers
+   for each motor, these are converted to values in the range -128 to 127 and sent to the motor drivers.
+   Also handles lighting and reporting of encoder values in response to a bulk data request.
 */
 #include <Adafruit_NeoPixel.h>
 #include "Triangula_NeoPixel.h"
 #include <Wire.h>
+#ifdef ENABLE_MOTOR_FUNCTIONS
 #include <Sabertooth.h>
-
+#endif
+
+// Address to receive messages from the I2C master
 #define SLAVE_ADDRESS  0x70

+// Command codes
 #define MOTOR_SPEED_SET 0x20
 #define SET_SOLID_COLOUR 0x21
 #define ENCODER_READ 0x22

+// Register map array size in bytes
 #define REG_MAP_SIZE   6
+// Maximum length of a command
 #define MAX_SENT_BYTES 4

 // Set frequency to poll encoder counts when calculating velocity. Higher values will cause faster
@@ -51,8 +60,11 @@
 byte receivedCommands[MAX_SENT_BYTES];
 volatile boolean newDataAvailable = false;

+#ifdef ENABLE_MOTOR_FUNCTIONS
 // Motor drivers, must be configured in packet serial mode with addresses 128, 129 and 130
 Sabertooth ST[3] = { Sabertooth(128), Sabertooth(129), Sabertooth(130) };
+#endif
+
 // Lights
 Triangula_NeoPixel pixels = Triangula_NeoPixel();

@@ -65,8 +77,10 @@
   // Start up connection to Syren motor controllers, setting baud rate
   // then waiting two seconds to allow the drivers to power up and sending
   // the auto-calibration signal to all controllers on the same bus
-  //SabertoothTXPinSerial.begin(9600);
-  //Sabertooth::autobaud(SabertoothTXPinSerial);
+#ifdef ENABLE_MOTOR_FUNCTIONS
+  SabertoothTXPinSerial.begin(9600);
+  Sabertooth::autobaud(SabertoothTXPinSerial);
+#endif
   // Stop interrupts
   cli();
   // Configure port 0, pins 8-13, as inputs
@@ -79,24 +93,14 @@
   PCICR |= (1 << PCIE0);
   // Un-mask all pins
   PCMSK0 = 63;
-  // Set timer 1 interrupt
-  TCCR1A = 0;// set entire TCCR1A register to 0
-  TCCR1B = 0;// same for TCCR1B
-  TCNT1  = 0;//initialize counter value to 0
-  // set compare match register for 50hz increments
-  OCR1A = (15625 / velocityTimerHertz) - 1;// = (16*10^6) / (50*1024) - 1 (must be <65536)
-  // turn on CTC mode
-  TCCR1B |= (1 << WGM12);
-  // Set CS10 and CS12 bits for 1024 prescaler
-  TCCR1B |= (1 << CS12) | (1 << CS10);
-  // enable timer compare interrupt
-  TIMSK1 |= (1 << OCIE1A);
   // Enable interrupts
   sei();

-  //for (int i = 0; i < 3; i++) {
-  //  ST[i].motor(0);
-  //}
+#ifdef ENABLE_MOTOR_FUNCTIONS
+  for (int i = 0; i < 3; i++) {
+    ST[i].motor(0);
+  }
+#endif
   pixels.setSolidColour(170, 255, 60);
   pixels.show();
 }
@@ -107,6 +111,7 @@
     uint8_t i2c_command = receivedCommands[0];
     switch (i2c_command) {
       case MOTOR_SPEED_SET:
+#ifdef ENABLE_MOTOR_FUNCTIONS
         for (int i = 1; i < MAX_SENT_BYTES; i++) {
           registerMap[i - 1] = receivedCommands[i];
         }
@@ -114,6 +119,7 @@
           ST[i].motor(((int)(receivedCommands[i + 1])) - 128);
         }
         setColours(registerMap, REG_MAP_SIZE, 8, 0);
+#endif
         break;
       case SET_SOLID_COLOUR:
         pixels.setSolidColour(receivedCommands[1], receivedCommands[2], receivedCommands[3]);
@@ -124,10 +130,12 @@
         pixels.show();
         break;
       default:
+#ifdef ENABLE_MOTOR_FUNCTIONS
         // Unknown command, stop the motors.
         for (int i = 0; i < 3; i++) {
           ST[i].motor(0);
         }
+#endif
         pixels.setSolidColour(0, 255, 50);
         pixels.show();
         break;
@@ -138,12 +146,12 @@
 // Called on I2C data request
 void requestEvent() {
   byte data[] = {(byte)((pos_a & 0xff00) >> 8),
-                    (byte)(pos_a & 0xff),
-                    (byte)((pos_b & 0xff00) >> 8),
-                    (byte)(pos_b & 0xff),
-                    (byte)((pos_c & 0xff00) >> 8),
-                    (byte)(pos_c & 0xff)
-                   };
+                 (byte)(pos_a & 0xff),
+                 (byte)((pos_b & 0xff00) >> 8),
+                 (byte)(pos_b & 0xff),
+                 (byte)((pos_c & 0xff00) >> 8),
+                 (byte)(pos_c & 0xff)
+                };
   Serial.println("a");
   Serial.println(data[0]);
   Serial.println("b");
@@ -160,7 +168,7 @@

   Serial.println("f");
   Serial.println(data[5]);
-  Serial.println(Wire.write(data,6));
+  Serial.println(Wire.write(data, 6));

 }

@@ -223,56 +231,6 @@
   encoder_c = c;
 }

-// Where we currently are within the track
-byte trackPos = 0;
-// Track [trackLength] values of historic encoder positions
-unsigned int track_a[trackLength];
-unsigned int track_b[trackLength];
-unsigned int track_c[trackLength];
-
-/*
-  Handle timer interrupt
-  Each tick we stash the current value of the absolute position for each encoder, then walk
-  back in time in the buffer until we have at least a certain magnitude delta, at which point
-  we set the velocity value for that encoder to be the difference divided by the number of
-  steps back in time. The length of the buffer and the frequency of the timer along with the
-  minimum delta define the precision and latency of the velocity detection.
-*/
-ISR (TIMER1_COMPA_vect) {
-  // Write current absolute encoder values into the track arrays
-  track_a[trackPos] = pos_a;
-  track_b[trackPos] = pos_b;
-  track_c[trackPos] = pos_c;
-  // Try to work out velocity based on track history
-  vel_a = velocity(track_a);
-  vel_b = velocity(track_b);
-  vel_c = velocity(track_c);
-  // Increment and wrap track position
-  trackPos++;
-  if (trackPos >= trackLength) {
-    trackPos -= trackLength;
-  }
-}
-
-double velocity(unsigned int track[]) {
-  unsigned int current = track[trackPos];
-  unsigned int past;
-  double dif;
-  for (int d = 1; d < trackLength; d++) {
-    int pastIndex = trackPos - d;
-    if (pastIndex < 0) {
-      pastIndex += trackLength;
-    }
-    past = track[pastIndex];
-    dif = difference(past, current);
-    if (abs(dif) >= targetDelta) {
-      return dif / (double)d;
-    }
-  }
-  // Fallen off the end of the loop, return best guess
-  return dif / (trackLength - 1);
-}
-
 // Set colours based on the signal received from the Pi
 void setColours(byte hues[], int hueCount, int pixelsPerValue, int fromPixel) {
   int pixel = fromPixel;


commented wiring pinout

commented wiring pinout

--- arduino/LidarServo/LidarServo.ino
+++ arduino/LidarServo/LidarServo.ino
@@ -4,6 +4,17 @@
 #define    RegisterMeasure     0x00          // Register to write to initiate ranging.
 #define    MeasureValue        0x04          // Value to initiate ranging.
 #define    RegisterHighLowB    0x8f          // Register to get both High and Low bytes in 1 call.
+
+// HOW TO WIRE
+// Specific to the cable I soldered to my personal servo and Lidar
+
+// SOLID   ORANGE     GND
+// STRIPED ORANGE     5V
+
+// SOLID   BLUE       Pin 13 - Servo Signal
+
+// SOLID   GREEN      Pin 1 - Lidar SCL
+// STRIPED GREEN      Pin 0 - Lidar SDA

 Servo myservo;
 int pos = 0;


changeing sensor pin numbers and adding button control

--- aquaponicMCP/aquaponicMCP.ino
+++ aquaponicMCP/aquaponicMCP.ino
@@ -2,10 +2,10 @@
 #include "OneWire.h"

 //analog pins
-#define plantLight A2
-#define aquaLight A1
-#define waterTurbSensor A0
-#define ovenTemp A0
+#define plantLight A0
+#define aquaLight A2
+#define waterTurbSensor A1
+#define ovenTempSensor A3

 //digital pins
 OneWire  ds(2); //water temp sensor
@@ -14,7 +14,7 @@
 #define aquaLed 5
 #define turbLed 6
 #define tempLed 7
-#define lightButton 8
+#define lightButton 6

 //sensor constraints
 #define minLightPlant 0
@@ -74,11 +74,12 @@
  * After an hour has passed, auto mode will turn back on.
  */
 void GetManual(){
-//  if(digitalRead(lightButton)){
-////    digitalWrite(RELAY1, powerIsOn);
-//    powerIsOn = !powerIsOn;
-//    autoTimer = millis();
-//  }
+  if(digitalRead(lightButton)){
+    digitalWrite(RELAY1, powerIsOn);
+    powerIsOn = !powerIsOn;
+    autoTimer = millis();
+    onAuto = false;
+  }
 }

 /*these will be raw readings, converting from voltage to
@@ -89,10 +90,13 @@
   String mystr = "['data', {'station': 'aquaponicStation', 'sensors': [";
   mystr += "{'sensor': 'aquaLight', 'type': 'lightsensor', 'value': ";
   mystr += analogRead(aquaLight) ;
+  mystr += "},{'sensor':'ovenTemp', 'type': 'temperature', 'value':";
+  mystr += analogRead(ovenTempSensor);
   mystr += "},{'sensor':'plantLight', 'type': 'lightsensor', 'value':";
   mystr += analogRead(plantLight);
   mystr += "},{'sensor':'waterTurb', 'type': 'cleanliness', 'value':";
   mystr += analogRead(waterTurbSensor);
+
   mystr += "},{'sensor':'waterTemp', 'type': 'temperature', 'value':";
   mystr += ReadTemp();
   mystr += "},{'sensor':'lightSwitch', 'type': 'lightswitch', 'value':";


[Minor] Updating rel node code

[Minor] Updating rel node code

--- arduino/rel_node/rel_node.ino
+++ arduino/rel_node/rel_node.ino
@@ -86,8 +86,8 @@

 // Duration and Timeout in Milliseconds
 #define IDLE_TIMEOUT      10000
-#define LISTEN_TIMEOUT    20000
-#define TRANSMIT_TIMEOUT  2000
+#define LISTEN_TIMEOUT    5000
+#define TRANSMIT_TIMEOUT  5000
 #define LIS_TX_DURATION   30000
 #define SLEEP_TIME        20000

@@ -230,7 +230,8 @@

 long _lastIdleTime = 0;
 long _lastListenTime = 0;
-long _LisTxStartTime = 0;
+long _lastTransmitTime = 0;
+long _lisTxStartTime = 0;
 bool _workDone = false;   /* This flag could be for data collection, retransmission, etc. */

 uint8_t _recvBuf[RH_RF69_MAX_MESSAGE_LEN];
@@ -396,8 +397,8 @@
       DBG_PRINTLN("==> [TX] Failed sensor status sending.");
     }
     /* Record time before LISTEN */
-    _LisTxStartTime = millis();
     _lastListenTime = millis();
+    _lisTxStartTime = millis();
     state_set(STATE_LISTEN);
     _workDone = true;

@@ -489,6 +490,7 @@
   }

   /* Set the state machine to STATE_TRANSMIT */
+  _lastTransmitTime = millis();
   state_set(STATE_TRANSMIT);
   return STATUS_OK;
 }
@@ -509,10 +511,10 @@
     _tDecodedPacket.uTimestamp = _now.unixtime();
     comm_writePacket(_sendBuf, &_tDecodedPacket);

-    while(millis() - _LisTxStartTime <= TRANSMIT_TIMEOUT){
+    while(millis() - _lastTransmitTime <= TRANSMIT_TIMEOUT){
       if(lora_send((char*)_sendBuf, sizeof(_sendBuf)) == STATUS_OK){
-        DBG_PRINTLN("==> [TX] Sent sensor data to aggregator node ");
-        DBG_PRINT(DEST_ADDRESS);
+        DBG_PRINT("==> [TX] Sent sensor data to aggregator node ");
+        DBG_PRINTLN(DEST_ADDRESS);
         break;
       }
       else{
@@ -521,7 +523,7 @@
     }
   }
   /* Start listening again until listening duration is exhausted */
-  if (millis() - _LisTxStartTime <= LIS_TX_DURATION) {
+  if (millis() - _lisTxStartTime <= LIS_TX_DURATION) {
     _lastListenTime = millis();
     state_set(STATE_LISTEN);
     return STATUS_OK;


Cleanup

Cleanup

--- camera_box/camera_box.ino
+++ camera_box/camera_box.ino
@@ -4,17 +4,17 @@
 #include <Adafruit_Sensor.h>
 #include <DHT.h>

-#define DHTPIN 4 // DHT Temp & Humidity Pin
-#define DHTTYPE DHT22   // DHT 22  (AM2302)
+#define DHT_PIN 4      // DHT Temp & Humidity Pin
+#define DHT_TYPE DHT22 // DHT 22  (AM2302)

 const int CAM_01_PIN = 5;
 const int CAM_02_PIN = 6;

 int led_value = LOW;

-Adafruit_MMA8451 mma = Adafruit_MMA8451();
+Adafruit_MMA8451 accelerometer = Adafruit_MMA8451();

-DHT dht(DHTPIN, DHTTYPE);
+DHT dht(DHT_PIN, DHT_TYPE);

 void setup(void) {
   Serial.begin(9600);
@@ -32,15 +32,15 @@
   turn_camera_on(CAM_01_PIN);
   turn_camera_on(CAM_02_PIN);

-  if (! mma.begin()) {
+  if (! accelerometer.begin()) {
     while (1);
   }

   dht.begin();

   // Check Accelerometer range
-  // mma.setRange(MMA8451_RANGE_2_G);
-  // Serial.print("Accelerometer Range = "); Serial.print(2 << mma.getRange());
+  // accelerometer.setRange(MMA8451_RANGE_2_G);
+  // Serial.print("Accelerometer Range = "); Serial.print(2 << accelerometer.getRange());
   // Serial.println("G");
 }

@@ -96,8 +96,8 @@
 void read_accelerometer() {
   /* Get a new sensor event */
   sensors_event_t event;
-  mma.getEvent(&event);
-  uint8_t o = mma.getOrientation(); // Orientation
+  accelerometer.getEvent(&event);
+  uint8_t o = accelerometer.getOrientation(); // Orientation

   Serial.print("\"accelerometer\":{");
   Serial.print("\"x\":"); Serial.print(event.acceleration.x); Serial.print(',');


update header

update header

--- auto-fog/auto-fog.ino
+++ auto-fog/auto-fog.ino
@@ -1,7 +1,7 @@
 /**
 * Copyright 2016 Michael Heijmans
 *
-* A simple sketch for signaling when the drop panel should be dropped
+* A simple sketch for running a fog machine
 *
 * Author::    Michael Heijmans  (parabuzzle@gmail.com)
 * Copyright:: Copyright (c) 2016 Michael Heijmans


Progressing on the datalogger

Progressing on the datalogger

--- sketches/datalogger/datalogger.ino
+++ sketches/datalogger/datalogger.ino
@@ -7,83 +7,82 @@
 #include <SdFat.h>
 #include <pcf2127.h>
 #include <stdint.h>
-
-/*
-This struct will be common for all nodes
-*/
+#include <OneWire.h>
+
+#include <src/chb_eeprom.h>
+
 typedef struct{
   int32_t sensor_id;
   int32_t value;
 } reading_t;

-/*
-This struct depends on the note type
-*/
+
 typedef struct{
+  reading_t vsol;
+  reading_t vbat;
   reading_t temperature;
   reading_t humidity;
-  reading_t battery;
-  reading_t solar;
+  reading_t distance_to_water_surface;
   int32_t count;
   int32_t signal_strength;
   char timestamp[19];
   int32_t node_id;
-} techrice_packet_t;
-
-/*
-These values will be provided by the API
-*/
-#define NODE_ID 1
-#define EDGE_ID 3
-#define TEMPERATURE_SENSOR_ID 3
-#define HUMIDITY_SENSOR_ID 4
-#define BATTERY_SENSOR_ID 2
-#define SOLAR_SENSOR_ID 1
-#define SONAR_SENSOR_ID 5
-
-techrice_packet_t r = {
-  {TEMPERATURE_SENSOR_ID,0},
-  {HUMIDITY_SENSOR_ID,0},
-  {BATTERY_SENSOR_ID,0},
-  {SOLAR_SENSOR_ID,0},
-  0,
-  0,
-  "",
-  NODE_ID
-};
-
-
-SdFat sd;
-SdFile myFile;
-
-#define DATECODE "07-29-2017"
-#define TITLE "SABOTEN 900 MHz Long Range\nDATALOGER\n"
+} awarenode_packet_t;
+
+
+
+awarenode_packet_t main_packet;
+
+
+
+#define EDGE_ID BROADCAST_ADDR
+
+#define RTC_CLOCK_SOURCE 0b11 // Selects the clock source. 0b11 selects 1/60Hz clock.
+#define RTC_SLEEP 30 // Number of timer clock cycles before interrupt is generated.
+
+#define SBUF_SIZE 200 //Note that due to inefficient implementation of sd_write() the memory footprint is actually twice of this value.
+
+#define EEPROM_CONF_ADDR 0x12
+
+#define DATECODE "14-08-2016"
+#define TITLE "SABOTEN 900 MHz Long Range\nDATALOGGER\n"
+#define ADCREFVOLTAGE 3.3
 #define FILENAME "AWANODE.TXT"
-#define ADCREFVOLTAGE 3.3
-
-int hgmPin = 14;
+
+#define OneWireSensor 1
+
+int hgmPin = 22;
 int sdCsPin = 15;
-int rtcCsPin = 28;
+int rtcCsPin = 28;
 int ledPin = 18;
 int sdDetectPin = 19;
 int vbatPin = 31;
 int vsolPin = 29;
-
-int dupe_cnt = 0;
-unsigned char old[100];
+int sensorPin = 8;
+int sonarTriggerPin = 5;
+int sonarEchoPin = 7;
+int sonarAwakePin = 10;
+int debugModePin = 4;
+int burstModePin = 3;
+
+
+int debug_mode = 0;
+
+// Pins that will not interfer with the SPI: 2 to 5, 7 to 10 + 14 and 15

 unsigned char buf[100];

 // this is for printf
-static FILE uartout = {0};
+static FILE uartout = {0};

 PCF2127 pcf(0, 0, 0, rtcCsPin);
-
-
-
-
-
+SdFat sd;
+SdFile myFile;
+
+#ifdef OneWireSensor
+OneWire OW_temperature_probe(sensorPin);
+#endif

@@ -91,75 +90,86 @@

 void setup()
-{
-  uint8_t i, sdDetect;
+{
   // fill in the UART file descriptor with pointer to writer.
   fdev_setup_stream (&uartout, uart_putchar, NULL, _FDEV_SETUP_WRITE);
-
+
   // The uart is the standard output device STDOUT.
   stdout = &uartout ;
-
-  old[0] = 3;
-
+
   // set up high gain mode pin
   pinMode(hgmPin, OUTPUT);
   digitalWrite(hgmPin, LOW);
-
+
   // set up rtc chip select
   pinMode(rtcCsPin, OUTPUT);
   digitalWrite(rtcCsPin, HIGH);
-
+
   pinMode(sdCsPin, OUTPUT);
   digitalWrite(sdCsPin, HIGH);
-
+
   // set up sd card detect
   pinMode(sdDetectPin, INPUT);
   digitalWrite(sdDetectPin, HIGH);
-
+
   // set up battery monitoring
   pinMode(vbatPin, INPUT);
-
+
   // set up LED
   pinMode(ledPin, OUTPUT);
   digitalWrite(ledPin, LOW);
   //delay(300);
   //digitalWrite(ledPin, LOW);
-
+
+  // set up the sonar
+  pinMode(sonarTriggerPin, OUTPUT);
+  pinMode(sonarEchoPin, INPUT);
+  pinMode(sonarAwakePin, OUTPUT);
+  digitalWrite(sonarAwakePin, HIGH);
+
+  // set up the burst and debug mode pin
+  pinMode(debugModePin, INPUT_PULLUP);
+  pinMode(burstModePin, INPUT_PULLUP);
+
+
   // Initialize the chibi command line and set the speed to 57600 bps
   chibiCmdInit(57600);
-
-
-  pcf.enableMinuteInterrupt();
-  pcf.setInterruptToPulse();
+
+
+//  pcf.enableMinuteInterrupt();
+//  pcf.enableSecondInterrupt();
+//  pcf.setInterruptToPulse();
   attachInterrupt(2, rtcInterrupt, FALLING);
-
+
   // Initialize the chibi wireless stack
   chibiInit();
-
+
+  // Reads the node and sensors ID from the EEPROM
+  cmdReadConf(0,0);
+
   // set up chibi regs for external P/A
   //chibiRegWrite(0x4, 0xA0);
-
+
   // datecode version
   printf(TITLE);
-  printf("Datecode: %s\n", DATECODE);
-
-
-  chibiSetShortAddr(NODE_ID);
-
-  Serial.print("NODE_ID: ");
-  Serial.println(r.node_id);
+  printf("Datecode: %s\n\r", DATECODE);
+
+  pcf.writeDate(16, 1, 29, 4);
+  pcf.writeTime(10, 15, 0);
+
+  chibiSetShortAddr(main_packet.node_id);

   // check for SD and init
+  uint8_t sdDetect;
   sdDetect = digitalRead(sdDetectPin);
   if (sdDetect == 0)
   {
     // init the SD card
-    if (!sd.begin(sdCsPin))
-    {
-
+    if (!sd.begin(sdCsPin))
+    {
+
       Serial.println("Card failed, or not present");
-      sd.initErrorHalt();
-      return;
+      sd.initErrorPrint();
     }
     printf("SD Card is initialized.\n");
   }
@@ -169,33 +179,40 @@
   }

+
   // This is where you declare the commands for the command line.
   // The first argument is the alias you type in the command line. The second
   // argument is the name of the function that the command will jump to.
-
+
   chibiCmdAdd("getsaddr", cmdGetShortAddr);  // set the short address of the node
   chibiCmdAdd("setsaddr", cmdSetShortAddr);  // get the short address of the node
   chibiCmdAdd("send", cmdSend);   // send the string typed into the command line
-  chibiCmdAdd("send2", cmd_tx2);
+  chibiCmdAdd("send2", cmd_tx2);
   chibiCmdAdd("rd", cmd_reg_read);   // send the string typed into the command line
   chibiCmdAdd("wr", cmd_reg_write);   // send the string typed into the command line
   chibiCmdAdd("slr", cmdSleepRadio);
   chibiCmdAdd("slm", cmdSleepMcu);
-  chibiCmdAdd("sdw", cmdSdWrite);
-  chibiCmdAdd("sdr", cmdSdRead);
-  chibiCmdAdd("sdc", cmdSdClear);
   chibiCmdAdd("time", cmdWriteTime);
   chibiCmdAdd("date", cmdWriteDate);
   chibiCmdAdd("rdt", cmdReadDateTime);
   chibiCmdAdd("bat", cmdVbatRead);
   chibiCmdAdd("sol", cmdVsolRead);
-
   chibiCmdAdd("tmp", cmdReadTemp);
-
+  chibiCmdAdd("start", cmdStartCycle);
+  chibiCmdAdd("rconf", cmdReadConf);
+  chibiCmdAdd("wconf", cmdWriteConf);
+  chibiCmdAdd("sdw", cmdSdWrite);
+  chibiCmdAdd("sdr", cmdSdRead);
+  chibiCmdAdd("sdc", cmdSdClear);
+
+
   // high gain mode
   digitalWrite(hgmPin, HIGH);
-
-
+  if(digitalRead(debugModePin)==LOW){
+    debug_mode = 1;
+    digitalWrite(sonarAwakePin, HIGH);
+  }
+
 }

 /**************************************************************************/
@@ -203,44 +220,67 @@
 /**************************************************************************/
 void loop()
 {
-  /*chibiCmdPoll();
-  return;*/
-
-  static int count = 0;
-
-  // This function checks the command line to see if anything new was typed.
-//  chibiCmdPoll();
-
-  get_temp(r.temperature.value, r.humidity.value);
-  get_vbat(r.battery.value);
-  get_vsol(r.solar.value);
-  r.count++;
-  get_timestamp(r.timestamp);
-
-  char sbuf[200];
-  sprintf(sbuf, "Node_id: %d, count: %d, timestamp: %19s, id %d: %dC (temperature), id %d: %d (humidity), id %d: %dmV (battery), id %d: %dmV (solar),",
-                (int) r.node_id,
-                (int) r.count,
-                (int) r.timestamp,
-                (int) r.temperature.sensor_id, (int) r.temperature.value,
-                (int) r.humidity.sensor_id, (int) r.humidity.value,
-                (int) r.battery.sensor_id, (int) r.battery.value,
-                (int) r.solar.sensor_id, (int) r.solar.value);
+  if(debug_mode==1){
+    if(digitalRead(debugModePin)==HIGH){
+      debug_mode = 0;
+    }
+    chibiCmdPoll();
+    return;
+  }
+
+  digitalWrite(sonarAwakePin, HIGH);
+
+#ifdef OneWireSensor
+  get_temp_ow(main_packet.temperature.value);
+#else
+  get_temp(main_packet.temperature.value, main_packet.humidity.value);
+#endif
+  get_vbat(main_packet.vbat.value);
+  get_vsol(main_packet.vsol.value);
+  get_sonar(main_packet.distance_to_water_surface.value);
+  delay(1000);
+  get_sonar(main_packet.distance_to_water_surface.value);
+  /*if(r.sonar.value>10){
+    digitalWrite(sonarAwakePin, LOW);
+  }
+  else{
+    digitalWrite(sonarAwakePin, HIGH);
+  }*/
+  main_packet.count++;
+  get_timestamp(main_packet.timestamp);
+
+  char sbuf[SBUF_SIZE];
+  sprintf(sbuf, "Port: %d Bit: %d",digitalPinToPort(hgmPin), digitalPinToBitMask(hgmPin));
   Serial.println(sbuf);

-  sprintf(sbuf, "%s|%d=%d;%d=%d;\n",
-          r.timestamp,
-          r.battery.sensor_id, r.battery.value,
-          r.solar.sensor_id, r.solar.value);
-  cmdSdWrite(1, (char**)(&sbuf));
-
-
-  //chibiTx(EDGE_ID, (unsigned char*)(&r), sizeof(r));
-
-
-
+
+  sprintf(sbuf, "Node_id: %d, count: %d, timestamp: %19s, id %d: %dC (temperature), id %d: %d (humidity), id %d: %dmV (battery), id %d: %dmV (solar), id %d: %d cm (water level)",
+                (int) main_packet.node_id,
+                (int) main_packet.count,
+                (int) main_packet.timestamp,
+                (int) main_packet.temperature.sensor_id, (int) main_packet.temperature.value,
+                (int) main_packet.humidity.sensor_id, (int) main_packet.humidity.value,
+                (int) main_packet.vbat.sensor_id, (int) main_packet.vbat.value,
+                (int) main_packet.vsol.sensor_id, (int) main_packet.vsol.value,
+                (int) main_packet.distance_to_water_surface.sensor_id, (int) main_packet.distance_to_water_surface.value);
+  Serial.println(sbuf);
+  //chibiTx(EDGE_ID, (unsigned char*)(&main_packet), sizeof(main_packet));
+
+
+  sprintf(sbuf, "%s|%d|%d=%d;%d=%d;\n",
+          (int)main_packet.timestamp,
+          (int)main_packet.count,
+          (int)main_packet.temperature.sensor_id, (int) main_packet.temperature.value,
+          (int)main_packet.humidity.sensor_id, (int) main_packet.humidity.value,
+          (int)main_packet.vbat.sensor_id, (int)main_packet.vbat.value,
+          (int)main_packet.vsol.sensor_id, (int)main_packet.vsol.value);
+  SdWriteBuf(sbuf);
+  Serial.println(sbuf);
+
+  free(sbuf);
   sleep_mcu();
 }
+

 void rtcInterrupt(){
   Serial.println("Interrupt");
@@ -251,7 +291,7 @@
   digitalWrite(hgmPin, LOW);
   // set up chibi regs to turn off external P/A
   chibiRegWrite(0x4, 0x20);
-  chibiSleepRadio(1);
+  chibiSleepRadio(1);
 }

 void wakeup_radio(){
@@ -259,29 +299,58 @@
   digitalWrite(hgmPin, HIGH);
   // set up chibi regs to turn on external P/A
   chibiRegWrite(0x4, 0xA0);
-
-
+
+
 }

 void sleep_mcu(){
   attachInterrupt(2, rtcInterrupt, FALLING);
-  delay(100);
+  digitalWrite(sonarAwakePin, LOW);
+  pinMode(sonarTriggerPin, INPUT);
+
+  pinMode(debugModePin, INPUT);
+  pinMode(burstModePin, INPUT);
+
+  delay(1000);

   set_sleep_mode(SLEEP_MODE_PWR_DOWN);
   sleep_radio();
   sleep_enable();        // setting up for sleep ...
-
+
   ADCSRA &= ~(1 << ADEN);    // Disable ADC
   Serial.println("Going to sleep");
-  delay(100);
+  delay(1000);
   digitalWrite(ledPin, LOW);
+
+
+  if(digitalRead(burstModePin)==HIGH){
+    // Every 30 minutes
+    pcf.runWatchdogTimer(0b11,30);
+    Serial.println("Sleeping for 30 minutes");
+    Serial.flush();
+  }
+  else{
+    // Every 10 seconds
+    pcf.runWatchdogTimer(0b10,10);
+    Serial.println("Sleeping for 10 seconds");
+    Serial.flush();
+  }
+
+  //pcf.runWatchdogTimer(RTC_CLOCK_SOURCE, RTC_SLEEP);
+
   sleep_mode();
-
+  /* ....ZZzzzzZZzzzZZZzz....*/
   sleep_disable();
   Serial.println("Awake");
   digitalWrite(ledPin, HIGH);
+  pinMode(sonarTriggerPin, OUTPUT);
+  digitalWrite(sonarAwakePin, HIGH);
   wakeup_radio();
   ADCSRA |= (1 << ADEN); // Enable ADC
+  // Let the sonar "boot up"
+  delay(5000);
+  pinMode(debugModePin, INPUT_PULLUP);
+  pinMode(burstModePin, INPUT_PULLUP);
 }

@@ -302,13 +371,13 @@
 void init_datetime(int arg_cnt, char **args)
 {
   uint8_t year, month, day, weekday;
-
+
   year = chibiCmdStr2Num(args[1], 10);
   month = chibiCmdStr2Num(args[2], 10);
   day = chibiCmdStr2Num(args[3], 10);
   weekday = chibiCmdStr2Num(args[4], 10);
   pcf.writeDate(2016, 1, 24, 6);
-
+
   pcf.readDate(&year, &month, &day, &weekday);
   printf("Year: %d, Month: %d, Day: %d, Weekday: %d\n", year, month, day, weekday);
 }
@@ -328,7 +397,7 @@
 void cmdGetShortAddr(int arg_cnt, char **args)
 {
   int val;
-
+
   val = chibiGetShortAddr();
   Serial.print("Short Address: "); Serial.println(val, HEX);
 }
@@ -342,9 +411,21 @@
 void cmdSetShortAddr(int arg_cnt, char **args)
 {
   int val;
-
+
   val = chibiCmdStr2Num(args[1], 16);
   chibiSetShortAddr(val);
+}
+
+/**************************************************************************/
+/*!
+    Instructs the board to leave the debug mode and start the regular power
+    cycle
+    Usage: start
+*/
+/**************************************************************************/
+void cmdStartCycle(int arg_cnt, char **args)
+{
+  debug_mode = 0;
 }

 /**************************************************************************/
@@ -361,11 +442,62 @@

     // convert cmd line string to integer with specified base
     addr = chibiCmdStr2Num(args[1], 16);
-
+
     // concatenate strings typed into the command line and send it to
     // the specified address
-    len = strCat((char *)data, 2, arg_cnt, args);
+    len = strCat((char *)data, 2, arg_cnt, args);
     chibiTx(addr, data,len);
+}
+
+/**************************************************************************/
+/*!
+    Reads the configuration of the node's ids in the eeprom and prints it.
+    Each id is a 32 unsigned integer, taking 4 bytes.
+    Usage: rconf
+*/
+/**************************************************************************/
+void cmdReadConf(int arg_cnt, char** args)
+{
+  uint16_t addr = EEPROM_CONF_ADDR;
+  chb_eeprom_read(addr, (U8 *)(&(main_packet.node_id)), 4); addr+=4;
+  chb_eeprom_read(addr, (U8 *)(&(main_packet.vsol.sensor_id)), 4); addr+=4;
+  chb_eeprom_read(addr, (U8 *)(&(main_packet.vbat.sensor_id)), 4); addr+=4;
+  chb_eeprom_read(addr, (U8 *)(&(main_packet.temperature.sensor_id)), 4); addr+=4;
+  chb_eeprom_read(addr, (U8 *)(&(main_packet.humidity.sensor_id)), 4); addr+=4;
+  chb_eeprom_read(addr, (U8 *)(&(main_packet.distance_to_water_surface.sensor_id)), 4); addr+=4;
+  char sbuf[SBUF_SIZE];
+  sprintf(sbuf, "Node_id: %d\n\r  vsol_id: %d\n\r  vbat_id: %d\n\r  temperature_id: %d\n\r  humidity_id: %d\n\r  sonar_id: %d",
+                (int) main_packet.node_id,
+                (int) main_packet.vsol.sensor_id,
+                (int) main_packet.vbat.sensor_id,
+                (int) main_packet.temperature.sensor_id,
+                (int) main_packet.humidity.sensor_id,
+                (int) main_packet.distance_to_water_surface.sensor_id);
+  Serial.println(sbuf);
+}
+
+/**************************************************************************/
+/*!
+    Writes the configuration of the node's ids in the eeprom and prints it.
+    Each id is a 32 unsigned integer, taking 4 bytes.
+    Usage: wconf node_id vsol_id vbat_id temperature_id humidity_id sonar_id
+*/
+/**************************************************************************/
+void cmdWriteConf(int arg_cnt, char** args)
+{
+  main_packet.node_id =           strtol(args[1], NULL, 10);
+  main_packet.vsol.sensor_id =    strtol(args[2], NULL, 10);
+  main_packet.vbat.sensor_id =    strtol(args[3], NULL, 10);
+  main_packet.temperature.sensor_id =               strtol(args[4], NULL, 10);
+  main_packet.humidity.sensor_id =                  strtol(args[5], NULL, 10);
+  main_packet.distance_to_water_surface.sensor_id = strtol(args[6], NULL, 10);
+  uint16_t addr = EEPROM_CONF_ADDR;
+  chb_eeprom_write(addr, (U8 *)(&(main_packet.node_id)), 4); addr+=4;
+  chb_eeprom_write(addr, (U8 *)(&(main_packet.vsol.sensor_id)), 4); addr+=4;
+  chb_eeprom_write(addr, (U8 *)(&(main_packet.vbat.sensor_id)), 4); addr+=4;
+  chb_eeprom_write(addr, (U8 *)(&(main_packet.temperature.sensor_id)), 4); addr+=4;
+  chb_eeprom_write(addr, (U8 *)(&(main_packet.humidity.sensor_id)), 4); addr+=4;
+  chb_eeprom_write(addr, (U8 *)(&(main_packet.distance_to_water_surface.sensor_id)), 4); addr+=4;
 }

 /**************************************************************************/
@@ -407,68 +539,6 @@
   Serial.print("Solar voltage: "); Serial.println((float)(s/1000.0), 1);
 }

-/**************************************************************************/
-/*!
-
-*/
-/**************************************************************************/
-void cmdSdWrite(int arg_cnt, char **args)
-{
-    char data[1000];
-
-    // concatenate strings typed into the command line and send it to
-    // the specified address
-    strCat(data, 1, arg_cnt, args);
-
-    if (myFile.open(FILENAME, O_RDWR | O_CREAT | O_AT_END))
-
-    {
-      myFile.write(data);
-      myFile.close();
-    }
-    else
-    {
-      printf("Error opening dataFile\n");
-    }
-}
-
-/**************************************************************************/
-/*!
-
-*/
-/**************************************************************************/
-void cmdSdRead()
-{
-    if (myFile.open(FILENAME, O_READ))
-
-    {
-      char data[101];
-      myFile.read(data, 100);
-      Serial.print((char *)data);
-      myFile.close();
-    }
-    else
-    {
-      printf("Error opening dataFile\n");
-    }
-}
-
-/**************************************************************************/
-/*!
-
-*/
-/**************************************************************************/
-void cmdSdClear()
-{
-    if (myFile.open(FILENAME, O_RDWR | O_CREAT | O_TRUNC))
-    {
-      myFile.close();
-    }
-    else
-    {
-      printf("Error opening dataFile\n");
-    }
-}

 /**************************************************************************/
 /*!
@@ -511,29 +581,29 @@

 /**************************************************************************/
-//
+//
 /**************************************************************************/
 void cmdSleepMcu(int arg_cnt, char **args)
 {
   printf("Sleeping MCU\n");
   delay(100);
-
+
   // set pullups on inputs
 //  pinMode(sdCsPin, INPUT);
 //nn  digitalWrite(sdCsPin, HIGH);
-
+
 //  pinMode(sdDetectPin, INPUT);
   digitalWrite(sdDetectPin, LOW);

   digitalWrite(ledPin, LOW);
-
+
   attachInterrupt(2, rtcInterrupt, FALLING);
   delay(100);

   set_sleep_mode(SLEEP_MODE_PWR_DOWN);
   chibiSleepRadio(0);
   sleep_enable();        // setting up for sleep ...
-
+
   ADCSRA &= ~(1 << ADEN);    // Disable ADC
   sleep_mode();

@@ -544,33 +614,33 @@
 }

 /**************************************************************************/
-//
+//
 /**************************************************************************/
 void cmdSleepRadio(int arg_cnt, char **args)
 {
   int val = strtol(args[1], NULL, 10);
-
+
   if (val)
   {
     digitalWrite(hgmPin, LOW);
-
+
     // set up chibi regs to turn off external P/A
     chibiRegWrite(0x4, 0x20);
   }
   else
   {
     digitalWrite(hgmPin, HIGH);
-
+
     // set up chibi regs to turn on external P/A
     chibiRegWrite(0x4, 0xA0);
   }
-
+
   // turn on/off radio
   chibiSleepRadio(val);
 }

 /**************************************************************************/
-//
+//
 /**************************************************************************/

@@ -578,56 +648,131 @@
 {
   uint8_t hours, minutes, seconds;
   uint8_t year, month, day, weekday;
-
+
   pcf.readTime(&hours, &minutes, &seconds);
   pcf.readDate(&year, &month, &day, &weekday);
-
+
   printf("Year: %d, Month: %d, Day: %d, Weekday: %d Hours: %d, Minutes: %d, Seconds: %d\n", year, month, day, weekday, hours, minutes, seconds);
 }

 /**************************************************************************/
-//
+//
 /**************************************************************************/
 void cmdWriteTime(int arg_cnt, char **args)
 {
   uint8_t hours, minutes, seconds;
-
+
   hours = chibiCmdStr2Num(args[1], 10);
   minutes = chibiCmdStr2Num(args[2], 10);
   seconds = chibiCmdStr2Num(args[3], 10);
   pcf.writeTime(hours, minutes, seconds);
-
+
   pcf.readTime(&hours, &minutes, &seconds);
   printf("Hours: %d, Minutes: %d, Seconds: %d\n", hours, minutes, seconds);
 }

 /**************************************************************************/
-//
+//
 /**************************************************************************/
 void cmdWriteDate(int arg_cnt, char **args)
 {
   uint8_t year, month, day, weekday;
-
+
   year = chibiCmdStr2Num(args[1], 10);
   month = chibiCmdStr2Num(args[2], 10);
   day = chibiCmdStr2Num(args[3], 10);
   weekday = chibiCmdStr2Num(args[4], 10);
   pcf.writeDate(year, month, day, weekday);
-
+
   pcf.readDate(&year, &month, &day, &weekday);
   printf("Year: %d, Month: %d, Day: %d, Weekday: %d\n", year, month, day, weekday);
 }

-
+bool get_sonar(int32_t &distance){
+  int32_t duration;
+  digitalWrite(sonarTriggerPin, LOW);
+  delayMicroseconds(2);
+  digitalWrite(sonarTriggerPin, HIGH);
+  delayMicroseconds(10);
+  digitalWrite(sonarTriggerPin, LOW);
+  duration = pulseIn(sonarEchoPin, HIGH);
+
+  distance = (duration/2) / 29.1;
+  if (distance >= 200){
+    distance = 200;
+  }
+  if (distance < 0){
+    distance = 0;
+  }
+
+  /*digitalWrite(ledPin, HIGH);
+  delay(distance*10);
+  digitalWrite(ledPin, LOW);*/
+
+}
+
+#ifdef OneWireSensor
+bool get_temp_ow(int32_t &temperature){
+    byte addr[8];
+    byte present = 0;
+    byte data[12];
+
+    if ( !OW_temperature_probe.search(addr)) {
+      Serial.println("No more addresses.");
+      Serial.println();
+      OW_temperature_probe.reset_search();
+      delay(250);
+      temperature=0;
+      OW_temperature_probe.search(addr);
+    }
+    Serial.print("ROM =");
+    for( int i = 0; i < 8; i++) {
+      Serial.write(' ');
+      Serial.print(addr[i], HEX);
+    }
+
+    OW_temperature_probe.reset();
+    OW_temperature_probe.select(addr);
+    OW_temperature_probe.write(0x44, 1);
+    delay(1000);
+    present = OW_temperature_probe.reset();
+    OW_temperature_probe.select(addr);
+    OW_temperature_probe.write(0xBE);         // Read Scratchpad
+    Serial.print("  Data = ");
+    Serial.print(present, HEX);
+    Serial.print(" ");
+    for ( int i = 0; i < 9; i++) {           // we need 9 bytes
+      data[i] = OW_temperature_probe.read();
+      Serial.print(data[i], HEX);
+      Serial.print(" ");
+    }
+    Serial.print(" CRC=");
+    Serial.print(OneWire::crc8(data, 8), HEX);
+    Serial.println();
+
+    int16_t raw = (data[1] << 8) | data[0];
+    byte cfg = (data[4] & 0x60);
+    // at lower res, the low bits are undefined, so let's zero them
+    if (cfg == 0x00) raw = raw & ~7;  // 9 bit resolution, 93.75 ms
+    else if (cfg == 0x20) raw = raw & ~3; // 10 bit res, 187.5 ms
+    else if (cfg == 0x40) raw = raw & ~1; // 11 bit res, 375 ms
+    //// default is 12 bit resolution, 750 ms conversion time
+    float celsius = (float)raw / 16.0;
+    Serial.print("  Temperature = ");
+    Serial.println(celsius);
+    temperature = (int)(celsius*100);
+    return true;
+}
+#endif

 bool get_temp(int32_t &temperature, int32_t& humidity){
-
+
     // It's ugly, isn't it?
-    int pin = 8;
+    int pin = sensorPin;
     int ret = 0;
     uint8_t bits[5];
     const int DHTLIB_TIMEOUT = (F_CPU/40000);
-
+
     // INIT BUFFERVAR TO RECEIVE DATA
     uint8_t mask = 128;
     uint8_t idx = 0;
@@ -641,7 +786,7 @@

     // REQUEST SAMPLE
     pinMode(pin, OUTPUT);
-    digitalWrite(pin, LOW); // T-be
+    digitalWrite(pin, LOW); // T-be
     delay(18);  //delay(wakeupDelay);
     digitalWrite(pin, HIGH);   // T-go
     delayMicroseconds(40);
@@ -678,7 +823,7 @@
         }

         if ((micros() - t) > 40)
-        {
+        {
             bits[idx] |= mask;
         }
         mask >>= 1;
@@ -726,7 +871,7 @@
     int i, addr, len;

     addr = chibiCmdStr2Num(args[1], 16);
-
+
     for (i=0; i<1000; i++)
     {
       sprintf((char *)data, "%04d", i);
@@ -774,3 +919,76 @@

+/**************************************************************************/
+/*!
+
+*/
+/**************************************************************************/
+void cmdSdWrite(int arg_cnt, char **args)
+{
+    char data[1000];
+
+    // concatenate strings typed into the command line and send it to
+    // the specified address
+    strCat(data, 1, arg_cnt, args);
+
+    SdWriteBuf(data);
+}
+
+/**************************************************************************/
+/*!
+
+*/
+/**************************************************************************/
+void SdWriteBuf(char *data)
+{
+    if (myFile.open(FILENAME, O_RDWR | O_CREAT | O_AT_END))
+
+    {
+      myFile.write(data);
+      myFile.close();
+    }
+    else
+    {
+      printf("Error opening dataFile\n");
+    }
+}
+
+
+/**************************************************************************/
+/*!
+
+*/
+/**************************************************************************/
+void cmdSdRead()
+{
+    if (myFile.open(FILENAME, O_READ))
+
+    {
+      char data[101];
+      myFile.read(data, 100);
+      Serial.print((char *)data);
+      myFile.close();
+    }
+    else
+    {
+      printf("Error opening dataFile\n");
+    }
+}
+
+/**************************************************************************/
+/*!
+
+*/
+/**************************************************************************/
+void cmdSdClear()
+{
+    if (myFile.open(FILENAME, O_RDWR | O_CREAT | O_TRUNC))
+    {
+      myFile.close();
+    }
+    else
+    {
+      printf("Error opening dataFile\n");
+    }
+}


Got the PID working! PID is properly set to run in "parallel" now just need to do the same for the motor and fan control.

--- sketch_steppermotor/sketch_steppermotor.ino
+++ sketch_steppermotor/sketch_steppermotor.ino
@@ -23,21 +23,37 @@
 int fan0 = 8;
 int fan2 = 2;
 int readySig = 70;
-const int BETA = 4267;
-const float R_ZERO = 100000.0;
-const float TO_VOLTS = 5.0/1024.0;
+const int BETA = 4092; // 4092 is the Beta for TDK 100k Epcos Therm #8304
+                        // 4267 is the Beta from the Semitec 104GT-2
+const float R_ZERO = 100000.0; // Resistance at 25C
+const float TO_VOLTS = 5.0/1024.0; // 5V board power / 1024 10bit range
 const float R_INF = R_ZERO*exp(1.0*-BETA/298.0);
+
+/* PID working variables*/
+int heat0 = 9; // Heater for extruder 0
+unsigned long lastTime;
+float Input, Output, Setpoint;
+float ITerm, lastInput;
+float kp, ki, kd;
+int SampleTime = 1000; //1 sec
+int outMin = 0; // The min output value, 0 is fully off
+int outMax = 255; // the max output value, 255 is the max for PWM
+
 void setup() {
   pinMode(13, OUTPUT);
   pinMode(fan0, OUTPUT);
   pinMode(fan2, OUTPUT);
   pinMode(readySig, OUTPUT);
+  pinMode(heat0, OUTPUT);
   digitalWrite(fan2, LOW);
+  Setpoint = 100;

   digitalWrite(readySig, HIGH);
 //  analogWrite(fan0, 255);
 //  analogWrite(fan2, 0);
   Serial.begin(9600);
+
+  SetTunings(50, 1, 9); // Sets the initial PID parameters

 //  pinMode(slaveSelectPin, OUTPUT);
 //  SPI.begin();
@@ -92,20 +108,56 @@

 }

-void loop() {
-  digitalWrite(13, HIGH);
-//  float resistance = 4700.0*5.0/(1.0*analogRead(thermNozzle)*TO_VOLTS)-4700;
-  float resistance = 4700.0*1.0/(5/(1.0*analogRead(thermNozzle)*TO_VOLTS)-1);
+void Compute()
+{
+  // if(!digitalRead(heatOnPin) return;
+  unsigned long now = millis();
+  int timeChange = (now - lastTime);
+  if(timeChange>=SampleTime)
+  {
+    Input = getCurrTemp();
+    /*Compute all the working error variables*/
+    double error = Setpoint - Input;
+    ITerm+= (ki * error);
+    if(ITerm > outMax) ITerm = outMax;
+    else if(ITerm < outMin) ITerm = outMin;
+    float dInput = (Input - lastInput);
+
+    /*Compute PID Output*/
+    Output = kp * error + ITerm- kd * dInput;
+    if(Output > outMax) Output = outMax;
+    else if(Output < outMin) Output = outMin;
+
+    String out = "Output: " + String(Output);
+    Serial.println(out);
+    analogWrite(heat0, Output);
+
+    /*Remember some variables for next time*/
+    lastInput = Input;
+    lastTime = now;
+  }
+}
+
+float getCurrTemp(){
+  float resistance = 4700.0/(5/(analogRead(thermNozzle)*TO_VOLTS)-1);
   String tov = "To Volts: " + String(TO_VOLTS, 9);
   String res = "Resist: " + String(resistance);
   String rinf = "R_INF: " + String(R_INF, 9);
-  Serial.println(tov);
   Serial.println(res);
-  Serial.println(rinf);
   float temp = BETA/log(resistance/R_INF)-273.15;
-  Serial.println(analogRead(thermNozzle));
-  Serial.println(temp);
-  delay(1000);
-  digitalWrite(13, LOW);
-  delay(50);
+  String tempString = "Temp: " + String(temp);
+  Serial.println(tempString);
+  return temp;
 }
+
+void SetTunings(double Kp, double Ki, double Kd)
+{
+  double SampleTimeInSec = ((double)SampleTime)/1000;
+  kp = Kp;
+  ki = Ki * SampleTimeInSec;
+  kd = Kd / SampleTimeInSec;
+}
+
+void loop() {
+  Compute();
+}


delay required to make blink work again with Arduino 1.6.x

--- ksp-gegi/ksp-gegi.ino
+++ ksp-gegi/ksp-gegi.ino
@@ -244,5 +244,5 @@
   updatePins();
   checkSerialInput();
   updateLeds();
-//  delay(200);
-}
+  delay(100);
+}


refine code for new clients

refine code for new clients

--- client/client.ino
+++ client/client.ino
@@ -27,11 +27,11 @@
 // In this simplified design, there is no need to save states on client for feedback
 // so I have deleted all state variables like IDLE, PENDING, CONNECTED, etc.

-SoftwareSerial XBee(2, 3); // RX, TX
+SoftwareSerial XBee(3,2); // RX, TX
 int ledStatePin = 13;
-int ledSignalPin = 11;
+int ledSignalPin = 10;
 int controlledPin = 12;
-int ledTargetPin = 10;
+int ledTargetPin = 11;

 int RECV_PIN = 8;
 IRrecv irrecv(RECV_PIN);
@@ -198,11 +198,17 @@
         //1st means selected by system as default candidate
         //080 means switched by user
         //do the same thing but has different meaning in terms of logging
+        DEBUG_TAGGING("my id: ", atoi(deviceId));
+        DEBUG_TAGGING(", select id: ", atoi(p.id));
+        DEBUG_TAGGING(", equal: ", atoi(deviceId)==atoi(p.id));
+        DEBUG_TAGGING("", "");
+
         if(exp_mode == MODE_IR) {
           if(statePending) {
             //only change led if it's in pending (is one of the candidates)
             //blink at low frequency
             if(atoi(p.id) == atoi(deviceId)) {
+
               blinkShort = false;
             } else {
               blinkShort = true;
@@ -212,6 +218,7 @@
             //MODE_LIST
             //only hovered is blinking (fast), all the others doesn't blink
             if(atoi(p.id) == atoi(deviceId)) {
+
               statePending = true;
               blinkShort = false;


clean-up

clean-up

--- VardeLED.ino
+++ VardeLED.ino
@@ -69,7 +69,6 @@

           // Poll packet. Send poll reply.
           case OpPoll:
-            //udp.read(buffer, min(udp.available(), (int)sizeof(buffer)));
             node.createPollReply();
             artnetSend(buffer, sizeof(ArtPollReply));
             break;
@@ -101,7 +100,6 @@

           // IpProg packet
           case OpIpProg:
-            //udp.read(buffer, min(udp.available(), (int)sizeof(buffer)));
             node.createIpProgReply();
             artnetSend(buffer, sizeof(ArtIpProgReply));
             break;


eta: use average

eta: use average

--- src/src.ino
+++ src/src.ino
@@ -116,8 +116,9 @@

   current_bearing = bearing(current_loc, current_dest);

-  eta_time = -delta_time * current_dist / delta_dist;
-  put_avg(eta_time / 1000);
+  double inst_eta = -delta_time * current_dist / delta_dist;
+  put_avg(inst_eta);
+  eta_time = get_avg();
 }

 // Used for simulating GPS data


refactor: remove unused fn call

refactor: remove unused fn call

--- src/src.ino
+++ src/src.ino
@@ -131,7 +131,6 @@

 void draw() {
   draw_dist_eta();
-  draw_lines();
 }

 // Used for simulating GPS data


Defaulting to a smaller TEMP_OFFSET

Defaulting to a smaller TEMP_OFFSET

--- controller/controller.ino
+++ controller/controller.ino
@@ -11,7 +11,7 @@

 #define TEMP_CMD       'S'   // Header tag for the temperature sync message
 #define TEMP_LEN        2    // Length of temperature payload
-#define TEMP_OFFSET     1.0  // Temperature offset
+#define TEMP_OFFSET     0.25 // Temperature offset
 #define TEMP_TARGET     64.0 // Temperature target

 int relay_status        = HIGH;


Clearing variables

Clearing variables

--- staff/staff.ino
+++ staff/staff.ino
@@ -22,7 +22,7 @@
 #define NIGHT_SPARKLES 8

 int maxPatternId = 8;
-int rotationInMillseconds = 29000; // 20 seconds for production¡
+int rotationInMillseconds = 20000; // 20 seconds for production¡

 //bool holdPattern = true;
 //int patternId = DISCO_TWIRL_2;
@@ -226,6 +226,18 @@
 void discoTwirl2() {

   if (firstTimeRunningThroughPattern) {
+     thishue = 0;                                          // You can change the starting hue value for the first wave.
+thisrot = 18;                                          // You can change how quickly the hue rotates for this wave. Currently 0.
+allsat = 255;                                         // I like 'em fully saturated with colour.
+thisdir = 0;                                             // You can change direction.
+thisspeed = 16;                                         // You can change the speed, and use negative values.
+allfreq = 1;                                         // You can change the frequency, thus overall width of bars.
+thisphase = 0;                                            // Phase change value gets calculated.
+thiscutoff = 200;                                     // You can change the cutoff value to display this wave. Lower value = longer wave.
+fade = 200;
+fadeUp = 0;
+
+
     thisrot = 0;                                          // You can change how quickly the hue rotates for this wave. Currently 0.
     allsat = 255;                                         // I like 'em fully saturated with colour.
     thisdir = 0;                                             // You can change direction.


fixed the classic fix vs stroke issue after migrating to the TFT library

--- libraries/Robot_Control/examples/explore/R03_Disco_Bot/R03_Disco_Bot.ino
+++ libraries/Robot_Control/examples/explore/R03_Disco_Bot/R03_Disco_Bot.ino
@@ -148,17 +148,17 @@
 // display the song
 void setInterface() {
   Robot.clearScreen();
-  Robot.fill(0, 0, 0);
+  Robot.stroke(0, 0, 0);
   Robot.text(musics[0], 0, 0);
 }

 // display the next song
 void select(int seq, boolean onOff) {
   if(onOff){//select
-    Robot.fill(0, 0, 0);
+    Robot.stroke(0, 0, 0);
     Robot.text(musics[seq], 0, 0);
   }else{//deselect
-    Robot.fill(255, 255, 255);
+    Robot.stroke(255, 255, 255);
     Robot.text(musics[seq], 0, 0);
   }
 }


Update ArduCAM_Shield_V2_Digital_Camera.ino

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


Report every minute.

Report every minute.

--- KegScribe.ino
+++ KegScribe.ino
@@ -33,10 +33,10 @@
 #define TAP2_IMPORT_CODE         F("KegScribeTap2")

 // number of milliseconds between recording to SD card
-#define RECORD_INTERVAL (1000UL*60UL*5UL)
+#define RECORD_INTERVAL (1000UL*60UL*1UL)

 // number of milliseconds between reports to the web server
-#define REPORT_INTERVAL 0 // (1000UL*60UL*1UL)
+#define REPORT_INTERVAL (1000UL*60UL*1UL)

 // number of seconds between calls to the NTP server
 #define NTP_INTERVAL    (60*60*24)


correct include statement

correct include statement

--- firmware/examples/basic-cwop.ino
+++ firmware/examples/basic-cwop.ino
@@ -1,4 +1,4 @@
-#include "cwop-particle.h"
+#include "cwop-particle/cwop-particle.h"
 #define CWOP_ID "FWxxxx"
 #define CWOP_LAT_DEG 00
 #define CWOP_LAT_MIN 00.00


deleted Robot_2_0.ino . Moved it to examples directory

--- Robot_2_0.ino
+++ Robot_2_0.ino
@@ -1,121 +0,0 @@
-#include "robot.h"
-
-#define BAUD_RATE		9600
-
-#define R_ENABLE		4
-#define R_MOTOR_1		5
-#define R_MOTOR_2		6
-#define R_MOTOR_MAX_PWM	255
-
-#define L_ENABLE		9
-#define L_MOTOR_1		11
-#define L_MOTOR_2		10
-#define L_MOTOR_MAX_PWM	255
-
-#define VCC				12
-
-#define COMMAND_DELAY	500
-
-Robot robot(R_ENABLE,R_MOTOR_1,R_MOTOR_2,L_ENABLE,L_MOTOR_1,L_MOTOR_2,VCC);
-
-unsigned long timer = 0;		//Stores the time when the last command was received
-
-char command = 'S';
-char last_command = 'S';
-
-bool autonomous = false;		//Stores if the robot is on autonomous mode
-
-////Ultrasonic test////
-
-#define US_VCC		A2
-#define US_TRIG		A4
-#define US_ECHO		A3
-#define US_GND		A5
-
-////////////////////////
-
-//Functions
-void getCommand();
-void useCommand();
-
-void setup()
-{
-	/*
-	 *Setting the PWM as a constant indicates that the method used to
-	 *change the robot speed will be using the method setSpeed, that
-	 *accepts a number between 0 and 100.
-	 */
-
-	robot.setMinPWM(80,80);
-	robot.setPWM(R_MOTOR_MAX_PWM,L_MOTOR_MAX_PWM);
-	robot.stop();
-
-	Serial.begin(BAUD_RATE);
-
-	////////////////Ultrasonic test////////////////
-
-	pinMode(US_VCC, OUTPUT);
-	pinMode(US_GND, OUTPUT);
-	digitalWrite(US_VCC, HIGH);
-	digitalWrite(US_GND, LOW);
-
-	robot.setUltrasonic(US_TRIG, US_ECHO, FRONT);
-
-	///////////////////////////////////////////////
-}
-
-void loop()
-{
-	bool read_sensors = true;
-
-	if(Serial.available() > 0)
-	{
-		/*
-		 * Read data from serial and control the robot
-		 */
-		getCommand();
-		robot.useCommand(command);
-	}
-	else if(millis() - timer > COMMAND_DELAY && !autonomous)
-	{
-		/*
-		 * If the last command received was greater than the command delay and
-		 * the robot is not autonomous, stop it
-		 */
-
-		 robot.stop();
-		 read_sensors = false;
-	}
-
-	if(autonomous)
-	{
-		/*
-		 * Autonomous mode
-		 * This piece of code was made just for testing
-		 */
-
-		float distance = robot.getUltrasonicDistance(FRONT, 1);
-		if(distance < 40)
-		{
-			robot.moveBackwards();
-		} else if (distance > 50)
-		{
-			robot.moveForward();
-		} else {
-			robot.stop();
-		}
-		delay(20);
-	}
-	else if(read_sensors)
-	{
-		Serial.println(robot.getUltrasonicDistance(FRONT, 1));
-	}
-}
-
-void getCommand()
-{
-	last_command = command;
-	command = Serial.read();
-	timer = millis();
-	Serial.println(command);
-}


Added pulse width detect to rad sensor pin

Attempt to filter out spurious signals.

--- RadBit/RadBit.ino
+++ RadBit/RadBit.ino
@@ -13,6 +13,10 @@
 RTC_Millis rtc;

 time_t countInterval = 60000;  // Sums counts per 60 seconds
+time_t advertisingInterval = 30000;
+
+volatile unsigned long pulseStart;
+const unsigned long pulseWidth = 50;

 RadFram rFram(framSzBytes);
@@ -20,6 +24,7 @@
 RadStorage radStorage(&rFram);

 Task countTask(&countFunc, countInterval, 0);
+Task advertisingTask(&enableAdvertising, advertisingInterval, 1);

 volatile bool radFlag = 0;
@@ -28,6 +33,10 @@
 const int intPin = 0;

 Tevisio_RD3024 radSensor(intPin);
+
+void enableAdvertising(){
+    Bean.enableAdvertising(true, 10000);
+}

 void blinkBean() {
   Bean.setLed(0, 250, 0);
@@ -43,9 +52,22 @@
   delay(75);
 }

+void powerSettings(){
+    Bean.setAccelerometerPowerMode(0x80); //Suspend mode (~0.5uA)
+
+    // Disable the ADC by setting the ADEN bit (bit 7)  of the
+    // ADCSRA register to zero.
+    ADCSRA = ADCSRA & B01111111;
+
+    // Disable the analog comparator by setting the ACD bit
+    // (bit 7) of the ACSR register to one.
+    ACSR = B10000000;
+
+}
+

 inline void startRadSensor() {
-  attachInterrupt(radSensor.getPin(), radEvent, FALLING);
+  attachInterrupt(radSensor.getPin(), radEventRise, RISING);
 }

 inline void stopRadSensor() {
@@ -56,7 +78,8 @@
   blinkBean();
   blinkBean();
   blinkBean();
-  delay(2000);
+  Bean.enableAdvertising(true);
+

   radStorage.begin();
@@ -80,13 +103,17 @@
   //TODO Power Manegment

   scheduler.addEvent(&countTask);
+  scheduler.addEvent(&advertisingTask);
+  Bean.enableAdvertising(true);
+  delay(5000);
+
 }

 void setup() {

   begin();
-  delay(5000);
+
   blinkBean();

   countTask.enable();
@@ -119,19 +146,32 @@
   scheduler.run();
   delay(5);

-}
-
-
-void radEvent() {
+
+}
+
+
+void radEventRise() {
   stopRadSensor();
-  radFlag = 1;
-  radCnt++;
-  startRadSensor();
+  pulseStart = micros();
+  attachInterrupt(radSensor.getPin(), radEventFall, FALLING);
+
+
+}
+
+void radEventFall() {
+  stopRadSensor();
+  if(micros() - pulseStart >= pulseWidth){
+      radFlag = 1;
+      radCnt++;
+  }
+  attachInterrupt(radSensor.getPin(), radEventRise, RISING);
+

 }

 void countFunc() {
+
   countTask.disable();
   stopRadSensor();
   DateTime temp = rtc.now();


added a little delay to the startup message

--- ScooterSpeedo.ino
+++ ScooterSpeedo.ino
@@ -56,7 +56,10 @@
     while (1);
   }
   mma.setRange(MMA8451_RANGE_8_G);
+
   lcd.print("Ready!");
+  delay(1000);
+  lcd.clear();
 }

 void loop() {
@@ -65,7 +68,7 @@
   /* Get a new sensor event */
   sensors_event_t event;
   mma.getEvent(&event);
-
+
   lcd.clear();

   lcd.print("Revolutions: ");
@@ -76,6 +79,7 @@
   lcd.print("AccY:");
   lcd.print(event.acceleration.y);
   lcd.print(" m/s^2");
+  // using blocking delay debounces the accelerometer and gives the display time to refresh
   delay(250);
 }

@@ -84,3 +88,4 @@
   tickCount = tickCount + 1;
   millisSinceLastTick = millis();
 }
+


Parameter swap in the CAN send function call fixed.

--- VSCP/examples/Seeed-Studio-CAN_BUS_Shield/Seeed-Studio-CAN_BUS_Shield.ino
+++ VSCP/examples/Seeed-Studio-CAN_BUS_Shield/Seeed-Studio-CAN_BUS_Shield.ino
@@ -78,7 +78,7 @@
              (((uint32_t)txMsg->vscpType)  <<  8) |
              txMsg->oAddr;

-  if (CAN_OK == canCom.sendMsgBuf(canMsgId, 1, txMsg->dataNum, 0, (unsigned char*)txMsg->data)) {
+  if (CAN_OK == canCom.sendMsgBuf(canMsgId, 1, 0, txMsg->dataNum, (unsigned char*)txMsg->data)) {

     status = true;
   }