removed non-volatile status and fixed cli

--- Arduino/hardware/REV10/REV10MessagePathTest/REV10SecureBHR/REV10SecureBHR.ino
+++ Arduino/hardware/REV10/REV10MessagePathTest/REV10SecureBHR/REV10SecureBHR.ino
@@ -114,6 +114,22 @@
 static constexpr uint8_t PP_OFF_MS = 250;
 // Mask for Port B input change interrupts.
 static constexpr uint8_t RFM23B_INT_MASK = (1 << (PIN_RFM_NIRQ&7));
+// Mask for Port D input change interrupts.
+static constexpr uint8_t SERIALRX_INT_MASK = (1 << 0); // Serial RX
+/////// STATS  // TODO
+// Singleton non-volatile stats store instance.
+//OTV0P2BASE::EEPROMByHourByteStats eeStats;
+//// Singleton stats-updater object.
+//typedef
+//    OTV0P2BASE::ByHourSimpleStatsUpdaterSampleStats <
+//      decltype(eeStats), &eeStats,
+//      OTV0P2BASE::SimpleTSUint8Sensor, static_cast<OTV0P2BASE::SimpleTSUint8Sensor*>(NULL), // Save code space when no occupancy tracking.
+//      decltype(AmbLight), &AmbLight,
+//      decltype(TemperatureC16), &TemperatureC16,
+//      decltype(RelHumidity), &RelHumidity,
+//      2
+//      > StatsU_t;
+//StatsU_t statsU;

 //========================================
 // LOCAL FUNCTIONS
@@ -219,6 +235,24 @@
     // TODO: try to ensure that OTRFM23BLink.handleInterruptSimple() is inlineable to minimise ISR prologue/epilogue time and space.
     if((changes & RFM23B_INT_MASK) && !(pins & RFM23B_INT_MASK))
         { PrimaryRadio.handleInterruptSimple(); }
+}
+
+// Previous state of port D pins to help detect changes.
+static volatile uint8_t prevStatePD;
+// Interrupt service routine for PD I/O port transition changes (including RX).
+ISR(PCINT2_vect)
+{
+    const uint8_t pins = PIND;
+    const uint8_t changes = pins ^ prevStatePD;
+    prevStatePD = pins;
+
+    // If an interrupt arrived from the serial RX then wake up the CLI.
+    // Use a nominally rising edge to avoid spurious trigger when other interrupts are handled.
+    // The will ensure that it is possible to wake the CLI subsystem with an extra CR or LF.
+    // It is OK to trigger this from other things such as button presses.
+    // TODO: ensure that resetCLIActiveTimer() is inlineable to minimise ISR prologue/epilogue time and space.
+    if((changes & SERIALRX_INT_MASK) && !(pins & SERIALRX_INT_MASK))
+    { OTV0P2BASE::CLI::resetCLIActiveTimer(); }
 }

@@ -420,18 +454,17 @@
         // Got plausible input so keep the CLI awake a little longer.
         OTV0P2BASE::CLI::resetCLIActiveTimer();
         // Process the input received, with action based on the first char...
-        bool showStatus = true; // Default to showing status.
         switch(buf[0])
         {
             // Explicit request for help, or unrecognised first character.
             // Not implemented so indicate unrecognised input.
-            default: case '?': { OTV0P2BASE::CLI::InvalidIgnored(); Serial.println(); showStatus = false; break; }
+            default: case '?': { OTV0P2BASE::CLI::InvalidIgnored(); Serial.println(); break; }
             // Exit/deactivate CLI immediately.
             // This should be followed by JUST CR ('\r') OR LF ('\n')
             // else the second will wake the CLI up again.
             case 'E': { OTV0P2BASE::CLI::makeCLIInactive(); break; }
             // Reset or display ID.
-            case 'I': { showStatus = OTV0P2BASE::CLI::NodeID().doCommand(buf, n); break; }
+            case 'I': { OTV0P2BASE::CLI::NodeID().doCommand(buf, n); break; }
             // Status line stats print and TX.
             case 'S':
             {
@@ -447,24 +480,17 @@
             }
             // Set new node association (nodes to accept frames from).
             // Only needed if able to RX and/or some sort of hub.
-            case 'A': { showStatus = OTV0P2BASE::CLI::SetNodeAssoc().doCommand(buf, n); break; }
+            case 'A': { OTV0P2BASE::CLI::SetNodeAssoc().doCommand(buf, n); break; }
             /**
             * @brief Set secret key.
             * @note  The OTRadioLink::SimpleSecureFrame32or0BodyTXV0p2::resetRaw3BytePersistentTXRestartCounterCond
             *        function pointer MUST be passed here to ensure safe handling of the key and the Tx message
             *        counter.
             */
-            case 'K': { showStatus = OTV0P2BASE::CLI::SetSecretKey(OTRadioLink::SimpleSecureFrame32or0BodyTXV0p2::resetRaw3BytePersistentTXRestartCounterCond).doCommand(buf, n); break; }
+            case 'K': { OTV0P2BASE::CLI::SetSecretKey(OTRadioLink::SimpleSecureFrame32or0BodyTXV0p2::resetRaw3BytePersistentTXRestartCounterCond).doCommand(buf, n); break; }
         }
-
-        // Almost always show status line afterwards as feedback of command received and new state.
-//        if(showStatus) { serialStatusReport(); } // FIXME
-        // Else show ack of command received.
-//        else {
-            Serial.println(F("OK"));
-//          }
-    }
-    else { Serial.println(); } // Terminate empty/partial CLI input line after timeout.
+        Serial.println(F("OK"));
+    } else { Serial.println(); } // Terminate empty/partial CLI input line after timeout.

     // Force any pending output before return / possible UART power-down.
     OTV0P2BASE::flushSerialSCTSensitive();
@@ -550,8 +576,9 @@
     // Set up async edge interrupts.
     ATOMIC_BLOCK (ATOMIC_RESTORESTATE)
     {
-        PCICR = 1 ;//| 4;  // 0x1 enables PB/PCMSK0. 0x4 enables PD/PCMSK2.
+        PCICR = 1 | 4;  // 0x1 enables PB/PCMSK0. 0x4 enables PD/PCMSK2.
         PCMSK0 = RFM23B_INT_MASK;
+        PCMSK2 = SERIALRX_INT_MASK;
     }

@@ -624,7 +651,6 @@
     stackCheck();

     // Set up some variables before sleeping to minimise delay/jitter after the RTC tick.
-    bool showStatus = false; // Show status at end of loop?
     // Sensor readings are taken late in each minute (where they are taken)
     // and if possible noise and heat and light should be minimised in this part of each minute to improve readings.
     // Sensor readings and (stats transmissions) are nominally on a 4-minute cycle.
@@ -771,8 +797,6 @@
                 DEBUG_SERIAL_PRINTLN();
             }
 #endif
-            // Show current status if appropriate.
-//            if(runAll) { showStatus = true; }  // TODO
             // Age errors/warnings.
             OTV0P2BASE::ErrorReporter.read();
             break;
@@ -803,7 +827,6 @@
     // then poll/prompt the user for input
     // using a timeout which should safely avoid overrun, ie missing the next basic tick,
     // and which should also allow some energy-saving sleep.
-//    if(showStatus) { serialStatusReport(); }
     if(OTV0P2BASE::CLI::isCLIActive()) {
         const uint8_t stopBy = nearOverrunThreshold - 1;
         char buf[BUFSIZ_pollUI];


Update Air_monitor.ino

Update Air_monitor.ino

Updated comments and useful info

--- Air_monitor.ino
+++ Air_monitor.ino
@@ -68,7 +68,7 @@
   0x07, 0x03, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
   0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00
 };
-int pin = 8;
+int pin = 8;  //inititalizing digital pin 8, dust sensor
 unsigned long duration;
 unsigned long starttime;
 unsigned long sampletime_ms = 5000;
@@ -77,8 +77,8 @@
 float concentration = 0;
 int sensorValue = 0;

-#define DHTPIN A2
-#define DHTTYPE DHT11
+#define DHTPIN A2  //defining temp and humi sensor analog pin
+#define DHTTYPE DHT11  //define the type of sensor. check the specsheet and seeed wiki
 DHT dht(DHTPIN, DHTTYPE);

 void setup() {
@@ -93,12 +93,12 @@
   delay(3000);
   SeeedOled.clearDisplay();

-  Serial.begin(9600);
+  Serial.begin(9600); //seting the serial speed. if including more sensors increase to a standard value. not needed at the moment as overall sampling speed is +/-5 secs
   pinMode(8, INPUT);
   starttime = millis();

-  Serial.println("Air Quality Gizmo by LMO");
-  Serial.println("Time s, Humidity %, Temperature C, PM ug/m^3, VOC mg/L, Hydrocarbs mg/m^3");
+  Serial.println("Air Quality Gizmo by LMO");
+  Serial.println("Time s, Humidity %, Temperature C, PM ug/m^3, VOC mg/L, Hydrocarbs mg/m^3");  //header of the text file; can be imported as csv in excell

   dht.begin();

@@ -129,7 +129,7 @@
   float t = dht.readTemperature();

   {
-    Serial.print(millis()/1000);
+    Serial.print(millis()/1000);  // elapsed seconds since boot
     Serial.print(",");
     Serial.print(h,1);
     Serial.print(",");
@@ -141,6 +141,9 @@
     Serial.print(",");
     Serial.print(vol_Formol,3);
     Serial.println("");
+
+    // no need to include any SD library as Open Hardware SD Logger works as a standalone arduino and records all serial output
+
   }
   {
     SeeedOled.clearDisplay();
@@ -158,14 +161,14 @@
     SeeedOled.setTextXY(4, 8);
     SeeedOled.putString("mg/m^3");

-    SeeedOled.setTextXY(5, 1);
+    SeeedOled.setTextXY(5, 1); // location of text , fifth row, first collumn
     SeeedOled.putString("Volatile OC:");
     SeeedOled.setTextXY(6, 1); // location to display variable
     SeeedOled.putFloat(vol,3); // variable to display
     SeeedOled.setTextXY(6, 8);
     SeeedOled.putString("mg/L");

-    delay(2000);
+    delay(2000); // screen delay to allow reading in the OLED

     SeeedOled.clearDisplay();
     SeeedOled.setTextXY(1, 1);


Testing Canvas fonts.

Testing Canvas fonts.

--- examples/Canvas/CosaCanvasFontST7735/CosaCanvasFontST7735.ino
+++ examples/Canvas/CosaCanvasFontST7735/CosaCanvasFontST7735.ino
@@ -43,14 +43,14 @@

 // ONLY SYSTEM_5x7 is possible if this is used before Glyphs

-#define SYSTEM_5x7
+//#define SYSTEM_5x7
 //#define FIXEDNUMS_8x16
 //#define SEGMENT_32x50

 //#define FONT_5x8
 //#define FONT_6x9
 //#define FONT_6x10
-//#define FONT_6x12
+#define FONT_6x12
 //#define FONT_6x13
 //#define FONT_6x13B
 //#define FONT_7x13
@@ -196,7 +196,7 @@

   textbox.set_canvas_color(Canvas::WHITE);
   textbox.set_text_color(Canvas::BLACK);
-  textbox.set_text_port(0, 0, tft.WIDTH, tft.HEIGHT);
+  textbox.set_text_port(1, 1, tft.WIDTH - 2, tft.HEIGHT - 2);

 #ifdef ONE_CHAR
   tftout << ONE_CHAR;


Cleaned up comments and structure for readability and clarification.

--- ardu-predator/ardu-predator.ino
+++ ardu-predator/ardu-predator.ino
@@ -1,24 +1,42 @@
-//Arduino Library must include the following library file collections.
-//These repos are forked on my gitHub or you can find them at...
-//https://github.com/jrowberg/i2cdevlib
+/**
+ * ardu-predator.ino
+ *
+ * @author Mike Muscato
+ * @date   2017-01-11
+ *
+ * =============  Attribution ==========================
+ * Based on MPU6050_Latest_code.ino
+ * Originally provided by "HC" aka "zhomeslice" on forum.arduino.cc
+ * at https://forum.arduino.cc/index.php?PHPSESSID=h4c6487i42hbb7uh6rjk0eadp1&topic=446713.msg3073854#msg3073854
+ *
+ * Original source committed in my repo for reference at: arduino/MPU6050/MPU6050_Latest_code/
+ * =====================================================
+ *
+ */
+
+// Arduino Library must include the following library file collections.
+// These repos are forked on my gitHub or you can find them at...
+// https://github.com/jrowberg/i2cdevlib
 #include "I2Cdev.h"
 #include "MPU6050_6Axis_MotionApps20.h"
 #include "Wire.h"

-//Standard included arduino servo library
+// Standard included arduino servo library
 #include "Servo.h"

-//initialize gyro instance
-//TODO:  Change this to initialize two gyros with +VDC/Ground arguments
+// Initialize gyro instance
+// TODO:  Update this to initialize two gyros with +VDC/Ground arguments
 MPU6050 mpu;

-//initialize servo instances
+// Initialize servo instances
 Servo yawServo;
 Servo pitchServo;

-#define DEBUG  //Comment to turn off Serial printing
-
-//Debug serial printing macros
+
+// Comment to turn off Serial printing
+#define DEBUG
+
+// DEBUG serial printing macros
 #ifdef DEBUG
 	//#define DPRINT(args...)  Serial.print(args)             //OR use the following syntax:
 	#define DPRINTSTIMER(t)    for (static unsigned long SpamTimer; (unsigned long)(millis() - SpamTimer) >= (t); SpamTimer = millis())
@@ -31,32 +49,42 @@
 #endif

-//TODO:  Find out if it's really necessary to turn on this LED...probably not.
+// TODO:  Find out if it's really necessary to turn on this LED...probably not.
 const int LED_PIN = 13;

-//Prevent the servos from turning beyond mechanical limits
+// Prevent the servos from rotating beyond mechanical limits
 const int maxPitch = 135;
 const int minPitch = 45;
-//Yaw direction is inverted via map() method in moveServos()
+// NOTE: Yaw direction is inverted via map() method in moveServos()
 const int maxYaw = 135;
 const int minYaw = 45;

-// supply gyro offsets here, scaled for min sensitivity use MPU6050_calibration.ino
+// supply gyro offsets here,
+// Use MPU6050_calibration.ino found at https://forum.arduino.cc/index.php?PHPSESSID=h4c6487i42hbb7uh6rjk0eadp1&topic=446713.msg3073854#msg3073854
+// Also copied in my repo:  arduino/MPU6050/
+//
 // Gyro 0 (head) calibrated at:   {-3074,  -2036,  1236,    63,    -16,     78}
 //                     XA      YA      ZA      XG      YG      ZG
 int MPUOffsets0[6] = {-3074,  -2036,  1236,    63,    -16,     78};

+// var to store the servo position when testing
+int pos = 0;
+
+// vars for angle values.
+float Yaw, Pitch, Roll;
+
+// Will be used for timing events.
 unsigned long currentMillis = 0;    // stores the value of millis() in each iteration of loop()
 unsigned long prevMillis = 0;    // stores the value of millis() in each iteration of loop()

-int pos = 0;    // variable to store the servo position when testing
+

 // ================================================================
 // ===                      i2c SETUP Items                     ===
 // ================================================================
 void i2cSetup() {
-  // join I2C bus (I2Cdev library doesn't do this automatically)
+  // Join I2C bus (I2Cdev library doesn't do this automatically)
 #if I2CDEV_IMPLEMENTATION == I2CDEV_ARDUINO_WIRE
   Wire.begin();
   TWBR = 24; // 400kHz I2C clock (200kHz if CPU is 8MHz)
@@ -65,6 +93,7 @@
 #endif
 }

+
 // ================================================================
 // ===               INTERRUPT DETECTION ROUTINE                ===
 // ================================================================
@@ -72,6 +101,7 @@
 void dmpDataReady() {
   mpuInterrupt = true;
 }
+

 // ================================================================
 // ===                      MPU DMP SETUP                       ===
@@ -174,20 +204,20 @@
 // ================================================================
 // ===                        MPU Math                          ===
 // ================================================================
-float Yaw, Pitch, Roll;
 void MPUMath() {
   mpu.dmpGetQuaternion(&q, fifoBuffer);
   mpu.dmpGetGravity(&gravity, &q);
   mpu.dmpGetYawPitchRoll(ypr, &q, &gravity);

-  //TODO: Move the +90 gyro/servo leveling math to another method,
-  //it doesn't belong here and will cause readability problems later.
+  // Add 90-degrees to center servos when sensor is level (e.g. 0 degrees)
+  // TODO: Move the +90 gyro/servo leveling magic number to another method,
+  // ...it doesn't belong here and will cause readability problems later.
   Yaw = (ypr[0] * 180.0 / M_PI) + 90;
   Pitch = (ypr[1] *  180.0 / M_PI) + 90;
   Roll = (ypr[2] *  180.0 / M_PI) + 90;

   /*
-  //Serial.log the current actual values of the gyro position.
+  // Serial.print the current actual values of the gyro position.
   DPRINTSTIMER(100) {
     DPRINTSFN(15, "\tYaw:", Yaw, 6, 1);
     DPRINTSFN(15, "\tPitch:", Pitch, 6, 1);
@@ -196,15 +226,17 @@
   }
   */

+  // Timer - don't try and move the servos too frequently, they need time to get to the current position.
+  // TODO: Remove delay magic number and move to global var for tuning mechanical
   if (currentMillis >= prevMillis + 15) {
     moveServos(round(Yaw), round(Pitch));
   }

-
-}
+}
+

 /**
- * Move the servos to the gyro postion
+ * Move the servos to the current gyro postion
  * =============================================================
  *
  * @author Mike Muscato
@@ -216,15 +248,14 @@
  */
 void moveServos(int servoYaw, int servoPitch) {

-  //TODO: Determine if yaw/pitch is beyond normal servo angles
-  //i.e. > 179 or < 0
-  //If so, assume actual gyro position and provide max servo value.
-  //Create trimAngles() method.
+  // TODO: Determine if yaw/pitch is beyond normal servo angles i.e. > 179 or < 0
+  // May not be necessary after adding 2nd gyro and using relative angles.
+  // If so, assume actual gyro position and provide max servo value.

-  //Invert Yaw
+  // Invert Yaw values for my servo orientation.
   int invertedYaw = map(servoYaw, 0, 179, 179, 0);

-  //Prevent the servos from moving farther than my head can rotate.
+  // Prevent the servos from panning farther than my head can rotate.
   if (invertedYaw > maxYaw) {
     invertedYaw = maxYaw;
   }
@@ -232,7 +263,7 @@
     invertedYaw = minYaw;
   }

-  //Prevent the servos from tilting farther than my head can nod.
+  // Prevent the servos from tilting farther than my head can nod.
   if (servoPitch > maxPitch) {
     servoPitch = maxPitch;
   }
@@ -240,6 +271,7 @@
     servoPitch = minPitch;
   }

+  // Print out the current yaw and pitch angle values being sent to the servos.
   DPRINTSTIMER(100) {
     DPRINTSFN(15, "\tServo - Yaw:", servoYaw, 6, 1);
     DPRINTSFN(15, "\tServo - invertYaw:", invertedYaw, 6, 1);
@@ -247,81 +279,92 @@
     DPRINTLN();
   }

-
+  // Move the servos to the current yaw/pitch values
   yawServo.write(invertedYaw);
   pitchServo.write(servoPitch);

+  // Reset the timer for comparison on the next loop
   prevMillis = currentMillis;

 }

-// ================================================================
-// ===                         Setup                            ===
-// ================================================================
+/**
+ * =============================================================
+ * ===                 Arduino Setup                         ===
+ * =============================================================
+ *
+ * @author Mike Muscato
+ * @date   2017-01-30
+ *
+ * @return {void}
+ */
 void setup() {
-  Serial.begin(115200); //115200
-  while (!Serial);
+  Serial.begin(115200);
+  while (!Serial);  // Wait for the connection to be established?
+
+  // Run MPU initializations
   Serial.println("i2cSetup");
   i2cSetup();
   Serial.println("MPU6050Connect");
   MPU6050Connect();
   Serial.println("Setup complete");
+
   pinMode(LED_PIN, OUTPUT);

+  // Assign PWM Pins to servo signal wires
   yawServo.attach(9);
   pitchServo.attach(10);

+  // Center the servos' start position
   yawServo.write(90);
   pitchServo.write(90);
 }

-// ================================================================
-// ===                          Loop                            ===
-// ================================================================
+/**
+ * =============================================================
+ * ===                  Arduino Loop                         ===
+ * =============================================================
+ *
+ * @author Mike Muscato
+ * @date   2017-01-30
+ *
+ * @return {void}
+ */
 void loop() {
-  currentMillis = millis();   // capture the latest value of millis()
-  if (mpuInterrupt ) { // wait for MPU interrupt or extra packet(s) available
+  currentMillis = millis();   // Capture the latest value of millis()
+  if (mpuInterrupt ) { // Wait for MPU interrupt or extra packet(s) available
     GetDMP();
   }

-  //for calibrating the start position in the hardware.
-  //TODO: Comment when completed or it will conflict with the
-  //motion of the robot.
+  // Uncomment for setting and adjusting the hardware start position.
+  // (e.g. Setting rotation and leveling the pan/tilt servo arms at initial 90-degree position)
+  // IMPORTANT: Comment out the moveServos() method call in MPUMath() when using this.
+  // TODO: Remove in final program once hardware and software calibration is completed.
+  //
   // yawServo.write(90);
   // pitchServo.write(90);

-  //for testing hardware
-  // //TODO: Comment when completed
-  // for (pos = 0; pos <= 180; pos += 1) { // goes from 0 degrees to 180 degrees
-  //   // in steps of 1 degree
-  //   yawServo.write(pos);              // tell servo to go to position in variable 'pos'
-  //   delay(20);                       // waits 15ms for the servo to reach the position
-  // }
-  // for (pos = 180; pos >= 0; pos -= 1) { // goes from 180 degrees to 0 degrees
-  //   yawServo.write(pos);              // tell servo to go to position in variable 'pos'
-  //   delay(20);                       // waits 15ms for the servo to reach the position
-  // }
-}
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
+}
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+


Added reset function and fixed 8th coil programming

--- ad9833/ad9833.ino
+++ ad9833/ad9833.ino
@@ -17,20 +17,22 @@
 // List of commands goes here.
 const char cmdFreq[] = "FREQ";
 const char cmdRead[] = "READ";
+const char cmdRst[]  = "RESET";

 // Set master clock frequency to 6MHz
 float f_MCK = 6000000.0;

 // Default frequencies for each coil.
 // The number of frequencies should match the number of coils
+// FREQ:1@20300:2@21700:3@22400:4@23600:5@24500:6@25100:7@26800:8@27500
 int coilFreqs[NUMCOILS] ={
-	20500, // Coil 1
-	21500, // Coil 2
-	22500, // Coil 3
-	23500, // Coil 4
+	20300, // Coil 1
+	21700, // Coil 2
+	22400, // Coil 3
+	23600, // Coil 4
 	24500, // Coil 5
-	25500, // Coil 6
-	26500, // Coil 7
+	25100, // Coil 6
+	26800, // Coil 7
 	27500  // Coil 8
 };

@@ -117,7 +119,30 @@
 }

-
+void resetAll()
+{
+  for(int i=0;i<NUMCOILS;i++)
+  {
+    reset(coilEnable[i]);
+  }
+}
+
+
+void reset(int pinNo)
+{
+    SPI.beginTransaction(SPISettings(SPI_CLOCK_DIV128, MSBFIRST, SPI_MODE2));
+    pinMode(pinNo, OUTPUT);
+    digitalWrite(pinNo,LOW);
+
+    delayMicroseconds(25);
+    SPI.transfer(highByte(0x2100));
+    SPI.transfer(lowByte(0x2100));
+
+    delayMicroseconds(25);
+    pinMode(pinNo, INPUT);
+    SPI.endTransaction();
+    delay(10);
+}

 void sendFreq(float freq, int pinNo)
@@ -161,7 +186,7 @@

 void sendAllFreqs()
 {
-	// Send each frequency 10 times to ensure SPI works
+	// Send each frequency 3 times to ensure SPI works
     for (int i = 0; i < NUMCOILS; i++)
     {
     	for (int j = 0; j < 3; j++){
@@ -183,9 +208,10 @@
 		cmd = strtok(NULL, " :");
 		return processFreqs(cmd);
 	}
-	else{
-		return NACK;
-	}
+	else if(!strcmp(cmd, cmdRst)){
+		resetAll();
+	}
+ else{return NACK;}
 }

@@ -216,9 +242,9 @@

 int isCoilValid(int coilNo)
 {
-	for(int i = 0; i < NUMCOILS; i++){
+	for(int i = 1; i <= NUMCOILS; i++){
 		if(i == coilNo){
-			return i + 1; // Add +1 to prevent false return
+			return i ; // Add +1 to prevent false return
 		}
 	}
 	return false;


tidyup

tidyup

--- Arduino/V0p2_Main/V0p2_Main.ino
+++ Arduino/V0p2_Main/V0p2_Main.ino
@@ -155,7 +155,7 @@
   '\0'
   };
 // Version (code/board) information printed as one line to serial (with line-end, and flushed); machine- and human- parseable.
-// Format: "board VXXXX REVY; YYYY/Mmm/DD HH:MM:SS".
+// Format: "board VX.X REVY YYYY/Mmm/DD HH:MM:SS".
 void serialPrintlnBuildVersion()
   {
   OTV0P2BASE::serialPrintAndFlush(F("board V0.2 REV"));


Now calls show() once after all pixels are drawn.

"Where did my commit go? Didn't I fix this earlier?" ~galaxyAbstractor

--- SuwakoHat/SuwakoEyes.ino
+++ SuwakoHat/SuwakoEyes.ino
@@ -69,16 +69,15 @@
       if (inverted) {
         if ((buffer >> 5-x)&1) {
           ledMatrix->drawPixel(y + _offsetY, x + _offsetX, _color);
-          ledMatrix->show();
         }
       } else {
         if ((buffer >> x)&1) {
           ledMatrix->drawPixel((y + _offsetY), (x + _offsetX), _color);
-          ledMatrix->show();
         }
       }
     }
   }
+  ledMatrix->show();
 }

 void animateLookAround() {


Put opening braces on separate line

Put opening braces on separate line

--- coffee-scale.ino
+++ coffee-scale.ino
@@ -22,8 +22,8 @@
 RunningAverage       filter(FILTER_SIZE);
 float                weight_in_grams;

-
-void setup() {
+void setup()
+{
   // Serial comm
   Serial.begin(38400);

@@ -37,8 +37,8 @@
 }

-
-void loop() {
+void loop()
+{
   filter.addValue(scale.get_units());
   weight_in_grams = filter.getAverage();
   gramsDisplay.displayGrams(weight_in_grams);


Bump version to v1.6.6

Bump version to v1.6.6


Updated example

Updated example

--- examples/FSKModem/FSKModem.ino
+++ examples/FSKModem/FSKModem.ino
@@ -77,7 +77,7 @@
   }

   // FSK modulation can be changed to OOK
-  // NOTE: When using OOK, the maximum bit rate is only 32.768 kbps!
+  // NOTE: When using OOK, the maximum bit rate is only 25 kbps!
   //       Also, data shaping changes from Gaussian filter to
   //       simple filter with cutoff frequency. Make sure to call
   //       setDataShapingOOK() to set the correct shaping!


Code review.

Code review.

--- examples/SetClock/SetClock.ino
+++ examples/SetClock/SetClock.ino
@@ -1,7 +1,7 @@
 /*
-This a simple serial port clock application using the RTC Nanoshield.
+This a simple application to set the current time for the RTC Nanoshield.

-Copyright (c) 2013 Circuitar
+Copyright (c) 2017 Circuitar
 This software is released under the MIT license. See the attached LICENSE file for details.
 */

@@ -31,9 +31,7 @@
     while(true);
   };

-  // Print current time and ask for the new time
   Serial.print("Current time:\n");
-  rtc.read();

   // Set date and time
   rtc.writeYear(2018);


report roll status change

report roll status change

--- _28-attiny85-nrf24-3pin-ir/attiny85-nrf24-3pin-ir-reed-interrupt/attiny85-nrf24-3pin-ir-reed-interrupt.ino
+++ _28-attiny85-nrf24-3pin-ir/attiny85-nrf24-3pin-ir-reed-interrupt/attiny85-nrf24-3pin-ir-reed-interrupt.ino
@@ -70,7 +70,8 @@
 #define IRENPIN 4 // p3 / A2
 #define DATA1PIN 3 // p2 // A3

-int16_t currentData1 ;
+int16_t doorStatus;
+int16_t rollStatus;

 void setup() {
   delay(20);
@@ -93,7 +94,7 @@

   unsigned long stopmilis = millis();
   payload.data2 = ( stopmilis - startmilis ) * 10 ;
-  payload.data1  = digitalRead(DATA1PIN) * 10 ;
+  payload.data1  = rollStatus = digitalRead(DATA1PIN) * 10 ;
   payload._salt = 0;
   payload.volt = readVcc();
   payload.devid = DEVICE_ID;
@@ -106,8 +107,8 @@
 void loop() {
   pinint_sleep();
   goToSleep ();
-  currentData1 = digitalRead(DATA1PIN);
-  if (currentData1 == 1 ) {
+  doorStatus = digitalRead(DATA1PIN);
+  if (doorStatus == 1 ) {
     return;
   } else {
     unsigned long startmilis = millis();
@@ -119,10 +120,12 @@
     payload.data1 = digitalRead(DATA1PIN) * 10;
     digitalWrite(IRENPIN, LOW);

-    if (payload.data1 == 10) {
+    //if (payload.data1 == 10) {
+    if ( rollStatus != payload.data1 ) {
       radio.powerUp();
       radio.write(&payload , sizeof(payload));
       radio.powerDown();
+      rollStatus = payload.data1;
     }
     unsigned long stopmilis = millis();
     payload.data2 = ( stopmilis - startmilis ) * 10 ;


Added slow servo down

Added slow servo down

--- EggBotArduino/EggBotArduino.ino
+++ EggBotArduino/EggBotArduino.ino
@@ -360,7 +360,20 @@
 						}
 						servoEnabled = false;
 					}
-					servo.write((int) value);
+					// Slow servo down
+					while (servo.read() != value){
+						if (servo.read() < value){
+							servo.write((int) servo.read()+1);
+							for (int i = 0; i < 10; i++) {
+							  SoftwareServo::refresh();
+							  delay(4);
+							}
+						}
+						else if (servo.read() > value){
+							servo.write((int) value);
+							SoftwareServo::refresh();
+						}
+					}
 				}
 				break;


update mkr1010 example

update mkr1010 example

--- examples/mkr1010/mkr1010.ino
+++ examples/mkr1010/mkr1010.ino
@@ -45,15 +45,18 @@
 void handleCommand(LosantCommand *command) {
   Serial.print("Command received: ");
   Serial.println(command->name);
-
   // Optional command payload. May not be present on all commands.
-  JsonObject payload = *command->payload;
-
+  //JsonObject payload = *command->payload;
+
   // Perform action specific to the command received.
   if(strcmp(command->name, "toggle") == 0) {
     toggle();
-    // Access values from payload
-    // change the key to the specific field in the payload
+    /**
+    * In Losant, including a payload along with your
+    * command is optional. This is an example of how
+    * to parse a JSON payload from Losant and print
+    * the value of a key called "temperature".
+    */
     // int temperature = payload["temperature"];
     // Serial.println(temperature);
   }


removed duplicate aws folder

removed duplicate aws folder

--- code/arduino/main/aws_sketch/aws_sketch_ino/aws_sketch_ino.ino
+++ code/arduino/main/aws_sketch/aws_sketch_ino/aws_sketch_ino.ino
@@ -1,321 +0,0 @@
-/*
- * main aws sketch
- *
- * DHT22 for T/H (digital)
- * BMP085 for T/P (analog)
- * LDR for reading light (analog)
- * LCD for display
- *
- * Davis 7852 Rain Gauge on INT0 (pin2)
- * GSM modem on hardware rx,tx8
- *
- *
- *
- */
-
-#include <avr/wdt.h>
-#include <Wire.h>
-#include <DHT22.h>
-#include <Adafruit_BMP085.h>
-#include <Time.h>
-#include <TimeAlarms.h>
-#include <DS1307RTC.h>
-#include <AWS.h>
-
-#define DHT22_PIN 6
-//#define AWS_NO_LCD 1
-//#define AWS_NO_GSM 1
-
-// Analog pin A4(SDA),A5(SCL)
-Adafruit_BMP085 bmp;
-DHT22 myDHT22(DHT22_PIN);
-
-
-#if !defined(AWS_NO_GSM)
-#include <SoftwareSerial.h>
-SoftwareSerial gsmSerial(4,5);
-#endif
-
-#if !defined(AWS_NO_LCD)
-#include <LiquidCrystal.h>
-LiquidCrystal lcd(7,8, 9, 10, 11, 12);
-int lcd_pin = 13;
-
-#endif
-
-// globals
-volatile int rain_counter = 0 ;
-volatile bool rain_counter_reset = false ;
-
-volatile unsigned long irq_time ;
-volatile unsigned long last_irq_time ;
-
-float dht22_temp ;
-float humidity ;
-int32_t pressure ;
-float total_rain = 0.0;
-
-const char *month_names[12] = {
-  "Jan", "Feb", "Mar", "Apr", "May", "Jun",
-  "Jul", "Aug", "Sep", "Oct", "Nov", "Dec"
-};
-
-tmElements_t tm;
-
-// return codes
-DHT22_ERROR_t dht22_code ;
-aws_error_t rtc_code ;
-
-void setup() {
-
-    // watchdog enabled
-    wdt_enable(WDTO_8S);
-
-    // DS1307 RTC
-    // DS1307RTC instance created in DS1307 lib
-    // DS1307RTC RTC = DS1307RTC();
-    // DS1307RTC constructor calls Wire.begin()
-    // sync interval is default 5 minutes
-
-    rtc_code = init_rtc(__TIME__,__DATE__);
-    micro_delay(20);
-
-    if(rtc_code == AWS_RTC_ERROR_NONE) {
-        setSyncProvider(RTC.get);
-        if(timeStatus()!= timeSet) {
-            // wait a bit
-            micro_delay(400);
-        }
-
-        // try again
-        if(timeStatus()!= timeSet) {
-          rtc_code = AWS_RTC_SYNC_ERROR ;
-        }
-    }
-
-    bmp.begin();
-    // INT0 interrupt
-    attachInterrupt(0,isr_pin2,RISING);
-    last_irq_time = 0 ;
-
-#if !defined(AWS_NO_SERIAL)
-    Serial.begin(9600);
-#endif
-
-#if !defined(AWS_NO_GSM)
-
-    gsmSerial.begin(9600);
-    gsmSerial.println("AT+CMGF=1");
-    micro_delay(20);
-    gsmSerial.println("AT+CSMS=1");
-    micro_delay(20);
-    gsmSerial.println("AT+CNMI=2,2,0,0");
-    micro_delay(20);
-#endif
-
-    Alarm.alarmRepeat(16,30,01, send_bulletin);
-
-}
-
-void isr_pin2() {
-
-    // @imp millis() donot advance inside an ISR
-    irq_time = millis();
-    if((irq_time - last_irq_time) > 250) {
-        rain_counter = rain_counter +1 ;
-        last_irq_time = irq_time ;
-    }
-}
-
-// param n is to ensure n*10 ms delay
-void micro_delay(int n) {
-    for(int i = 0 ; i < n ; i++) {
-        delayMicroseconds(10000);
-        // pat watchdog every 100*10 ms
-        if((i > 100) && (i %100 == 0 ))
-            wdt_reset();
-    }
-}
-
-void update_display() {
-
-    // DHT22 pin needs 2 seconds
-    micro_delay(250);
-    dht22_code = myDHT22.readData();
-
-    if(dht22_code == DHT_ERROR_NONE) {
-        dht22_temp = myDHT22.getTemperatureC();
-        humidity = myDHT22.getHumidity();
-
-    } else {
-        // absurd value
-        dht22_temp = 9999.0 ;
-    }
-
-    pressure = bmp.readPressure();
-    calculate_rain();
-
-#if !defined(AWS_NO_SERIAL)
-    serial_output();
-#endif
-
-#if !defined(AWS_NO_LCD)
-    lcd_output();
-#endif
-
-}
-
-void send_bulletin() {
-    Serial.println("inside send bulletin");
-    int hr = hour();
-
-    // reset rain counter at 9AM
-    // condition >= is for a power failure
-    // missing the 9'0 clock window
-    if(!rain_counter_reset && (hr >= 9)) {
-        rain_counter_reset = true ;
-        rain_counter = 0 ;
-    }
-
-    if(hr != 9 && rain_counter_reset) {
-        rain_counter_reset = false ;
-    }
-
-#if !defined(AWS_NO_GSM)
-    gsmSerial.print("\r");
-    micro_delay(20);
-    gsmSerial.print("AT+CMGF=1\r");
-    micro_delay(20);
-    gsmSerial.print("AT+CMGS=\"+918553518338\"\r");
-    micro_delay(20);
-    // pat watchdog
-    wdt_reset();
-
-    gsmSerial.print("Yuktix H");
-    if(dht22_code !=  DHT_ERROR_NONE) {
-        gsmSerial.println("ERR");
-        gsmSerial.print(dht22_code);
-
-    } else {
-        gsmSerial.println(humidity);
-        gsmSerial.print(" T");
-        gsmSerial.print(dht22_temp);
-    }
-
-    gsmSerial.print(" P");
-    gsmSerial.print(pressure);
-    gsmSerial.print(" R");
-    gsmSerial.print(total_rain);
-    gsmSerial.println();
-    gsmSerial.write(0x1A);
-    micro_delay(100);
-    // pat watchdog
-    wdt_reset();
-
-#endif
-
-}
-
-void calculate_rain() {
-    // arduino float is 2 decimal places
-    total_rain = rain_counter * 0.01 ;
-}
-
-aws_error_t init_rtc(const char* str_time, const char* str_date) {
-
-    int hour, min, sec;
-    char month[12]; int day, year;
-    uint8_t month_index;
-
-    if (sscanf(str_time, "%d:%d:%d", &hour, &min, &sec) != 3) return AWS_RTC_COMPILER_ERROR;
-    if (sscanf(str_date, "%s %d %d", month, &day, &year) != 3) return AWS_RTC_COMPILER_ERROR;
-
-    tm.Hour = hour;
-    tm.Minute = min;
-    tm.Second = sec;
-
-
-    for (month_index = 0; month_index < 12; month_index++) {
-        if (strcmp(month, month_names[month_index]) == 0) break;
-    }
-
-    if (month_index >= 12) return AWS_RTC_COMPILER_ERROR;
-
-    tm.Day = day;
-    tm.Month = month_index + 1;
-    tm.Year = CalendarYrToTm(year);
-
-    // set this date time to DS1307 chip
-    bool flag = RTC.write(tm);
-    if(!flag) return AWS_RTC_WRITE_ERROR ;
-
-    return AWS_RTC_ERROR_NONE;
-
-}
-
-#if !defined(AWS_NO_SERIAL)
-void serial_output() {
-    Serial.print("Yuktix H");
-    if(dht22_code !=  DHT_ERROR_NONE) {
-        Serial.println("ERR");
-        Serial.print(dht22_code);
-
-    } else {
-        Serial.println(humidity);
-        Serial.print(" T");
-        Serial.print(dht22_temp);
-    }
-
-    Serial.print(" P");
-    Serial.print(pressure);
-    Serial.print(" R");
-    Serial.print(total_rain);
-
-}
-#endif
-
-#if !defined(AWS_NO_LCD)
-void lcd_output() {
-
-    int t1 ;
-    int p1 ;
-    int h1 ;
-
-    pinMode(lcd_pin, OUTPUT);
-    digitalWrite(lcd_pin, HIGH);
-    lcd.begin(16,2);
-    lcd.clear();
-    // line1
-    lcd.setCursor(0,0);
-    lcd.print("YUKTIX H");
-    if(dht22_code !=  DHT_ERROR_NONE) {
-        lcd.print("ERR");
-        lcd.setCursor(0,1);
-        lcd.print(dht22_code);
-
-    } else {
-        h1 = round(humidity);
-        lcd.print(h1);
-        lcd.print("%");
-        lcd.setCursor(0,1);
-        lcd.print("T");
-        t1 = round(dht22_temp);
-        lcd.print(t1);
-    }
-
-    lcd.print(" P");
-    p1 = round(pressure/10.0);
-    lcd.print(p1);
-    lcd.print(" R");
-    lcd.print(total_rain);
-}
-#endif
-
-void loop() {
-
-    update_display();
-    wdt_reset();
-    // refresh in 30 seconds
-    micro_delay(2750);
-    Alarm.delay(1000);
-}


Run on light instead of absence

Run on light instead of absence

--- MidiLEDSensor/MidiLEDSensor.ino
+++ MidiLEDSensor/MidiLEDSensor.ino
@@ -9,7 +9,7 @@

 void loop(void) {
   int pinRead0 = analogRead(LEDPORT);
-  if (pinRead0 > THRESHOLD) {
+  if (pinRead0 < THRESHOLD) {
     noteOn(0x90, NOTE, 0x45);
   } else {
     noteOn(0x90, NOTE, 0x00);


Preliminary support for pca9685

Preliminary support for pca9685

--- src/Full_decoder/Full_decoder.ino
+++ src/Full_decoder/Full_decoder.ino
@@ -1,6 +1,10 @@
-#include <Servo.h>
-
 #include "config.h"
+
+#if PINSERVO == 1
+#warning "USING SERVO"
+  #include <Servo.h>
+#endif
+
 #define VERSION 10200
 /* We're a loconet decoder! */
 #include <LocoNet.h>
@@ -19,6 +23,7 @@
 ConfiguredPin* confpins[MAX];
 uint8_t pins_conf = 0;

+/* TLC5947 Support*/
 #include "Adafruit_TLC5947.h"

 // How many boards do you have chained?
@@ -30,6 +35,14 @@
 #define oe  -1  // set to -1 to not use the enable pin (its optional)

 Adafruit_TLC5947 tlc = Adafruit_TLC5947(NUM_TLC5974, clock, data, latch);
+
+/* PCA9685 Support */
+
+#include <Adafruit_PWMServoDriver.h>
+
+// Default address = 0x40
+Adafruit_PWMServoDriver pca = Adafruit_PWMServoDriver();
+

 void enableServos();
 void disableServos();
@@ -113,7 +126,17 @@
       case 101: // TLC5947 PWM LED Controller.
         pin_config = ((eeprom_read_word((uint16_t*)&(_CV.conf[slot].output.options)) & 0x01) == 0x01);
         confpins[slot] = new TLC5947pin(&tlc, slot, pin, address, pin_config, pin, 1000);
-        break;
+        break;
+      case 102: // PCA9686
+        pos1  = eeprom_read_word((uint16_t*)&(_CV.conf[slot].servo.pos1));
+        pos2  = eeprom_read_word((uint16_t*)&(_CV.conf[slot].servo.pos2));
+        speed = eeprom_read_word((uint16_t*)&(_CV.conf[slot].servo.speed));
+        fbslot1  = eeprom_read_word((uint16_t*)&(_CV.conf[slot].servo.fbslot1));
+        fbslot2  = eeprom_read_word((uint16_t*)&(_CV.conf[slot].servo.fbslot2));
+        powerpin = eeprom_read_word((uint16_t*)&(_CV.conf[slot].servo.pwrslot));
+        confpins[slot] = new PCA9685Servo(&pca, slot, pin, address, pos1, pos2, speed, powerpin, fbslot1, fbslot2);
+        confpins[slot]->restore_state(eeprom_read_word((uint16_t*)&(_CV.conf[slot].servo.state)));
+        break;
       default:
         confpins[slot] = new ConfiguredPin(slot, pin, address);
         break;
@@ -125,9 +148,9 @@
 void setup() {
 #ifdef USE_SERIAL
   Serial.begin(57600);
-  while (!Serial){
+ /* while (!Serial){
     ;
-  }
+  }*/
 #endif

   DEBUG("Universal decoder v");


change simple toggle clients to 'power' instead of lampclient with 'brightness'

--- client/client.ino
+++ client/client.ino
@@ -263,7 +263,7 @@
         laptopBridging(p);
       } else if(strcmp(deviceId, deviceLamp) == 0
         || strcmp(deviceId, deviceFan) == 0) {
-        lampClient(p);
+        powerClient(p);

       }
     }
@@ -325,26 +325,27 @@
   Serial.println(deviceId);
 }

-void lampClient(struct XBeePacket p) {
+void powerClient(struct XBeePacket p) {
   DEBUG_PRINTLN("command issued");
-  if (strcmp(p.func, "R") == 0 && strcmp(p.var, "BRI") == 0 ) {
-    // read the current status and reply
-    int status = digitalRead(controlledPin);
-    if (status == 0) {
-      sendXBeePacketFromRaw(&XBee, deviceId, "A", "BRI", "OFF");
-    } else {
-      sendXBeePacketFromRaw(&XBee, deviceId, "A", "BRI", " ON");
-    }
-  }
-  else if (strcmp(p.func, "C") == 0 && strcmp(p.var, "BRI") == 0 && strcmp(p.data, " ON") == 0) {
+  // if (strcmp(p.func, "R") == 0 && strcmp(p.var, "POW") == 0 ) {
+  //   // read the current status and reply
+  //   int status = digitalRead(controlledPin);
+  //   if (status == 0) {
+  //     sendXBeePacketFromRaw(&XBee, deviceId, "A", "POW", "OFF");
+  //   } else {
+  //     sendXBeePacketFromRaw(&XBee, deviceId, "A", "POW", " ON");
+  //   }
+  // }
+  //taking out because now it auto reply when selected, glass won't send R msg
+  if (strcmp(p.func, "C") == 0 && strcmp(p.var, "POW") == 0 && strcmp(p.data, " ON") == 0) {
     DEBUG_PRINTLN("turned on");
     digitalWrite(controlledPin, HIGH);
-    sendXBeePacketFromRaw(&XBee, deviceId, "A", "BRI", " ON");
-  }
-  else if (strcmp(p.func, "C") == 0 && strcmp(p.var, "BRI") == 0 && strcmp(p.data, "OFF") == 0) {
+    sendXBeePacketFromRaw(&XBee, deviceId, "A", "POW", " ON");
+  }
+  else if (strcmp(p.func, "C") == 0 && strcmp(p.var, "POW") == 0 && strcmp(p.data, "OFF") == 0) {
     DEBUG_PRINTLN("turned off");
     digitalWrite(controlledPin, LOW);
-    sendXBeePacketFromRaw(&XBee, deviceId, "A", "BRI", "OFF");
+    sendXBeePacketFromRaw(&XBee, deviceId, "A", "POW", "OFF");
   }
   else {
     // error message
@@ -354,14 +355,14 @@

 void replyStatus() {
   DEBUG_PRINTLN("ask for client status");
-  if(strcmp(deviceId, deviceLamp) == 0) {
+  if(strcmp(deviceId, deviceLamp) == 0 || strcmp(deviceId, deviceFan) == 0) {
     int status = digitalRead(controlledPin);
     if (status == 0) {
-      sendXBeePacketFromRaw(&XBee, deviceId, "A", "BRI", "OFF");
+      sendXBeePacketFromRaw(&XBee, deviceId, "A", "POW", "OFF");
     } else {
-      sendXBeePacketFromRaw(&XBee, deviceId, "A", "BRI", " ON");
-    }
-  } else if(strcmp(deviceId, deviceTV) == 0) {
+      sendXBeePacketFromRaw(&XBee, deviceId, "A", "POW", " ON");
+    }
+  } else if(strcmp(deviceId, deviceTV) == 0 || strcmp(deviceId, deviceMusic) == 0) {
     //send a read status cmd to the laptop and wait for reply
     //curently only volume is needed
     Serial.print(deviceId);


Update UltraDisOnSeeedSerialLcd.ino

Update UltraDisOnSeeedSerialLcd.ino

Change the serial pin because of the Grove - Base Shield without D11/D12 interface.

--- UltrasonicRanger/examples/UltraDisOnSeeedSerialLcd/UltraDisOnSeeedSerialLcd.ino
+++ UltrasonicRanger/examples/UltraDisOnSeeedSerialLcd/UltraDisOnSeeedSerialLcd.ino
@@ -30,7 +30,7 @@
 #include <SerialLCD.h>
 #include "Ultrasonic.h"

-SerialLCD slcd(11,12);
+SerialLCD slcd(4,5);
 Ultrasonic ultrasonic(7);
 void setup()
 {


no message

no message

--- SabreMaster.ino
+++ SabreMaster.ino
@@ -1,325 +0,0 @@
-/*
-* SabreMaster
-*
-* Created: 19-12-2013 23:05:30
-* Author: CE-Designs
-*/
-
-#include "Sabre.h"
-#include "GUI.h"
-#include "Wire.h"
-#include "EEPROM.h"
-#include "CharacterOLED.h"
-#include "IRremote.h"
-
-#define INCREASE 0x00
-#define DECREASE 0x01
-
-Sabre dac;	// dac
-
-GUI gui(25, 26, 27, 28, 29, 30, 31);	// define the pins for the OLED
-
-IRrecv	irrecv(10);				// set the IR receiver pin
-decode_results results;			// object for storing the IR decode results
-
-const byte remoteDelay = 140;	// Delay in milliseconds after each key press of the remote
-
-byte IRcode;
-byte lastKey;
-
-unsigned long SR_Millis = 0;
-
-enum GUI_states
-{
-	HomeScreen, MainMenu, InputSettingsMenu, DacSettingsMenu, DateTimeMenu, DisplayMenu
-};
-
-void setup()
-{
-	//Serial.begin(9600);		// for debugging
-	Wire.begin();			// join the I2C bus
-	dac.begin(false, 100);	// true = dual mono mode | false = stereo mode, Clock frequency (MHz)
-
-	//////////////////////////////////////////////////////////////////////////
-	dac.Status.DSD_Mode=true;
-	dac.Status.Lock = true;
-
-	//dac.Attenuation = 49;
-	//dac.DefaultAttenuation = 49;
-	//dac.writeDefaultAttenuation();
-
-	//dac.setBitMode(dac.BitMode32);			// or dac.BitMode16 | dac.BitMode20 | dac.BitMode24
-	//dac.setSerialDataMode(dac.I2S);			// or dac.LJ | dac.RJ
-	//dac.setDPLLbandwidth(dac.DPLL_Best);	//
-	//dac.setDeEmphasisSelect(dac.f44_1kHz);	// or dac.f32kHz | dac.f48kHz
-
-	//////////////////////////////////////////////////////////////////////////
-
-	irrecv.enableIRIn();		// Start the receiver
-
-	gui.sabreDAC = dac;
-	gui.start();		// Start the user interface + initialize the display
-	gui.printHomeScreen(dac.SelectedInput, 99 - dac.Attenuation);
-}
-
-
-
-
-// Main Loop
-void loop()
-{
-	// IR routines
-	if (irrecv.decode(&results)) {
-		setIRcode();
-		irrecv.resume(); // Receive the next value
-	}
-
-	// If a remote control key is pressed than let the GUI class
-	// decide on which function to call
-	if (IRcode != 0)
-	{
-		switch (IRcode)
-		{
-			case KEY_UP:
-			handleKeyUp();
-			lastKey = KEY_UP;
-			break;
-			case KEY_DOWN:
-			handleKeyDown();
-			lastKey = KEY_DOWN;
-			break;
-			case KEY_LEFT:
-			handleKeyLeft();
-			delay(remoteDelay * 2);
-			lastKey = KEY_LEFT;
-			break;
-			case KEY_RIGHT:
-			handleKeyRight();
-			delay(remoteDelay * 2);
-			lastKey = KEY_RIGHT;
-			break;
-			case KEY_CENTER:
-			//handleKeyCenter();
-			lastKey = KEY_CENTER;
-			break;
-			case KEY_MENU:
-			handleKeyMenu();
-			lastKey = KEY_MENU;
-			break;
-			case KEY_PLAY_PAUSE:
-			lastKey = KEY_PLAY_PAUSE;
-			break;
-			default:
-			// do nothing
-			break;
-		}
-		delay(remoteDelay);
-		IRcode = 0;
-	}
-
-	// print sample rate every 500 ms and only when the home screen is showing
-	if (millis() - SR_Millis >= 500 && gui.GUI_State == HomeScreen)
-	{
-		gui.printSampleRate(5, 2);
-		SR_Millis = millis();
-	}
-
-} // end of Main Loop
-
-
-// sets the IR code
-void setIRcode()
-{
-	if (results.value == REPEAT)
-	{
-		IRcode = lastKey;	// make IRcode the same as the last valid IR code
-	}
-	else
-	{
-		IRcode = (results.value >> 8) & 0xff;
-		IRcode = (IRcode << 1) & 0xff;
-	}
-}
-
-
-void handleKeyUp()
-{
-	switch (gui.GUI_State)
-	{
-		case HomeScreen:
-		setVolume(INCREASE);
-		break;
-		case MainMenu:
-		gui.PrintSelectedInputSettings((gui.Setting -= 1) % SETTINGS_COUNT);
-		break;
-	}
-}
-
-void handleKeyDown()
-{
-	switch (gui.GUI_State)
-	{
-		case HomeScreen:
-		setVolume(DECREASE);
-		break;
-		case MainMenu:
-		gui.PrintSelectedInputSettings((gui.Setting += 1) % SETTINGS_COUNT);
-		break;
-	}
-}
-
-void handleKeyLeft()
-{
-	switch (gui.GUI_State)
-	{
-		case HomeScreen:
-		// CORRECTION FOR INPUT SELECTION ERROR
-		if (dac.SelectedInput == 0)
-		{
-			dac.SelectedInput -= (255 % NUMBER_OF_INPUTS);
-			handleKeyLeft();
-		}
-		// END CORRECTION
-		setInput(dac.SelectedInput -= 1);
-		break;
-		case MainMenu:
-		changeSetting(-1);
-		break;
-	}
-}
-
-void handleKeyRight()
-{
-	switch (gui.GUI_State)
-	{
-		case HomeScreen:
-		if (dac.SelectedInput == 255)
-		{
-			dac.SelectedInput += (255 % NUMBER_OF_INPUTS);
-			handleKeyRight();
-		}
-		setInput(dac.SelectedInput += 1);
-		break;
-		case MainMenu:
-		changeSetting(+1);
-		break;
-	}
-}
-
-void handleKeyMenu()
-{
-	switch (gui.GUI_State)
-	{
-		case HomeScreen:
-		gui.sabreDAC = dac;
-		gui.GUI_State += 1;
-		gui.printInputSettingsMenu(dac.SelectedInput);
-		break;
-		case MainMenu:
-		dac.writeInputConfiguration(dac.SelectedInput); // write settings to the EEPROM
-		gui.GUI_State -= 1;
-		gui.printHomeScreen(dac.SelectedInput, 99 - dac.Attenuation);
-		break;
-	}
-}
-
-// increases or decreases the volume
-void setVolume(byte value)
-{
-	if (value == INCREASE)
-	{
-		if (dac.Attenuation > 0)
-		{
-			dac.setVolume(dac.Attenuation -= 1);
-		}
-	}
-	else
-	{
-		if (dac.Attenuation < 99)
-		{
-			dac.setVolume(dac.Attenuation += 1);
-		}
-	}
-	gui.printLargeAttenuation(99 - dac.Attenuation, 13);
-}
-
-void setInput(byte value)
-{
-	dac.selectInput(dac.SelectedInput);
-	gui.sabreDAC = dac;
-	gui.printInputName(0, 0);
-	gui.printLargeInput(dac.SelectedInput, 0);
-	dac.writeSelectedInput();
-}
-
-void changeSetting(int value)
-{
-	switch (gui.Setting % SETTINGS_COUNT)
-	{
-		case 0:
-		/* Your code here */
-		break;
-		case 1:
-		dac.setFIRrolloffSpeed((dac.Config[dac.SelectedInput].FIR_FILTER += value) % 2);
-		gui.sabreDAC = dac;
-		gui.printFIRsetting(1, 1);
-		break;
-		case 2:
-		dac.setIIRbandwidth((dac.Config[dac.SelectedInput].IIR_BANDWIDTH += value) % 4);
-		gui.sabreDAC = dac;
-		gui.printIIRsetting(1, 1);
-		break;
-		case 3:
-		dac.setNotchDelay((dac.Config[dac.SelectedInput].NOTCH_DELAY += value) % 6);
-		gui.sabreDAC = dac;
-		gui.printNotchSetting(1, 1);
-		break;
-		case 4:
-		dac.setQuantizer((dac.Config[dac.SelectedInput].QUANTIZER += value) % 6);
-		gui.sabreDAC = dac;
-		gui.printQuantizerSetting(1, 1);
-		break;
-		case 5:
-		dac.setDPLLbandwidth((dac.Config[dac.SelectedInput].DPLL_BANDWIDTH += value) % 9);
-		gui.sabreDAC = dac;
-		gui.printDPLLbandwidthSetting(1, 1);
-		break;
-		case 6:
-		dac.setDPLLBandwidth128x((dac.Config[dac.SelectedInput].DPLL_BW_128X += value) % 2);
-		gui.sabreDAC = dac;
-		gui.printDPLLmultiplierSetting(1, 1);
-		break;
-		case 7:
-		dac.setOSFfilter((dac.Config[dac.SelectedInput].OSF_FILTER += value) % 2);
-		gui.sabreDAC = dac;
-		gui.printOSFfilterSetting(1, 1);
-		break;
-		case 8:
-		dac.setSPDIFenable((dac.Config[dac.SelectedInput].SPDIF_ENABLE += value) % 2);
-		gui.sabreDAC = dac;
-		gui.printSPDIFenableSetting(1, 1);
-		break;
-		case 9:
-		dac.setSerialDataMode((dac.Config[dac.SelectedInput].SERIAL_DATA_MODE += value) % 3);
-		gui.sabreDAC = dac;
-		gui.printSerialDataModeSetting(1, 1);
-		break;
-		case 10:
-		dac.setSPDIFsource((dac.Config[dac.SelectedInput].SPDIF_SOURCE += value) % 8);
-		gui.sabreDAC = dac;
-		gui.printSPDIFsourceSetting(1, 1);
-		break;
-		case 11:
-		dac.setBitMode((dac.Config[dac.SelectedInput].BIT_MODE += value) % 4);
-		gui.sabreDAC = dac;
-		gui.printBitmodeSetting(1, 1);
-		break;
-		case 12:
-		dac.setDeEmphasisSelect((dac.Config[dac.SelectedInput].DE_EMPHASIS_SELECT += value) % 4);
-		gui.sabreDAC = dac;
-		gui.printDeemphFilterSetting(1, 1);
-		break;
-	}
-
-
-}


GRB not RGB

GRB not RGB

--- arduino_responder.ino
+++ arduino_responder.ino
@@ -63,22 +63,22 @@
     //first light
     if (str.indexOf('a') >= 0) {
       //LED number, RGB
-      strip.setPixelColor(0, 255, 140, 0);
+      strip.setPixelColor(0, 140, 255, 0);
     }

     //second light
     if (str.indexOf('b') >= 0) {
-      strip.setPixelColor(1, 255, 140, 0);
-    }
+      strip.setPixelColor(1, 140, 255, 0);
+    }

     //third light
     if (str.indexOf('c') >= 0) {
-      strip.setPixelColor(2, 255, 140, 0);
+      strip.setPixelColor(2, 140, 255, 0);
     }

     //fourth light
     if (str.indexOf('d') >= 0) {
-      strip.setPixelColor(3, 255, 140, 0);
+      strip.setPixelColor(3, 140, 255, 0);
     }

     //york north
@@ -86,22 +86,22 @@
     //first light
     if (str.indexOf('3') >= 0) {
       //LED number, RGB
-      strip.setPixelColor(4, 255, 140, 0);
+      strip.setPixelColor(4, 140, 255, 0);
     }

     //second light
     if (str.indexOf('f') >= 0) {
-      strip.setPixelColor(5, 255, 140, 0);
+      strip.setPixelColor(5, 140, 255, 0);
     }

     //third light
     if (str.indexOf('g') >= 0) {
-      strip.setPixelColor(6, 255, 140, 0);
+      strip.setPixelColor(6, 140, 255, 0);
     }

     //fourth light
     if (str.indexOf('h') >= 0) {
-      strip.setPixelColor(7, 255, 140, 0);
+      strip.setPixelColor(7, 140, 255, 0);
     }

     //high south


Work in progress

Work in progress

--- frontdoor/frontdoor.ino
+++ frontdoor/frontdoor.ino
@@ -1,8 +1,7 @@
+#include <stdint.h>
+
 #include <SPI.h>
-
 #include <RF24.h>
-#include <nRF24L01.h>
-#include <RF24_config.h>

 //We always have to include the library
 #include "LedControl.h"
@@ -10,7 +9,7 @@
 #include "font.h"

 static LedControl lc = LedControl(/*data*/ 2, /*clk*/ 4, /*cs*/ 3, /*#devices*/ 2);
-static long int address = 0x66996699L;  // So that's 0x0066996699
+static uint64_t address = 0x66996699LL;  // So that's 0x0066996699

 static RF24 rf(/*ce*/ 9, /*cs*/ 10);

@@ -34,13 +33,17 @@
   lc.clearDisplay(0);
   lc.clearDisplay(1);

-  /* NRF init */
-    Serial.begin(115200);
+    Serial.begin(9600);
+    Serial.println("Hello world!");
+
+    /* NRF init */
     rf.begin();
-    rf.setRetries(15, 15);
+    Serial.print("Is plus? ");
+    Serial.println(rf.isPVariant() ? "yes" : "no");
+
     rf.enableDynamicPayloads();
-    rf.openReadingPipe(0, address);
-    rf.startListening();
+    rf.openReadingPipe(1, address);
+    rf.startListening();
 }

 // reverses bit order in a byte
@@ -145,24 +148,29 @@

 void loop(void)
 {
-  static char text[32] = "Spoorlaan 5d   PIZZA   ";
-  static char buf[32];
+  static char text[32] = " PIZZA ";
   static boolean avail = false;

   // prepare text
-  if (avail) {
-    avail = false;
-    memset(buf, 0, sizeof(buf));
-    if (rf.read(&buf, sizeof(buf))) {
-      uint8_t len = buf[0];
-	    if (len > 31) {
-	      len = 31;
-	    }
-      strncpy(text, buf + 1, len);
-      text[len] = '\0';
-      Serial.println(text);
+    while (rf.available()) {
+        char buf[32];
+        memset(buf, 0, sizeof(buf));
+        rf.read(&buf, sizeof(buf));
+        if (memcmp(buf + 1, "DOOR", 4) == 0) {
+            uint8_t len = buf[0];
+            if (len < 4) {
+                len = 4;
+            }
+            if (len > 31) {
+                len = 31;
+            }
+            strncpy(text, buf + 5, len - 4);
+            text[len - 4] = '\0';
+            Serial.print("Received: '");
+            Serial.print(text);
+            Serial.println("'");
+        }
     }
-  }

   // display text
   int i;
@@ -171,12 +179,6 @@

     int j;
     for (j = 0; j < GLYPH_WIDTH; j++) {
-      if (rf.available()) {
-        // stop drawing current text, and prepare to receive a new one
-        avail = true;
-        return;
-      }
-
       scroll();
       update_display();
       delay(25);


Update NRF reception logic, this should hopefully get rid of the reception weirdness (receiving the previous message when a new message is sent)

--- frontdoor/frontdoor.ino
+++ frontdoor/frontdoor.ino
@@ -152,23 +152,23 @@
   static boolean avail = false;

   // prepare text
-    while (rf.available()) {
+    if (rf.available()) {
         char buf[32];
-        memset(buf, 0, sizeof(buf));
-        rf.read(&buf, sizeof(buf));
-        if (memcmp(buf + 1, "DOOR", 4) == 0) {
-            uint8_t len = buf[0];
-            if (len < 4) {
-                len = 4;
+        boolean done = false;
+        while (!done) {
+            memset(buf, 0, sizeof(buf));
+            done = rf.read(&buf, sizeof(buf));
+            if (memcmp(buf + 1, "DOOR", 4) == 0) {
+                uint8_t len = buf[0];
+                if ((len < 4) || (len > 31)) {
+                    continue;
+                }
+                strncpy(text, buf + 5, len - 4);
+                text[len - 4] = '\0';
+                Serial.print("Received: '");
+                Serial.print(text);
+                Serial.println("'");
             }
-            if (len > 31) {
-                len = 31;
-            }
-            strncpy(text, buf + 5, len - 4);
-            text[len - 4] = '\0';
-            Serial.print("Received: '");
-            Serial.print(text);
-            Serial.println("'");
         }
     }


timer and remote request send added

timer and remote request send added

--- nodmcu.ino
+++ nodmcu.ino
@@ -4,10 +4,9 @@
 #include <ArduinoJson.h>
 #include <WiFiManager.h>
 #include <Servo.h>
-
+#include <SimpleTimer.h>

 Servo servo;
-
 /*
  *const int PIN_LED = 2; // D4 on NodeMCU and WeMos. Controls the onboard LED.
  *
@@ -18,6 +17,10 @@
 const int TRIGGER_PIN = D3; // D3 on NodeMCU and WeMos.
 const int LED_PIN = D7; //Diod pin
 const int MOTOR_PIN = D5; //Motor pin
+const int HTTPPORT = 80;
+const char* HOST = "345.kiev.ua"; //host for remote job
+String URL = "/publicfiles.php?id="; //url for check state, where id is devise MAC /without ":"
+
 /*
  * Alternative trigger pin. Needs to be connected to a button to use this pin. It must be a momentary connection
  * not connected permanently to ground. Either trigger pin will work.
@@ -29,6 +32,8 @@
 bool initialConfig = false;

 std::unique_ptr<ESP8266WebServer> server;
+SimpleTimer timer;
+
 //-------------main functions----------------------------------------
   void goFeed(String sval) {
         int ival = sval.toInt();
@@ -37,7 +42,6 @@
           strcpy(msg, "Servo has been moved to : ");
           strcat(msg, sval.c_str());
           server->send(200, "text/plain", msg);
-          Serial.println(sval);
   }
   void goFeedSlow(String sval) {
         int ival = sval.toInt();
@@ -53,14 +57,13 @@
                  delay(5);
                  }
                  delay(200); // for fill the bank))
-                 //servo.write(0);   // replaced by for for noise reduce
-                 //delay(500);
+                 //servo.write(0); delay(500);  // replaced by for for noise reduce
         }
           char msg[100];
           strcpy(msg, "Performed cycles : ");
           strcat(msg, sval.c_str());
           server->send(200, "text/plain", msg);
-          Serial.println(sval);
+          Serial.println("Eat and be quiet.");
   }
   void goblink(int i){
     if ((i%10) == 0){
@@ -75,9 +78,44 @@
          digitalWrite(pin, HIGH);
     }
   }
-  void checkRepo(int interval){
-
-  }
+  void checkRepo(){
+    // Use WiFiClient class to create TCP connections
+      WiFiClient client;
+  if (!client.connect(HOST, HTTPPORT)) { Serial.println("connection to remote server failed"); return; }
+  // We now create a URI for the request
+  URL += getID(WiFi.macAddress());
+  Serial.print("Requesting URL: ");
+  Serial.println(URL);
+
+  // This will send the request to the server
+  client.print(String("GET ") + URL + " HTTP/1.1\r\n" +
+               "Host: " + HOST + "\r\n" +
+               "Connection: close\r\n\r\n");
+  unsigned long timeout = millis();
+  while (client.available() == 0) {
+    if (millis() - timeout > 5000) {
+      Serial.println(">>> Client Timeout !");
+      client.stop();
+      return;
+    }
+  }
+  // Read all the lines of the reply from server and print them to Serial
+  while(client.available()){
+    String line = client.readStringUntil('\r');
+    Serial.print(line);
+   }
+ }
+String getID(String str){
+  int j=0;
+  String dev_id;
+  for(int i=0; i <17; i++){
+      if(str[i]!=':'){
+          dev_id += str[i];
+          j++;
+         }
+      }
+      return dev_id;
+}
 //------------- end main functions----------------------------------------
 void setup() {
   pinMode(LED_PIN, OUTPUT);
@@ -86,9 +124,9 @@
   int start_time = millis(); // remember starttime
   servo.attach(MOTOR_PIN);
   servo.write(0); //ставим вал под 0
-  // put your setup code here, to run once:

-
+  timer.setInterval(20000, checkRepo);
+
   Serial.begin(115200);
   Serial.print("\n Starting at :");
   Serial.println(start_time);
@@ -118,7 +156,7 @@
     Serial.println("Starting http server...");
     server.reset(new ESP8266WebServer(WiFi.localIP(), 80));
         server->on("/whoami", [](){
-          server->send(200, "text/plain", "{\"device_name\" : \"PetFeeder\", \"version\" : \"1.0\"}");
+          server->send(200, "application/json", "{\"device_name\" : \"PetFeeder\", \"version\" : \"1.0\"}");
         });
         server->on("/servo", [](){
           goFeed(server->arg("val"));
@@ -127,12 +165,10 @@
           goFeedSlow(server->arg("val"));
         });
         server->begin();
-    Serial.println("Custom HTTP server started");
-    doblink(LED_PIN, 1, 5000);
-
+        Serial.println("Custom HTTP server started");
+        doblink(LED_PIN, 1, 5000);
   }
 }
-

 void loop() {
   // is configuration portal requested?
@@ -162,5 +198,6 @@
   // put your main code here, to run repeatedly:
     if (WiFi.status()==WL_CONNECTED){
   server->handleClient();
+  timer.run();
     }
 }


Boat will now change tack every 20 seconds when heading into the wind

--- Arduino/Sailbot/Sailbot.ino
+++ Arduino/Sailbot/Sailbot.ino
@@ -36,7 +36,8 @@
 #define MAX_RUDDER 10.0

 unsigned long lastDataPacketSent;
-unsigned long timeOnCurrentTack;
+unsigned long timeOnTackSequence;
+unsigned long lastAutomaticUpdate;

 char state;
 char remoteState;
@@ -48,7 +49,7 @@
 float rudder;
 float sheet;
 float tackAngle;
-float tackTime;
+unsigned long tackTime;

 Servo tillerServo;
 Servo sheetServo;
@@ -59,6 +60,7 @@
   remoteState = SBTSailbotModelStateManualControl;
   windDirection = -1.0;
   tackAngle = 90.0 * M_PI / 180.0;
+  tackTime = 20.0 * 1000.0; // 20 seconds
   calibratedWind = false;
   imu = RTIMU::createIMU(&settings);                        // create the imu object

@@ -82,6 +84,7 @@
   RFduinoBLE.begin();

   lastDataPacketSent = millis();
+  lastAutomaticUpdate = millis();
 }

 void setRudder(float newAngle) {
@@ -116,15 +119,20 @@

     // Update rudder and sheet
     if (state == SBTSailbotModelStateAutomaticControl) {
+      timeOnTackSequence += now - lastAutomaticUpdate;
+      if (timeOnTackSequence > tackTime * 2)
+        timeOnTackSequence = 0;
       float rudderAngle;
       float angleToWind = angleSubtractf(windDirection, automaticHeading);
       if (abs(angleToWind) < tackAngle / 2.0) {
         float tack = angleToWind > 0 ? tackAngle / 2.0 : -tackAngle / 2.0;
+        if (timeOnTackSequence > tackTime)
+          tack = -tack;
         rudderAngle = angleSubtractf(angleSubtractf(windDirection, tack), heading);
-        Serial.print("Angle towards wind: "); Serial.println(angleToWind * 180.0 / M_PI);
       } else {
         rudderAngle = angleSubtractf(automaticHeading, heading);
       }
+      lastAutomaticUpdate = now;
       setRudder(40.0 * rudderAngle / M_PI);

     } else if (state == SBTSailbotModelStateRecoveryMode) {
@@ -160,9 +168,13 @@
     memcpy(&buffer[14], &sheet, sizeof(sheet));

     RFduinoBLE.send((char*)&buffer, 2 + 4 * sizeof(float));
-    Serial.print("Heading: "); Serial.print(heading);
-    Serial.print(" Automatic heading: "); Serial.print(automaticHeading);
-    Serial.print(" Wind direction: "); Serial.println(windDirection);
+    Serial.print("heading: "); Serial.print(heading);
+    Serial.print(" automaticHeading: "); Serial.print(automaticHeading);
+    Serial.print(" windDirection: "); Serial.print(windDirection);
+    Serial.print(" rudder: "); Serial.print(rudder);
+    Serial.print(" sheet: "); Serial.print(sheet);
+    Serial.print(" timeOnTackSequence: "); Serial.print(timeOnTackSequence);
+    Serial.print(" tackTime: "); Serial.println(tackTime);
   }
 }

@@ -184,6 +196,8 @@
     case SBTSailbotModelHeaderAutomaticControl: {
         remoteState = SBTSailbotModelStateAutomaticControl;
         int newHeading;
+        timeOnTackSequence = 0; // reset time on current tack
+        lastAutomaticUpdate = millis();
         memcpy(&newHeading, &data[1], sizeof(newHeading));
         automaticHeading = ((float)newHeading) * M_PI / 180.0;
         Serial.print("Automatic heading: "); Serial.println(automaticHeading);
@@ -223,6 +237,6 @@
 }

 float angleSubtractf(float angleOne, float angleTwo) {
-    return atan2f(sinf(angleOne - angleTwo), cosf(angleOne - angleTwo));
-}
-
+  return atan2f(sinf(angleOne - angleTwo), cosf(angleOne - angleTwo));
+}
+


tuned the seeking algorithm

tuned the seeking algorithm

--- MPU6050_-_Stepper_Gyro/MPU6050_-_Stepper_Gyro.ino/MPU6050_-_Stepper_Gyro.ino.ino
+++ MPU6050_-_Stepper_Gyro/MPU6050_-_Stepper_Gyro.ino/MPU6050_-_Stepper_Gyro.ino.ino
@@ -139,10 +139,10 @@
   devStatus = mpu.dmpInitialize();

   // supply your own gyro offsets here, scaled for min sensitivity
-  mpu.setXGyroOffset(220);
+  mpu.setXGyroOffset(220); //220
   mpu.setYGyroOffset(76);
   mpu.setZGyroOffset(-85);
-  mpu.setZAccelOffset(1788); // 1688 factory default for my test chip
+  mpu.setZAccelOffset(1688); // 1688 factory default for my test chip

   // make sure it worked (returns 0 if so)

@@ -215,65 +215,74 @@
     // otherwise, check for DMP data ready interrupt (this should happen frequently)
   } else if (mpuIntStatus & 0x02) {
     // wait for correct available data length, should be a VERY short wait
-    while (fifoCount < packetSize)
+    while (fifoCount < packetSize)
       fifoCount = mpu.getFIFOCount();
   }
-    // read a packet from FIFO
-    mpu.getFIFOBytes(fifoBuffer, packetSize);
-
-    // track FIFO count here in case there is > 1 packet available
-    // (this lets us immediately read more without waiting for an interrupt)
-    fifoCount -= packetSize;
-
-    //record the origin once the gyro data has stabilized
-    if (loopcount == 2000) {
-      mpu.dmpGetQuaternion(&q, fifoBuffer);
-      mpu.dmpGetGravity(&gravity, &q);
-      mpu.dmpGetYawPitchRoll(ypr, &q, &gravity);
-      origin[0] = (ypr[0]);
-      origin[1] = (ypr[1]);
-      origin[2] = (ypr[2]);
-
-      // blink LED to indicate that origin has been set
-      blinkState = !blinkState;
-      digitalWrite(LED_PIN, blinkState);
-    }
-
-    // display Euler angles in degrees
+  // read a packet from FIFO
+  mpu.getFIFOBytes(fifoBuffer, packetSize);
+
+  // track FIFO count here in case there is > 1 packet available
+  // (this lets us immediately read more without waiting for an interrupt)
+  fifoCount -= packetSize;
+
+  //record the origin once the gyro data has stabilized
+  if (loopcount == 2000) {
     mpu.dmpGetQuaternion(&q, fifoBuffer);
     mpu.dmpGetGravity(&gravity, &q);
     mpu.dmpGetYawPitchRoll(ypr, &q, &gravity);
+    origin[0] = (ypr[0]);
+    origin[1] = (ypr[1]);
+    origin[2] = (ypr[2]);
+
+    // blink LED to indicate that origin has been set
+    blinkState = !blinkState;
+    digitalWrite(LED_PIN, blinkState);
+  }
+
+  // display Euler angles in degrees
+  mpu.dmpGetQuaternion(&q, fifoBuffer);
+  mpu.dmpGetGravity(&gravity, &q);
+  mpu.dmpGetYawPitchRoll(ypr, &q, &gravity);
 #if 1
-    Serial.print("ypr\t");
-    Serial.print(origin[0] * 180 / M_PI);
-    Serial.print("\t");
-    Serial.print(loopcount);
-    Serial.print("\t");
-    Serial.print(offset);
-    Serial.print("\t");
-    Serial.print(ypr[0] * 180 / M_PI);
-    Serial.print("\t");
-    Serial.print(ypr[1] * 180 / M_PI);
-    Serial.print("\t");
-    Serial.println(ypr[2] * 180 / M_PI);
+  Serial.print("ypr\t");
+  Serial.print(origin[0] * 180 / M_PI);
+  Serial.print("\t");
+  Serial.print(loopcount);
+  Serial.print("\t");
+  Serial.print(offset);
+  Serial.print("\t");
+  Serial.print(ypr[0] * 180 / M_PI);
+  Serial.print("\t");
+  Serial.print(ypr[1] * 180 / M_PI);
+  Serial.print("\t");
+  Serial.println(ypr[2] * 180 / M_PI);
 #endif

-    //turn the stepper
-    if (loopcount > 2000) {
-      offset = (ypr[0] * 180 / M_PI) - (origin[0] * 180 / M_PI);
-
-      if (offset >= 1) {
-        Direction = 1;
-        stepper(1);
-      } else if (offset <= -1) {
-        Direction = 0;
-        stepper(1);
+  //turn the stepper
+  if (loopcount > 2000) {
+    offset = (ypr[0] * 180 / M_PI) - (origin[0] * 180 / M_PI);
+
+    if (offset >= 1) {
+      Direction = 1;
+      if (offset >= 4) {
+        stepper(2);
+      } else {
+        stepper(offset);
+      }
+    } else if (offset <= -1) {
+      Direction = 0;
+      if (offset <= -4) {
+        stepper (2);
+      } else {
+        stepper(-offset);
       }
     }

-    //count the number of program loops for debugging
-    loopcount += 1 ;
-
+  }
+
+  //count the number of program loops for debugging
+  loopcount += 1 ;
+
 }

 //stepping through this pattern moves the rotor of the stepper motor by 1 step


Update DMASpi_example1.ino

Update DMASpi_example1.ino

Picked a better CS pin - this was LED_BUILTIN (13) before, which is SCK. Bad.

--- examples/DMASpi_example1/DMASpi_example1.ino
+++ examples/DMASpi_example1/DMASpi_example1.ino
@@ -1,8 +1,8 @@
 #include <ChipSelect.h>
 #include <DmaSpi.h>

-// create a chip select object. This one uses the pin that the built-in LED is connected to.
-ActiveLowChipSelect<LED_BUILTIN> cs;
+// create a chip select object. This one uses pin 14.
+ActiveLowChipSelect<14> cs;

 void setup() {
   DMASPI0.begin();


fix example

fix example

--- examples/Parser-KeyValue/Parser-KeyValue.ino
+++ examples/Parser-KeyValue/Parser-KeyValue.ino
@@ -47,8 +47,8 @@
             Serial.print("Alarm: ");
             Serial.println(cmdParser.getValueFromKey_P(PSTR("ALARM")));

-            Serial.print("Alarm: ");
-            Serial.println(cmdParser.getValueFromKey_P(PSTR("ALARM")));
+            Serial.print("Valve: ");
+            Serial.println(cmdParser.getValueFromKey_P(PSTR("VALVE")));
         } else {
             Serial.println("Command is not run!");
         }
@@ -60,11 +60,11 @@

     // alarm an
     if (cmdParser.equalValueFromKey_P(PSTR("ALARM"), PSTR("YES"))) {
-        Serial.println("alarm on");
+        Serial.println("Alarm on");

     } else {
         Serial.println("Alarm off");
     }

-    sleep(30000);
+    delay(30000);
 }


Fix a typo in MQTT example code.

Fix a typo in MQTT example code.

--- examples/IRMQTTServer/IRMQTTServer.ino
+++ examples/IRMQTTServer/IRMQTTServer.ino
@@ -374,7 +374,7 @@
   // Calculate how many hexidecimal characters there are.
   uint16_t inputLength = str.length() - strOffset;
   if (inputLength == 0) {
-    debug("Zero length AirCon code encounterd. Ignored.");
+    debug("Zero length AirCon code encountered. Ignored.");
     return;  // No input. Abort.
   }


reduce code size

reduce code size

--- test_configSIM808.ino
+++ test_configSIM808.ino
@@ -13,12 +13,12 @@
 SimpleTimer timer;

 char* key;
-char dateTime[10];
-char gpsMode[3];
+char dateTime[11];
+char gpsMode[4];
 char latitude[11];
-char north_south[1];
+char north_south[2];
 char longitude[11];
-char east_west[1];
+char east_west[2];
 char positionFix[2];
 char numSatelite[2];
 char hdop[5];
@@ -33,38 +33,11 @@
 //my variables MKY
 //const int BUFFER_SIZE = 110;
 const int BUFFER_SIZE = 90;
-boolean matchLocationMessage = true;
-String content = "";
-//char character;
-//T char bufferSerial[BUFFER_SIZE];  // CREATE THIS BUFFER IN ORDER TO READ SERIAL AT ONCE
-//T1 char infoLocation[BUFFER_SIZE];
+
 char buffer[20];                 // WHAT WE ARE READING INTO
-int posTemp;
 int posBuf;
 int seconds=0;
 int Powerkey=6;                 //Power pin for SIM808
-
-enum _parseState
-{
-  PS_DETECT_NEW_LINE, //first byte to init sync
-  PS_READ_GPS_MODE,
-  PS_READ_TIME,
-  PS_READ_LATITUDE,
-  PS_READ_NORTH_SOUTH,
-  PS_READ_LONGITUDE,
-  PS_READ_EAST_WEST,
-  PS_READ_POSITION_FIX,
-  PS_READ_NUM_SAT,
-  PS_READ_HDOP,
-  PS_READ_ALTITUDE,
-  PS_READ_ALT_UNIT,
-  PS_READ_GEOID_SEPARATION,
-  PS_READ_GEOID_UNIT,
-  PS_READ_TTFF,
-  PS_DETECT_MSG_TYPE,
-  PS_DETECT_MSG_TYPE2
-};
-byte state =  PS_DETECT_NEW_LINE; //PS_DETECT_MSG_TYPE;

 /*******************************************************************************************
@@ -222,7 +195,6 @@
 void GetGPSLocation(){
 char infoLocation[BUFFER_SIZE];

-
   while(GPRS.available()){
     GPRS.read();
   }
@@ -245,39 +217,22 @@
      //delay(15);
    }

-   //powerGPS(0);
-   //Serial.print("valor i= ");
-   //Serial.println(i);
-
-   //Copy buffered information in GPRS serial port and the last position of array.
-   //T strcpy(bufferSerial,infoLocation);
-   posTemp = posBuf;
-   //T resetInfoLocationBuffer(); //clean the just received data in the GPRS buffer
-
-
-   //exit condition for parse the GPS location
-   matchLocationMessage = true;
-
-   //parse each character of buffer to extract GPS information
-   for(int i =0; i<posTemp; i++){
-    if(matchLocationMessage==true){
-      //T GPSAnalyzer(bufferSerial[i]);
-      GPSAnalyzer(infoLocation[i]);
-    }
-   }
-
-   SendGPSLocation();
+ if (!GPSAnalyzer(infoLocation)){
+    Serial.println("Extraction of GPS data failed");
+ } else Serial.println("Extraction of GPS data successfull");
+
+ SendGPSLocation();
 }

-void resetBuffer()
+/*void resetBuffer()
 {
   memset(buffer, 0, sizeof(buffer));
   //Serial.print("Valor do pos: ");
   //Serial.println(pos);
   pos = 0;
 }//BASICALLY TO RESET THE BUFFER
-
+*/
 /*void resetInfoLocationBuffer()
 {
   memset(infoLocation, 0, sizeof(buffer));
@@ -390,27 +345,101 @@
   }
 }

-// =====================================================================
-// Analyze the Serial information received after request the information
-// AT+CCPSINF=2
-// =====================================================================
-//AT+CGPSINF=2, get GPS location with format
-//Message ID       = 2
-//UTC time         = [hhmmss.sss]
-//Latitude         = [+/-[0dd.dddd]]
-//N/S indicator    = [N/S]
-//Longitude        = [+/-[0ddd.dddd]]
-//E/W indicator    = [W/E]
-//Position fix     = 1
-//Satellites used  = range 0 to 12
-//HDOP             = x.xx
-//MSL Altitude     = xxx.x
-//Units            = M
-//Geoid Separation = xxx
-//Units            = M
-void GPSAnalyzer(byte b) {
-
-   if ((b != ',')){
+/********************************************************************************
+ * boolean GPSAnalyzer(char *gpsBuffer)
+ * Analyze the Serial information received after request the information
+ * AT+CCPSINF=2
+ * +CGPSINF: 2,050656.000,0030.2706,N,00120.1007,E,1,9,0.90,51.9,M,7.0,M,,
+ * AT+CGPSINF=2, get GPS location with format
+ * Message ID       = 2
+ * UTC time         = [hhmmss.sss]
+ * Latitude         = [+/-[0dd.dddd]]
+ * N/S indicator    = [N/S]
+ * Longitude        = [+/-[0ddd.dddd]]
+ * E/W indicator    = [W/E]
+ * Position fix     = 1
+ * Satellites used  = range 0 to 12
+ * HDOP             = x.xx
+ * MSL Altitude     = xxx.x
+ * Units            = M
+ * Geoid Separation = xxx
+ * Units            = M
+ * +CGPSINF: 2,050656.000,0030.2706,N,00120.1007,E,1,9,0.90,51.9,M,7.0,M,,
+ ********************************************************************************/
+boolean GPSAnalyzer(char *gpsBuffer) {
+   char *token;
+
+   /* get the first token */
+   Serial.println("****************Content of gpsBuffer*******************");
+
+   //Command sent
+   token = strtok(gpsBuffer,"\n\r" );
+   if(token != NULL) {
+     Serial.print("Command sent:");
+     Serial.println(token);
+   }else return false;
+
+   token = strtok(NULL, ":");
+   if(token != NULL) {
+     Serial.print("Command response:");
+     Serial.println(token);
+   }else return false;
+
+   //Get CGPSINF_MODE
+   token = strtok(NULL, ",");
+   if(token != NULL) {
+      strcpy(gpsMode,token);
+      Serial.println("************************************************************ ");
+      Serial.print("CGPSINF_MODE    : ");
+      Serial.println(gpsMode);
+   }else return false;
+
+
+   //Get time
+   token = strtok(NULL, ",");
+   if(token != NULL) {
+      strcpy(dateTime,token);
+      Serial.print("TIME            : ");
+      Serial.println(dateTime);
+   }else return false;
+
+   //Get Latitude
+   token = strtok(NULL, ",");
+   if(token != NULL) {
+      strcpy(latitude,token);
+      Serial.print("LATITUDE        : ");
+      Serial.println(latitude);
+   }else return false;
+
+   //Get North or South
+   token = strtok(NULL, ",");
+   if(token != NULL) {
+      strcpy(north_south,token);
+      Serial.print("N/S INDICATOR  : ");
+      Serial.println(north_south);
+   }else return false;
+
+   //Get Longitude
+   token = strtok(NULL, ",");
+   if(token != NULL) {
+      strcpy(longitude,token);
+      Serial.print("LONGITUDE       : ");
+      Serial.println(longitude);
+   }else return false;
+
+   //Get East or West
+   token = strtok(NULL, ",");
+   if(token != NULL) {
+      strcpy(east_west,token);
+      Serial.print("E/W INDICATOR   : ");
+      Serial.println(east_west);
+      Serial.println("************************************************************ ");
+
+   }else return false;
+
+   return true;
+
+/*   if ((b != ',')){
        buffer[pos++] = b;
    }

@@ -717,8 +746,7 @@

   //use goto to put it at sms begining
   }
-  //return;
+  //return;*/
  }

-


Icone non visualizzate se notifiche = 0

Icone non visualizzate se notifiche = 0

--- WerCA_nightly/WerCA_nightly.ino
+++ WerCA_nightly/WerCA_nightly.ino
@@ -71,10 +71,10 @@
 //Implementazioni variabili ELP
 char ELP_data[20];
 char time[5];
-char num_sms = '0';
-char num_calls = '0';
-char num_email = '0';
-char num_other = '0';
+int num_sms = '0';
+int num_calls = '0';
+int num_email = '0';
+int num_other = '0';
 char incoming_number[15];
 char incoming_name[16];
 char phone_battery;
@@ -395,10 +395,10 @@
             switch(ELP_data[0])
             {
               case 'A':  //NOTIFICHE
-                num_sms = ELP_data[1];
-                num_calls = ELP_data[2];
-                num_email = ELP_data[3];
-                num_other = ELP_data[4];
+                num_sms = ELP_data[1] - '0';
+                num_calls = ELP_data[2] - '0';
+                num_email = ELP_data[3] - '0';
+                num_other = ELP_data[4] - '0';

                 //SALVA LE ORE
                 for(int i=0; i<=5; i++){
@@ -413,24 +413,37 @@
                 display.setCursor(54,0);
                 display.print(time);

-                display.drawBitmap(0, 12, icon_phone_16, 16, 16, BLACK);
-                display.drawBitmap(22, 12, icon_sms_16, 16, 16, BLACK);
-                display.drawBitmap(44, 12, icon_email_16, 16, 16, BLACK);
-                display.drawBitmap(66, 12, icon_web_16, 16, 16, BLACK);
+                if(num_calls > 0){
+                  display.drawBitmap(0, 12, icon_phone_16, 16, 16, BLACK);
+                  display.setCursor(3,30);
+                  display.setTextSize(2);
+                  display.print(num_calls);
+                }
+
+                if(num_sms > 0){
+                  display.drawBitmap(22, 12, icon_sms_16, 16, 16, BLACK);
+                  display.setCursor(25,30);
+                  display.setTextSize(2);
+                  display.print(num_sms);
+                }
+
+                if(num_email > 0){
+                  display.drawBitmap(44, 12, icon_email_16, 16, 16, BLACK);
+                  display.setCursor(47,30);
+                  display.setTextSize(2);
+                  display.print(num_email);
+                }
+
+                if(num_other > 0){
+                  display.drawBitmap(66, 12, icon_web_16, 16, 16, BLACK);
+                  display.setCursor(69,30);
+                  display.setTextSize(2);
+                  display.print(num_other);
+                }

                 display.display();

-                /*
-                display.setCursor(12, 8);
-                display.print("SMS       ");
-                display.print(num_sms);
-                display.print("\n  Chiamate  ");
-                display.print(num_calls);
-                display.print("\n  Email     ");
-                display.print(num_email);
-                display.display();
-                */
-
+
               break;

               case 'B':  //Chiamata in arrivo


Parse state into the motorcycle state global

--- Event_Printer/Event_Printer.ino
+++ Event_Printer/Event_Printer.ino
@@ -136,7 +136,8 @@
 void handle_MSG_ID_ABS_Control_Module(unsigned char *data, unsigned char length)
 {
     // BRAKE LEVERS
-    unsigned char value = LO_NIBBLE(data[6]);
+    byte value = LO_NIBBLE(data[6]);
+    motorcycle_state.brake_levers = (K25_Brake_Lever_State)value;
     DEBUG_PRINT("Brake Levers: ");
     if( value == 0x07 ) DEBUG_PRINT("Front");
     else if( value == 0x0B ) DEBUG_PRINT("Rear");
@@ -146,6 +147,7 @@

     // ABS Status
     value = HI_NIBBLE(data[1]);
+    motorcycle_state.abs_system = (K25_ABS_State)value;
     DEBUG_PRINT("ABS: ");
     if( value == 0x05 ) DEBUG_PRINT("ON");
     else if( value == 0x0B ) DEBUG_PRINT("OFF");
@@ -163,7 +165,8 @@
     DEBUG_PRINT_LN();

     // CLUTCH LEVER
-    unsigned char value = LO_NIBBLE(data[4]);
+    byte value = LO_NIBBLE(data[4]);
+    motorcycle_state.clutch = (K25_Clutch_Lever_State)value;
     DEBUG_PRINT("Clutch: ");
     if( value == 0x0A ) DEBUG_PRINT("IN");
     else if( value == 0x06 ) DEBUG_PRINT("OUT");
@@ -174,7 +177,8 @@
 void handle_MSG_ID_ZFE_Control_Module(unsigned char *data, unsigned char length)
 {
     // HIGH BEAM
-    unsigned char value = LO_NIBBLE(data[6]);
+    byte value = LO_NIBBLE(data[6]);
+    motorcycle_state.high_beam = (K25_High_Beam_State)value;
     DEBUG_PRINT("High beam ");
     if( value == 0x09 ) DEBUG_PRINT("ON");
     else if( value == 0x0A ) DEBUG_PRINT("OFF");
@@ -183,6 +187,7 @@

     // TURN SIGNAL
     value = data[7];
+    motorcycle_state.turn_signals = (K25_Turn_Signals_State)value;
     DEBUG_PRINT("Turn Signals ");
     if( value == 0xCF ) DEBUG_PRINT("OFF");
     else if( value == 0xD7 ) DEBUG_PRINT("LEFT ONLY");
@@ -195,7 +200,8 @@
 void handle_MSG_ID_ZFE_Control_Module_2(unsigned char *data, unsigned char length)
 {
     // HEATED GRIPS
-    unsigned char value = HI_NIBBLE(data[7]);
+    byte value = HI_NIBBLE(data[7]);
+    motorcycle_state.heated_grips = (K25_Heated_Grips_State)value;
     DEBUG_PRINT("Heated Grips: ");
     if( value == 0x0F ) DEBUG_PRINT("OFF");
     else if( value == 0x0C ) DEBUG_PRINT("LOW");
@@ -205,6 +211,7 @@

     // INFO BUTTON
     value = HI_NIBBLE(data[5]);
+    motorcycle_state.info_button = (K25_Info_Button_State)value;
     DEBUG_PRINT("Info Button: ");
     if( value == 0x05 ) DEBUG_PRINT("SHORT PRESS");
     else if( value == 0x06 ) DEBUG_PRINT("LONG PRESS");


Corrected Increment Bug in WatchDogSleep, added freeMemory Check

--- ATTinyRFSerialTest.ino
+++ ATTinyRFSerialTest.ino
@@ -38,7 +38,7 @@
 #define network 210      // RF12 Network group
 #define freq RF12_433MHZ // Frequency of RFM12B module

-#define USE_ACK           // Enable ACKs, comment out to disable
+//#define USE_ACK           // Enable ACKs, comment out to disable
 #define RETRY_PERIOD 5    // How soon to retry (in seconds) if ACK didn't come in
 #define RETRY_LIMIT 5     // Maximum number of times to retry
 #define ACK_TIME 10       // Number of milliseconds to wait for an ack
@@ -70,12 +70,12 @@
   sinit();
 #endif

-  rf12_initialize(myNodeID,freq,network); // Initialize RFM12 with settings defined above
-  rf12_sleep(0);                          // Put the RFM12 to sleep
-  PRR = bit(PRTIM1); // only keep timer 0 going
+  rf12_initialize(myNodeID,freq,network);  // Initialize RFM12 with settings defined above
+  rf12_sleep(0);                           // Put the RFM12 to sleep
+  PRR = bit(PRTIM1);                       // only keep timer 0 going
   ADCSRA &= ~ bit(ADEN);
-  bitSet(PRR, PRADC); // Disable the ADC to save power
-  setup_watchdog(7);
+  bitSet(PRR, PRADC);                      // Disable the ADC to save power
+  setup_watchdog(6);

 }

@@ -100,13 +100,12 @@
 //--------------------------------------------------------------------------------------------------
 // Sleep Configuration
 //-------------------------------------------------------------------------------------------------
-// 0=16ms, 1=32ms,2=64ms,3=128ms,4=250ms,5=500ms
-// 6=1 sec,7=2 sec, 8=4 sec, 9= 8sec
-void setup_watchdog(int sleepMode) {
+// 0=16ms, 1=32ms,2=64ms,3=128ms,4=250ms,5=500ms,6=1 sec,7=2 sec, 8=4 sec, 9=8 sec
+void setup_watchdog(uint8_t sleepMode) {

   byte sleepByte;
-  if (sleepMode > 9 ) sleepMode=9;
-  sleepByte = sleepMode & 7;
+  if (sleepMode > 9 ) sleepMode = 9;
+  sleepByte = sleepMode & 0x07;
   if (sleepMode > 7) sleepByte |= (1<<5);
   sleepByte |= (1<<WDCE);

@@ -119,18 +118,19 @@

 void sleep(uint8_t sleepTime) {

-  while(watchdog_counter++ < sleepTime) {
+  do {
     set_sleep_mode(SLEEP_MODE_PWR_DOWN);             // select the watchdog timer mode
     sleep_enable();                                  // enable the sleep mode ready for use
     sleep_mode();                                    // trigger the sleep
     sleep_disable();                                 // prevent further sleeps
-  }
-  watchdog_counter = 0;
+  } while(watchdogCounter < sleepTime);
+
+  watchdogCounter = 0;

 }

 ISR(WDT_vect) {
-  watchdog_counter++;
+  watchdogCounter++;
 }

@@ -256,9 +256,17 @@
 #endif
 // Serial Functions End

-
-
-
-
-
-
+//--------------------------------------------------------------------------------------------------
+// Free Available Memory Function
+//--------------------------------------------------------------------------------------------------
+int freeMemory() {
+  extern int __heap_start, *__brkval;
+  int v;
+  return (int) &v - (__brkval == 0 ? (int) &__heap_start : (int) __brkval);
+}
+
+
+
+
+
+


fix buffer overflow bugs

fix buffer overflow bugs

--- V1_0.ino
+++ V1_0.ino
@@ -159,12 +159,12 @@
         actualValue = (sensorValue / 1023.00) * divider;
         v1 = actualValue;
         v2 = (actualValue - v1) * 100;
-        snprintf(voltage, 30, "%i.%02i", v1, v2);
+        snprintf(voltage, sizeof(voltage), "%i.%02i", v1, v2);

     cBusy = true;
     sprintf(datastring,"$$$$%s,%li,%02i:%02i:%02i,%s,%s,%s,%i,%s",callsign,ticks,hour,minute,second,latbuf,lonbuf,altbuf,sats,voltage);
     unsigned int CHECKSUM = gps_CRC16_checksum(datastring);  // Calculates the checksum for this datastring
-    char checksum_str[6];
+    char checksum_str[7];
     sprintf(checksum_str, "*%04X\n", CHECKSUM);
     strcat(datastring,checksum_str);
     cBusy = false;
@@ -397,4 +397,4 @@

     }
   }
-}
+}