RFduino V0.9.15

RFduino V0.9.15

restart packet sending if BLE disconnectes during transfer of packets
11 min watchdog enabled

--- LBridge_RFduino_V09/LBridge_RFduino_V09.ino
+++ LBridge_RFduino_V09/LBridge_RFduino_V09.ino
@@ -63,25 +63,32 @@
  *  - bugfix to enable live sensor change (@bertrooode, @chaosbiber)
  *  - minor bugfixes
  * V0.9.11
- *  - fixed LimiTTer mode (comment USE_XBRIDGE2 out)
+ *  - fixed code errors in LimiTTer mode, no tested before (uncomment #define USE_XBRIDGE2 to activate)
  * V0.9.12
- *  - removed while (!Serial), replaced by a fixed delay
- *  - removed own printf code to avoid stack overflow
- *  - added while (RDduinoBLE.radioActive); after ...BLE.send
+ *  - removed useless while (!Serial), replaced by a fixed delay, RFduino Serial implementation is interrupt driven, only work on Arduino
+ *  - removed own printf code to avoid stack overflow, serial output only done with Serial.printf() now
+ *  - added while (RDduinoBLE.radioActive); after ...BLE.send / to be tested
  * V0.9.13
- *  - this version number was skipped
+ *  - this version number was intentional skipped
  * V0.9.14
- *  - replaced all String class depend code to char[] type to reduce heavy memory usage of String class
- *  - added stack_check() code / no action / display function call history after remaining memory is too low
+ *  - replaced all String class depend code to char[] type to reduce heavy memory usage of the String class
+ *  - added stack_check() code / no action taken on underflow / displays function call history after remaining memory is too low
+ *  - track and display absolute minimum of available memory
  *  - removed radioActive check before/after BLE.send routines
  *  - reduced BLE packet length to 20 bytes fixed to avoid sending 2 packets / xDrip accepts shorter packets
  *    if the length is coded correctly at start of packet
+ * V0.9.15
+ *  - restart of BLE stack when not connected at end of loop() to heal slowly packet transmission after reconnect (experimental)
+ *  - restart BLE stack if BLE lost during sending the current queue (40 s waiting time)
+ *  - testing function result of BLE.send to check proper BLE stack queue filling (currently RFduino only)
+ *  - added watchdog again to overcome possible RFduino freezing due to BLE stack overload
  */

  /*
   * to do:
   * - clear up SHADOWFRAM code, implemented with #defined parts and bool flag
   * - adopt Simblee FLASH handling
+  * - reintegrate a classic watchdog timer to overcome RFduino freezing
   */

 /* ********************* program configuration options **********************/
@@ -92,30 +99,33 @@
 #define USE_XBRIDGE2            // uncomment to use two way xbridge2 protocol with backfilling instead of LimiTTer
                                 // ASCII protocol (one way communication)
 #define USE_SHADOWFRAM          // uncomment to work with a shadow FRAM copy of the Libre sensor FRAM
-#define SHORTSTARTCYCLE         // uncomment to have 10 inital 1 min cycles to have faster sensor start (@FPV_UAV)
-
-/*
- * debug and other less important options
- * add an "N_" prefix to disbale the option
- */
-//#define DEBUG                 // uncomment to have verbose debug output
-//#define FRAM_DEBUG                 // uncomment to have verbose debug output for FRAM mechanism
+#define SERIALOFF               // switch off Serial interface during ULP for power saving
+//#define SHOW_BLESTATECHANGE     // uncomment to have serial BLE connect/disconnect messages (see also #define SERIALOFF)
+
+//#define SHORTSTARTCYCLE         // uncomment to have 10 inital 1 min cycles to have faster sensor start (@FPV_UAV)
+
+// debug and other less important options, uncomment to disbale the option
 //#define SIM_MINUTES_UPCOUNT     // for testing backfilling with dead sensor, disable for active sensors!

-//#define SHOW_BLESTATECHANGE     // uncomment to have serial BLE connect/disconnect messages
-#define SERIALOFF               // switch off Serial interface during ULP
+//#define DEBUG                   // uncomment to have verbose debug output
+//#define FRAM_DEBUG              // uncomment to have verbose debug output for FRAM mechanism
+
+//#define BLE_REAL_LEN            // use real length of BLE packets to send or limit to 20 chars?
+//#define SEND_LIMITTER_SA      // send sensor minutes via LimiTTer string
+#define USE_WDT               // use watchdog with 11 min duration
+
+/* ******************** BLE and central seetings ***************************** */

 #define UARTDELAY 2000          // delay after switching serial interface on/off

-/* ******************** BLE and central seetings ***************************** */
 #define DXQUEUESIZE (9*12)     // 12 h of queue (remember and send the last x hours when reconnected via BLE)

 #define LB_NAME   "xbridgeR"    // dont change "xbridge", space for 1 char left to indicate different versions
 #define LB_ADVERT "rfduino"     // dont change "rfduino"
                                 // length of device name and advertisement <=15!!!
 #define LB_VERSION "V0.9"       // program version
-#define LB_MINOR_VERSION ".14"  // indicates minor version
-#define LB_DATETIME "180320_2008" // date_time
+#define LB_MINOR_VERSION ".15"  // indicates minor version
+#define LB_DATETIME "180326_0915" // date_time
 #define SPIKE_HEIGHT 40         // minimum delta to be a spike

 #ifdef RFD
@@ -126,8 +136,6 @@
 #define MIN_VOLTAGE 2200        // minimum voltage where BLE will work properly (@FPV-UAV)
 #endif RFD

-//#define BLE_REAL_LEN            // use real length of BLE packets to send or limit to 20 chars?
-
 /* ****************************** includes ********************************** */

 #ifdef RFD
@@ -141,8 +149,6 @@
 #include <Stream.h>
 #include <Memory.h>
 #include <itoa.h>
-
-//#include <itoa.h>             // support functions for sprintf(...)

 // by @clvsjr9 to Arduino 1.6.5 compile
 //#include <data_types.h>
@@ -209,7 +215,9 @@
 bool use_shadowfram = 0;
 #endif

+#ifdef SEND_LIMITTER_SA
 unsigned long last_raw = 0;         // last sended RAW value
+#endif
 int batteryPcnt = 0;                // battery capacity in %

 unsigned long loop_cnt = 0;         // count the 5 mins loops
@@ -219,7 +227,7 @@
 unsigned char bleBuf[BLEBUFLEN];
 int bleBufRi = 0;                   // BLE read and write index
 int bleBufWi = 0;
-bool BTconnected = false;
+static boolean BTconnected = false;

 unsigned long startMinutesSinceStart = 0;
 unsigned long startMillisSinceStart = 0;
@@ -236,7 +244,6 @@

 bool BatteryOK = false;

-byte noOfBuffersToTransmit = 1;     // LimiTTer type string
 char TxBuffer[30];

 byte NFCReady = 0;            // 0 - not initialized, 1 - initialized, no data, 2 - initialized, data OK
@@ -339,7 +346,7 @@
 SensorDataDataType sensorData;

 /*
- * optimisation possible - data are stored in 3 different arrays
+ * to be optimised - data are stored in 3 different arrays
  */

 byte sensorDataHeader[24];
@@ -447,6 +454,9 @@
 #ifdef SERIALOFF
   Serial.print("-serialOff");
 #endif
+#ifdef USE_WDT
+  Serial.print("-WDT");
+#endif

   getSoCData();
   printSoCData();
@@ -473,6 +483,10 @@
   initSensor(&sensor);      // initialize the sensor data structure for FRAM shadowing
 #endif

+#ifdef USE_WDT
+  configWDT();              // wind up watch dog timer in case of RFduino freezing do a reset
+#endif
+
   setupBluetoothConnection();

   // init xbridge queue
@@ -482,7 +496,8 @@
   // set timestamps in queue for inital backfilling
   initialFillupBackfillTimestamps();
 #endif
-  print_state("NFCReady = "); Serial.print(NFCReady); Serial.print(", BatOK = "); Serial.print(BatteryOK);
+  print_state("");
+  Serial.printf("NFCReady = %d, BatOK = %d", NFCReady, BatteryOK);

   check_stack("#setup#");
   memAndStack("setup()");
@@ -512,7 +527,7 @@
 void memAndStack(char *func)
 {
   print_state("");
-  Serial.printf("(%s) - free RAM = %d, minimum memory available: %d", func, freeMemory(), minimumMemory);
+  Serial.printf("(%s) - free RAM = %d, min. RAM avail log: %d", func, freeMemory(), minimumMemory);
   int v;
   Serial.print(", Stack Size = ");
   // stack memory of RFduino begins at 0x20003FFF
@@ -604,6 +619,10 @@
   Serial.print("Simblee) ===");
 #endif

+#ifdef USE_WDT
+  restartWDT();
+#endif
+
   // show memory for debug
   memAndStack("loop()");
   // display current data from RFduino
@@ -632,14 +651,9 @@
 #endif
       dataTransferBLE();
     }
-    else {
-      print_state("no sensor data to transmit");
-    }
-  }
-  else {
-    print_state("low Battery - go sleep");
-  }
-
+    else {  print_state("no sensor data to transmit");  }
+  }
+  else {  print_state("low Battery - go sleep");  }
   // calculate sleep time ajusted to runPeriod cycle
   unsigned long sleep_time = (60000 * runPeriod) - (mymillis() - time_loop_started)%60000;

@@ -650,9 +664,12 @@
     Serial.print(" ms) set to 5 min fix");
     sleep_time = 5*60000L;
   }
+
+  restartBtStack(0);
+
   print_state("loop #"); Serial.print(loop_cnt-1); Serial.print(" - end - NFCReady = ");
   Serial.print(NFCReady); Serial.print(", sleep for "); Serial.print(sleep_time/1000); Serial.print(" s");
-
+
   // @bertroode: wait for serial output in process
   Serial.flush();
   delay(100);
@@ -791,6 +808,7 @@
     // 1 min distance
     Serial.printf(" %d (-%d min)", (scale_bg(sensorData.trend[i])+500)/1000, i);
   }
+#if 0
   if ( 0 ) {
     long average;
     Serial.println("");
@@ -803,6 +821,7 @@
       Serial.printf("%d avg: %d, ", i, (average+500)/1000);
     }
   }
+#endif 0
   print_state("--->BG history:\r\n");
   // 15 min distance, starts at 18 min from now
   for (int i = 0; i < 32; i++) {
@@ -873,6 +892,25 @@
   minutesSinceProgramStart = (mymillis() / (60000));
 }
 #endif USE_XBRIDGE2
+
+/* ************************* NFC/SPI handling **************************** */
+
+#ifdef USE_WDT
+void configWDT()
+{
+  print_state("configure watchdog timer");
+  NRF_WDT->CONFIG = (WDT_CONFIG_SLEEP_Run << WDT_CONFIG_SLEEP_Pos) | (WDT_CONFIG_HALT_Pause << WDT_CONFIG_HALT_Pos);
+  NRF_WDT->CRV = 32768 * 60 * 11;         // 11 minut
+  NRF_WDT->RREN |= WDT_RREN_RR0_Msk;
+  NRF_WDT->TASKS_START = 1;
+}
+
+void restartWDT()
+{
+//  print_state("restart watchdog timer");
+  NRF_WDT->RR[0] = WDT_RR_RR_Reload;
+}
+#endif

 /* ************************* NFC/SPI handling **************************** */

@@ -1486,8 +1524,8 @@
         #ifdef DEBUG
         // Print to Serial for debugging
         if (RXBuffer[0] == 0x80)  {
-            print_state("readSingleBlock: block #");
-            Serial.printf("%d:", blockNum);
+            print_state("");
+            Serial.printf("readSingleBlock: block #%d:", blockNum);
 #ifdef FRAM_DEBUG
             for (byte i = 3; i < RXBuffer[1] + 3 - 4; i++) {
                 Serial.print(RXBuffer[i], HEX);
@@ -1495,8 +1533,8 @@
             }
 #endif
         } else {
-            print_statef("readSingleBlock: block #");
-            Serial.printf("%d not available, response code is: ", blockNum);
+            print_statef("");
+            Serial.printf("readSingleBlock: block #%d not available, response code is: ", blockNum);
             Serial.println(RXBuffer[0], HEX);
         }
 //        Serial.println(" ");
@@ -1757,9 +1795,9 @@
   analogSelection(VDD_1_3_PS);
 #ifdef RFD
   uint16_t sensorValue1 = readVDD();
-  print_state(""); Serial.printf("readVDD() = %d, ", sensorValue1);
+//  print_state(""); Serial.printf("readVDD() = %d, ", sensorValue1);
   int sensorValue = analogRead(1);
-  Serial.printf("analogRead(1) = %d, ", sensorValue);
+//  Serial.printf("analogRead(1) = %d, ", sensorValue);
   SoCData.voltage = sensorValue * (360 / 1023.0) * 10;
   SoCData.temperatureC = RFduino_temperature(CELSIUS);
   SoCData.temperatureF = RFduino_temperature(FAHRENHEIT);
@@ -1769,9 +1807,9 @@
   SoCData.temperatureC = Simblee_temperature(CELSIUS);
   SoCData.temperatureF = Simblee_temperature(FAHRENHEIT);
 #endif
-  Serial.printf(", TempC = %f", SoCData.temperatureC);
+//  Serial.printf(", TempC = %f", SoCData.temperatureC);
   SoCData.voltagePercent = map(SoCData.voltage, MIN_VOLTAGE, MAX_VOLTAGE, 0, 100);
-  Serial.printf(", Batt = %d", SoCData.voltagePercent);
+//  Serial.printf(", Batt = %d", SoCData.voltagePercent);
   if (SoCData.voltage < MIN_VOLTAGE)
     BatteryOK = false;
   else
@@ -1876,8 +1914,8 @@
   if (!sensorData.sensorDataOK)
     print_state("Sensor data error");
   else {
-    print_state("BG raw reading: ");
-    Serial.printf("%d, therm. temp est.: %f", sensorData.trend[0], sensorData.trendTemperature[0]);
+//    print_state("");
+//    Serial.printf("BG raw reading: %d, therm. temp est.: %f", sensorData.trend[0], sensorData.trendTemperature[0]);
   }
 }

@@ -2116,7 +2154,6 @@

 void decodeSensorFooter()
 {
-//  memAndStack("decodeSensorFooter()");
   check_stack("#dsf#");
 }

@@ -2240,7 +2277,7 @@
 {
   check_stack("#sblec#");

-  print_state("setupBluetoothConnection()");
+  print_state("configure and start BLE stack");
 #ifdef RFD
   if (protocolType == 1) RFduinoBLE.deviceName = LB_NAME;
 #ifdef USE_XBRIDGE2
@@ -2284,12 +2321,13 @@

   if ( !BTconnected ) {
     print_state("");
-    Serial.printf("dataTransferBLE(), wait 40 s for BLE connect (protocolType = %d) ...", protocolType);
-  }
-  for (int i = 0; i < 40; i++) {
+    Serial.printf("dataTransferBLE(), wait 100 s for BLE connect (protocolType = %d) ...", protocolType);
+  }
+  for (int i = 0; i < 100; i++) {
     if (BTconnected) {
-      if (protocolType == 1)
+      if (protocolType == 1) {
         sendToXdripViaBLE();
+      }
       else {
         print_state("");
         Serial.printf(" *** wrong protocol type %d", protocolType);
@@ -2303,6 +2341,25 @@
   NFCReady = 1;
 }

+void restartBtStack(boolean waitForBT)
+{
+  // if we loosed the BLE connection during transfer or whatever reason restart the BLE stack here
+  if (!BTconnected)
+  {
+    print_state("restarting BT stack, stop BLE");
+    // check for endless loop
+    while (!RFduinoBLE.radioActive) {};
+    while (RFduinoBLE.radioActive) {};
+    RFduinoBLE.end();
+    setupBluetoothConnection();
+    // wait for max 40 s for BLE reconnect
+    if ( waitForBT ) {
+      Serial.printf(" - waiting up to 50 s for reconnect");
+      waitDoingServicesInterruptible(50000, &BTconnected, 1);
+    }
+  }
+}
+
 /*
  * send the BG reading to xDrip+
  */
@@ -2311,35 +2368,48 @@
   check_stack("#stxvble#");

 #ifndef USE_XBRIDGE2
-  // LimiTTer styl as ASCII string
-  noOfBuffersToTransmit = 1;
-
   TxBuffer[0] = '\0';
   sprintf(TxBuffer, "%d %d %d %d", \
     sensorData:TREND[0] * 100, SoCData.voltage, SoCData.voltagePercent, sensorData.minutesSinceProgramStart/10);

-  print_state("sendToXdripViaBLE: ");
-  Serial.printf("%s", TxBuffer);
+  print_state("");
+  Serial.printf("sendToXdripViaBLE: %s", TxBuffer);
 #ifdef RFD
   // send is queued (the ble stack delays send to start of next tx window)
-  while ( !RFduinoBLE.send(TxBuffer, strlen(TxBuffer)) );
-//  while ( RFduinoBLE.radioActive);
+  while ( !RFduinoBLE.send(TxBuffer, strlen(TxBuffer)) ) {
+    // check for endless loop needed!
+    ;
+  }
+  // wait for end of BLE stack time slot (roughly 6 ms)
+  while ( RFduinoBLE.radioActive);
 #else
   SimbleeBLE.send(TxBuffer, strlen(TxBuffer));
-//  while ( SimbleeBLE.radioActive);
+  while ( SimbleeBLE.radioActive);
 #endif
 #else /* USE_XBRIDGE2 */
   boolean resend_pkt = 0;
+  int more_than_one = 0;
+  // if we are connected via BLE, the queue contains BG readings to be send and we have enough time left
   while ((Pkts.read != Pkts.write) && BTconnected && ((mymillis() - pkt_time) < ((DXQUEUESIZE + 1) * 5000) )) {
     got_ack = 0;
+    unsigned long got_ack_time;

     // dont send a 0 entry
     if ( Pkts.buffer[Pkts.read].raw ) {

+      // waiting time before next packet will be sended
+      if ( more_than_one++ )
+        waitDoingServices(100, 1);
+      got_ack_time = mymillis();
+      print_state("");
+      Serial.printf("try sending [%d BG / -%d min / %d] - ", Pkts.buffer[Pkts.read].raw/1000, (mymillis() - Pkts.buffer[Pkts.read].ms)/60000, Pkts.read);
+//      Serial.printf("[%d/-%d]", Pkts.buffer[Pkts.read].raw/1000, (mymillis() - Pkts.buffer[Pkts.read].ms)/60000);
+
       sendBgViaBLE(&Pkts.buffer[Pkts.read]);

+#ifdef SEND_LIMITTER_SA
       last_raw = Pkts.buffer[Pkts.read].raw;
-
+#endif
       // wait 10 s for ack
       int j;
       for ( j = 0 ; j < 10 ; j++ ) {
@@ -2350,43 +2420,52 @@
         }
       }
     }
-    // when it was 0 incremnt read counter
+    // when it was 0 increment read counter
     else {
-      print_state("do not send 0, increment read pointer instead, simulate ACK");
+      print_state("do not send a raw value containing 0, increment read pointer instead, simulate ACK");
       got_ack = 1;
     }

     if (got_ack) {
-      Serial.printf(" - got ack (read %d, write %d), inc read to ", Pkts.read, Pkts.write);
+      Serial.printf("ACK / %d ms", mymillis()-got_ack_time);
+//      Serial.printf(" (read %d, write %d), inc read to ", Pkts.read, Pkts.write);
       if ( ++Pkts.read >= DXQUEUESIZE )
         Pkts.read = 0;     //increment read position since we got an ack for the last package
-      Serial.print(Pkts.read);
-      Serial.print(" - ");
+//      Serial.printf("%d - ", Pkts.read);
       resend_pkt = 0;
     }
     else {
       if ( !resend_pkt ) {
-        print_state("no ack received, try again");
+        print_state("no ACK received, try again");
         resend_pkt = 1;
+        // restart BT stack in case of BT transfer breaks after some blocks sended
+        restartBtStack(1);
+        // wait additional 5 s for DexCollectionService to sttle
+        if ( BTconnected )
+          delay(5000);
       }
       else {
-        print_state("no ack received, try again next wakeup");
+        print_state("no ACK received, try again next wakeup");
         resend_pkt = 0;
         break;
       }
     }
   } /* while (send all packets available) */
-
+//  print_state("end of while schleife");
+//  waitDoingServices(100, 1);
+
+#ifdef SEND_LIMITTER_SA
   // transfer the sensor livetime with the last successful tranmitted BG reading
   // currently not supported as an wixel device
-  if ( 0 ) {
-//  if ( ((loop_cnt % 12) == 0) && (last_raw != 0) )
+  if ( ((loop_cnt % 12) == 0) && (last_raw != 0) ) {
+    print_state("send LimiTTer type sensor age ...");
+//    waitDoingServices(100, 1);
     if ( got_ack ) {
       char packet[30];
       // build a LimiTTer string
       packet[0] = '\0';
       batteryPcnt = min(map(SoCData.voltage, MIN_VOLTAGE, MAX_VOLTAGE, 0, 100), 100); // Convert voltage to percentage
-      sprintf(packet, "%s 216 %s %s", last_raw, batteryPcnt, sensorData.minutesSinceStart);
+      sprintf(packet, "%d 216 %d %d", last_raw, batteryPcnt, sensorData.minutesSinceStart);
       print_state("");
       Serial.printf("send sensor lifetime in LimiTTer ASCII format: [%s]", packet);
       send_data((unsigned char*)packet, strlen(packet));
@@ -2394,6 +2473,7 @@
       last_raw = 0;
     }
   }
+#endif SEND_LIMITTER_SA

 #endif /* USE_XBRIDGE2 */
 }
@@ -2530,10 +2610,10 @@
   nRawRecord msg;
   unsigned char msgbuf[80];
   check_stack("#sbgvb#");
-
+/*
   print_state("");
-  Serial.printf("sendBGOverBLE(%d), delay %d min", pPkt->raw/1000, (mymillis() - pPkt->ms)/60000);
-
+  Serial.printf("send[%d]@-%dmin", pPkt->raw/1000, (mymillis() - pPkt->ms)/60000);
+*/
   if ( !BTconnected ) {
     print_state("no BT connection, skip");
     return (0);
@@ -2719,6 +2799,9 @@
       Serial.println("R-command received.");
     #endif
     readAllData();
+#ifdef USE_XBRIDGE2
+    fillupMissingReadings(0);
+#endif
     dataTransferBLE();
   }
   // we don't respond to unrecognised commands.


remove arduino specific ifdefs

remove arduino specific ifdefs

--- examples/StandardFirmata/StandardFirmata.ino
+++ examples/StandardFirmata/StandardFirmata.ino
@@ -92,11 +92,7 @@
   // do not always require the register read so upon interrupt you call Wire.requestFrom()
   if (theRegister != REGISTER_NOT_SPECIFIED) {
     Wire.beginTransmission(address);
-    #if ARDUINO >= 100
     Wire.write((byte)theRegister);
-    #else
-    Wire.send((byte)theRegister);
-    #endif
     Wire.endTransmission();
     // do not set a value of 0
     if (i2cReadDelayTime > 0) {
@@ -120,11 +116,7 @@
   i2cRxData[1] = theRegister;

   for (int i = 0; i < numBytes && Wire.available(); i++) {
-    #if ARDUINO >= 100
     i2cRxData[2 + i] = Wire.read();
-    #else
-    i2cRxData[2 + i] = Wire.receive();
-    #endif
   }

   // send slave address, register and received bytes
@@ -346,11 +338,7 @@
       Wire.beginTransmission(slaveAddress);
       for (byte i = 2; i < argc; i += 2) {
         data = argv[i] + (argv[i + 1] << 7);
-        #if ARDUINO >= 100
         Wire.write(data);
-        #else
-        Wire.send(data);
-        #endif
       }
       Wire.endTransmission();
       delayMicroseconds(70);


add protoypes

add protoypes

--- examples/StandardFirmata/StandardFirmata.ino
+++ examples/StandardFirmata/StandardFirmata.ino
@@ -31,6 +31,19 @@

 #include "application.h"
 #include <Firmata.h>
+
+void readAndReportData(byte address, int theRegister, byte numBytes);
+void outputPort(byte portNumber, byte portValue, byte forceSend);
+void checkDigitalInputs(void);
+void setPinModeCallback(byte pin, int mode);
+void analogWriteCallback(byte pin, int value);
+void digitalWriteCallback(byte port, int value);
+void reportAnalogCallback(byte analogPin, int value);
+void reportDigitalCallback(byte port, int value);
+void sysexCallback(byte command, byte argc, byte *argv);
+void enableI2CPins();
+void disableI2CPins();
+void systemResetCallback();

 // move the following defines to Firmata.h?
 #define I2C_WRITE 0x00


Simplify Blink

Simplify Blink

--- examples/Widgets/LED/LED_Blink/LED_Blink.ino
+++ examples/Widgets/LED/LED_Blink/LED_Blink.ino
@@ -17,8 +17,6 @@
  *
  * App project setup:
  *   LED widget on V1
- *   LED widget on V2
- *   LED widget on V3
  *
  * WARNING :
  * For this example you'll need SimpleTimer library:
@@ -38,12 +36,7 @@
 // Go to the Project Settings (nut icon).
 char auth[] = "YourAuthToken";

-// Select your pin with physical button
-const int btnPin = 7;
-
 WidgetLED led1(V1);
-WidgetLED led2(V2);
-WidgetLED led3(V3);

 SimpleTimer timer;

@@ -52,16 +45,11 @@
   Serial.begin(9600); // See the connection status in Serial Monitor
   Blynk.begin(auth);

-  // Setup physical button pin (active low)
-  pinMode(btnPin, INPUT_PULLUP);
-
   while (Blynk.connect() == false) {
     // Wait until connected
   }

   timer.setInterval(1000L, blinkLedWidget);
-  timer.setInterval(300L, fadeLedWidget);
-  timer.setInterval(500L, buttonLedWidget);
 }

 // V1 LED Widget is blinking
@@ -69,42 +57,10 @@
 {
   if (led1.getValue()) {
     led1.off();
-    BLYNK_LOG("LED1: off");
+    BLYNK_LOG("LED on V1: off");
   } else {
     led1.on();
-    BLYNK_LOG("LED1: on");
-  }
-}
-
-// V2 LED Widget is fading
-void fadeLedWidget()
-{
-  static int value = 0;
-  static int delta = 30;
-  value += delta;
-  if (value > 255 || value < 0) {
-    delta = -delta;
-  } else {
-    BLYNK_LOG("LED2: %d", value);
-    led2.setValue(value);
-  }
-}
-
-// V3 LED Widget represents the physical button state
-boolean btnState = false;
-void buttonLedWidget()
-{
-  // Read button
-  boolean isPressed = (digitalRead(btnPin) == LOW);
-
-  // If state has changed...
-  if (isPressed != btnState) {
-    if (isPressed) {
-      led3.on();
-    } else {
-      led3.off();
-    }
-    btnState = isPressed;
+    BLYNK_LOG("LED on V1: on");
   }
 }


Buttons Implemented

Buttons Implemented

--- zippy_the_fox.ino
+++ zippy_the_fox.ino
@@ -71,6 +71,7 @@

 // -- Robot Status --
 char robotState = IDLE;
+char restartExitMaze = 0;

 // -- Encoder --
 long entryTurnDistance[30], exitTurnDistance[30], nextTurnDistance = -999;
@@ -181,8 +182,10 @@
 	ENABLE_STANDBY;

 	initialiseBot();
+
+	DISABLE_STANDBY;

-	robotState = WORKING;
+	robotState = IDLE;
 }

 void leftButtonControl()
@@ -213,11 +216,16 @@
 	if (counter > 5)
 	{
 		DISABLE_STANDBY;
+		RED_LED_LEFT_OFF;
+		RED_LED_RIGHT_OFF;
+
 		delay(500);
+
 		ENABLE_STANDBY;
-
-		reducePath();
-		exitMaze();
+		RED_LED_RIGHT_ON;
+		RED_LED_LEFT_ON;
+
+		restartExitMaze = 1;
 	}
 }

@@ -280,6 +288,10 @@

 	while (true)
 	{
+		if (restartExitMaze)
+		{
+			exitMaze();
+		}
 		if (_adaptiveSpeed)
 		{
 			if (stringCounter == 0)
@@ -350,8 +362,9 @@

 void loop()
 {
+	ENABLE_STANDBY;
 	enterMaze();
-
+
 	RED_LED_LEFT_ON;
 	RED_LED_RIGHT_ON;

@@ -485,6 +498,12 @@
 {
 	while (true)
 	{
+		if (restartExitMaze)
+		{
+			stringCounter = 0;
+			restartExitMaze = 0;
+		}
+
 		foundLeft = 0, foundStraight = 0, foundRight = 0;

 		motorEncoder.write(0);
@@ -514,6 +533,13 @@

 				while (1)
 				{
+					if (restartExitMaze)
+					{
+						RED_LED_LEFT_ON;
+						RED_LED_RIGHT_ON;
+						exitMaze();
+					}
+
 					RED_LED_LEFT_OFF;
 					RED_LED_RIGHT_OFF;
 					GREEN_LED_LEFT_ON;


Add LPD8806 settings

Add LPD8806 settings

Swap the DATA_PIN, CLOCK_PIN order in the FastLED.addLeds<> call (WAT)
and it works!
Plus debug red-green-blue startup flash if needed.

--- blume.ino
+++ blume.ino
@@ -10,6 +10,11 @@
 #define CHIPSET     APA102
 #define APA_MHZ 4
 #define LED_SETTINGS CHIPSET, DATA_PIN, CLOCK_PIN, COLOR_ORDER, DATA_RATE_MHZ(APA_MHZ)
+/* For LPD8806:
+#define COLOR_ORDER BRG
+#define CHIPSET     LPD8806
+#define LED_SETTINGS CHIPSET, CLOCK_PIN, DATA_PIN, COLOR_ORDER
+ */

 #define EEPROM_SAVE_TIMEOUT_MS 5000
 #define EEPROM_START_POINTER_ADDR 0x0
@@ -81,6 +86,22 @@
   restoreFromSettings();
   // Make sure we won't save unless we get new settings
   saveTarget = 0;
+
+  /*
+  FastLED.setBrightness(255);
+  fill_solid(leds, NUM_LEDS, 0xFF0000);
+  FastLED.delay(1000);
+  Serial.println("did the thing");
+  fill_solid(leds, NUM_LEDS, 0x00FF00);
+  FastLED.delay(1000);
+  Serial.println("yep");
+  fill_solid(leds, NUM_LEDS, 0x0000FF);
+  FastLED.delay(1000);
+  Serial.println("done");
+  fill_solid(leds, NUM_LEDS, 0x000000);
+  FastLED.delay(1000);
+  Serial.println("clear");
+  */
 }


alarm screen asthetic updates

alarm screen asthetic updates

--- display/display.ino
+++ display/display.ino
@@ -39,8 +39,8 @@
 int i = 0;

 // Keep track of screen inversion and alarm state
-int inverted = 0;
-int activeAlarm = 0;
+volatile int inverted = 0;
+volatile int activeAlarm = 0;

 Adafruit_ILI9341 tft = Adafruit_ILI9341(CS_SCREEN, DC);
 Adafruit_STMPE610 ts = Adafruit_STMPE610(CS_TOUCH);
@@ -64,11 +64,11 @@
 // Create settings page buttons

 /*for ECGMin value*/
-Button ECGPlus = Button(100,70,18,18,ILI9341_BLACK,true,&tft);
-Button ECGMinus = Button(30,70,18,18,ILI9341_BLACK,true,&tft);
+Button ECGPlus = Button(100,67,18,25,ILI9341_RED,true,&tft);
+Button ECGMinus = Button(30,67,18,25,ILI9341_RED,true,&tft);
 /*for ECGMax value*/
-Button ECGPlus1 = Button(250,70,18,18,ILI9341_BLACK,true,&tft);
-Button ECGMinus1 = Button(180,70,18,18,ILI9341_BLACK,true,&tft);
+Button ECGPlus1 = Button(250,67,18,25,ILI9341_RED,true,&tft);
+Button ECGMinus1 = Button(180,67,18,25,ILI9341_RED,true,&tft);

 Button SP02Plus = Button(30,120,18,18,ILI9341_WHITE,true,&tft);
@@ -229,9 +229,10 @@

 void ECGSettings_setup(void){
   /* MINIMUM VALUE */
+  tft.fillRect(52, 67, 45, 25, ILI9341_LIGHTGREY);
   tft.setCursor(63, 72);
   tft.setTextSize(2);
-  tft.setTextColor(ILI9341_GREEN);
+  tft.setTextColor(ILI9341_BLACK);
   tft.printf("%d", DEFAULT_ECG_MIN);

   createVLabel(0, 55, ecgLabel, 2, ILI9341_GREEN);
@@ -241,9 +242,10 @@
   createHLabel(104, 72, "+", 2, ILI9341_WHITE);

   /* MAXIMUM VALUE */
+  tft.fillRect(202, 67, 45, 25, ILI9341_LIGHTGREY);
   tft.setCursor(213, 72);
   tft.setTextSize(2);
-  tft.setTextColor(ILI9341_GREEN);
+  tft.setTextColor(ILI9341_BLACK);
   tft.printf("%d", DEFAULT_ECG_MAX + biasECGMax);

   ECGPlus1.draw();
@@ -340,35 +342,40 @@
 }

 void toggleInvert(void) {
+    cli();
     if (inverted) {
-        tft.invertDisplay(0);
+        tft.invertDisplay(false);
         inverted = 0;
     } else {
-        tft.invertDisplay(1);
+        tft.invertDisplay(true);
         inverted = 1;
     }
+    sei();
     return;
 }

 // Interrupts for sampling and alarm system
 IntervalTimer sample_timer;
-//IntervalTimer alarm_timer;
+IntervalTimer alarm_timer;

 void throwAlarm(void) {
-    //alarm_timer.begin(alarm_isr, 10000);
-    //alarm_timer.priority(130);
+    cli();
+    alarm_timer.begin(alarm_isr, 1000000);
+    alarm_timer.priority(100);
     activeAlarm = 1;
+    sei();
 }

 void stopAlarm(void) {
-    //alarm_timer.end();
+    cli();
+    alarm_timer.end();
     activeAlarm = 0;
+    sei();
 }

 void setup(void){
-  tft.invertDisplay(0);
-  inverted = 0;
+  //tft.invertDisplay(true);
   gui_setup();
   product_title();
   ECG_setup();
@@ -386,7 +393,7 @@
 }

 void alarm_isr(void) {
-    //toggleInvert();
+    toggleInvert();
     return;
 }

@@ -396,6 +403,7 @@
   /*main screen*/
   if (currentMode == HOMESCREEN){
     MainScreenInit();
+    stopAlarm();
     while (currentMode == HOMESCREEN){
   		if (display_count >= 10) {
     		ecg.display_signal();
@@ -438,13 +446,14 @@
   /*alarm screen*/
   if (currentMode == ALARMSCREEN){
     SettingsScreenInit();
+    //throwAlarm();
     while(currentMode == ALARMSCREEN){
       TS_Point p = getFixedCoordinates();
       if(ECGPlus.isTapped(p.x,p.y)){
         biasECGMin += 1;
         /*for two digit numbers*/
         if (DEFAULT_ECG_MIN + biasECGMin < 100){
-          tft.fillRect(56, 72, 45, 20, ILI9341_BLACK);
+          tft.fillRect(52, 67, 45, 25, ILI9341_LIGHTGREY);
           tft.setCursor(63, 72);
           tft.setTextSize(2);
           tft.setTextColor(ILI9341_GREEN);
@@ -452,7 +461,7 @@
           }
         else if (DEFAULT_ECG_MIN + biasECGMin > 99){
           /*for three digit numbers*/
-          tft.fillRect(56, 72, 45, 20, ILI9341_BLACK);
+          tft.fillRect(52, 67, 45, 25, ILI9341_LIGHTGREY);
           tft.setCursor(56, 72);
           tft.setTextSize(2);
           tft.setTextColor(ILI9341_GREEN);
@@ -463,7 +472,7 @@
         biasECGMin -= 1;
         /*for two digit numbers*/
         if (DEFAULT_ECG_MIN + biasECGMin < 100){
-          tft.fillRect(56, 72, 45, 20, ILI9341_BLACK);
+          tft.fillRect(52, 67, 45, 25, ILI9341_LIGHTGREY);
           tft.setCursor(63, 72);
           tft.setTextSize(2);
           tft.setTextColor(ILI9341_GREEN);
@@ -471,7 +480,7 @@
           }
         else if (DEFAULT_ECG_MIN + biasECGMin > 99){
           /*for three digit numbers*/
-          tft.fillRect(56, 72, 45, 20, ILI9341_BLACK);
+          tft.fillRect(52, 67, 45, 25, ILI9341_LIGHTGREY);
           tft.setCursor(56, 72);
           tft.setTextSize(2);
           tft.setTextColor(ILI9341_GREEN);


Conditional on HOME_ASSISTANT_MQTT_DISCOVERY_CONFIG

--- Arilux_AL-LC0X.ino
+++ Arilux_AL-LC0X.ino
@@ -64,7 +64,9 @@

 char friendlyName[32];
 char configBuf[512];
-StaticJsonBuffer<512> HOME_ASSISTANT_MQTT_DISCOVERY_CONFIG;
+#ifdef HOME_ASSISTANT_MQTT_DISCOVERY
+  StaticJsonBuffer<512> HOME_ASSISTANT_MQTT_DISCOVERY_CONFIG;
+#endif

 volatile uint8_t cmd = ARILUX_CMD_NOT_DEFINED;


Added separate timeout constant for reconnection.

--- thermometer.ino
+++ thermometer.ino
@@ -82,12 +82,13 @@
 const byte PIN_LM35 = A0;                       // Ambient temperature sensor LM35DZ
 const unsigned int REF_VOLTAGE = 3300;          // Reference voltage for analog reading in millivolts
 const float COEF_LM35 = 0.0805861;              // Centigrades per bit - Resolution 12bit, reference 3.3V, 10mV/degC
+
+
+//-------------------------------------------------------------------------
+// System configuration
+//-------------------------------------------------------------------------
 const unsigned int TIMEOUT_WATCHDOG = 10000;    // Watchdog timeout in milliseconds
-
-
-//-------------------------------------------------------------------------
-// System configuration
-//-------------------------------------------------------------------------
+const unsigned int TIMEOUT_RECONNECT = 10000;   // Reconnection timeout in milliseconds
 unsigned int reconnects;

 //-------------------------------------------------------------------------
@@ -224,7 +225,7 @@
 void watchConnection()
 {
     static unsigned long tsMeasure;
-    if (millis() - tsMeasure >= TIMEOUT_WATCHDOG)
+    if (millis() - tsMeasure >= TIMEOUT_RECONNECT)
     {
         tsMeasure = millis();
         if (!Particle.connected())


report full resolution rssi when in hex mode ("1x")

--- examples/RF12/RF12demo/RF12demo.ino
+++ examples/RF12/RF12demo/RF12demo.ino
@@ -780,7 +780,10 @@
     }
 #if RF69_COMPAT
     Serial.print(" (");
-    Serial.print(-(RF69::rssi>>1));
+    if (useHex)
+        showByte(RF69::rssi);
+    else
+        Serial.print(-(RF69::rssi>>1));
     Serial.print(')');
 #endif
     Serial.println();


update to debounce - use constant already existing...

--- src/main.ino
+++ src/main.ino
@@ -43,7 +43,6 @@
   pinMode(POCKET_OPERATOR_SYNC_SIGNAL, OUTPUT);

   sei(); // turn on interupts...
-

   // setup OLED...
   delay(40);
@@ -105,7 +104,7 @@
     buttonDown++;
   }
   else {
-    if(buttonDown > 10) {
+    if(buttonDown > BUTTON_DEBOUNCE_TIME) {
       returnValue = 1; // set return value on release....
     }
     buttonDown = 0;


Delete FunkyFellow1_1.ino

Delete FunkyFellow1_1.ino

Dont need it anymore

--- FunkyFellow1_1.ino
+++ FunkyFellow1_1.ino
@@ -1,451 +0,0 @@
-/*
-FunkyFellow1_1.ino
-Filter effect using state variable filters.
-Thanks to Paul Stoffregen, www.PJRC.com, that made the great audio library fro Teensy! Plus all the other great stuff!
-This code can be loaded into a Teensy3.1/3.2 with a Audio sheild. Use a I2C 64x128 OLED screen to show the graphics.
-Hold the On/Off switch for 1 sek to edit the input gain with pot1.
-Activate sine modulation mode by holding Mode/tap button in 2 sek.
-All in all use the OpenEffectsBox from OnkartGromt.
- */
-#include <EEPROM.h>
-#include <Bounce.h>
-#include <Audio.h>
-#include <Wire.h>
-#include <SPI.h>
-#include <SD.h>
-#include <SerialFlash.h>
-#include <Adafruit_GFX.h>
-#include <Adafruit_SSD1306.h>
-
-#define OLED_RESET 4
-Adafruit_SSD1306 display(OLED_RESET);
-
-// GUItool: begin automatically generated code
-AudioSynthWaveform       waveform1;      //xy=106,573
-AudioSynthWaveformDc     dc1;            //xy=109,473
-AudioInputI2S            i2s1;           //xy=140,314
-AudioSynthWaveformDc     dc2;            //xy=140.88888549804688,358.8888854980469
-AudioEffectMultiply      multiply2;      //xy=248,532
-AudioAnalyzePeak         peak3;          //xy=254,573
-AudioEffectMultiply      multiply3;      //xy=298.8888854980469,313.8888854980469
-AudioMixer4              mixer3;         //xy=393,492
-AudioFilterStateVariable filter1;        //xy=456,147
-AudioEffectMultiply      multiply1;      //xy=495,420
-AudioAnalyzePeak         peak1;          //xy=673,420
-AudioFilterStateVariable filter2;        //xy=759,151
-AudioFilterStateVariable filter3;        //xy=759,204
-AudioFilterStateVariable filter4;        //xy=759,257
-AudioMixer4              mixer2;         //xy=911,78
-AudioMixer4              mixer1;         //xy=911,216
-AudioMixer4              mixer4;         //xy=1187,295
-AudioAnalyzeFFT1024      fft1024_1;      //xy=1385,389
-AudioAnalyzePeak         peak2;          //xy=1394,297
-AudioOutputI2S           i2s2;           //xy=1394,342
-AudioConnection          patchCord1(waveform1, 0, multiply2, 1);
-AudioConnection          patchCord2(waveform1, peak3);
-AudioConnection          patchCord3(dc1, 0, multiply2, 0);
-AudioConnection          patchCord4(dc1, 0, mixer3, 0);
-AudioConnection          patchCord5(i2s1, 0, multiply3, 0);
-AudioConnection          patchCord6(dc2, 0, multiply3, 1);
-AudioConnection          patchCord7(multiply2, 0, mixer3, 1);
-AudioConnection          patchCord8(multiply3, 0, multiply1, 0);
-AudioConnection          patchCord9(multiply3, 0, filter1, 0);
-AudioConnection          patchCord10(multiply3, fft1024_1);
-AudioConnection          patchCord11(multiply3, 0, mixer4, 3);
-AudioConnection          patchCord12(mixer3, 0, multiply1, 1);
-AudioConnection          patchCord13(filter1, 0, filter2, 0);
-AudioConnection          patchCord14(filter1, 0, mixer2, 0);
-AudioConnection          patchCord15(filter1, 1, filter3, 0);
-AudioConnection          patchCord16(filter1, 1, mixer2, 1);
-AudioConnection          patchCord17(filter1, 2, filter4, 0);
-AudioConnection          patchCord18(filter1, 2, mixer2, 2);
-AudioConnection          patchCord19(multiply1, peak1);
-AudioConnection          patchCord20(multiply1, 0, filter1, 1);
-AudioConnection          patchCord21(multiply1, 0, filter2, 1);
-AudioConnection          patchCord22(multiply1, 0, filter3, 1);
-AudioConnection          patchCord23(multiply1, 0, filter4, 1);
-AudioConnection          patchCord24(filter2, 0, mixer1, 0);
-AudioConnection          patchCord25(filter3, 1, mixer1, 1);
-AudioConnection          patchCord26(filter4, 2, mixer1, 2);
-AudioConnection          patchCord27(mixer2, 0, mixer4, 0);
-AudioConnection          patchCord28(mixer1, 0, mixer4, 1);
-AudioConnection          patchCord29(mixer4, peak2);
-AudioConnection          patchCord30(mixer4, 0, i2s2, 0);
-AudioConnection          patchCord31(mixer4, 0, i2s2, 1);
-AudioControlSGTL5000     sgtl5000_1;     //xy=662.0000305175781,536.0000305175781
-// GUItool: end automatically generated code
-
-//Pinout board rev1
-int Pot1 = A6;    // select the input pin for the potentiometer
-int Pot2 = A3;    // select the input pin for the potentiometer
-int Pot3 = A2;    // select the input pin for the potentiometer
-int Pot4 = A1;    // select the input pin for the potentiometer
-int CV1 = A10;
-int CV2 = A11;
-
-int Tap1 = 0;
-int Tap2 = 1;
-
-int SW1 = A12;
-int SW2 = A13;
-
-int ledPin1 = 3;      // select the pin for the LEDonoff
-int ledPin2 = 4;      // select the pin for the LEDyellow
-int ledPin3 = 5;      // select the pin for the LEDmode/tap
-
-//Variables for values
-boolean Tap1Value = 0;
-boolean Tap2Value = 0;
-float Pot1Value = 0;
-float Pot2Value = 0;
-float Pot3Value = 0;
-float Pot4Value = 0;
-int SW1Value = 0;
-int SW2Value = 0;
-float CV1Value = 0;
-float CV2Value = 0;
-float Pot1ValueOld = 0;  // variable to store the previous value
-float Pot2ValueOld = 0;
-float Pot3ValueOld = 0;
-float Pot4ValueOld = 0;
-int SW1ValueOld = 0;
-int SW2ValueOld = 0;
-int Tap1ValueOld = 1;
-int Tap2ValueOld = 1;
-int CV1ValueOld = 0;
-int Tap1Timer = 0;
-int Tap2Timer = 0;
-float margin  = 0.1;
-int modulationMode = 0;
-boolean Tap2Pressed = 0;
-int filterOrder = 24;
-int GraphFreq = 0;
-float ffund = 0;
-
-// Variables
-int ledStateONOFF = LOW;         // the current state of the output pin
-int buttonState0;             // the current reading from the input pin
-int lastButtonState0 = LOW;   // the previous reading from the input pin
-int ledStateBOOST = LOW;         // the current state of the output pin
-int buttonState1;             // the current reading from the input pin
-int lastButtonState1 = LOW;   // the previous reading from the input pin
-
-unsigned long lastDebounceTime0 = 0;  // the last time the output pin was toggled
-unsigned long lastDebounceTime1 = 0;  // the last time the output pin was toggled
-unsigned long debounceDelay = 50;    // the debounce time; increase if the output flickers
-
-float peak = 0.0;
-float peak_2 = 0.0;
-float peak_3 =0.0;
-int spanfreq = 500;
-int offsetfreq = 201;
-int movingfreq = 500;
-int octave = 7;
-float level = 0.85;
-float modFreq = 3;
-float modFreqOld = 3;
-float InLevel = 0;
-
-const int myInput = AUDIO_INPUT_LINEIN;
-
-float mapfloat(float x, float in_min, float in_max, float out_min, float out_max)
-{
-  return (x - in_min) * (out_max - out_min) / (in_max - in_min) + out_min;
-}
-Bounce OnOff = Bounce(Tap1, 30 );
-Bounce BoostOnOff = Bounce(Tap2, 30);
-
-void setup() {
-  AudioMemory(100);
-  InLevel = float(EEPROM.read(0)/255.0);
-  dc2.amplitude(1, 20);
-  sgtl5000_1.enable();  // Enable the audio shield
-  sgtl5000_1.inputSelect(myInput);
-  sgtl5000_1.volume(0.8);
-  sgtl5000_1.lineInLevel(5);   // 1,33Vp-p
-  sgtl5000_1.lineOutLevel(13); // 3.16Vp-p
-  fft1024_1.windowFunction(AudioWindowHanning1024);
-
-  pinMode(ledPin1, OUTPUT);
-  pinMode(ledPin2, OUTPUT);
-  pinMode(ledPin3, OUTPUT);
-  pinMode(Tap1, INPUT);
-  pinMode(Tap2, INPUT);
-  mixer3.gain(0, 1);
-  mixer3.gain(1, 0);
-  mixer4.gain(0, 0);
-  mixer4.gain(1, 0);
-  mixer4.gain(3, 1.65);
-  mixer1.gain(0, 1);    //24order filter
-  mixer1.gain(1, 1);
-  mixer1.gain(2, 1);
-  mixer1.gain(3, 0);
-  mixer2.gain(0, 1);    //12 order filter
-  mixer2.gain(1, 1);
-  mixer2.gain(2, 1);
-  mixer2.gain(3, 0);
-  sgtl5000_1.dacVolume (level);
-  sgtl5000_1.autoVolumeControl(2,0,0,0.7,50,100);  //maxGain,response,hard limit,threshold,attack, decay
-  sgtl5000_1.autoVolumeEnable();
-  Serial.begin(115200);
-  display.begin(SSD1306_SWITCHCAPVCC, 0x3C);  // initialize with the I2C addr 0x3C (for the 128x64)
-  display.clearDisplay();
-  delay(100);
-}
-
-//Main loop
-void loop() {
-  OnOff.update();      //update the bounce
-  BoostOnOff.update();
-
-  // read the value from the sensor:
-  Pot1Value = analogRead(Pot1);    //Sense
-  Pot2Value = analogRead(Pot2);    //Resonance
-  Pot3Value = analogRead(Pot3);    //Freq
-  Pot4Value = analogRead(Pot4);    //Mode
-  Tap1Value = digitalRead(Tap1);   //On off
-  Tap2Value = digitalRead(Tap2);   //Mode/Tap
-  SW1Value = analogRead(SW1);      //Filter char
-  SW2Value = analogRead(SW2);      //Direction
-  CV1Value = analogRead(CV1);      //CV input
-  CV2Value = analogRead(CV2);      //EXP input
-
-  Pot1Value = mapfloat(Pot1Value, 0, 1023, 1, 0);        //Sense
-  Pot2Value = mapfloat(Pot2Value, 0, 1023, 2, 0.7);      //Resonance
-  GraphFreq = map(Pot3Value, 0, 1023, 90, 30);           //Moving point of Graph
-  Pot3Value = map(Pot3Value, 0, 1023, 1500, 150);        //Freq
-  Pot4Value = mapfloat(Pot4Value, 0, 1023, 10.0, 0.1);   //ModFreq
-  SW1Value = map(SW1Value, 0, 1023, 5, 0);               //Filter char
-  SW1Value = constrain(SW1Value, 1, 5);
-  SW2Value = map(SW2Value, 0, 1023, 5, 0);               //Direction
-  SW2Value = constrain(SW2Value, 1, 5);
-  CV1Value = map(CV1Value, 0, 1023, 10, 1);              //Octave CVinput
-  CV2Value = map(CV2Value, 0, 1023, 1500, 150);          //Freq expression pedal
-
-  buttonState0 = OnOff.read();
-  if (lastButtonState0 != buttonState0){
-      // only toggle the state if the new button state is HIGH
-      if (buttonState0 == LOW) {
-        ledStateONOFF = !ledStateONOFF;
-      }
-  }
-  buttonState1 = BoostOnOff.read();
-  if (lastButtonState1 != buttonState1){
-      // only toggle the state if the new button state is HIGH
-      if (buttonState1 == LOW) {
-        ledStateBOOST = !ledStateBOOST;
-      }
-  }
-
-    // set the outputs:
-  digitalWrite(ledPin1, ledStateONOFF);
-  lastButtonState0 = buttonState0;  //save readings to next round
-  lastButtonState1 = buttonState1;
-
-  //Sets the sense multiplication factor
-  if (SW2Value == 3)dc1.amplitude(Pot1Value);
-  else if (SW2Value == 5)dc1.amplitude(-Pot1Value);
-
-  //read the signal input peak
-  if (peak1.available())  peak = peak1.read();
-  if (peak2.available())  peak_2 = peak2.read();    //Output peak
-  if (peak3.available())  peak_3 = peak3.read();
-
-  if (modulationMode == 0){
-    analogWrite(ledPin2, peak_2*400);    //yellow LED
-    if (Pot4Value <= 5)filterOrder = 12;
-    else filterOrder = 24;
-    }
-  else analogWrite(ledPin2, (peak_3)*100);  //modulation active
-
-  if (CV1Value <1) octave = 6;  //Check if CVinput is active
-  else octave = CV1Value;
-
-  if (CV2Value <100) spanfreq = Pot3Value;  //Check if exp pedal is active
-  else spanfreq = CV2Value;
-
-  if (SW2Value == 3) movingfreq = peak*2 * spanfreq + spanfreq ;
-  if (SW2Value == 5) movingfreq = -peak *2* spanfreq + spanfreq ;
-  if (SW2Value == 1) movingfreq = spanfreq;    //not moving filter
-
-  filter1.frequency(movingfreq);
-  filter1.resonance(Pot2Value);
-  filter1.octaveControl(octave);
-  filter2.frequency(movingfreq);
-  filter2.resonance(Pot2Value);
-  filter2.octaveControl(octave);
-  filter3.frequency(movingfreq);
-  filter3.resonance(Pot2Value);
-  filter3.octaveControl(octave);
-  filter4.frequency(movingfreq);
-  filter4.resonance(Pot2Value);
-  filter4.octaveControl(octave);
-
-  waveform1.frequency(Pot4Value);
-
-if (!Tap2Value && (Tap2Value == Tap2ValueOld) && modulationMode == 0 && Tap2Pressed == 0){ //turn on modulation
-  Serial.print("TIME0\n");
-  Tap2Timer++;
-  if (Tap2Timer > 15){
-    mixer3.gain(0,0);
-    mixer3.gain(1,1);
-    modulationMode = 1;
-    analogWrite(ledPin2,255);
-    digitalWrite(ledPin3,HIGH);
-    Tap2Pressed = 1;
-  }
-}
-else if (!Tap2Value && (Tap2Value == Tap2ValueOld) && modulationMode == 1 && Tap2Pressed == 0){ //turn off modulation
-  Serial.print("TIME1\n");
-  Tap2Timer++;
-  if (Tap2Timer > 15){
-    mixer3.gain(0,1);
-    mixer3.gain(1,0);
-    modulationMode = 0;
-    analogWrite(ledPin2,255);
-    digitalWrite(ledPin3,LOW);
-    Tap2Pressed = 1;
-  }
-}
-else if (Tap2Value){
-  Tap2Timer = 0;
-  Tap2Pressed = 0;
-  }
-
-//BYPASS MODE
-  if (ledStateONOFF == 0){
-      mixer4.gain(0, 0);
-      mixer4.gain(1, 0);
-      mixer4.gain(2, 0);
-      mixer4.gain(3, 1.65);
-  }
-  else {
-      mixer4.gain(3, 0);  //Always turn off bypass signal
-    if (SW1Value == 3) {  //HP
-      if (filterOrder == 12) { //   12db/dec
-        mixer4.gain(0, 1.3);
-        mixer4.gain(1, 0);
-        mixer2.gain(0, 0);
-        mixer2.gain(1, 0);
-        mixer2.gain(2, 1);
-        }
-      else if (filterOrder == 24) {    //24db/dec
-        mixer4.gain(0, 0);
-        mixer4.gain(1, 1.3);
-        mixer1.gain(0, 0);
-        mixer1.gain(1, 0);
-        mixer1.gain(2, 1);
-      }
-    }
-    else if (SW1Value == 1) {  //BP
-       if (filterOrder == 12) { //   12db/dec
-        mixer4.gain(0, 1.3);
-        mixer4.gain(1, 0);
-        mixer2.gain(0, 0);
-        mixer2.gain(1, 1);
-        mixer2.gain(2, 0);
-        }
-      else if (filterOrder == 24) {    //24db/dec
-        mixer4.gain(0, 0);
-        mixer4.gain(1, 1.3);
-        mixer1.gain(0, 0);
-        mixer1.gain(1, 1);
-        mixer1.gain(2, 0);
-      }
-    }
-    else if (SW1Value == 5) { //LowPass
-       if (filterOrder == 12) { //   12db/dec
-        mixer4.gain(0, 1.3);
-        mixer4.gain(1, 0);
-        mixer2.gain(0, 1);
-        mixer2.gain(1, 0);
-        mixer2.gain(2, 0);
-        }
-      else if (filterOrder == 24) {    //24db/dec
-        mixer4.gain(0, 0);
-        mixer4.gain(1, 1.3);
-        mixer1.gain(0, 1);
-        mixer1.gain(1, 0);
-        mixer1.gain(2, 0);
-      }
-    }
-  }
-display.clearDisplay();
-if (!Tap1Value && (Tap1Value == Tap1ValueOld)){    //When Mode/tap is held down you can adjust the input gain of the input
-  Serial.print("TIME");
-  Tap1Timer++;
-  if (Tap1Timer > 15){
-    InLevel = analogRead(Pot1);
-    InLevel = mapfloat(InLevel,0,1023,1,0.2);
-    dc2.amplitude(InLevel,10);
-    delay(50);
-    EEPROM.write(0, InLevel*255);
-    analogWrite(ledPin2, 255);
-    //display.clearDisplay();
-    display.setTextSize(1);
-    display.setTextColor(WHITE);
-    display.setCursor(5, 10);
-    display.print("Input:");
-    display.print(InLevel);
-    display.display();
-  }
-}
-else if (Tap1Value){
-  Tap1Timer = 0;
-//  peak = peak1.read();   //read the signal output peak
-  if (peak == -1)(peak = 0);
-  analogWrite(ledPin2, peak*100);
-}
-if(fft1024_1.available()){        //Display FFT on screen
- // display.clearDisplay();
-  for (int i=0; i<42; i++) {
-    float fft = fft1024_1.read(i)*512;
-    //Serial.print(fft);
-    //Serial.print(",");
-    display.drawLine(i*3, 64, i*3, 64-fft, WHITE);
-    display.drawLine(i*3+1, 64, i*3+1, 64-fft, WHITE);
-    display.drawLine(i*3+2, 64, i*3+2, 64-fft, WHITE);
-  }
-}
-//  display.clearDisplay();
-  GraphFreq = movingfreq/15;
- if(SW1Value ==5){    //LP
-    display.drawLine(0, 32, GraphFreq-5, 32, WHITE);
-    display.drawLine(GraphFreq-5, 32, GraphFreq, 35-Pot2Value*4, WHITE);
-    display.drawLine(GraphFreq, 35-Pot2Value*4, GraphFreq+5, 32, WHITE);
-    display.drawLine(GraphFreq+5, 32, GraphFreq+(48-filterOrder), 64, WHITE);
- }
- else if(SW1Value == 3){    //HP
-    display.drawLine(128, 32, GraphFreq+5, 32, WHITE);
-    display.drawLine(GraphFreq+5, 32, GraphFreq, 35-Pot2Value*4, WHITE);
-    display.drawLine(GraphFreq, 35-Pot2Value*4, GraphFreq-5, 32, WHITE);
-    display.drawLine(GraphFreq-5, 32, GraphFreq-(48-filterOrder), 64, WHITE);
- }
-  else {    //BP
-    display.drawLine(GraphFreq-(48-filterOrder), 64, GraphFreq-5, 32, WHITE);
-    display.drawLine(GraphFreq+5, 32, GraphFreq, 35-Pot2Value*4, WHITE);
-    display.drawLine(GraphFreq, 35-Pot2Value*4, GraphFreq-5, 32, WHITE);
-    display.drawLine(GraphFreq+5, 32, GraphFreq+(48-filterOrder), 64, WHITE);
- }
-  display.setTextSize(1);
-  display.setTextColor(WHITE);
-  display.setCursor(80, 10);
-  display.print("fc:");
-  display.print(movingfreq);
-  display.display();
-
-   Serial.print(" InLevel: ");
-   Serial.print(InLevel);
-   Serial.print(" Filterorder: ");
-   Serial.println(filterOrder);
-
-   Pot1ValueOld = Pot1Value;
-   Pot2ValueOld = Pot2Value;
-   Pot3ValueOld = Pot3Value;
-   Pot4ValueOld = Pot4Value;
-   SW1ValueOld = SW1Value;
-   SW2ValueOld = SW2Value;
-   Tap1ValueOld = Tap1Value;
-   Tap2ValueOld = Tap2Value;
-   CV1ValueOld = CV1Value;
-}


Update ClockJitterMeas.ino

Update ClockJitterMeas.ino

--- src/ClockJitterMeas.ino
+++ src/ClockJitterMeas.ino
@@ -1,40 +1,42 @@
-//
-// ClockJitterMeas.ino : measurement of the jitter on a clock.
-// Negative pulses are applied to the digital input #2.
-// On each falling edge, the arduino 1MHz timer is read and its content is sent over the COM interface
-//
-
-//#define selfTest
-
-const byte pulseInput = 2; // the input on which the pulse is applied
-const byte pulseOutput = 13; // the output that generates a pulse (for autotest, connect D13 to D2)
-
-volatile unsigned long int prevTime;
-
-// interrupt service routine
-void isr() { Serial.println((unsigned long int)micros(),HEX); }
-
-void setup() {
-  // init serial port
-  Serial.begin(230400);
-
-  // configures pulse input
-  pinMode(pulseInput, INPUT);
-  attachInterrupt(digitalPinToInterrupt(pulseInput), isr, RISING);
-
-  // configures pulse output (selftest)
-  pinMode(pulseOutput, OUTPUT);
-  digitalWrite(pulseOutput, LOW); // default state
-
-  prevTime = micros();
-}
-
-void loop() {
-# ifdef selfTest
-  digitalWrite(pulseOutput, HIGH);
-  while ((signed long int)(micros()-prevTime)<937); // 9/9600 * 1e6 = 937.5µs
-  digitalWrite(pulseOutput, LOW);
-  while ((signed long int)(micros()-prevTime)<10000);
-  prevTime+=10000;
-# endif
+//
+// ClockJitterMeas.ino : measurement of the jitter on a clock.
+// Pulses are applied to the digital input #2.
+// On each rising edge, the arduino 1MHz timer content is sent over the COM interface.
+// The format on the COM interface is HEX ascii terminated by an EOL (end of line).
+// Selftest feature: uncomment "#define selfTest" to get pulses on output #13
+//
+
+//#define selfTest
+
+const byte pulseInput = 2; // the input on which the pulse is applied
+const byte pulseOutput = 13; // the output that generates a pulse (for selftest: connect D13 to D2)
+
+volatile unsigned long int prevTime;
+
+// interrupt service routine
+void isr() { Serial.println((unsigned long int)micros(),HEX); }
+
+void setup() {
+  // init serial port
+  Serial.begin(230400);
+
+  // configures pulse input
+  pinMode(pulseInput, INPUT);
+  attachInterrupt(digitalPinToInterrupt(pulseInput), isr, RISING);
+
+  // configures pulse output (selftest)
+  pinMode(pulseOutput, OUTPUT);
+  digitalWrite(pulseOutput, LOW); // default state
+
+  prevTime = micros();
 }
+
+void loop() {
+# ifdef selfTest
+  digitalWrite(pulseOutput, HIGH);
+  while ((signed long int)(micros()-prevTime)<937); // 9/9600 * 1e6 = 937.5µs
+  digitalWrite(pulseOutput, LOW);
+  while ((signed long int)(micros()-prevTime)<10000);
+  prevTime+=10000;
+# endif
+}


Update Button_alt.ino

Update Button_alt.ino

--- Arduino/Basics/Digital/Button_alt.ino
+++ Arduino/Basics/Digital/Button_alt.ino
@@ -2,9 +2,9 @@
 Button
 Carlos Castellanos | 2014 | ccastellanos.com

-Press and relasese to turn an LED on, then press and relasese again to turn off
+Press and relase to turn an LED on, then press and relase again to turn off

-Note: this example works best witha momentary pushbutton or similary biased switch
+Note: this example works best witha momentary pushbutton or similarly biased switch

 Schematic, see:


ESP8266 has no serialEvent.

ESP8266 has no serialEvent.

--- water_heater_monitor/water_heater_monitor.ino
+++ water_heater_monitor/water_heater_monitor.ino
@@ -42,9 +42,7 @@
   // defined outside of the sketch. These tasks include
   // setting up, and maintaining, a WiFi connection.
   delay(100);
-}

-void serialEvent() {
   while (Serial.available()) {
     char c = Serial.read();


required change for compatibility with Leonardo and probably other boards

--- examples/receive_interrupt/receive_interrupt.ino
+++ examples/receive_interrupt/receive_interrupt.ino
@@ -15,6 +15,7 @@
 // the cs pin of the version after v1.1 is default to D9
 // v0.9b and v1.0 is default D10
 const int SPI_CS_PIN = 9;
+const int CAN_INT_PIN = 2;

 MCP_CAN CAN(SPI_CS_PIN);                                    // Set CS pin

@@ -36,7 +37,7 @@
     }
     SERIAL.println("CAN BUS Shield init ok!");

-    attachInterrupt(0, MCP2515_ISR, FALLING); // start interrupt
+    attachInterrupt(digitalPinToInterrupt(CAN_INT_PIN), MCP2515_ISR, FALLING); // start interrupt
 }

 void MCP2515_ISR()


Update sh1106_128x64_spi.ino

Update sh1106_128x64_spi.ino

--- examples/sh1106_128x64_spi/sh1106_128x64_spi.ino
+++ examples/sh1106_128x64_spi/sh1106_128x64_spi.ino
@@ -1,5 +1,5 @@
 /*********************************************************************
-This is an example for our Monochrome OLEDs based on SSD1306 drivers
+This is an example for our Monochrome OLEDs based on SH1106 drivers

   Pick one up today in the adafruit shop!
   ------> http://www.adafruit.com/category/63_98
@@ -27,13 +27,13 @@
 #define OLED_DC    11
 #define OLED_CS    12
 #define OLED_RESET 13
-Adafruit_SSD1306 display(OLED_MOSI, OLED_CLK, OLED_DC, OLED_RESET, OLED_CS);
+Adafruit_SH1106 display(OLED_MOSI, OLED_CLK, OLED_DC, OLED_RESET, OLED_CS);

 /* Uncomment this block to use hardware SPI
 #define OLED_DC     6
 #define OLED_CS     7
 #define OLED_RESET  8
-Adafruit_SSD1306 display(OLED_DC, OLED_RESET, OLED_CS);
+Adafruit_SH1106 display(OLED_DC, OLED_RESET, OLED_CS);
 */

 #define NUMFLAKES 10
@@ -61,7 +61,7 @@
   B01110000, B01110000,
   B00000000, B00110000 };

-#if (SSD1306_LCDHEIGHT != 64)
+#if (SH1106_LCDHEIGHT != 64)
 #error("Height incorrect, please fix Adafruit_SH1106.h!");
 #endif

@@ -69,7 +69,7 @@
   Serial.begin(9600);

   // by default, we'll generate the high voltage from the 3.3v line internally! (neat!)
-  display.begin(SSD1306_SWITCHCAPVCC);
+  display.begin(SH1106_SWITCHCAPVCC);
   // init done

   // Show image buffer on the display hardware.


Faster ripple

Faster ripple

--- examples/sorenson-curtains/sorenson-curtains.ino
+++ examples/sorenson-curtains/sorenson-curtains.ino
@@ -67,7 +67,7 @@

   input = new AudioShieldInput(&peak, &note);

-  viz = new RippleVisualization(input, 75, 1, true);
+  viz = new RippleVisualization(input, 50, 1, true);

   anim1 = new CurtainAnimation(viz, leds1);
   anim2 = new CurtainAnimation(viz, leds2);


RFID scanning works!

RFID scanning works!

--- firmware/sentry.ino
+++ firmware/sentry.ino
@@ -17,9 +17,12 @@
 #define LED_PIN D7
 #define MAX_CARDS 1000

+// Dont demand wifi before our code starts running.
+SYSTEM_MODE(MANUAL);
+
 // Represents a card, including how to identify it and what to do when it's scanned.
 typedef struct {
-  char* rfid; // the code from the reader
+  int rfid; // the code from the reader
   bool allow; // true if allowed in, false if not
   char* greeting; // Text that will be shown the card owner when scanned
 } Card;
@@ -33,14 +36,96 @@
 // Number of cards in memory right now.
 uint numCards = 0;

+// Are we connected to the Particle cloud.
+bool connected = false;
+bool connecting = false;
+
 void setup() {
+  Serial.begin(9600);
+  Serial1.begin(9600);
+
   pinMode(LED_PIN, OUTPUT);
+
   Particle.subscribe("sentry/update-members", updateMembers);
+
   lcd.begin(16, 2);
-  resetLCD();
+  lcd.print("Connecting...");
+
+  // resetLCD();
 }

 void loop() {
+  checkCardReader();
+  manageParticleConnection();
+}
+
+void checkCardReader() {
+  uint8_t i = 0;
+  char hexcode[9];
+  int result;
+
+  if (Serial1.available() > 0) {
+    delay(20); // Let the buffer fil up for a jif
+
+    while (Serial1.available() > 0) {
+      // First three bytes are the header, last 3 bytes are the footer.
+      if (i < 3 || i >= 11) {
+        Serial1.read();
+
+      // 8 bytes of meat.
+      } else {
+        hexcode[i-3] = Serial1.read();
+      }
+
+      // Next byte.
+      i++;
+    }
+
+    // Convert hex string to an integer.
+    result = (int)strtol(hexcode, NULL, 16);
+
+    // Take actions based on the card scanned.
+    checkCode(result);
+  }
+}
+
+void manageParticleConnection() {
+  // Connected, last we knew.
+  if (connected) {
+
+    // Process particle events.
+    Particle.process();
+
+    // If we were connecting, we are aren't anymore.
+    if (connecting) {
+      connecting = false;
+    }
+
+    // If we are no longer connected, record that state.
+    if (!Particle.connected()) {
+      connected = false;
+      connecting = false;
+      lcd.clear();
+      lcd.print("Connecting...");
+    }
+
+  // Not connected, last we knew.
+  } else {
+
+    // Does Partcile say we're connected? record that state.
+    if (Particle.connected()) {
+      connected = true;
+      connecting = false;
+      resetLCD();
+
+    // Not connected, and not connecting, so lets try to connect.
+    } else if (!connecting) {
+      Particle.connect();
+      connecting = true;
+      lcd.clear();
+      lcd.print("Connecting...");
+    }
+  }
 }

 void resetLCD() {
@@ -78,7 +163,7 @@

   // Loop until we are out of tokens.
   while (token != NULL) {
-    if      (fieldIdx == 0) cards[numCards].rfid = token;
+    if      (fieldIdx == 0) cards[numCards].rfid = atoi(token);
     else if (fieldIdx == 1) cards[numCards].allow = (strcmp(token, "1") == 0);
     else if (fieldIdx == 2) cards[numCards].greeting = token;

@@ -95,29 +180,44 @@
     }
   }

-  flashDebugLEDs();
-  // showUpdatedMembersOnLCD();
+  // flashDebugLEDs();
+  showUpdatedMembersOnLCD();
+}
+
+void checkCode(int code) {
+  Card card;
+
+  lcd.clear();
+
+  for (int i = 0; i < numCards; i++) {
+    card = cards[i];
+    if (card.rfid == code) {
+      lcd.print(card.greeting);
+      delay(3000);
+      resetLCD();
+      return;
+    }
+  }
+
+  lcd.print(" ACCESS  DENIED ");
+  delay(3000);
+  resetLCD();
 }

 // TEMP
 //
 void showUpdatedMembersOnLCD() {
   lcd.clear();
-  lcd.print("UPDATE!");
+  lcd.print("     UPDATE!    ");
   lcd.setCursor(0, 1);
   lcd.print("  Got ");
   lcd.print(numCards);
   lcd.print(" cards.");
-  delay(3000);
-
-  for (int i = 0; i < numCards; i++) {
-    lcd.clear();
-    lcd.print(cards[i].greeting);
-    delay(3000);
-  }
+  delay(2000);

   resetLCD();
 }
+
 void flashDebugLEDs() {
   for (int i = 0; i < numCards; i++) {
     digitalWrite(LED_PIN, HIGH);


Lexical fix

Lexical fix

--- examples/testShell/testShell.ino
+++ examples/testShell/testShell.ino
@@ -84,12 +84,12 @@
                 break;
             case SE_CC_ledOn:
                 if( ledControl) {
-                    //digitalWrite(LED_BUILTIN, HIGH);
+                    digitalWrite(LED_BUILTIN, HIGH);
                 }
                 break;
             case SE_CC_ledOff:
                 if( ledControl) {
-                    //digitalWrite(LED_BUILTIN, LOW);
+                    digitalWrite(LED_BUILTIN, LOW);
                 }
                 break;
             default:


Improve roundtrip measurement; info print was included.

--- examples/Ethernet/CosaICMPping/CosaICMPping.ino
+++ examples/Ethernet/CosaICMPping/CosaICMPping.ino
@@ -54,11 +54,12 @@
 #define IP 192,168,1,150
 #define SUBNET 255,255,255,0
 static const uint8_t mac[6] __PROGMEM = { MAC };
-static const char hostname[] __PROGMEM = "CosaICMPping";

 // W5100 Ethernet Controller
 W5100 ethernet(mac);

+// ICMP header (section from /usr/include/netinet/ip_icmp.h)
+// All message type and codes included (not really needed)
 struct icmphdr
 {
   uint8_t type;			/* message type */
@@ -125,8 +126,8 @@
 #define ICMP_EXC_TTL		0	/* TTL count exceeded		*/
 #define ICMP_EXC_FRAGTIME	1	/* Fragment Reass time exceeded	*/

-// This is missing in the W5100 device driver to make the IPRAW mode
-// receive frame more explicit
+// This is missing in the W5100 device driver to make the IPRAW socket
+// receive frame more explicit (available reports full frame)
 struct IPRAW_HEADER {
   uint8_t src[4];
   uint16_t port;
@@ -151,7 +152,7 @@
   Socket* sock = ethernet.socket(Socket::IPRAW, IPPROTO_ICMP);
   ASSERT(sock != NULL);

-  INFO("Build ICMP echo request block", 0);
+  INFO("Build ICMP echo request block", 0); trace.flush();
   icmphdr req;
   static uint16_t seq = 0;
   req.type = ICMP_ECHO;
@@ -168,18 +169,22 @@
   int res = sock->send(&req, sizeof(req), dest, 0);
   if (res < 0) goto error;

-  INFO("Receive the reply", 0);
-  uint32_t roundtrip;
+  // Wait for the reply
+  const static uint8_t RETRY_MAX = 16;
+  uint32_t stop;
   icmphdr reply;
   uint8_t src[4];
   uint16_t port;
-  for (uint8_t retry = 0; retry < 10; retry++) {
+  for (uint8_t retry = 0; retry < RETRY_MAX; retry++) {
     if ((res = sock->available()) > 0) break;
     delay(1);
   }
+
+  // Check size of reply before actually recieving
   if (res != sizeof(reply) + sizeof(IPRAW_HEADER)) goto error;
   res = sock->recv(&reply, sizeof(reply), src, port);
-  roundtrip = RTC::micros();
+  stop = RTC::micros();
+  INFO("Receive the reply", 0);

   // Sanity check the reply; right size, type, id, seq nr, and checksum
   if (res != sizeof(reply)) goto error;
@@ -189,8 +194,7 @@
   if (INET::checksum(&reply, sizeof(reply)) != 0) goto error;

   // Calculate the time for the ping roundtrip
-  roundtrip -= reply.timestamp;
-  INFO("Roundtrip: %ul us", roundtrip);
+  INFO("Roundtrip: %ul us", stop - reply.timestamp);

  error:
   sock->close();


Rework Board/CPU detection to try and better compile for attiny

--- CoreIR.ino
+++ CoreIR.ino
@@ -32,15 +32,17 @@
 #endif

 //check which arduino board we are using and build accordingly
-#if defined(__AVR_ATtiny84__) || defined(__AVR_ATtiny167__) || defined(__AVR_ATtiny85)
+#if defined(__AVR_ATtiny84__) || defined(__AVR_ATtiny167__) || defined(__AVR_ATtiny85__)
   //if using an attiny build with all defaults, don't define anything
 #elif defined(__AVR_ATmega32U4__)
   //if using an arduino micro build with eeprom enabled and different LED pin
   #define atmega
   #define micro
-#else
+#elif defined(__AVR_ATmega328p__) || defined(__AVR_ATmega64__) || defined(__AVR_ATmega128__) || defined(__AVR_ATmega328__) || defined(__AVR_ATmega168__)
   //if using an atmega328p or similar build with eeprom enabled
   #define atmega
+#else
+  //define nothing
 #endif

 #if defined(softout)
@@ -102,11 +104,13 @@
   digitalWrite(bridgePinIn, HIGH);
   pinMode(bridgePinOut, OUTPUT);
   digitalWrite(bridgePinOut, LOW);
-
+
+  #ifdef atmega
     Serial.begin(9600);
     #if defined(micro) & defined(debug)
       while (!Serial)
     #endif
+  #endif

   #if defined(softout)
@@ -173,6 +177,7 @@
 }

 void loop() {
+  #ifdef atmega
   //serial data stuff for coreir-uplink support
   // send data only when you receive data:
   if (easylap_on == 1) {
@@ -217,6 +222,7 @@
         }
       }
     }
+    #endif

   #if defined(softout)
     mySerial.write(bit1); // transmit one byte at a time.


v6.2 Bug fix and clean up

v6.2 Bug fix and clean up

--- GPSLCD.ino
+++ GPSLCD.ino
@@ -11,25 +11,25 @@
   decode the GPS NMEA messages. The parameters are then displayed on a
   20x4 LCD using the LiquidCrystal_I2C library.

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

 #include "GPSLCD.h"
@@ -77,9 +77,6 @@
   static bool leftInitialization = false;
   static bool creditToggle = true;
   static bool invalidSatellitesToggle = true;
-  bool dataValid; // Data valid from the GPS module
-  GPSStruct GPSData; // Holds the GPS data coming from the GPS module
-  unsigned long now = millis(); // The time "now"
   static unsigned long prevDateTime = TOGGLETIME_INTERVAL;
   static unsigned long prevHeadingTime = TOGGLETIME_INTERVAL;
   static unsigned long prevHdopTime = TOGGLETIME_INTERVAL;
@@ -91,6 +88,9 @@
   bool displayHdop = !digitalRead(DISPLAY_HDOP_SW);
   bool cardinal8_16 = !digitalRead(CARDINAL_SW);
   bool lowSpeedOverride = !digitalRead(LOW_SPEED_OVERRIDE);
+  bool dataValid; // Data valid from the GPS module
+  GPSStruct GPSData; // Holds the GPS data coming from the GPS module
+  unsigned long now = millis(); // The time "now"

 #ifdef DATA_VALID_OVERRIDE
   const bool dataValidOverride = true; // Set true to override data valid for debugging
@@ -161,7 +161,7 @@
       leftInitialization = true;
       lcd.clear(); // Clear the LCD
     }
-
+
     // Display the latest info from the gps object
     // which it derived from the data sent by the GPS unit
     // Send data to the LCD
@@ -188,11 +188,8 @@
       } // if (GPSData.satellites == 0)
       else if (GPSData.satellites <= 9) {
         lcd.print(" "); // Blank leading char
-        lcd.print(GPSData.satellites);
       }
-      else {
-        lcd.print(GPSData.satellites);
-      }
+      lcd.print(GPSData.satellites);
     } // if ((pastSatellites != GPSData.satellites) ||(GPSData.satellites == 0))
     lcd.setCursor(0, 1); // Go to 2nd line
     lcd.print("Lon: ");
@@ -212,13 +209,13 @@
       else { // if (!localUTCTimeDate)
         // Display Hdop
         displayHdopOnLCD(GPSData.hdop, displayHdop, now,
-                          &prevHdopTime, &hdopToggle);
+                         &prevHdopTime, &hdopToggle);
       } // if (!localUTCTimeDate)
     } // if ((digitalRead(ALTITUDE_DATE_TIME_SW)))
     else {
       // Display Hdop
       displayHdopOnLCD(GPSData.hdop, displayHdop, now,
-                        &prevHdopTime, &hdopToggle);
+                       &prevHdopTime, &hdopToggle);
     } // if ((digitalRead(ALTITUDE_DATE_TIME_SW)))
     lcd.setCursor(0, 2); // Go to 3rd line
     lcd.print("Spd: ");
@@ -283,7 +280,7 @@
           if (localUTCTimeDate) {
             // Convert UTC time to local time (no need to convert the date)
             DST = convertToLocal(&hour, &year, &month,
-                                  &day, GPSData.lon, false); // false means no date conversion
+                                 &day, GPSData.lon, false); // false means no date conversion
           }
           else { // if (localUTCTimeDate)
             if (display12_24_Hour) {
@@ -338,7 +335,7 @@
           if (localUTCTimeDate) {
             // Convert UTC date to local date
             bool DST = convertToLocal(&hour, &year, &month,
-                                       &day, GPSData.lon, true); // true means date conversion
+                                      &day, GPSData.lon, true); // true means date conversion
           } // if (localUTCTimeDate)
           if (month < 10) lcd.print("0");
           lcd.print(month);
@@ -406,7 +403,7 @@
 // Returns the day of week for a given date.
 uint8_t dayOfWeek(uint16_t year, uint8_t month, uint8_t day)
 {
-  return(zeller(year, month, day) % 7) + 1;
+  return (zeller(year, month, day) % 7) + 1;
 }
 //----------------------------------------------------------

@@ -490,7 +487,7 @@
    http://www.edaboard.com/thread101516.html
 */
 bool convertToLocal(uint8_t* hour, uint16_t* year, uint8_t* month,
-                     uint8_t* day, const double lon, bool convertDate) {
+                    uint8_t* day, const double lon, bool convertDate) {

   uint8_t DaysAMonth [] = {31, 28, 31, 30, 31, 30, 31, 31, 30, 31, 30, 31};

@@ -547,7 +544,7 @@

 // Dislpays Hdop or horizontal position error on the LCD
 void displayHdopOnLCD(uint32_t Hdop, bool HdopSelect, unsigned long now,
-                       unsigned long* prevHdopTime, bool* hdopToggle) {
+                      unsigned long* prevHdopTime, bool* hdopToggle) {
   if (!HdopSelect) {
     // Display Horizontal Dilution of Precision (Hdop) with the format X.X
     // It comes in from the GPS module as XXX


default to not using EEPROM

default to not using EEPROM

--- BiblioPixelSerialReceiver.ino
+++ BiblioPixelSerialReceiver.ino
@@ -10,8 +10,8 @@
 /****************************
 All Firmware options go here!
 ****************************/
-// Comment out below line if EEPROM unavailable on your board
-#define USE_EEPROM
+// Uncomment below line if EEPROM available on your board
+// #define USE_EEPROM

 // If not using EEPROM, you can specify device ID here
 #ifndef USE_EEPROMo


Add drawZigZag

Add drawZigZag

--- dee-oh-tee.ino
+++ dee-oh-tee.ino
@@ -101,6 +101,14 @@
   }
 }

+void drawZigZag(int startX, int endX, int yDisplacementFromCenter, int numberOfZigs, int xDegreesPerCycle) {
+  float xDistanceBetweenZigs = (float)(endX - startX) / (float)numberOfZigs;
+  for (int i = 0; i < numberOfZigs; i++) {
+    const int zigSign = (i % 2 == 0) ? 1 : -1;
+    moveToPoint(startX + i * xDistanceBetweenZigs, zigSign * yDisplacementFromCenter, xDegreesPerCycle);
+  }
+}
+
 void drawRectangle(int startX, int startY, int width, int height, int xDegreesPerCycle) {
   if (startX + width > USABLE_DEGREES || startY + height > USABLE_DEGREES) {
     Serial.print("The requested rectangle goes beyond the servo's usable range");
@@ -142,6 +150,8 @@

     drawEllipse(0, 0, USABLE_DEGREES / 4, USABLE_DEGREES / 4, 3, CLOCKWISE);

+//    drawZigZag(-USABLE_DEGREES / 2, USABLE_DEGREES / 2, USABLE_DEGREES / 4, 20, 15);
+
     disableLaser();
   }
 }


Map characters to voltage values

Map characters to voltage values

--- core/core.ino
+++ core/core.ino
@@ -60,6 +60,60 @@
       return "E";
     case 175 ... 204:
       return "F";
+    case 205 ... 234:
+      return "G";
+    case 235 ... 264:
+      return "H";
+    case 265 ... 294:
+      return "I";
+    case 295 ... 324:
+      return "J";
+    case 325 ... 354:
+      return "K";
+    case 355 ... 384:
+      return "L";
+    case 385 ... 404:
+      return "M";
+    case 405 ... 434:
+      return "N";
+    case 435 ... 464:
+      return "O";
+    case 465 ... 494:
+      return "P";
+    case 495 ... 524:
+      return "Q";
+    case 525 ... 554:
+      return "R";
+    case 555 ... 584:
+      return "S";
+    case 585 ... 604:
+      return "T";
+    case 605 ... 634:
+      return "U";
+    case 635 ... 664:
+      return "V";
+    case 665 ... 694:
+      return "W";
+    case 695 ... 724:
+      return "X";
+    case 725 ... 754:
+      return "Y";
+    case 755 ... 784:
+      return "Z";
+    case 785 ... 804:
+      return " ";
+    case 805 ... 834:
+      return ".";
+    case 835 ... 864:
+      return "!";
+    case 865 ... 894:
+      return "?";
+    case 895 ... 924:
+      return "EOC";
+    case 925 ... 954:
+      return "EOF";
+    case 955 ... 204:
+      return "F";
     default:
       return "";
   }
@@ -85,15 +139,15 @@

   drawLogo();
   delay(1200);
-
+
   colorWipe(yellow, 15);
   drawPhone();
   delay(1200);
-
+
 //  colorWipe(purple, 15);
 //  drawSMS();
 //  delay(1200);
-
+
   crossFade(purple, teal, 15, 5);

   matrix.show();
@@ -121,12 +175,12 @@

 // Fade pixel (x, y) from startColor to endColor
 void fadePixel(int x, int y, RGB startColor, RGB endColor, int steps, int wait) {
-  for(int i = 0; i <= steps; i++)
+  for(int i = 0; i <= steps; i++)
   {
      int newR = startColor.r + (endColor.r - startColor.r) * i / steps;
      int newG = startColor.g + (endColor.g - startColor.g) * i / steps;
      int newB = startColor.b + (endColor.b - startColor.b) * i / steps;
-
+
      matrix.drawPixel(x, y, matrix.Color(newR, newG, newB));
      matrix.show();
      delay(wait);
@@ -140,7 +194,7 @@
      int newR = startColor.r + (endColor.r - startColor.r) * i / steps;
      int newG = startColor.g + (endColor.g - startColor.g) * i / steps;
      int newB = startColor.b + (endColor.b - startColor.b) * i / steps;
-
+
      matrix.fillScreen(matrix.Color(newR, newG, newB));
      matrix.show();
      delay(wait);
@@ -148,9 +202,9 @@
 }

 void drawLogo() {
-  // This 8x8 array represents the LED matrix pixels.
+  // This 8x8 array represents the LED matrix pixels.
   // A value of 1 means we’ll fade the pixel to white
-  int logo[8][8] = {
+  int logo[8][8] = {
    {0, 0, 0, 0, 0, 0, 0, 0},
    {0, 1, 1, 0, 0, 1, 1, 0},
    {0, 1, 1, 0, 0, 1, 1, 0},
@@ -160,7 +214,7 @@
    {0, 1, 1, 0, 0, 1, 1, 0},
    {0, 0, 0, 0, 0, 0, 0, 0}
   };
-
+
   for(int row = 0; row < 8; row++) {
     for(int column = 0; column < 8; column++) {
      if(logo[row][column] == 1) {
@@ -171,9 +225,9 @@
 }

 void drawLogoRound(){
-  // This 8x8 array represents the LED matrix pixels.
+  // This 8x8 array represents the LED matrix pixels.
   // A value of 1 means we’ll fade the pixel to white
-  int logo[8][8] = {
+  int logo[8][8] = {
    {0, 0, 0, 0, 0, 0, 0, 0},
    {0, 0, 1, 1, 1, 1, 0, 0},
    {0, 1, 0, 0, 0, 0, 1, 0},
@@ -183,20 +237,20 @@
    {0, 0, 1, 1, 1, 1, 0, 0},
    {0, 0, 0, 0, 0, 0, 0, 0}
   };
-
+
   for(int row = 0; row < 8; row++) {
     for(int column = 0; column < 8; column++) {
      if(logo[row][column] == 1) {
        fadePixel(column, row, purple, white, 30, 0);
      }
    }
-  }
+  }
 }

 void drawPhone(){
-  // This 8x8 array represents the LED matrix pixels.
+  // This 8x8 array represents the LED matrix pixels.
   // A value of 1 means we’ll fade the pixel to white
-  int logo[8][8] = {
+  int logo[8][8] = {
    {0, 0, 0, 0, 0, 0, 0, 0},
    {0, 1, 1, 1, 1, 1, 1, 0},
    {1, 1, 1, 1, 1, 1, 1, 1},
@@ -206,20 +260,20 @@
    {0, 1, 0, 0, 0, 0, 1, 0},
    {0, 1, 1, 1, 1, 1, 1, 0}
   };
-
+
   for(int row = 0; row < 8; row++) {
     for(int column = 0; column < 8; column++) {
      if(logo[row][column] == 1) {
        fadePixel(column, row, purple, white, 8, 0);
      }
    }
-  }
+  }
 }

 void drawSMS(){
-  // This 8x8 array represents the LED matrix pixels.
+  // This 8x8 array represents the LED matrix pixels.
   // A value of 1 means we’ll fade the pixel to white
-  int logo[8][8] = {
+  int logo[8][8] = {
    {1, 1, 1, 1, 1, 1, 1, 1},
    {1, 0, 0, 0, 0, 0, 0, 1},
    {1, 0, 0, 1, 1, 0, 0, 1},
@@ -229,24 +283,24 @@
    {0, 0, 0, 0, 0, 1, 1, 0},
    {0, 0, 0, 0, 0, 0, 1, 0}
   };
-
+
   for(int row = 0; row < 8; row++) {
     for(int column = 0; column < 8; column++) {
      if(logo[row][column] == 1) {
        fadePixel(column, row, purple, white, 30, 0);
      }
    }
-  }
+  }
 }

 void scrollText(String textToDisplay) {
   int x = matrix.width();
   int pixelsInText = textToDisplay.length() * 7;
-
+
   matrix.setCursor(x, 0);
   matrix.print(textToDisplay);
   matrix.show();
-
+
   while(x > (matrix.width() - pixelsInText)) {
     matrix.fillScreen(matrix.Color(red.r, red.g, red.b));
     matrix.setCursor(--x, 0);


changes 2.0

changes 2.0

--- XBee_rob_function_2.0/xBee_2.0/xBee_2.0.ino
+++ XBee_rob_function_2.0/xBee_2.0/xBee_2.0.ino
@@ -74,11 +74,17 @@
 while(z < 300 && h==0){
     joint++;
     h++;
+    if(joint > 4){
+      joint = 4;
+    }
     break;
 }
 while(z > 700 && h==0){
    joint--;
    h++;
+   if(joint < 1){
+    joint = 1;
+   }
    break;
 }
   if(z >= 460 && z <= 470){
@@ -194,7 +200,7 @@
     Serial.print(" Z = ") && Serial.print(z);
     Serial.print(" EMG Ch.1 = ") && Serial.print(emg1);
     Serial.print(" EMG Ch.2 = ") && Serial.print(emg2);
-    Serial.print(" green = ") && Serial.print(green);
+    Serial.print(" joint number= ") && Serial.print(joint);
     Serial.println();
  }
   }


fix integer overflow in glimmer()

fix integer overflow in glimmer()

--- Christmas/Christmas.ino
+++ Christmas/Christmas.ino
@@ -101,13 +101,14 @@
   for(int i=0; i<1024; ++i)
   {
     float theta = i * PI / 32;
+    const float halfBright = 255.0 / 2;

-    analogWrite(3, (cos(theta + offsets[0]) + 1) * 128);
-    analogWrite(5, (cos(theta + offsets[1]) + 1) * 128);
-    analogWrite(6, (cos(theta + offsets[2]) + 1) * 128);
-    analogWrite(9, (cos(theta + offsets[3]) + 1) * 128);
-    analogWrite(10, (cos(theta + offsets[4]) + 1) * 128);
-    analogWrite(11, (cos(theta + offsets[5]) + 1) * 128);
+    analogWrite(3, (cos(theta + offsets[0]) + 1) * halfBright);
+    analogWrite(5, (cos(theta + offsets[1]) + 1) * halfBright);
+    analogWrite(6, (cos(theta + offsets[2]) + 1) * halfBright);
+    analogWrite(9, (cos(theta + offsets[3]) + 1) * halfBright);
+    analogWrite(10, (cos(theta + offsets[4]) + 1) * halfBright);
+    analogWrite(11, (cos(theta + offsets[5]) + 1) * halfBright);

     delay(10);
   }


rfi request for information added

rfi request for information added

--- hb.ino
+++ hb.ino
@@ -1,6 +1,5 @@
+#define HB_VERSION "HoneyBee Arduino interpreter version 0.0.1"
 /*
- HB interpretor
-
 outline of HoneyBee UltraMini TransmitionFormat version 0.0.1
 1_hbumtf_v0
 nodes:
@@ -29,13 +28,12 @@
   int value;
   char process[PROCESS_SIZE];
 } Node;
-// Node n;

 // Pin 13 has an LED connected on most Arduino boards.
 // give it a name:
 int led = 13;
 String inputString = "";         // a string to hold incoming data
-boolean stringComplete = false;  // whether the string is complete
+boolean stringComplete = false;  // serial inputString is complete

 boolean intComplete = false;
 int node_index = 0;
@@ -87,6 +85,11 @@
   }
   else if (state == 0) {
     debug("outside_cmd|"+inputString);
+    if (inputString == "rfi") {
+      Serial.println(HB_VERSION);
+      Serial.println(state);
+      debugAllNodes();
+    }
   }
   if (state == 1 && inputString == "nodes:") {
     node_i = 0;
@@ -186,4 +189,6 @@
       Serial.println("");
     }
   }
+
+
 }


cleaning

cleaning

--- hb.ino
+++ hb.ino
@@ -43,22 +43,20 @@

 // Pin 13 has an LED connected on most Arduino boards.
 // give it a name:
-int led = 13;
+//int led = 13;
 String inputString = "";         // a string to hold incoming data
 boolean stringComplete = false;  // serial inputString is complete

-boolean intComplete = false;
-int node_index = 0;
 Node nodes[10];
-int edge_index = 0;
 Edge edges[10];

 // hbumtf parser vars.
 // state 0=outside_com, 1=loading, 2=nodes, 3=edges
 int state = 0;
+// run_state 0=not_running, 1=running, 2=on_hold
 short run_state = 0;
 boolean graph_loaded = 0;
-
+boolean run_noisy = 0;

 // message queue
 short message_count = 0;
@@ -69,7 +67,7 @@
   Serial.begin(9600);
   // reserve 200 bytes for the inputString:
   inputString.reserve(200);
-  pinMode(led, OUTPUT);
+  //pinMode(led, OUTPUT);

 }

@@ -81,6 +79,14 @@
       #ifdef DUBUG_BUILD
       Serial.println(message_str);
       delay(2000);
+      #endif
+    }
+    else {
+      set_run_state(0);
+      #ifdef DUBUG_BUILD
+      Serial.print("no messages in queue");
+      Serial.print(", party is over. run_state: ");
+      Serial.println(run_state);
       #endif
     }
   }
@@ -98,13 +104,6 @@
   debug(e_type);
   debug(e_part2);
   #endif
-  if (msg[0] == '\0')  {
-    #ifdef DUBUG_BUILD
-    debug("no msg in pm");
-    #endif
-    set_run_state(0);
-    return;
-  }
   if (e_type == "msg") {
     e_part2.toCharArray(e2, 11);
     e_index = get_edge("msg", e2, -1);
@@ -232,14 +231,6 @@
     String message = "flo:";
     message += itoa_buff;
     enq_message(message);
-  }
-  else {
-    set_run_state(0);
-    #ifdef DUBUG_BUILD
-    Serial.print("no transition form ");
-    Serial.print(n_index, DEC);
-    Serial.println(" party is over.");
-    #endif
   }
 }


Port to SmartMatrix 3.0

Port to SmartMatrix 3.0

--- AnimatedGIFs.ino
+++ AnimatedGIFs.ino
@@ -54,11 +54,9 @@
   * https://github.com/pixelmatix/AnimatedGIFs/issues
   */

-#include <math.h>
-#include <stdlib.h>
+#include <SmartMatrix3.h>
 #include <SPI.h>
 #include <SD.h>
-#include <SmartMatrix_32x32.h>
 #include "GIFDecoder.h"

 #define DISPLAY_TIME_SECONDS 10
@@ -69,8 +67,21 @@
 const rgb24 COLOR_BLACK = {
     0, 0, 0 };

-// Smart Matrix instance
-SmartMatrix matrix;
+/* SmartMatrix configuration and memory allocation */
+#define COLOR_DEPTH 24                  // known working: 24, 48 - If the sketch uses type `rgb24` directly, COLOR_DEPTH must be 24
+const uint8_t kMatrixWidth = 32;        // known working: 32, 64, 96, 128
+const uint8_t kMatrixHeight = 32;       // known working: 16, 32, 48, 64
+const uint8_t kRefreshDepth = 36;       // known working: 24, 36, 48
+const uint8_t kDmaBufferRows = 4;       // known working: 4
+const uint8_t kPanelType = SMARTMATRIX_HUB75_32ROW_MOD16SCAN; // use SMARTMATRIX_HUB75_16ROW_MOD8SCAN for common 16x32 panels
+const uint8_t kMatrixOptions = (SMARTMATRIX_OPTIONS_NONE);    // see http://docs.pixelmatix.com/SmartMatrix for options
+const uint8_t kBackgroundLayerOptions = (SM_BACKGROUND_OPTIONS_NONE);
+const uint8_t kScrollingLayerOptions = (SM_SCROLLING_OPTIONS_NONE);
+
+SMARTMATRIX_ALLOCATE_BUFFERS(matrix, kMatrixWidth, kMatrixHeight, kRefreshDepth, kDmaBufferRows, kPanelType, kMatrixOptions);
+SMARTMATRIX_ALLOCATE_BACKGROUND_LAYER(backgroundLayer, kMatrixWidth, kMatrixHeight, COLOR_DEPTH, kBackgroundLayerOptions);
+SMARTMATRIX_ALLOCATE_SCROLLING_LAYER(scrollingLayer, kMatrixWidth, kMatrixHeight, COLOR_DEPTH, kScrollingLayerOptions);
+

 // Chip select for SD card on the SmartMatrix Shield
 #define SD_CS 15
@@ -80,20 +91,19 @@
 int num_files;

 void screenClearCallback(void) {
-  matrix.fillScreen({0,0,0});
+  backgroundLayer.fillScreen({0,0,0});
 }

 void updateScreenCallback(void) {
-  matrix.swapBuffers();
+  backgroundLayer.swapBuffers();
 }

 void drawPixelCallback(int16_t x, int16_t y, uint8_t red, uint8_t green, uint8_t blue) {
-  matrix.drawPixel(x, y, {red, green, blue});
+  backgroundLayer.drawPixel(x, y, {red, green, blue});
 }

 // Setup method runs once, when the sketch starts
 void setup() {
-
     setScreenClearCallback(screenClearCallback);
     setUpdateScreenCallback(updateScreenCallback);
     setDrawPixelCallback(drawPixelCallback);
@@ -104,17 +114,21 @@
     Serial.begin(115200);

     // Initialize matrix
+    matrix.addLayer(&backgroundLayer);
+    matrix.addLayer(&scrollingLayer);
     matrix.begin();
+
+    // configure matrix options
     matrix.setBrightness(defaultBrightness);

     // Clear screen
-    matrix.fillScreen(COLOR_BLACK);
-    matrix.swapBuffers();
+    backgroundLayer.fillScreen(COLOR_BLACK);
+    backgroundLayer.swapBuffers();

     // initialize the SD card at full speed
     pinMode(SD_CS, OUTPUT);
     if (!SD.begin(SD_CS)) {
-        matrix.scrollText("No SD card", -1);
+        scrollingLayer.start("No SD card", -1);
         Serial.println("No SD card");
         while(1);
     }
@@ -123,13 +137,13 @@
     num_files = enumerateGIFFiles(GIF_DIRECTORY, false);

     if(num_files < 0) {
-        matrix.scrollText("No gifs directory", -1);
+        scrollingLayer.start("No gifs directory", -1);
         Serial.println("No gifs directory");
         while(1);
     }

     if(!num_files) {
-        matrix.scrollText("Empty gifs directory", -1);
+        scrollingLayer.start("Empty gifs directory", -1);
         Serial.println("Empty gifs directory");
         while(1);
     }
@@ -137,7 +151,6 @@

 void loop() {
-
     unsigned long futureTime;
     char pathname[30];


make connectedness checking into a function

--- examples/esp8266_firmware/esp8266_firmware.ino
+++ examples/esp8266_firmware/esp8266_firmware.ino
@@ -35,7 +35,7 @@
 	if (led_mode == LED_ACTIVITY) {
 		is_on = millis() - last_activity < 500;
 	} else if (led_mode == LED_CONNECTION) {
-		is_on = WiFi.status() == WL_CONNECTED;
+		is_on = is_connected();
 	} else if (led_mode == LED_OFF) {
 		is_on = false;
 	} else if (led_mode == LED_ON) {
@@ -62,7 +62,7 @@

 	// If a timeout of 0 is used this might try forever, locking up the code.
 	unsigned long before = millis();
-	while (WiFi.status() != WL_CONNECTED) {
+	while (is_connected()) {
 		if (timeout && millis() - before > timeout) {
 			return;
 		}
@@ -103,6 +103,10 @@
 	// The chip remembers its last ssid and password, so generally just running the server will make it reachable,
 	// even without reconfiguring.
 	server.begin();
+}
+
+bool is_connected() {
+	return WiFi.status() == WL_CONNECTED;
 }

 void handle_request() {
@@ -286,7 +290,7 @@
 		if (command == COMMAND_DEBUG){
 			send_data(String("ssid"), ssid);
 			send_data(String("password"), password);
-			send_data(String("connected"), String(WiFi.status() == WL_CONNECTED));
+			send_data(String("connected"), String(is_connected()));
 			send_data(String("led_mode"), String(led_mode));
 			send_data(String("baud rate"), String(baud_rate));
 			send_data(String("ip"), format_ip(WiFi.localIP()));
@@ -300,7 +304,7 @@
 		} else if (command == COMMAND_CONNECT) {
 			connect();
 		} else if (command == COMMAND_IS_CONNECTED) {
-			send_data(COMMAND_IS_CONNECTED, String(WiFi.status() == WL_CONNECTED));
+			send_data(COMMAND_IS_CONNECTED, String(is_connected()));
 		} else if (command == COMMAND_DISCONNECT) {
 			disconnect();
 		} else if (command == COMMAND_GET_IP) {


Updated setTime()

Updated setTime()

--- arduino-nixie-clock/arduino-nixie-clock.ino
+++ arduino-nixie-clock/arduino-nixie-clock.ino
@@ -44,8 +44,10 @@

 void setTime(unsigned short new_hour, unsigned short new_minute, unsigned short new_second)
 {
+  hour = new_hour;
+  minute = new_minute;
+  second = new_second;
   milliseconds = (new_hour * 60 * 60 + new_minute * 60 + new_second) * 1000;
-  updateTime();
 }

 void displayDigit(unsigned short digit, unsigned short pin)


Simplify IMU disconnected error code

Simplify IMU disconnected error code

--- Vertex.ino
+++ Vertex.ino
@@ -47,16 +47,8 @@
   Serial.begin(115200);

   // Initialize sensors
-  if (!accel.begin()) {
-    Serial.println(F("No LSM303"));
-    while(true);
-  }
-  if (!mag.begin()) {
-    Serial.println(F("No LSM303"));
-    while(true);
-  }
-  if (!bmp.begin()) {
-    Serial.println(F("No BMP180"));
+  if (!accel.begin() || !mag.begin() || !bmp.begin()) {
+    fatalError();
     while(true);
   }


Cleanup HMTL_Module socket initialization

--- HMTL_Module/HMTL_Module.ino
+++ HMTL_Module/HMTL_Module.ino
@@ -56,10 +56,8 @@
 XBeeSocket xbee;
 byte xbee_data_buffer[RS485_BUFFER_TOTAL(SEND_BUFFER_SIZE)];

-Socket *serial_socket = NULL;
-
-#define NUM_SOCKETS 2
-Socket *sockets[NUM_SOCKETS] = { NULL, NULL };
+#define MAX_SOCKETS 2
+Socket *sockets[MAX_SOCKETS] = { NULL, NULL };

 config_hdr_t config;
 output_hdr_t *outputs[HMTL_MAX_OUTPUTS];
@@ -92,10 +90,11 @@
   { HMTL_PROGRAM_NONE, NULL, NULL},
   { HMTL_PROGRAM_BLINK, program_blink, program_blink_init },
   { HMTL_PROGRAM_TIMED_CHANGE, program_timed_change, program_timed_change_init },
+  { HMTL_PROGRAM_FADE, program_fade, program_fade_init },
+
   { HMTL_PROGRAM_LEVEL_VALUE, program_level_value, program_level_value_init },
   { HMTL_PROGRAM_SOUND_VALUE, program_sound_value, program_sound_value_init },
-  { HMTL_PROGRAM_FADE, program_fade, program_fade_init },
-  { PROGRAM_SENSOR_DATA, process_sensor_data, NULL }
+  { PROGRAM_SENSOR_DATA, process_sensor_data, program_sensor_data_init }
 };
 #define NUM_PROGRAMS (sizeof (program_functions) / sizeof (hmtl_program_t))

@@ -123,23 +122,23 @@
     DEBUG_ERR_STATE(1);
   }

+  byte num_sockets = 0;
+
   if (outputs_found & (1 << HMTL_OUTPUT_RS485)) {
     /* Setup the RS485 connection */
     rs485.setup();
     rs485.initBuffer(rs485_data_buffer, SEND_BUFFER_SIZE);
-    serial_socket = &rs485;
-    sockets[0] = &rs485;
+    sockets[num_sockets++] = &rs485;
   }

   if (outputs_found & (1 << HMTL_OUTPUT_XBEE)) {
     /* Setup the RS485 connection */
     xbee.setup();
     xbee.initBuffer(xbee_data_buffer, SEND_BUFFER_SIZE);
-    serial_socket = &xbee;
-    sockets[1] = &xbee;
-  }
-
-  if (serial_socket == NULL) {
+    sockets[num_sockets++] = &xbee;
+  }
+
+  if (num_sockets == 0) {
     DEBUG_ERR("No sockets configured");
     DEBUG_ERR_STATE(2);
   }
@@ -148,7 +147,7 @@
   manager = ProgramManager(outputs, active_programs, objects, HMTL_MAX_OUTPUTS,
                            program_functions, NUM_PROGRAMS);

-  handler = MessageHandler(config.address, &manager, sockets, NUM_SOCKETS);
+  handler = MessageHandler(config.address, &manager, sockets, num_sockets);

   DEBUG2_VALUELN("HMTL Module initialized, v", HMTL_MODULE_BUILD);
   Serial.println(F(HMTL_READY));
@@ -248,9 +247,17 @@
 }

-/*
- * Record relevant sensor data for programatic usage
- */
+/*******************************************************************************
+ * Program handler for processing incoming sensor data
+ */
+
+boolean program_sensor_data_init(msg_program_t *msg,
+                                 program_tracker_t *tracker,
+                                 output_hdr_t *output) {
+  DEBUG3_PRINTLN("Initializing sensor data handler");
+  return true;
+}
+
 boolean process_sensor_data(output_hdr_t *output,
                             void *object,
                             program_tracker_t *tracker) {
@@ -267,7 +274,7 @@
       }

       memcpy(sound_data, data, copy_len);
-      sound_channels = sensor->data_len / sizeof (uint16_t);
+      sound_channels = sensor->data_len / (byte)sizeof (uint16_t);
       DEBUG4_COMMAND(
                      DEBUG4_VALUE(" SOUND:", sound_channels);
                      for (byte i = 0; i < sound_channels; i++) {


pre loop

pre loop

--- run/arduino/arduinoActuator/arduinoActuator.ino
+++ run/arduino/arduinoActuator/arduinoActuator.ino
@@ -10,8 +10,8 @@

 void setup() {
   // put your setup code here, to run once:
-  pinMode(pwmPin,OUTPUT);
-  pinMode(dirPin,OUTPUT);
+  pinMode(pwmPin, OUTPUT);
+  pinMode(dirPin, OUTPUT);

   setActuatorValue(currentVal);

@@ -28,20 +28,19 @@

 void setActuatorValue(int value) {
   if (value > 0) {
+    digitalWrite(dirPin, HIGH);
     analogWrite(pwmPin, 255);
-
-    digitalWrite(dirPin, HIGH);
     delay((300/100) * value);
     analogWrite(pwmPin, 0);
   }
   else if (value < 0) {
+    digitalWrite(dirPin, LOW);
     analogWrite(pwmPin, 255);
-
-    digitalWrite(dirPin, LOW);
     delay((300/100) * value * -1);
     analogWrite(pwmPin, 0);
   }
   else {
+    digitalWrite(dirPin, HIGH);
     analogWrite(pwmPin, 0);
   }
   delay(5);


added another function for random twinkles

--- yun-control-light-all-strips-together.ino
+++ yun-control-light-all-strips-together.ino
@@ -67,6 +67,11 @@

 unsigned long currentMillis = millis();
 long previousMillis = 0; // for wait times
+
+
+int bright = 1; //select 1 thru 10
+int brightRaw = 1; //select 1 thru 10
+

 // Listen on default port 5555, the webserver on the Yun
 // will forward there all the HTTP requests for us.
@@ -104,7 +109,7 @@
           allColor(strip.Color(0, 0, 0)); //off
           break;
         case 1:
-          //softBlink(strip.Color(redVal, greenVal, blueVal), 255, 50); // blue
+          allColor((unsigned long)random(0x01000000)); // random color
           break;
         case 2:
           // blink in pixels one at a time
@@ -133,7 +138,7 @@
           //          client.println(wait);

           c = strip.Color(redVal, greenVal, blueVal);
-          neoPixelToChange = 0;
+          //neoPixelToChange = 0;
           while (neoPixelToChange <= NUMPIXELS) {

             // this call allows us to check if there is a new command, thereby interrupting the current loop
@@ -152,7 +157,45 @@
           }
           break;
         case 3:
-         // softBlink(strip.Color(0, 0, 255), defaultBrightness, 50); // blue
+
+
+          brightRaw = client.parseInt();
+          bright = constrain(brightRaw, 1, 10);
+
+           // fills with random
+
+          totalCycles = 5000;
+          currentCycles = 0;
+          while ( totalCycles > currentCycles ) {
+
+            YunClient client = server.accept();
+            if (client) {
+              break;
+              client.stop();
+            }
+
+            uint32_t wait;
+
+            if ( waitTime > 0 ) {
+              wait = waitTime;
+            } else {
+              // just to have a sane wait time if nothing is specified
+              wait = 50;
+            }
+
+            currentMillis = millis();
+            if (currentMillis - previousMillis > wait) {
+              previousMillis = currentMillis;
+              int randr = random(0,(25*bright));
+              int randg = random(0,(25*bright));
+              int randb = random(0,(25*bright));
+              int randi = random(1,strip.numPixels());
+              int randii = random(1,strip.numPixels());
+              strip.setPixelColor(constrain(randi, 0, 255), constrain(randr, 0, 255), constrain(randg, 0, 255), constrain(randb, 0, 255));
+              strip.show();
+              neoPixelToChange++;
+            }
+          }
           break;
         case 4:
           //rainbow


Delete OTTO_todo.ino

Delete OTTO_todo.ino


Update Fade.ino

Update Fade.ino

--- examples/Basics/Fade/Fade.ino
+++ examples/Basics/Fade/Fade.ino
@@ -3,12 +3,6 @@

  This example shows how to fade the Red LED on pin 12
  using the analogWrite() function.
-
- The analogWrite() function uses PWM, so if
- you want to change the pin you're using, be
- sure to use another PWM capable pin. On most
- Arduino, the PWM pins are identified with
- a "~" sign, like ~3, ~5, ~6, ~9, ~10 and ~11.

  */


tiny change

tiny change

--- WifiWeatherGuy.ino
+++ WifiWeatherGuy.ino
@@ -136,6 +136,7 @@
 			f.print(body);
 			f.close();
 			server.send(200);
+			WiFi.setAutoConnect(false);
 			ESP.restart();
 		} else
 			server.send(400, "text/plain", "No body!");


v0.8.2 update/更新2

v0.8.2 update/更新2

Important update…

Fix  Fake GPS wrong time…
Fix  Dead Loop…
Fix  Dead Webserver setup…
with a CLEAR_SETTING bit
reduce upload period to LASS server to 30 sec

--- Device_LinkItOne/LASS/LASS.ino
+++ Device_LinkItOne/LASS/LASS.ino
@@ -81,6 +81,7 @@
 #define VER_FORMAT "3"  // version number has been increased to 2 since v0.7.0
 #define VER_APP "0.8.2"
 #define SETTING_VERSION 2
+#define CLEAR_SETTING 0  //modify this to 1 if you cant change your FT_ID

 // Blynk
 #if BLYNK_ENABLE == 1
@@ -1995,6 +1996,13 @@
 }

 //----- MQTT -----
+
+void mqttPrintCurrentMsg(){
+      Serial.print("Pack MQTT Topic:");
+      Serial.println(mqttTopic);
+      Serial.println(msg);
+}
+
 #if ALARM_ENABLE == 1
 void msgDisplay(char* topic, byte* payload, unsigned int len){
   int i;
@@ -2014,6 +2022,7 @@
   //Serial.println(msg);

 }
+

 void mqttSubscribeRoutine(){
@@ -2457,6 +2466,7 @@
      delay(10);
   }

+  if((!setting_load()) || isHigh){
     Serial.println("Entering WIFI Setup Section...");
     setting_init();
     Serial.println("Default Setting loaded...");
@@ -2485,9 +2495,13 @@

     while (checkWifiConnected() == 0)
       {
+        LWiFi.connect(setting.wifi_ssid, LWiFiLoginInfo(wifi_auth, wifi_pass));
+        Serial.println("WebPage DefaultMode");
       }
     server.begin();
+    while(1){
       webserver_loop();
+    }
   }

    if(LED_MODE != LED_MODE_OFF){ // LED_MODE_OFF never light on
@@ -2523,9 +2537,11 @@
     }
     String wifi_pass=setting.wifi_pass;
     wifi_pass.trim();
-    while (checkWifiConnected() == 0)
-      {
-      }
+    while (checkWifiConnected() == 0){
+      Serial.println("Connect WIFI");
+      LWiFi.connect(setting.wifi_ssid, LWiFiLoginInfo(wifi_auth, wifi_pass));
+      delay(1000);
+    }
     Serial.println("Wifi Connected...send NTP info now");
     Udp.begin(2390);
     retrieveNtpTime();


Some more cleanup.

Some more cleanup.

--- examples/sms/sms.ino
+++ examples/sms/sms.ino
@@ -27,13 +27,7 @@
     callInfo cinfo = A6l.checkCallStatus();
     if (cinfo.direction == DIR_INCOMING) {
        if (cinfo.number == "919999999999")
-        {
-          //add + before your country code as it doesn't appear in the if messages don't get send ex-
-          // CLIP: "91**********",145,,,,1
-          // String new_number="+" + cinfo.number;
-          // Serial.println(new_number);
            A6l.sendSMS(new_number, "I can't come to the phone right now, I'm a machine.");
-        }
         A6l.hangUp();
     }