Delete LBridgev_PR_170311.ino

Delete LBridgev_PR_170311.ino

--- LBridgev_PR_170311.ino
+++ LBridgev_PR_170311.ino
@@ -1,1882 +0,0 @@
-/*
-   It scans the Freestyle Libre Sensor every 5 minutes
-   and sends the data to the xDrip Android app. You can
-   see the data in the serial monitor of Arduino IDE, too.
-   If you want another scan interval, simply change the
-   sleepTime value. To work with Android 4 you have to disable
-   all lines containing a "for Android 4" comment and set the
-   sleep time to 36.
-
-   This sketch is based on a sample sketch for the BM019 module
-   from Solutions Cubed.
-
-   Wiring for UNO / Pro-Mini:
-
-   Arduino          BM019           BLE-HM11
-   IRQ: Pin 9       DIN: pin 2
-   SS: pin 10       SS: pin 3
-   MOSI: pin 11     MOSI: pin 5
-   MISO: pin 12     MISO: pin4
-   SCK: pin 13      SCK: pin 6
-   I/O: pin 3 (VCC with Android 4)  VCC: pin 9
-   I/O: pin 5                       TX:  pin 2
-   I/O: pin 6                       RX:  pin 4
-*/
-
-/*
- * VWI, V 0.1, 03/2017
- * LBridge, a LimiTTer with xBridge Protocol extension and power saving mods. This sketch is based on LimiTTer code (JoernL)
- * for NFC reading and sleep mode handling and a port of the xBridge2 protocol with queueing from savek-cc.
- * Thanks to JoernL and savek-cc!
- *
- * Hardwaresource in xDrip has to be set to "LimiTTer". Please use an xDrip+ version >= nightly build 2107/02/09
- *
- * The xBridge2 protocol is used to send BG readings to xDrip+. In case of failure it queues up not sended BG readings
- * with the correct timestamp and send them within the next BLE connection. There should be no missed BG readings
- * when LimiTTer is worn.
- */
-
-#include <SPI.h>
-#include <SoftwareSerial.h>
-#include <avr/sleep.h>
-#include <avr/power.h>
-#include <avr/wdt.h>
-
-#define LNAME F("AT+NAMELBri0311")
-
-/* ************************************************ */
-/* *** config #DEFINES *** */
-/* ************************************************ */
-
-#define N_SHOW_LIMITTER       // show original Limitter output
-#define USE_DEAD_SENSOR       // we can test with a dead sensor
-#define N_SEND_ERROR_COUNTERS // send error counter values via BLE
-#define N_HW_BLE              // detect BLE conn status with system LED pin connected to arduino pin 2
-#define N_DYNAMIC_TXID        // get TXID automatically
-#define N_AUTOCAL_WDT         // code for auto calibrating WDT timing
-
-/* ********************************************* */
-/* ********* LimiTTer stuff ******************** */
-/* ********************************************* */
-
-#define MIN_V 3450 // battery empty level
-#define MAX_V 4050 // battery full level
-
-const int SSPin = 10;   // Slave Select pin
-const int IRQPin = 9;   // Sends wake-up pulse for BM019
-const int NFCPin1 = 7;  // Power pin BM019
-const int NFCPin2 = 8;  // Power pin BM019
-const int NFCPin3 = 4;  // Power pin BM019
-const int BLEPin = 3;   // BLE power pin.
-const int MOSIPin = 11;
-const int SCKPin = 13;
-
-#ifdef HW_BLE
-const int bleSysLedPin = 2; // connect to Sys LED pin of HM-1x
-#endif
-
-byte RXBuffer[24];
-byte NFCReady = 0;  // used to track NFC state
-byte FirstRun = 1;
-byte batteryLow;
-int batteryPcnt;
-long batteryMv;
-
-// sleeptime in multipliers of 8 s
-int sleepTime = 32;
-
-int noDiffCount = 0;
-int sensorMinutesElapse;
-float lastGlucose;
-float trend[16];
-
-SoftwareSerial ble_Serial(5, 6); // RX | TX
-
-/* ************************************************* */
-/* *** VWI control stuff *** */
-/* ************************************************ */
-
-// global error counters
-unsigned long loop_count = 0;          // of main loop
-unsigned long ble_connect_errors = 0;  // no BLE connect after 40 s wait time
-unsigned long nfc_read_errors = 0;     // e. g. no sensor in range
-unsigned long nfc_scan_count = 0;      // how many scans?
-unsigned long nfc_inv_cmd_count = 0;   // how much SetInventroy commands?
-
-unsigned long nfc_prot_set_cmd_errors = 0;
-unsigned long nfc_inv_cmd_errors = 0;
-unsigned long nfc_read_mem_errors = 0;
-unsigned long resend_pkts_events = 0;
-unsigned long queue_events = 0;
-
-#ifdef SEND_ERROR_COUNTERS
-static boolean send_error_counters_via_ble = 0;
-#endif
-
-static boolean show_ble = 1;        // what is shown in serial monitor
-static boolean show_state = 1;      // show print_state() infos, disabled ftm
-
-boolean sensor_oor;                 // sensor out of range
-int ble_answer;                     // char from BLE reeived?
-boolean ble_lost_processing = 1;    // send AT+RESET after OK+LOST?
-
-// absolute progam run time in s counting also sleep() phase
-unsigned long prg_run_time = 0;     // in sec
-
-unsigned long loop_start_time;      // loop starting time in ms
-unsigned long loop_time;            // curretn loop duration in ms
-unsigned long ble_start_time = 0;   // time when BLE starts ms
-unsigned long ble_connect_time = 0; // time up to BLE connection in ms
-
-float avg_sleepTime = 0;            // average sleep time
-float bleTime = 0;                  // average arduino+BLE time
-float bleNFCTime = 0;
-
-/* ************************************************************* */
-/* *** code ported form xBridge2.c *** */
-/* ************************************************************* */
-
-// defines the xBridge protocol functional level.  Sent in each packet as the last byte.
-#define DEXBRIDGE_PROTO_LEVEL (0x01)
-
-static volatile boolean do_sleep = 0;     // indicates we should go to sleep between packets
-static volatile boolean got_ack = 0;      // indicates if we got an ack during the last do_services.
-static volatile boolean dex_tx_id_set;    // indicates if the Dexcom Transmitter id (settings.dex_tx_id) has been set.  Set in doServices.
-static volatile boolean ble_connected;    // bit indicating the BLE module is connected to the phone.  Prevents us from sending data without this.
-#ifdef HW_BLE
-static volatile boolean hwble_connected;  // bit indicating the BLE module is connected to the phone.  Prevents us from sending data without this.
-#endif
-
-static volatile boolean got_ok;           // flag indicating we got OK from the HM-1x
-
-static volatile unsigned long pkt_time = 0;
-static volatile unsigned long abs_pkt_time = 0;
-static volatile unsigned long last_abs_pkt_time = 0;
-
-//define the maximum command string length for USB commands.
-#define COMMAND_MAXLEN 40
-
-//structure of a USB command
-typedef struct _command_buff
-{
-  unsigned char commandBuffer[COMMAND_MAXLEN];
-  unsigned char nCurReadPos;
-} t_command_buff;
-
-static t_command_buff command_buff;
-
-typedef struct _Dexcom_packet
-{
-  unsigned long raw;
-  unsigned long ms;
-} Dexcom_packet;
-
-#define DXQUEUESIZE 36 // 3 h of queue
-
-typedef struct {
-  volatile unsigned char read;
-  volatile unsigned char write;
-  Dexcom_packet buffer[DXQUEUESIZE];
-} Dexcom_fifo;
-
-Dexcom_fifo Pkts;
-
-Dexcom_packet * DexPkt;
-
-// structure of a raw record we will send.
-typedef struct _RawRecord
-{
-  unsigned char size; //size of the packet.
-  unsigned char cmd_code; // code for this data packet.  Always 00 for a Dexcom data packet.
-  unsigned long raw;  //"raw" BGL value. ??? use unfiltered NFC readings here?
-  unsigned long filtered; //"filtered" BGL value
-  unsigned char dex_battery;  //battery value
-  unsigned char my_battery; //xBridge battery value
-  unsigned long dex_src_id;   //raw TXID of the Dexcom Transmitter
-  unsigned long delay;
-  unsigned char function; // Byte representing the xBridge code funcitonality.  01 = this level.
-} RawRecord;
-
-// _xBridge_settings - Type definition for storage of xBridge_settings
-// used for compatibility
-typedef struct _xBridge_settings
-{
-  unsigned long dex_tx_id;     //4 bytes
-  unsigned long uart_baudrate; //4 bytes
-} xBridge_settings;     //14 bytes total
-
-xBridge_settings settings;
-
-// array of HM-1x baudrates for rate detection.
-unsigned long uart_baudrate[9] = {9600L,19200L,38400L,57600L,115200L,4800,2400,1200,230400L};
-
-/* ********************************************* */
-/*  help functions */
-/* *********************************************** */
-
-// get free mem available
-extern unsigned int __bss_end;
-extern unsigned int __heap_start;
-extern void *__brkval;
-int freeMemory() {
-  int free_memory;
-
-  if((int)__brkval == 0)
-    free_memory = ((int)&free_memory) - ((int)&__bss_end);
-  else
-    free_memory = ((int)&free_memory) - ((int)__brkval);
-
-  return free_memory;
-}
-
-// millis() since program start, Arduino millis() are not counting when in sleep mode
-unsigned long abs_millis(void)
-{
-  return(prg_run_time*1000 + (millis() - loop_start_time));
-}
-
-/* **************************************************************** */
-/* modified LimiTTer code */
-/* **************************************************************** */
-
-// initialize the hardware
-void setup() {
-    // NFC part
-    pinMode(IRQPin, OUTPUT);
-    digitalWrite(IRQPin, HIGH);
-    pinMode(SSPin, OUTPUT);
-    digitalWrite(SSPin, HIGH);
-    pinMode(NFCPin1, OUTPUT);
-    digitalWrite(NFCPin1, HIGH);
-    pinMode(NFCPin2, OUTPUT);
-    digitalWrite(NFCPin2, HIGH);
-    pinMode(NFCPin3, OUTPUT);
-    digitalWrite(NFCPin3, HIGH);
-
-    // BLE part
-    pinMode(BLEPin, OUTPUT); // Disable this for Android 4
-    digitalWrite(BLEPin, HIGH); // Disable this for Android 4
-    ble_start_time = millis();
-    ble_connected = 0;
-#ifdef HW_BLE
-    hwble_connected = 0;
-    pinMode(bleSysLedPin, INPUT);
-#endif
-
-    // NFC part
-/* not needed here, is done in SPI.begin(), acoording to Bert Roode, 170302
-    pinMode(MOSIPin, OUTPUT);
-    pinMode(SCKPin, OUTPUT);
-*/
-    // try this first
-    Serial.begin(9600);
-}
-
-/* *********************************************************** */
-/* LimiTTer code, only small modifications */
-/* *********************************************************** */
-
-void SetProtocol_Command() {
-unsigned long ct;
-
-  digitalWrite(SSPin, LOW);
-  SPI.transfer(0x00);  // SPI control byte to send command to CR95HF
-  SPI.transfer(0x02);  // Set protocol command
-  SPI.transfer(0x02);  // length of data to follow
-  SPI.transfer(0x01);  // code for ISO/IEC 15693
-  SPI.transfer(0x0D);  // Wait for SOF, 10% modulation, append CRC
-  digitalWrite(SSPin, HIGH);
-  delay(1);
-
-  ct = millis();
-  digitalWrite(SSPin, LOW);
-  while( RXBuffer[0] != 8 )
-    {
-    RXBuffer[0] = SPI.transfer(0x03);  // Write 3 until
-    RXBuffer[0] = RXBuffer[0] & 0x08;  // bit 3 is set
-    if ( (millis() - ct) > 1000) {
-      print_state(F(" - poll SetProtocol_Command not successfull"));
-      break;
-    }
-
-    }
-  digitalWrite(SSPin, HIGH);
-  delay(1);
-
-  digitalWrite(SSPin, LOW);
-  SPI.transfer(0x02);   // SPI control byte for read
-  RXBuffer[0] = SPI.transfer(0);  // response code
-  RXBuffer[1] = SPI.transfer(0);  // length of data
-  digitalWrite(SSPin, HIGH);
-
-  if ((RXBuffer[0] == 0) & (RXBuffer[1] == 0))  // is response code good?
-    {
-    print_state(F(" - Protocol Set Command OK"));
-    NFCReady = 1; // NFC is ready
-    }
-  else
-    {
-    print_state(F(" - Protocol Set Command FAIL"));
-    NFCReady = 0; // NFC not ready
-    nfc_prot_set_cmd_errors++;
-    }
-}
-
-void Inventory_Command() {
-unsigned long ct;
-  digitalWrite(SSPin, LOW);
-  SPI.transfer(0x00);  // SPI control byte to send command to CR95HF
-  SPI.transfer(0x04);  // Send Receive CR95HF command
-  SPI.transfer(0x03);  // length of data that follows is 0
-  SPI.transfer(0x26);  // request Flags byte
-  SPI.transfer(0x01);  // Inventory Command for ISO/IEC 15693
-  SPI.transfer(0x00);  // mask length for inventory command
-  digitalWrite(SSPin, HIGH);
-  delay(1);
-
-  ct = millis();
-  digitalWrite(SSPin, LOW);
-  while(RXBuffer[0] != 8)
-    {
-    RXBuffer[0] = SPI.transfer(0x03);  // Write 3 until
-    RXBuffer[0] = RXBuffer[0] & 0x08;  // bit 3 is set
-    if ( (millis() - ct) > 1000) {
-      print_state(F(" - poll Inventory_Command not successfull"));
-      break;
-    }
-    }
-  digitalWrite(SSPin, HIGH);
-  delay(1);
-
-  digitalWrite(SSPin, LOW);
-  SPI.transfer(0x02);   // SPI control byte for read
-  RXBuffer[0] = SPI.transfer(0);  // response code
-  RXBuffer[1] = SPI.transfer(0);  // length of data
-  for (byte i=0;i<RXBuffer[1];i++)
-      RXBuffer[i+2]=SPI.transfer(0);  // data
-  digitalWrite(SSPin, HIGH);
-  delay(1);
-
-  if (RXBuffer[0] == 128)  // is response code good?
-    {
-    print_state(F(" - Sensor in range ... OK"));
-    NFCReady = 2;
-    sensor_oor = 0;
-    }
-  else
-    {
-    print_state(F(" - Sensor out of range"));
-    NFCReady = 1;
-    nfc_inv_cmd_errors++;
-    sensor_oor = 1;
-    }
- }
-
-float Read_Memory() {
- byte oneBlock[8];
- String hexPointer = "";
- String trendValues = "";
- String hexMinutes = "";
- String elapsedMinutes = "";
- float trendOneGlucose;
- float trendTwoGlucose;
- float currentGlucose = 0;  // initialise to avoid compiler warning
- float shownGlucose;
- float averageGlucose = 0;
- int glucosePointer;
- int validTrendCounter = 0;
- float validTrend[16];
-  unsigned long ct;
-
- for ( int b = 3; b < 16; b++) {
-
-  digitalWrite(SSPin, LOW);
-  SPI.transfer(0x00);  // SPI control byte to send command to CR95HF
-  SPI.transfer(0x04);  // Send Receive CR95HF command
-  SPI.transfer(0x03);  // length of data that follows
-  SPI.transfer(0x02);  // request Flags byte
-  SPI.transfer(0x20);  // Read Single Block command for ISO/IEC 15693
-  SPI.transfer(b);  // memory block address
-  digitalWrite(SSPin, HIGH);
-  delay(1);
-
-  ct = millis();
-  digitalWrite(SSPin, LOW);
-  while(RXBuffer[0] != 8)
-    {
-    RXBuffer[0] = SPI.transfer(0x03);  // Write 3 until
-    RXBuffer[0] = RXBuffer[0] & 0x08;  // bit 3 is set
-    if ( (millis() - ct) > 1000) {
-      print_state(F(" - poll Read_Memory"));
-      break;
-    }
-    }
-  digitalWrite(SSPin, HIGH);
-  delay(1);
-
-  digitalWrite(SSPin, LOW);
-  SPI.transfer(0x02);   // SPI control byte for read
-  RXBuffer[0] = SPI.transfer(0);  // response code
-  RXBuffer[1] = SPI.transfer(0);  // length of data
- for (byte i=0;i<RXBuffer[1];i++)
-   RXBuffer[i+2]=SPI.transfer(0);  // data
-
-  digitalWrite(SSPin, HIGH);
-  delay(1);
-
- for (int i = 0; i < 8; i++)
-   oneBlock[i] = RXBuffer[i+3];
-
-  char str[24];
-  unsigned char * pin = oneBlock;
-  const char * hex = "0123456789ABCDEF";
-  char * pout = str;
-  for(; pin < oneBlock+8; pout+=2, pin++) {
-      pout[0] = hex[(*pin>>4) & 0xF];
-      pout[1] = hex[ *pin     & 0xF];
-  }
-  pout[0] = 0;
-#ifdef SHOW_LIMITTER
-  Serial.println(str);
-#endif
-  trendValues += str;
- }
-
- digitalWrite(SSPin, LOW);
-  SPI.transfer(0x00);  // SPI control byte to send command to CR95HF
-  SPI.transfer(0x04);  // Send Receive CR95HF command
-  SPI.transfer(0x03);  // length of data that follows
-  SPI.transfer(0x02);  // request Flags byte
-  SPI.transfer(0x20);  // Read Single Block command for ISO/IEC 15693
-  SPI.transfer(39);  // memory block address
-  digitalWrite(SSPin, HIGH);
-  delay(1);
-
-  digitalWrite(SSPin, LOW);
-  while(RXBuffer[0] != 8)
-    {
-    RXBuffer[0] = SPI.transfer(0x03);  // Write 3 until
-    RXBuffer[0] = RXBuffer[0] & 0x08;  // bit 3 is set
-    }
-  digitalWrite(SSPin, HIGH);
-  delay(1);
-
-  digitalWrite(SSPin, LOW);
-  SPI.transfer(0x02);   // SPI control byte for read
-  RXBuffer[0] = SPI.transfer(0);  // response code
-  RXBuffer[1] = SPI.transfer(0);  // length of data
- for (byte i=0;i<RXBuffer[1];i++)
-   RXBuffer[i+2]=SPI.transfer(0);  // data
-
-  digitalWrite(SSPin, HIGH);
-  delay(1);
-
- for (int i = 0; i < 8; i++)
-   oneBlock[i] = RXBuffer[i+3];
-
-  char str[24];
-  unsigned char * pin = oneBlock;
-  const char * hex = "0123456789ABCDEF";
-  char * pout = str;
-  for(; pin < oneBlock+8; pout+=2, pin++) {
-      pout[0] = hex[(*pin>>4) & 0xF];
-      pout[1] = hex[ *pin     & 0xF];
-  }
-  pout[0] = 0;
-
-#ifdef SHOW_LIMITTER
-  Serial.println(str);
-#endif
-
-  elapsedMinutes += str;
-
-  if (RXBuffer[0] == 128) // is response code good?
-    {
-      hexMinutes = elapsedMinutes.substring(10,12) + elapsedMinutes.substring(8,10);
-      hexPointer = trendValues.substring(4,6);
-      sensorMinutesElapse = strtoul(hexMinutes.c_str(), NULL, 16);
-      glucosePointer = strtoul(hexPointer.c_str(), NULL, 16);
-
-#ifdef SHOW_LIMITTER
-      Serial.println(F(""));
-      Serial.print(F("Glucose pointer: "));
-      Serial.print(glucosePointer);
-      Serial.println(F(""));
-#endif
-      int ii = 0;
-      for (int i=8; i<=200; i+=12) {
-        if (glucosePointer == ii)
-        {
-          if (glucosePointer == 0)
-          {
-            String trendNow = trendValues.substring(190,192) + trendValues.substring(188,190);
-            String trendOne = trendValues.substring(178,180) + trendValues.substring(176,178);
-            String trendTwo = trendValues.substring(166,168) + trendValues.substring(164,166);
-            currentGlucose = Glucose_Reading(strtoul(trendNow.c_str(), NULL ,16));
-            trendOneGlucose = Glucose_Reading(strtoul(trendOne.c_str(), NULL ,16));
-            trendTwoGlucose = Glucose_Reading(strtoul(trendTwo.c_str(), NULL ,16));
-
-            if (FirstRun == 1)
-               lastGlucose = currentGlucose;
-
-            if (((lastGlucose - currentGlucose) > 50) || ((currentGlucose - lastGlucose) > 50))
-            {
-               if (((lastGlucose - trendOneGlucose) > 50) || ((trendOneGlucose - lastGlucose) > 50))
-                  currentGlucose = trendTwoGlucose;
-               else
-                  currentGlucose = trendOneGlucose;
-            }
-          }
-          else if (glucosePointer == 1)
-          {
-            String trendNow = trendValues.substring(i-10,i-8) + trendValues.substring(i-12,i-10);
-            String trendOne = trendValues.substring(190,192) + trendValues.substring(188,190);
-            String trendTwo = trendValues.substring(178,180) + trendValues.substring(176,178);
-            currentGlucose = Glucose_Reading(strtoul(trendNow.c_str(), NULL ,16));
-            trendOneGlucose = Glucose_Reading(strtoul(trendOne.c_str(), NULL ,16));
-            trendTwoGlucose = Glucose_Reading(strtoul(trendTwo.c_str(), NULL ,16));
-
-            if (FirstRun == 1)
-               lastGlucose = currentGlucose;
-
-            if (((lastGlucose - currentGlucose) > 50) || ((currentGlucose - lastGlucose) > 50))
-            {
-               if (((lastGlucose - trendOneGlucose) > 50) || ((trendOneGlucose - lastGlucose) > 50))
-                  currentGlucose = trendTwoGlucose;
-               else
-                  currentGlucose = trendOneGlucose;
-            }
-          }
-          else
-          {
-            String trendNow = trendValues.substring(i-10,i-8) + trendValues.substring(i-12,i-10);
-            String trendOne = trendValues.substring(i-22,i-20) + trendValues.substring(i-24,i-22);
-            String trendTwo = trendValues.substring(i-34,i-32) + trendValues.substring(i-36,i-34);
-            currentGlucose = Glucose_Reading(strtoul(trendNow.c_str(), NULL ,16));
-            trendOneGlucose = Glucose_Reading(strtoul(trendOne.c_str(), NULL ,16));
-            trendTwoGlucose = Glucose_Reading(strtoul(trendTwo.c_str(), NULL ,16));
-
-
-            if (FirstRun == 1)
-               lastGlucose = currentGlucose;
-
-            if (((lastGlucose - currentGlucose) > 50) || ((currentGlucose - lastGlucose) > 50))
-            {
-               if (((lastGlucose - trendOneGlucose) > 50) || ((trendOneGlucose - lastGlucose) > 50))
-                  currentGlucose = trendTwoGlucose;
-               else
-                  currentGlucose = trendOneGlucose;
-            }
-          }
-        }
-
-        ii++;
-      }
-
-     for (int i=8, j=0; i<200; i+=12,j++) {
-          String t = trendValues.substring(i+2,i+4) + trendValues.substring(i,i+2);
-          trend[j] = Glucose_Reading(strtoul(t.c_str(), NULL ,16));
-       }
-
-    for (int i=0; i<16; i++)
-    {
-      if (((lastGlucose - trend[i]) > 50) || ((trend[i] - lastGlucose) > 50)) // invalid trend check
-         continue;
-      else
-      {
-         validTrend[validTrendCounter] = trend[i];
-         validTrendCounter++;
-      }
-    }
-
-    if (validTrendCounter > 0)
-    {
-      for (int i=0; i < validTrendCounter; i++)
-         averageGlucose += validTrend[i];
-
-      averageGlucose = averageGlucose / validTrendCounter;
-
-      if (((lastGlucose - currentGlucose) > 50) || ((currentGlucose - lastGlucose) > 50))
-         shownGlucose = averageGlucose; // If currentGlucose is still invalid take the average value
-      else
-         shownGlucose = currentGlucose; // All went well. Take and show the current value
-    }
-    else
-      shownGlucose = currentGlucose; // If all is going wrong, nevertheless take and show a value
-
-    if ((lastGlucose == currentGlucose) && (sensorMinutesElapse > 21000)) // Expired sensor check
-      noDiffCount++;
-
-    if (lastGlucose != currentGlucose) // Reset the counter
-      noDiffCount = 0;
-
-    if (currentGlucose != 0)
-      lastGlucose = currentGlucose;
-
-    NFCReady = 2;
-    FirstRun = 0;
-
-    print_state(F(" - bg reading "));
-    Serial.print(shownGlucose);
-    Serial.print(F(", BatLev: "));
-    Serial.print(batteryPcnt);
-    Serial.print(F("%, "));
-    Serial.print(F("BatMv: "));
-    Serial.print(batteryMv);
-    Serial.print(F("mV, "));
-    Serial.print(F("SensLife: "));
-    Serial.print(sensorMinutesElapse);
-    Serial.print(F(" min elapsed"));
-
-    print_state(F(" - 15 minutes-trend: "));
-    for (int i=0; i<16; i++) {
-      Serial.print(trend[i]);
-      Serial.print(F(" "));
-      if ( i == 8 )
-        Serial.println(F(""));
-    }
-
-#ifdef USE_DEAD_SENSOR
-    // we do support tests with expired sensors!
-    noDiffCount = 0;
-#endif
-
-    if (noDiffCount > 5)
-      return 0;
-    else
-      return shownGlucose;
-    }
-  else
-    {
-    Serial.print(F("Read Memory Block Command FAIL"));
-    NFCReady = 0;
-    nfc_read_mem_errors++;
-    }
-    return(0);  // return added to avoid compiler warning
- }
-
-float Glucose_Reading(unsigned int val) {
-        int bitmask = 0x0FFF;
-        return ((val & bitmask) / 8.5);
-}
-
-/* ******************************************* */
-/* *** Vcc and sleep *** */
-/* ******************************************* */
-
-int readVcc() {
-  // Read 1.1V reference against AVcc
-  // set the reference to Vcc and the measurement to the internal 1.1V reference
-  #if defined(__AVR_ATmega32U4__) || defined(__AVR_ATmega1280__) || defined(__AVR_ATmega2560__)
-    ADMUX = _BV(REFS0) | _BV(MUX4) | _BV(MUX3) | _BV(MUX2) | _BV(MUX1);
-  #elif defined (__AVR_ATtiny24__) || defined(__AVR_ATtiny44__) || defined(__AVR_ATtiny84__)
-    ADMUX = _BV(MUX5) | _BV(MUX0);
-  #elif defined (__AVR_ATtiny25__) || defined(__AVR_ATtiny45__) || defined(__AVR_ATtiny85__)
-    ADMUX = _BV(MUX3) | _BV(MUX2);
-  #else
-    ADMUX = _BV(REFS0) | _BV(MUX3) | _BV(MUX2) | _BV(MUX1);
-  #endif
-
-  delay(2); // Wait for Vref to settle
-  ADCSRA |= _BV(ADSC); // Start conversion
-  while (bit_is_set(ADCSRA,ADSC)); // measuring
-
-  uint8_t low  = ADCL; // must read ADCL first - it then locks ADCH
-  uint8_t high = ADCH; // unlocks both
-
-  batteryMv = (high<<8) | low;
-
-  batteryMv = 1125300L / batteryMv; // Calculate Vcc (in mV); 1125300 = 1.1*1023*1000
-  int batteryLevel = min(map(batteryMv, MIN_V, MAX_V, 0, 100), 100); // Convert voltage to percentage
-  return batteryLevel;
-}
-
-void goToSleep(const byte interval, int time) {
-  // say how long we want to sleep in absolute
-  print_state(F(" - go to sleep for "));
-  Serial.print((time)*8);
-  Serial.print(F(" s - "));
-  waitDoingServices(100, 1);
-  for (int i=0; i<time; i++) {
-    MCUSR = 0;
-    WDTCSR |= 0b00011000;
-    WDTCSR =  0b01000000 | interval;
-    set_sleep_mode (SLEEP_MODE_PWR_DOWN);
-    sleep_enable();
-    sleep_cpu();
-  }
-}
-ISR(WDT_vect)
- {
- wdt_disable();
- }
-
-void lowBatterySleep() {
-
-//  shutNFCDown();
-  shutBLEDown(0);
-
-  print_state(F("Battery low! LEVEL: "));
-  Serial.print(batteryPcnt);
-  Serial.print(F("%"));
-  waitDoingServices(100, 1);
-
- // Switch LED on and then off shortly
-  for (int i=0; i<10; i++) {
-    digitalWrite(SCKPin, HIGH);
-    delay(50);
-    digitalWrite(SCKPin, LOW);
-    delay(100);
-  }
-
-  MCUSR = 0;
-  WDTCSR |= 0b00011000;
-  WDTCSR =  0b01000000 | 0b100001;
-  set_sleep_mode (SLEEP_MODE_PWR_DOWN);
-  sleep_enable();
-  sleep_cpu();
-  sleep_disable();
-  power_all_enable();
-  wdt_reset();
-}
-
-void wakeUp(void)
-{
-  sleep_disable();
-  power_all_enable();
-  wdt_reset();
-}
-
-// LimiTTer code to save battery
-void check_battery(void)
-{
-  // LimiTTer battery OK ?
-  batteryPcnt = readVcc();
-  if (batteryPcnt < 1)
-    batteryLow = 1;
-  while (batteryLow == 1)
-  {
-    lowBatterySleep();
-    batteryPcnt = readVcc();
-    if (batteryPcnt > 10)
-    {
-      batteryLow = 0;
-      wakeUp();
-//      wakeBLEUp();
-      waitDoingServices(250, 1);
-    }
-  }
-}
-
-/* ************************************************ */
-/* *** calibration of WDT oscillator *** */
-/* *** see http://forum.arduino.cc/index.php/topic,38046.0.html *** */
-/* *** and http://forum.arduino.cc/index.php?topic=49549.0 *** /
-/* ************************************************ */
-
-#ifdef AUTOCAL_WDT
-
-long timeSleep = 0;  // total time due to sleep
-float calibv = 0.93; // ratio of real clock with WDT clock
-volatile byte isrcalled = 0;  // WDT vector flag
-
-// Internal function: Start watchdog timer
-// byte psVal - Prescale mask
-void WDT_On (byte psVal)
-{
- // prepare timed sequence first
- byte ps = (psVal | (1<<WDIE)) & ~(1<<WDE);
- cli();
- wdt_reset();
- /* Clear WDRF in MCUSR */
- MCUSR &= ~(1<<WDRF);
- // start timed sequence
- WDTCSR |= (1<<WDCE) | (1<<WDE);
- // set new watchdog timeout value
- WDTCSR = ps;
- sei();
-}
-
-// Internal function.  Stop watchdog timer
-void WDT_Off() {
- cli();
- wdt_reset();
- /* Clear WDRF in MCUSR */
- MCUSR &= ~(1<<WDRF);
- /* Write logical one to WDCE and WDE */
- /* Keep old prescaler setting to prevent unintentional time-out */
- WDTCSR |= (1<<WDCE) | (1<<WDE);
- /* Turn off WDT */
- WDTCSR = 0x00;
- sei();
-}
-
-// Calibrate watchdog timer with millis() timer(timer0)
-void calibrate() {
- // timer0 continues to run in idle sleep mode
- set_sleep_mode(SLEEP_MODE_IDLE);
- long tt1=millis();
- doSleep(256);
- long tt2=millis();
- calibv = 256.0/(tt2-tt1);
-}
-
-// Estimated millis is real clock + calibrated sleep time
-long estMillis() {
- return millis()+timeSleep;
-}
-
-// Delay function
-void sleepCPU_delay(long sleepTime) {
- ADCSRA &= ~(1<<ADEN);  // adc off
- PRR = 0xEF; // modules off
-
- set_sleep_mode(SLEEP_MODE_PWR_DOWN);
- int trem = doSleep(sleepTime*calibv);
- timeSleep += (sleepTime-trem);
-
- PRR = 0x00; //modules on
- ADCSRA |= (1<<ADEN);  // adc on
-}
-
-// internal function.
-int doSleep(long timeRem) {
- byte WDTps = 9;  // WDT Prescaler value, 9 = 8192ms
-
- isrcalled = 0;
- sleep_enable();
- while(timeRem > 0) {
-   //work out next prescale unit to use
-   while ((0x10<<WDTps) > timeRem && WDTps > 0) {
-     WDTps--;
-   }
-   // send prescaler mask to WDT_On
-   WDT_On((WDTps & 0x08 ? (1<<WDP3) : 0x00) | (WDTps & 0x07));
-   isrcalled=0;
-   while (isrcalled==0) {
-     // turn bod off
-     MCUCR |= (1<<BODS) | (1<<BODSE);
-     MCUCR &= ~(1<<BODSE);  // must be done right before sleep
-     sleep_cpu();  // sleep here
-   }
-   // calculate remaining time
-   timeRem -= (0x10<<WDTps);
- }
- sleep_disable();
- return timeRem;
-}
-
-// wdt int service routine
-ISR(WDT_vect) {
- WDT_Off();
- isrcalled=1;
-}
-
-#endif /* AUTOCAL_WDT */
-
-/* ************************************************ */
-/* *** BLE handling *** */
-/* ************************************************ */
-
-// init HM-1x module
-int setupBLE()
-{
-  int i;
-
-  //detect HM-1x baudrate, if not currently set
-  print_state(F(" - determining HM-1x baudrate"));
-
-  for( i = 0 ; i <= 8 ; i++ ) {
-    init_command_buff(&command_buff);
-    print_state(F(" - trying ")); Serial.print(uart_baudrate[i]);
-    settings.uart_baudrate = uart_baudrate[i];
-    ble_Serial.begin(uart_baudrate[i]);
-    send_string(F("AT"), 100);
-    if ( waitDoingServicesInterruptible(500,&got_ok,1) )
-      break;
-  }
-
-  if(!got_ok){
-    print_state(F("Could not detect baudrate of HM-1x, setting 9600"));
-    settings.uart_baudrate=9600;
-    resetBLE();
-    return(0);
-  }
-
-  print_state(F(" - baudrate set to "));
-  Serial.print(settings.uart_baudrate);
-  init_command_buff(&command_buff);
-  return(1);
-}
-
-// Configure the BlueTooth module with a name.
-// from LimiTTer setp() moved to here
-void configBLE() {
-  send_string(F("AT"), 100);        // cut BLE connection to do commands
-  send_ble_string(F("AT+RENEW"));   // restore factory defaults
-  send_ble_string(F("AT+IMME1"));   // be sure not to be connected before the AT commands are done
-  send_ble_string(LNAME);           // set unique LimiTTer name, max 11 (not 12) chars
-  send_ble_string(F("AT+VERR?"));   // look for correct BLE module - answer schould be "HMSoft V54x"
-                                    // to detect fake modules which starts with 115200
-  send_ble_string(F("AT+ADDR?"));   // get MAC address
-  send_ble_string(F("AT+NOTI1"));   // notify CONNECT and LOST
-  send_ble_string(F("AT+RESET"));   // reset the module
-  waitDoingServices(500, 1);
-  if ( !ble_connected )
-    send_string(F("AT+START"), 200);  // all AT commands done, now we can connect
-}
-
-void resetBLE(void)
-{
-  print_state(F(" - reset BLE, power down - 500 ms - power up - 500 ms"));
-
-  digitalWrite(5, LOW); // Disable this for Android 4
-  digitalWrite(6, LOW); // Disable this for Android 4
-  digitalWrite(BLEPin, LOW); // Disable this for Android 4
-
-  waitDoingServices(500, 1);
-
-  digitalWrite(BLEPin, HIGH);
-  digitalWrite(5, HIGH);
-  digitalWrite(6, HIGH);
-
-  waitDoingServices(500, 1);
-
-}
-
-void wakeBLEUp(void)
-{
-  digitalWrite(BLEPin, HIGH);
-  digitalWrite(5, HIGH);
-  digitalWrite(6, HIGH);
-
-  ble_start_time = millis();
-  ble_connected = 0;
-#ifdef HW_BLE
-  hwble_connected = 0;
-#endif
-
-  // wait 1 s for initial connect, time for a fast BLE connect
-  waitDoingServicesInterruptible(1000, &ble_connected, 1);
-
-//  send_string(F("AT"), 100);        // cut BLE connection to do commands
-  send_ble_string(F("AT+RENEW"));   // restore factory defaults
-  send_ble_string(F("AT+IMME1"));   // first do all AT commands
-  send_ble_string(LNAME);           // set unique LimiTTer name, max 11 (not 12) chars
-  send_ble_string(F("AT+NOTI1"));   // notify CONNECT and LOST
-  send_ble_string(F("AT+RESET"));   // reset the BLE module
-  waitDoingServices(500, 1);
-  if ( !ble_connected )
-    send_string(F("AT+START"), 200);  // all AT commands done, now we can connect
-
-  print_state(F(" - wake up - wait 40 s for BLE\r\n"));
-  int i;
-  for ( i = 0 ; i < 40 ; i++) {
-    waitDoingServices(1000, 1);
-    // typical CONN/LOST time difference is 1 - 2 s, mostly happens at the beginning of loop
-    // wait for this 2 s before break
-    if ( ble_connected ) {
-      print_state(F(" - connected, wait to manage CONN+LOST cyle then send packet(s)"));
-      // LOST on CONN mostly after 800 - 900 ms
-      waitDoingServices(2000, 1);
-      break;
-    }
-  }
-
-  // must be connected here to start communication
-  if ( !ble_connected )
-    ble_connect_errors++;
-
-  // send error counters to xDrip+ for future use
-#ifdef SEND_ERROR_COUNTERS
-  if ( ble_connected && send_error_counters_via_ble ) {
-    ble_Serial.print(F("E"));
-    ble_Serial.print(loop_count);
-    ble_Serial.print(F(" "));
-    ble_Serial.print(ble_connect_errors);
-    ble_Serial.print(F(" "));
-    ble_Serial.print(nfc_prot_set_cmd_errors);
-    ble_Serial.print(F(" "));
-    ble_Serial.print(nfc_inv_cmd_errors);
-    ble_Serial.print(F(" "));
-    ble_Serial.print(nfc_read_mem_errors);
-    ble_Serial.print(F(" "));
-    ble_Serial.print(resend_pkts_events);
-    ble_Serial.print(F(" "));
-    ble_Serial.print(queue_events);
-    send_error_counters_via_ble = 0;
-  }
-#endif
-}
-
-void shutBLEDown(boolean quit_ble)
-{
-  // cut BLE conection via AT command
-  if ( quit_ble && ble_connected ) {
-    print_state(F(" - disconnect BLE, wait 2 s then sleep"));
-    ble_lost_processing = 0;
-    send_string(F("AT"), 100);
-    waitDoingServices(1500, 1);
-    ble_lost_processing = 0;
-  }
-
-  digitalWrite(5, LOW); // Disable this for Android 4
-  digitalWrite(6, LOW); // Disable this for Android 4
-  digitalWrite(BLEPin, LOW); // Disable this for Android 4
-
-  ble_connected = 0;
-#ifdef HW_BLE
-  hwble_connected = 0;
-#endif
-}
-
-/* ************************************************** */
-/* *** NFC handling *** */
-/* ************************************************** */
-
-// new function to fit Limitter in xBridge concept, called from loop(), formerly in setup()
-void configNFC(void)
-{
-  SPI.begin();
-
-  SPI.setDataMode(SPI_MODE0);
-  SPI.setBitOrder(MSBFIRST);
-  SPI.setClockDivider(SPI_CLOCK_DIV32);
-
-  delay(10);                      // send a wake up
-  digitalWrite(IRQPin, LOW);      // pulse to put the
-  delayMicroseconds(100);         // BM019 into SPI
-  digitalWrite(IRQPin, HIGH);     // mode
-  delay(10);
-  digitalWrite(IRQPin, LOW);
-
-  SPI.end();    // according to Bert Roode 170227. Nested SPI.begin() and SPI.end()
-}
-
-void wakeNFCUp(void)
-{
-// print_state(F(" - mem avail "));
-// Serial.print(freeMemory());
-
-  digitalWrite(NFCPin1, HIGH);
-  digitalWrite(NFCPin2, HIGH);
-  digitalWrite(NFCPin3, HIGH);
-  digitalWrite(IRQPin, HIGH);
-
-  SPI.begin();
-
-  SPI.setDataMode(SPI_MODE0);
-  SPI.setBitOrder(MSBFIRST);
-  SPI.setClockDivider(SPI_CLOCK_DIV32);
-  delay(10);
-  digitalWrite(IRQPin, LOW);
-  delayMicroseconds(100);
-  digitalWrite(IRQPin, HIGH);
-  delay(10);
-  digitalWrite(IRQPin, LOW);
-
-  NFCReady = 0;
-}
-
-void shutNFCDown(void)
-{
-// print_state(F(" - mem avail "));
-// Serial.print(freeMemory());
-
-  SPI.end();
-
-  digitalWrite(MOSIPin, LOW);
-  digitalWrite(SCKPin, LOW);
-  digitalWrite(NFCPin1, LOW); // Turn off all power sources completely
-  digitalWrite(NFCPin2, LOW); // for maximum power save on BM019.
-  digitalWrite(NFCPin3, LOW);
-  digitalWrite(IRQPin, LOW);
-}
-
-/* ****************************************************************** */
-/* port of xBridge2 code */
-/* ***************************************************************** */
-
-// send data to BLE
-void send_data(unsigned char *msg, unsigned char len)
-{
-  unsigned char i = 0;
-
-  for( i = 0; i < len; i++ )
-    ble_Serial.write(msg[i]);
-
-  // wait up to 40 chars (@9600)
-  delay(40);
-  print_state(F(" - sending: <"));
-  for ( i = 0 ; i < len ; i++ ) {
-    Serial.print(msg[i], HEX);
-    Serial.print(F(" "));
-  }
-  Serial.print(F(">"));
-  print_state(F(" - response: "));
-}
-
-// due to Arduino cast problems between String and char * use extra function
-int send_ble_string(String cmd)
-{
-  int i;
-  unsigned long now;
-  boolean timeout;
-
-  if ( !ble_connected ) {
-    for ( i = 0 ; i < 3 ; i++ ) {
-      if ( show_ble ) {
-        print_state(F(" ->("));
-        Serial.print(cmd);
-        Serial.print(F(") - "));
-      }
-
-      ble_Serial.print(cmd);
-
-      now = millis();
-      ble_answer = 0;
-      timeout = 1;
-
-      while ( (millis() - now) < 2000 ) {
-        waitDoingServices(30, 1);
-        if ( ble_answer == 2 ) {
-          ble_answer = 0;
-          timeout = 0;
-          break;
-        }
-      }
-      waitDoingServices(100, 1);
-
-      if ( timeout ) {
-        resetBLE();
-      }
-      else
-        return(1);
-    }
-    return(0);
-  }
-  return(0);
-}
-
-void send_string(String cmd, int dly)
-{
-  ble_Serial.print(cmd);
-  if ( show_ble ) {
-    print_state(F(" ->("));
-    Serial.print(cmd);
-    Serial.print(F(") - "));
-  }
-  waitDoingServices(dly, 1);
-}
-
-// send a beacon with the TXID
-void sendBeacon(void)
-{
-  //char array to store the response in.
-  unsigned char cmd_response[7];
-  //return if we don't have a connection or if we have already sent a beacon
-  //prepare the response
-  //responding with number of bytes,
-  cmd_response[0] = sizeof(cmd_response);
-  //responding to command 01,
-  cmd_response[1] = 0xF1;
-  //return the encoded TXID
-  memcpy(&cmd_response[2], &settings.dex_tx_id, sizeof(settings.dex_tx_id));
-  cmd_response[6] = DEXBRIDGE_PROTO_LEVEL;
-  send_data(cmd_response, sizeof(cmd_response));
-}
-
-int init_command_buff(t_command_buff* pCmd)
-{
-  if(!pCmd)
-    return 0;
-  memset(pCmd->commandBuffer, 0, COMMAND_MAXLEN);
-  pCmd->nCurReadPos = 0;
-  return 0;
-}
-
-//decode a command received ??
-int commandBuffIs(char* command)
-{
-  unsigned char len = strlen(command);
-  if(len != command_buff.nCurReadPos)
-    return(0);
-  return( memcmp(command, command_buff.commandBuffer, len)==0 );
-}
-
-// decode incoming serial/USB or BLE data commands
-int doCommand(void)
-{
-  // TXID packet?
-  if(command_buff.commandBuffer[1] == 0x01 && command_buff.commandBuffer[0] == 0x06)
-  {
-    memcpy(&settings.dex_tx_id, &command_buff.commandBuffer[2],sizeof(settings.dex_tx_id));
-    // send back the TXID we think we got in response
-    return(0);
-  }
-  // ACK packet?
-  if(command_buff.commandBuffer[0] == 0x02 && command_buff.commandBuffer[1] == 0xF0 && !got_ack) {
-    got_ack = 1;
-    init_command_buff(&command_buff);
-    return(0);
-  }
-  if( toupper(command_buff.commandBuffer[0]) == 'B' ) {
-    if ( show_ble ) {
-      print_state(F(" - B command - dont show BLE communication"));
-      show_ble = 0;
-    }
-    else {
-      print_state(F(" - B command - show BLE communication"));
-      show_ble = 1;
-    }
-  }
-  if( toupper(command_buff.commandBuffer[0]) == 'S' ) {
-    if ( show_state ) {
-      print_state(F(" - S command - dont show states"));
-      show_state = 0;
-    }
-    else {
-      show_state = 1;
-      print_state(F(" - S command - show states"));
-    }
-  }  // "OK+..." answer from BLE?
-  if( commandBuffIs("OK") )
-  {
-    got_ok = 1;;
-    return(0);
-  }
-  // we don't respond to unrecognised commands.
-  return(1);
-}
-
-typedef struct {
-  unsigned char pattern[8];   // pattern string including '\0'
-} t_pattern;
-
-t_pattern okstr[3] = {
-  { "OK+CONN" },  // HM-1x answer when BLE connection is active
-  { "OK+LOST" },  // HM-1x answer when BLE connection is disconnected
-  { "OK+ERRS" }   // message sent via BLE to force LBridge to send error counters via BLE
-};
-
-#ifdef HW_BLE
-// detect BLE connection status via SysLED pin on HM-1x module
-void bleConnectMonitor() {
-  //to store the time we went high
-  static unsigned long timer;
-  //to store P1_2 the last time we looked.
-  static boolean last_ble_check;
-  boolean last_ble;
-
-  last_ble = hwble_connected;
-  // if P1_2 is high, ble_connected is low, and the last_ble_check was low, sav the time and set last_ble_check.
-  if ( digitalRead(bleSysLedPin) && !hwble_connected && !last_ble_check) {
-    timer = millis();
-    last_ble_check = 1;
-  // otherwise if P1_2 goes low, and ble_connected is high, we cancel everything.
-  } else if ( !digitalRead(bleSysLedPin) ) {
-    hwble_connected =0;
-    last_ble_check = 0;
-  //otherwise, if P1_2 has been high for more than 550ms, we can safely assume we have ble_connected, so say so.
-  } else if ( digitalRead(bleSysLedPin) && last_ble_check && ((millis() - timer)>550)) {
-    hwble_connected = 1;
-  }
-
-  // show if BLE state has changed here
-  if ( last_ble != hwble_connected ) {
-    print_state(F(" - ***** HW BLE "));
-    if ( hwble_connected )
-      Serial.print(F("connected"));
-    else
-      Serial.print(F("lost"));
-  }
-}
-#endif /* HW_BLE */
-
-// detect BLE connection status via software / AT commands
-boolean monitor_ble(unsigned char b)
-{
-  static int bi = 0;
-  int i, c_found = 0;
-
-  if ( show_ble ) {
-    if ( b >= ' ' && b < 128 ) {
-      Serial.write(b);
-    }
-    else {
-      Serial.print(b, HEX);
-      Serial.print(F(" "));
-    }
-  }
-
-  for ( i = 0 ; i < 3 ; i++) {
-    if ( b == okstr[i].pattern[bi] )
-      c_found |= 1;
-  }
-
-  if ( c_found )
-    bi++;
-  else
-    bi = 0;
-
-  if ( bi == 7 ) { // one of pattern complete
-    bi = 0;
-    if ( b == okstr[0].pattern[6] ) {
-        ble_connected = 1;
-        print_state(F(" - +++++ BLE connected after "));
-        ble_connect_time = millis();
-        Serial.print( millis() - ble_start_time );
-        Serial.print(F(" ms"));
-        return(1);
-    } else if ( b == okstr[1].pattern[6] ) {
-        ble_connected = 0;
-        ble_connect_time = 0;
-        print_state(F(" - +++++ BLE lost after "));
-        Serial.print( millis() - ble_start_time );
-        Serial.print(F(" ms"));
-
-        // ??? test
-        if ( ble_lost_processing )
-          send_string(F("AT+RESET"), 500);
-
-        return(1);
-    } else if ( b == okstr[2].pattern[6] ) {
-#ifdef SEND_ERROR_COUNTERS
-        send_error_counters_via_ble = 1;
-        print_state(F(" - send error counters after next wakeup"));
-        return(1);
-#endif
-    }
-  }
-  return(0);
-}
-
-// Process any commands from BLE
-int controlProtocolService()
-{
-  static unsigned long cmd_to;
-  // ok this is where we check if there's anything happening incoming on the USB COM port or UART 0 port.
-  int nRet = 1;
-  int i;
-  unsigned char b;
-
-  //if we have timed out waiting for a command, clear the command buffer and return.
-  if(command_buff.nCurReadPos > 0 && (millis() - cmd_to) > 2000)
-  {
-    print_state(F(" - got <-["));
-    for ( i = 0 ; i  < command_buff.nCurReadPos ; i++ )
-    if ( command_buff.commandBuffer[0] >= ' ') {
-      Serial.write(command_buff.commandBuffer[i]);
-    }
-    else {
-      Serial.print(F("0x"));
-      Serial.print(command_buff.commandBuffer[i], HEX);
-      Serial.print(F(" "));
-    }
-    Serial.print(F("]"));
-    // clear command buffer if there was anything
-    init_command_buff(&command_buff);
-    return(nRet);
-  }
-  //while we have something in either buffer,
-  while( (Serial.available() || ble_Serial.available()) && command_buff.nCurReadPos < COMMAND_MAXLEN) {
-
-    if ( ble_answer == 0 ) {
-//      Serial.print("-1-");
-      ble_answer = 1;
-    }
-
-    if ( ble_Serial.available() )
-      monitor_ble( b = ble_Serial.read() );
-    else
-      b = Serial.read();
-
-    command_buff.commandBuffer[command_buff.nCurReadPos] = b;
-    command_buff.nCurReadPos++;
-    cmd_to = millis();
-    // if it is the end for the byte string, we need to process the command
-    // valid data packet or "OK" received?
-    if(      command_buff.nCurReadPos == command_buff.commandBuffer[0] \
-         || (command_buff.commandBuffer[0] == 'O' && command_buff.commandBuffer[1] == 'K' ) \
-         || (command_buff.nCurReadPos == 1 && toupper(command_buff.commandBuffer[0]) == 'B') \
-         || (command_buff.nCurReadPos == 1 && toupper(command_buff.commandBuffer[0]) == 'S') )
-     {
-      // ok we got the end of a command;
-      if(command_buff.nCurReadPos) {
-        // do the command
-        nRet = doCommand();
-        //re-initialise the command buffer for the next one.
-        init_command_buff(&command_buff);
-        // break out if we got a breaking command
-        if(!nRet)
-          return(nRet);
-      }
-    }
-    // otherwise, if the command is not up to the maximum length, add the character to the buffer.
-  }
-
-  if ( ble_answer == 1 ) {
-//    Serial.print("-2-");
-    ble_answer = 2;
-  }
-
-  if ( command_buff.nCurReadPos ){
-    //re-initialise the command buffer for the next one.
-    init_command_buff(&command_buff);
-  }
-  return(nRet);
-}
-
-// process each of the services we need to be on top of.
-// if bWithProtocol is true, also check for commands on both USB and UART
-int doServices(unsigned char bWithProtocol)
-{
-  dex_tx_id_set = (settings.dex_tx_id != 0);
-#ifdef HW_BLE
-  bleConnectMonitor();
-#endif
-  if(bWithProtocol)
-    return(controlProtocolService());
-  return(1);
-}
-
-#ifdef DYNAMIC_TXID
-//format an array to decode the dexcom transmitter name from a Dexcom packet source address.
-char SrcNameTable[32] = { '0', '1', '2', '3', '4', '5', '6', '7',
-              '8', '9', 'A', 'B', 'C', 'D', 'E', 'F',
-              'G', 'H', 'J', 'K', 'L', 'M', 'N', 'P',
-              'Q', 'R', 'S', 'T', 'U', 'W', 'X', 'Y' };
-
-char dex_addr[6];
-
-// convert the passed uint32 Dexcom source address into an ascii string in the passed char addr[6] array.
-char *dexcom_src_to_ascii(unsigned long src)
-{
-  //each src value is 5 bits long, and is converted in this way.
-  dex_addr[0] = SrcNameTable[(src >> 20) & 0x1F];   //the last character is the src, shifted right 20 places, ANDED with 0x1F
-  dex_addr[1] = SrcNameTable[(src >> 15) & 0x1F];   //etc
-  dex_addr[2] = SrcNameTable[(src >> 10) & 0x1F];   //etc
-  dex_addr[3] = SrcNameTable[(src >> 5) & 0x1F];    //etc
-  dex_addr[4] = SrcNameTable[(src >> 0) & 0x1F];    //etc
-  dex_addr[5] = 0;  //end the string with a null character.
-  return (char *)dex_addr;
-}
-
-unsigned long asciiToDexcomSrc(char addr[6])
-{
-  // prepare a uint32 variable for our return value
-  unsigned long src = 0;
-  // look up the first character, and shift it 20 bits left.
-  src |= (getSrcValue(addr[0]) << 20);
-  // look up the second character, and shift it 15 bits left.
-  src |= (getSrcValue(addr[1]) << 15);
-  // look up the third character, and shift it 10 bits left.
-  src |= (getSrcValue(addr[2]) << 10);
-  // look up the fourth character, and shift it 50 bits left.
-  src |= (getSrcValue(addr[3]) << 5);
-  // look up the fifth character
-  src |= getSrcValue(addr[4]);
-  //printf("asciiToDexcomSrc: val=%u, src=%u\r\n", val, src);
-  return src;
-}
-
-/* getSrcValue - function to determine the encoding value of a character in a Dexcom Transmitter ID.
-Parameters:
-srcVal - The character to determine the value of
-Returns:
-uint32 - The encoding value of the character.
-*/
-unsigned long getSrcValue(char srcVal)
-{
-  unsigned char i = 0;
-
-  for(i = 0; i < 32; i++)
-  {
-    if (SrcNameTable[i]==srcVal) break;
-  }
-  //printf("getSrcVal: %c %u\r\n",srcVal, i);
-  return i & 0xFF;
-}
-#endif /* DYNAMIC_TXID */
-
-// use function instead of macro, use pointer to flag, volatile boolen <var> dont work on Arduino!!!
-int waitDoingServicesInterruptible(unsigned long wait_time, volatile boolean *break_flag, unsigned char bProtocolServices)
-{
-  unsigned long start_wait = millis();
-  while ( (millis() - start_wait ) < wait_time ) {
-    doServices(bProtocolServices);
-    if ( *break_flag ) {
-      return(1);
-    }
-    delay(20);
-  }
-  return(0);
-}
-
-void waitDoingServices(unsigned long wait_time, unsigned char bProtocolServices)
-{
-  unsigned long start_wait = millis();
-  while ( (millis() - start_wait ) < wait_time )
-  {
-    doServices(bProtocolServices);
-    delay(20);
-  }
-}
-
-// help function to read the Freestyle Libre sensor
-// in LimiTter part of loop(), moved to reuse xBridge code
-int get_nfc_reading(float *ptr)
-{
-  // store the current wixel milliseconds so we know how long we are waiting.
-  unsigned long start = millis();
-  unsigned long ms = 3000;  // try for 3 seconds, then leave
-  // set the return code to timeout indication, as it is the most likely outcome.
-  float act_glucose;
-
-  // while we haven't reached the delay......
-  while ( (millis() - start) < ms ) {
-    if (NFCReady == 0) {
-      SetProtocol_Command(); // ISO 15693 settings
-      waitDoingServices(100, 1);
-      continue;
-    }
-    else if (NFCReady == 1) {
-      for (int i=0; i<3; i++) {
-        Inventory_Command(); // sensor in range?
-        nfc_inv_cmd_count++;
-        if (NFCReady == 2)
-          break;
-        waitDoingServices(1000, 1);
-      }
-      if (NFCReady == 1) {
-        // count missed readings
-        nfc_read_errors++;
-        print_state(F(" - NFC timed out"));
-        return(0);
-      }
-    }
-    else if ( NFCReady == 2 ) {
-      act_glucose = Read_Memory();
-      nfc_scan_count++;
-#ifdef SHOW_LIMITTER
-      Serial.print(F("\r\nGlucose level: "));
-      Serial.println(act_glucose);
-      Serial.println(F("15 minutes-trend: "));
-      for (int i=0; i<16; i++)
-        Serial.println(trend[i]);
-      Serial.print(F("Battery level: "));
-      Serial.print(batteryPcnt);
-      Serial.println(F("%"));
-      Serial.print(F("Battery mVolts: "));
-      Serial.print(batteryMv);
-      Serial.println(F("mV"));
-      Serial.print(F("Sensor lifetime: "));
-      Serial.print(sensorMinutesElapse);
-      Serial.print(F(" minutes elapsed"));
-#endif /* SHOW_LIMITTER */
-      // only for showing package content
-      *ptr = act_glucose;
-      return(1);
-    }
-  }
-  // timeout
-  return(0);
-}
-
-// wait for a NFC reading and put it into Dexcom_packet
-int get_packet(Dexcom_packet* pPkt)
-{
-  // store the current wixel milliseconds so we know how long we are waiting.
-  unsigned long start = millis();
-  // set the return code to timeout indication, as it is the most likely outcome.
-  float glucose;
-
-  if ( get_nfc_reading(&glucose) ) {
-    pPkt->raw = glucose*1000;    // use C casting for conversion of float to unsigned long
-    pkt_time = millis();
-    pPkt->ms = abs_millis();
-/*
-    print_state(F(" - packet read at "));
-    Serial.print(pPkt->ms/1000);
-    Serial.print(F(" s"));
-*/
-    if ( abs_pkt_time != 0 )
-      last_abs_pkt_time = abs_pkt_time;
-    abs_pkt_time = pPkt->ms;
-/*
-    print_state(F(" - last packet read "));
-    Serial.print((abs_millis() - last_abs_pkt_time)/1000);
-    Serial.print(F(" s before"));
-*/
-    return(1);
-  }
-  else
-    pkt_time = millis();    // to avoid endless waiting if no packet can be read
-  return(0);
-}
-
-//function to format and send the passed Dexom_packet.
-int print_packet(Dexcom_packet* pPkt)
-{
-  RawRecord msg;
-
-  //prepare the message
-  msg.size = sizeof(msg);
-  msg.cmd_code = 0x00;
-  msg.raw = pPkt->raw;
-  msg.filtered = pPkt->raw;
-  msg.dex_battery = 214;  // simulate good dexcom transmitter battery
-  msg.my_battery = batteryPcnt;
-  msg.dex_src_id = settings.dex_tx_id;
-  msg.delay = abs_millis() - pPkt->ms;
-  msg.function = DEXBRIDGE_PROTO_LEVEL; // basic functionality, data packet (with ack), TXID packet, beacon packet (also TXID ack).
-
-  if ( !ble_connected )
-    return(0);
-/*
-  print_state(F(" - sending packet with a delay of "));
-  Serial.print(msg.delay/1000);
-  Serial.print(F(" s"));
-*/
-  send_data( (unsigned char *)&msg, msg.size);
-
-  return(1);
-}
-
-// print timestamp and current status/action
-void print_state(String str)
-{
-  Serial.println(F(""));
-  Serial.print(millis());
-  Serial.print(str);
-}
-
-// main processing loop
-void loop(void)
-{
-  int i;
-  unsigned long var_sleepTime;
-  boolean evtflg1;
-  boolean evtflg2;
-  int get_packet_result;
-
-  waitDoingServices(2000, 1);
-
-  print_state(F(" - ************************"));
-  print_state(F(" - *** LBridge starting ***"));
-//  print_state(F(" - *** Version )); Serial.print(LNAME); Serial.print(F(" ***"));
-  print_state(F(" - *** mem: "));
-  Serial.print(freeMemory()); Serial.print(F(" ***"));
-  print_state(F(" - ************************"));
-
-  loop_start_time = millis();             // log the current time
-  init_command_buff(&command_buff);       //initialise the command buffer
-
-  for ( i = 0 ; i < 3 ; i++ ) {
-    if ( setupBLE() )                 // Open the UART and initialize HM-1x module
-      break;
-  }
-
-  waitDoingServices(2000, 1); // wait for possible OK+LOST
-  configBLE();                // configure the BLE module
-  configNFC();                // initialize and configure the NFC module
-
-  // wait for a BLE connection to xDrip to get a TXID if needed
-  print_state(F(" - initial wake up, waiting 40s fixed for BLE / time for a xDrip+ BT scan if needed\r\n"));
-  waitDoingServices(40000, 1);
-
-  // if BLE connected wait some time to get an answer for TXID
-  if ( ble_connected )
-    waitDoingServices(3000, 1);
-
-#ifdef DYNAMIC_TXID
-  // if dex_tx_id is zero, we do not have an ID to filter on.  So, we keep sending a beacon every 5 seconds until it is set.
-  print_state(F(" - testing TXID"));
-  settings.dex_tx_id = 0xFFFFFFFF;
-  // should we ask for a TXID?
-  if(settings.dex_tx_id >= 0xFFFFFFFF)
-    settings.dex_tx_id = 0;
-  // instead of save current TXID to EEPROM get it every time from xDrip using the Beacon mechanism
-  while(settings.dex_tx_id == 0) {
-    print_state(F(" - no TXID. Sending beacon"));
-    // wait until we have a BLE connection
-//    while(!ble_connected) doServices(1);
-    if ( !waitDoingServicesInterruptible(40000, &ble_connected, 1) && (settings.dex_tx_id != 0) )
-      break;
-    waitDoingServices(1000, 1);
-    //send a beacon packet
-    sendBeacon();
-    // set flag dex_tx_id_set
-    doServices(0);
-    //wait 5 seconds, beatify output
-    waitDoingServicesInterruptible(5000, &dex_tx_id_set, 1);
-  }
-
-  print_state(F(" - new TXID is ")); Serial.print(settings.dex_tx_id, HEX); Serial.print(F(" ("));
-  // and show first 5 char from the TXID setting in xDrips menue
-  Serial.print(dexcom_src_to_ascii(settings.dex_tx_id)); Serial.print(F(")"));
-
-#else
-  settings.dex_tx_id = 0xA5B1AE;    // -> "ABCDE" xBridge Wixel default
-#endif /* DYNAMIC_TXID */
-
-  // initialize to empty queue
-  Pkts.read = 0;
-  Pkts.write = 0;
-
-  print_state(F(" - entering main loop"));
-
-  while (1)
-  {
-    check_battery();    // check for low battery and go to sleep here if wrong
-//    print_state(F(" - wake up NFC"));
-    wakeNFCUp();
-    get_packet_result = get_packet(&Pkts.buffer[Pkts.write]);
-//    print_state(F(" - shut NFC down"));
-    shutNFCDown();
-
-    if ( sensor_oor )
-      print_state(F(" - sensor out of range"));
-
-    if( get_packet_result ) {
-      print_state(F(" - got packet, stored at position "));
-      Serial.print(Pkts.write);
-      Serial.print(F(", incrementing write to "));
-      // so increment write position for next round...
-      if ( ++Pkts.write >= DXQUEUESIZE )
-        Pkts.write = 0;
-      Serial.print(Pkts.write);
-      if (Pkts.read == Pkts.write) {
-        print_state(F(" - queue overflow, incrementing read overwriting oldest entry"));
-        if ( ++Pkts.read >= DXQUEUESIZE ) //overflow in ringbuffer, overwriting oldest entry, thus move read one up
-          Pkts.read = 0;
-      }
-
-      do_sleep = 1; // we got a packet, so we are aligned with the 5 minute interval - so go to sleep after sending out packets
-    }
-    else {
-      print_state(F(" - did not receive a pkt with "));
-      Serial.print(Pkts.write-Pkts.read);
-      Serial.print(F(" pkts in queue"));
-//      if ( ble_connected )
-//        sendBeacon();
-      do_sleep = 1; // no NFC reading, go to sleep to save battery
-    }
-
-    if ( (loop_count > 0) && !sensor_oor ) {
-//      print_state(F(" - wake up BLE"));
-      wakeBLEUp();
-    }
-
-    if ( (Pkts.read != Pkts.write) && !sensor_oor ) { // if we have a packet
-      // we wait up to 40 s for BLE connect
-      while (!ble_connected && ((millis() - pkt_time) < 40000 )) {
-        print_state(F(" - packet waiting for ble connect"));
-        if ( waitDoingServicesInterruptible(10000, &ble_connected, 1) ) {
-          print_state(F(" - connected, wait before sending the packet"));
-          waitDoingServices(2000, 1);
-        }
-      }
-
-      evtflg1 = 0;
-      evtflg2 = 0;
-      // we got a connection, so send pending packets now - at most for two minutes after the last packet was received
-      // wait enough time to empty the complete queue!
-      while ((Pkts.read != Pkts.write) && ble_connected && ((millis() - pkt_time) < ((DXQUEUESIZE+1)*1000) )) {
-        got_ack = 0;
-
-        print_packet(&Pkts.buffer[Pkts.read]);
-
-        // wait 10 s for ack
-        int j;
-        for ( j = 0 ; j < 10 ; j++ ) {
-          waitDoingServicesInterruptible(1000, &got_ack, 1);
-          if ( !ble_connected ) {
-            print_state(F(" - connection lost during wait for ack, go to sleep"));
-            break;
-          }
-        }
-
-        if (got_ack) {
-          print_state(F(" - got ack for read position "));
-          Serial.print(Pkts.read); Serial.print(F(" while write is "));
-          Serial.print(Pkts.write); Serial.print(F(", incrementing read to "));
-          if ( ++Pkts.read >= DXQUEUESIZE )
-            Pkts.read = 0;     //increment read position since we got an ack for the last package
-          Serial.print(Pkts.read);
-          if ( !evtflg1 && (Pkts.read != Pkts.write) ) {  // when still available we have a queue event
-            evtflg1 = 1;
-            queue_events++;
-          }
-        }
-        else {
-          print_state(F(" - no ack received, try again next wakeup"));
-          if ( !evtflg2 ) {
-            evtflg2 = 1;
-            resend_pkts_events++;   // we got no ACK, pkts to be resended
-          }
-          break;
-        }
-      }
-    }
-
-    // can't safely sleep if we didn't get an ACK, or if we are already sleeping!
-    if ( do_sleep )
-    {
-      // empty serial out buffer and open tasks
-      waitDoingServices(500, 1);
-
-      // ensure to use 300 s for a full cycle of loop() and sleeping
-      loop_time = millis() - loop_start_time;
-      if ( loop_time < 290000 )
-        var_sleepTime = (((300000 - loop_time)/1000)+4) / 8;
-      else
-        var_sleepTime = 32;
-
-      print_state(F(" - loop time ")); Serial.print(loop_time); Serial.print(F(" ms, sleep for "));
-      Serial.print(var_sleepTime*8); Serial.print(F("s"));
-      Serial.print(F(", complete loop is ")); Serial.print((loop_time+var_sleepTime*8000)/1000);
-      Serial.print(F(" s"));
-
-      shutBLEDown(1);          // cut BLE connection and switch HM-1x OFF
-
-      goToSleep(0b100001, var_sleepTime);    // mask for 8s
-
-      // waking up, power on BLE, initialze NFC
-      // count programm run time up
-      prg_run_time += (loop_time + var_sleepTime*8000)/1000;
-      loop_start_time = millis();       // set start point for loop
-      do_sleep = 0;                     // clear do_sleep, cause we have just woken up.
-      init_command_buff(&command_buff); // no BLE connection
-
-      print_state(F(" - ******************************************************************"));
-      print_state(F(" - loop ")); Serial.print(++loop_count);
-      Serial.print(F(" BLE conn errors ")); Serial.print(ble_connect_errors);
-      Serial.print(F(" run time ")); Serial.print(prg_run_time); Serial.print(F(" s"));
-      print_state(F(" - InvCmdErr ")); Serial.print(nfc_inv_cmd_errors);
-      Serial.print(F(" ProtCmdErr ")); Serial.print(nfc_prot_set_cmd_errors);
-      Serial.print(F(" ReadMem Err ")); Serial.print(nfc_read_mem_errors);
-      Serial.print(F(" NFC scans ")); Serial.print(nfc_scan_count);
-      print_state(F(" - ResndPktEvt ")); Serial.print(resend_pkts_events);
-      Serial.print(F(" QueueEvt ")); Serial.print(queue_events);
-
-      if ( loop_count > 1 ) {
-        avg_sleepTime += var_sleepTime*8;
-        bleTime += loop_time;
-      }
-      else {
-        avg_sleepTime = 0;
-        bleTime = 0;
-      }
-      print_state(F(" - avg. sleep time: "));  Serial.print(avg_sleepTime/loop_count);
-      Serial.print(F(" s, "));
-      Serial.print(F("ProMini+BLE On: "));  Serial.print((bleTime/loop_count)/1000);
-      Serial.print(F(" s"));
-
-      wakeUp();
-      waitDoingServices(250,1);
-    }
-  }
-}
-
-


Add in XBee transmission of data and NAN values for missing sensors.


Added module PCB version 3

Added module PCB version 3

--- HMTL_Modules/HMTL_Bringup/HMTL_Bringup.ino
+++ HMTL_Modules/HMTL_Bringup/HMTL_Bringup.ino
@@ -23,9 +23,9 @@
 /******/

 /* VERSION specific values ***************************************************/
-#define HMTL_VERSION 1
-
-#if HMTL_VERSION == 1
+#define HMTL_VERSION 3
+
+#if (HMTL_VERSION == 1)
 #define RED_LED    9
 #define GREEN_LED 10
 #define BLUE_LED  11
@@ -38,7 +38,7 @@

 #define DATA_PIN 12
 #define CLOCK_PIN 8
-#elif (HMTL_VERSION == 2) || (HMTL_VERSION == 3)
+#elif (HMTL_VERSION == 2)
 #define RED_LED   10
 #define GREEN_LED 11
 #define BLUE_LED  13
@@ -49,10 +49,21 @@

 #define DATA_PIN 12
 #define CLOCK_PIN 8
+#elif (HMTL_VERSION == 3)
+#define RED_LED   11
+#define GREEN_LED 13
+#define BLUE_LED  10
+
+#define PIN_RS485_1  4
+#define PIN_RS485_2  7
+#define PIN_RS485_3  5
+
+#define DATA_PIN 12
+#define CLOCK_PIN 8
 #endif

 /* Board specific values */
-#define DEVICE_ID  0x10
+#define DEVICE_ID  0x0011

 #define NUM_PIXELS 105

@@ -190,6 +201,7 @@

 void loop() {

+  DEBUG_PRINTLN(0, "White");
   for (unsigned int i=0; i < pixels.numPixels(); i++)
     pixels.setPixelRGB(i, 255, 255, 255);
   pixels.update();
@@ -203,6 +215,7 @@
   digitalWrite(value_output.pin, LOW);
 #endif

+  DEBUG_PRINTLN(0, "Red");
   digitalWrite(rgb_output.pins[0], HIGH);
   for (unsigned int i=0; i < pixels.numPixels(); i++)
     pixels.setPixelRGB(i, 255, 0, 0);
@@ -210,6 +223,7 @@

   delay(1000);

+  DEBUG_PRINTLN(0, "Green");
   digitalWrite(rgb_output.pins[0], LOW);
   digitalWrite(rgb_output.pins[1], HIGH);
   for (unsigned int i=0; i < pixels.numPixels(); i++)
@@ -218,6 +232,7 @@

   delay(1000);

+  DEBUG_PRINTLN(0, "Blue");
   digitalWrite(rgb_output.pins[1], LOW);
   digitalWrite(rgb_output.pins[2], HIGH);
   for (unsigned int i=0; i < pixels.numPixels(); i++)


Clean up stray backslash in Connection-close: literal

--- analogjson.ino
+++ analogjson.ino
@@ -557,7 +557,7 @@

 // basic unsuccessful reply
 const char reply400[] =
-    "HTTP/1.1 400 Bad Request\r\n\Connection: close\r\n\r\n";
+    "HTTP/1.1 400 Bad Request\r\nConnection: close\r\n\r\n";

 // reading pins and producing JSON


non-interactive version: started with string tokenisation...

--- Memory/FlashReader/FlashReader.ino
+++ Memory/FlashReader/FlashReader.ino
@@ -40,9 +40,9 @@
 #define DEBUG
 // execute test code (if any)
 #undef TEST
-#define INTERACTIVE   1
+#define INTERACTIVE   0
 #if (INTERACTIVE == 0)
- #undef DEBUG
+ //#undef DEBUG
 #endif

 // http://arduiniana.org/libraries/streaming/
@@ -87,11 +87,14 @@

   /* Initialize serial output at UART_BAUD_RATE bps */
   Serial.begin(UART_BAUD_RATE);
+#ifdef DEBUG
   Serial << F("FlashReader.ino starting ...") << endl;
+#endif // DEBUG

   eeprom.setType(eepromType);
 }

+#if (INTERACTIVE != 0)
 //
 // flash strings for the main menu
 //
@@ -104,13 +107,50 @@
         "t    - set EPROM <t>ype\n"
         "h, ? - display this <h>elp\n"
       /*  "Ctrl-] - leave miniterm.py\n" */ );
-
+#endif // INTERACTIVE
+
+#if (INTERACTIVE == 0)
+ // Calculate based on max input size expected for one command
+ #define INPUT_SIZE 64
+
+char inputLine[INPUT_SIZE+1] = { 0 };
+int lineLength = 0;
+bool lineComplete = false;
+#endif // INTERACTIVE

 /**  */
 void loop() {

   static bool first = true;
+#if (INTERACTIVE == 0)
+  static byte output_format = 1;
+#else
   static byte output_format = 0;
+#endif // INTERACTIVE
+
+#if (INTERACTIVE == 0)
+
+  int ch = Serial.read();
+
+  if ( ch == -1 ) return;
+
+  // check for LF or add character to inputLine
+  if ( ch == 0x0a || ch == 0x0d ) {
+    lineComplete = true;
+  }
+  else {
+    // Add the final 0 to end the C string
+    inputLine[lineLength++] = ch;
+    inputLine[lineLength] = 0;
+
+    // too many chars entered? clear line buffer and issue warning
+    if ( lineLength == INPUT_SIZE ) {
+      lineLength = 0;
+      inputLine[lineLength] = 0;
+      Serial << F("ERR: max. line length exceeded!") << endl;
+    }
+  }
+#endif // INTERACTIVE

 #ifdef TEST
   testCode();
@@ -243,6 +283,78 @@
     }
   }
 #endif // INTERACTIVE
+
+#if (INTERACTIVE == 0)
+  #define MAX_OPTIONS   5
+  //
+  // valid commands:
+  // 't ?' - get E(E)PROM type
+  // 't <t>' - set E(E)PROM type
+  // 'r <addr> <len>' - read <len> bytes starting from address <addr>
+  // 'w <addr> <bytes>' - write <bytes> (in IHEX format) to address <addr>
+  //
+  if ( lineComplete ) {
+
+    Serial << strlen(inputLine) << " '" << inputLine << "'" << endl;
+
+    char *command = NULL;
+    int nopts = 0;
+    char* token = strtok(inputLine, " ");
+    char *option[MAX_OPTIONS];
+    bool err = false;
+
+    while ( token && !err ) {
+
+      // 'command' token must have length of 1
+      if ( strlen(token) == 1 && !command ) {
+        command = token;
+      }
+      // 'command' token found, now check for options
+      else if ( command ) {
+        if ( nopts == MAX_OPTIONS ) {
+          err = true;
+          Serial << F("ERR: maximum number of options exceeded") << endl;
+        }
+        option[nopts++] = token;
+      }
+      else if ( !command ) {
+        Serial << F("ERR: no command found!") << endl;
+        err = true;
+      }
+
+      // find next token
+      token = strtok(0, " ");
+    }
+
+    // final control output after tokenisation
+    if ( command && !err ) {
+      Serial << F("command= '") << command << "'" << endl;
+      for ( int i=0; i<nopts; ++i )
+        Serial << F("option[") << i << F("]= '") << option[i] << "'" << endl;
+    }
+
+    if ( !err ) {
+      switch ( command[0] ) {
+        case 't': break;
+        case 'r': break;
+        case 'w': break;
+        case '?': break;
+        default:
+          Serial << F("ERR: unknown command entered!") << endl;
+          err = true;
+      }
+    }
+
+    if ( !err ) {
+      Serial << F("OK") << endl;
+    }
+
+    lineLength = 0;
+    inputLine[lineLength] = 0;
+
+    lineComplete = false;
+  }
+#endif // INTERACTIVE
 }


Fixed conflict that gave different values depending on whether sensor was in Port 1 or 2.

--- VernierServo/VernierServo.ino
+++ VernierServo/VernierServo.ino
@@ -1,5 +1,5 @@
 /*
-VernierServo (v 2014.12)
+VernierServo (v 2015.04)
 Reads a Vernier analog (BTA) sensor connnected to pin A0 of the Arduino or the
 BTA 1 connector. This sketch controls the arm on a servo motor in response to
 this voltage from the sensor. The servo motor is assumed to be connected to
@@ -15,19 +15,36 @@
 you can make the connection to proper line for the servo motor from DIO4 (pin 9) of the
 BTD2 connector (the pin closest to the tab).

-There is currently a conflict that doesn't allow the Redboard to communicate
-correctly with a servo motor through the Digital Control Unit (DCU-BTA).
+If you connect the servo motor (3-pin) connector on a DCU and connect the DCU to
+the BTD2 connector on the Arduino Interface Shield, this (2015.04) version will work.
+The DCU will require an external power supply as the power received from the Redboard/
+Arduino is not sufficient to drive the servo.
+
 */

 #include <Servo.h>
 Servo myservo;  // create servo object to control a servo
 int Sensorpin = 0;  // analog pin used to connect the potentiomete
-
+
+
 void setup()
 {
   myservo.attach(9);  // attaches the servo on pin 9 to the servo object
-}
-
+
+/* the 6 lines below are only needed if you plan to use this sketch with a servo motor
+connected to the 3-pin connector on a DCU. The reason this is required is that the DCU
+has internal electronics to only allow its 4th pin to be turned on when the other first
+three lines are off.
+*/
+
+  pinMode(6, OUTPUT);
+  pinMode(7, OUTPUT);
+  pinMode(8, OUTPUT);
+  pinMode(9, OUTPUT);
+  digitalWrite(6, LOW);
+  digitalWrite(7, LOW);
+  digitalWrite(8, LOW);
+}
 void loop()
 {
   int val = analogRead(Sensorpin);     // reads the voltage (value between 0 and 1023)


Added Min and Max. Tested the outputs and they work :).

--- ServerSketch/ServerSketch.ino
+++ ServerSketch/ServerSketch.ino
@@ -710,17 +710,21 @@
         //fPinValSum += g_aPins[i].value;
         fPinValSum += (g_aPins[i].value - g_aPins[i].input_min)/(g_aPins[i].input_max - g_aPins[i].input_min);  // Adding the Max/Min formula

-        if( !g_aPins[_iOutPinNum].is_analog && fPinValSum >= DIGITAL_VOLTAGE_THRESHOLD) // Digital threshold
-          fPinValSum = 1.0;
-        else
-          fPinValSum = 0.0;
-
+       if( !g_aPins[_iOutPinNum].is_analog )
+       {
+         if( fPinValSum >= DIGITAL_VOLTAGE_THRESHOLD) // Digital threshold
+           fPinValSum = 1.0;
+         else
+           fPinValSum = 0.0;
+       }
+        /*
         Serial.print(i); Serial.print(" --> "); Serial.println(_iOutPinNum);
         Serial.print(" Min: "); Serial.println(g_aPins[i].input_min);
         Serial.print(" Max: "); Serial.println(g_aPins[i].input_max);
         Serial.print(" Value: "); Serial.println(g_aPins[i].value);
         Serial.print(" Scales value: "); Serial.println(g_aPins[i].value - g_aPins[i].input_min)/(g_aPins[i].input_max - g_aPins[i].input_min);
         Serial.print(" -fPinValSum: "); Serial.println(fPinValSum);
+        */
       }
     }
   }


気圧の単位を変更、その他バグフィックス

気圧の単位を変更、その他バグフィックス

--- Arduino/ESP_BME280_To_Ambient/ESP_BME280_To_Ambient.ino
+++ Arduino/ESP_BME280_To_Ambient/ESP_BME280_To_Ambient.ino
@@ -370,8 +370,8 @@
   delay(10);
   temp      = bme.readTempC();
   humidity  = bme.readFloatHumidity();
-  pressure  = bme.readFloatPressure() / 100;
-
+  pressure  = bme.readFloatPressure() / 100.0;
+
   //  OLEDへ表示
   display.clear();

@@ -403,7 +403,7 @@

 const int kMaxJsonBuffer = kMaxBlocks * 100;

-StaticJsonBuffer<kMaxJsonBuffer> jsonBuffer;
+StaticJsonBuffer<kMaxJsonBuffer*2> jsonBuffer;
 char jsonPrintBuffer[kMaxJsonBuffer];

 bool sendStorageToAmbient() {


tweaks to live wire code, inclusing startup pulse behavior

--- src/MotorCode/MotorCode.ino
+++ src/MotorCode/MotorCode.ino
@@ -5,13 +5,19 @@
 #include <AFMotor.h>

 AF_DCMotor motor(4);
-int incomingByte = 0;
+int incomingByte = 0;
 void setup() {
   Serial.begin(9600);           // set up Serial library at 9600 bps
    motor.run(RELEASE);
+
+   // Quickly start and stop to know the motor is on
+   motor.run(FORWARD);
+   motor.setSpeed(255);
+   delay(500);
+   motor.run(RELEASE);
 }
 void loop() {
-  Serial.println("I am on");
+  Serial.println("I am the motorshield.");
   if (Serial.available() > 0) {
       // read the incoming byte:
       incomingByte = Serial.read();
@@ -22,16 +28,20 @@

       }
       else if(incomingByte == 1 || incomingByte == 49){
-         motor.run(FORWARD);
-        motor.setSpeed(200);
+        motor.run(FORWARD);
+        motor.setSpeed(110);
       }
       else if(incomingByte == 2 || incomingByte == 50){
-         motor.run(FORWARD);
-        motor.setSpeed(220);
+        motor.run(FORWARD);
+        motor.setSpeed(160);
       }
       else if(incomingByte == 3 || incomingByte == 51){
-         motor.run(FORWARD);
-        motor.setSpeed(240);
+        motor.run(FORWARD);
+        motor.setSpeed(210);
+      }
+      else if(incomingByte == 4 || incomingByte == 52){
+        motor.run(FORWARD);
+        motor.setSpeed(255);
       }
    }
    delay(500);              // wait for a second


Delete error.ino

Delete error.ino

--- TSI_linefollower_v1/error.ino
+++ TSI_linefollower_v1/error.ino
@@ -1,48 +0,0 @@
-// Returns an estimated position of the robot with respect to a line.
-// The estimate is made using a weighted average of the sensor indices
-// multiplied by 1000, so that a return value of 0 indicates that
-// the line is directly below sensor 0, a return value of 1000
-// indicates that the line is directly below sensor 1, 2000
-// indicates that it's below sensor 2000, etc.  Intermediate
-// values indicate that the line is between two sensors.  The
-// formula is:
-//
-//    0*value0 + 1000*value1 + 2000*value2 + ...
-//   --------------------------------------------
-//         value0  +  value1  +  value2 + ...
-
-
-long linePosition(Pin *sensor_number)
-{
-  unsigned long numerator = 0;
-  unsigned long denominator = 0;
-  static long  x;
-  long l, r;
-  unsigned long weight[8] = {6000, 1120, 335, 138, 72, 45, 32, 25};   //добавить умножение на 1000
-
-  for (unsigned char i = 0, j = 8; i < 8; i++, j--) {
-    unsigned char value = sensor_number[i].getValue();
-    numerator += value * j * 1000 * weight[i];
-    denominator += value * weight[i];
-  }
-  if (denominator) l = numerator / denominator;
-  else l = 0;
-
-  numerator = 0; denominator = 0;
-  for (unsigned char i = 0, j = 8; i < 8; i++, j--) {
-    unsigned char value = sensor_number[15 - i].getValue();
-    numerator += value * j * 1000 * weight[i];
-    denominator += value * weight[i];
-  }
-  if (denominator) r = numerator / denominator;
-  else r = 0;
-
-
-  if (!l && !r) {
-    if (x > 0) return 9000;
-    else return -9000;
-  }
-
-  x = -l + r;
-  return x;
-}


Last version test board.

Last version test board.

--- test/PoE-test/PowerBoard-Basisboard-v1.1/Basic-Tests/Basic-Tests.ino
+++ test/PoE-test/PowerBoard-Basisboard-v1.1/Basic-Tests/Basic-Tests.ino
@@ -1,10 +1,10 @@
 // https://wiki.makerspaceleiden.nl/mediawiki/index.php/Powernode_1.1
 //
-#define AART_LED        (GPIO_NUM_16)
-#define RELAY           (GPIO_NUM_5)
-#define CURRENT_COIL    (GPIO_NUM_36)
-#define SW1             (GPIO_NUM_2)
-#define SW2             (GPIO_NUM_39)
+#define AART_LED        (GPIO_NUM_16) // ok
+#define RELAY           (GPIO_NUM_5)  // ok
+#define CURRENT_COIL    (GPIO_NUM_36) // ok
+#define SW1             (GPIO_NUM_2)  // ok
+#define SW2             (GPIO_NUM_39)
 #define OPTO1           (GPIO_NUM_34)
 #define OPTO2           (GPIO_NUM_35)


FIRST version of Arduino code that works. Still needs improvements.

--- arduino/mazeball/mazeball.ino
+++ arduino/mazeball/mazeball.ino
@@ -1,12 +1,41 @@
-#define DELAY 100
+/**
+ * Algoritmo
+ *
+ * Se ha comando,
+ *   se comando de girar
+ *     gira no eixo e sentido desejado
+ *     inicia contagem de tempo girando no eixo
+ *   se comando de parar
+ *     para ambos os eixos
+ * senao,
+ *   se esta movendo algum eixo
+ *     faz tomada de tempo atual
+ *     se esta movendo ha mais tempo que o maximo
+ *       para o movimento
+ *
+ */

-/**
- * Inicialmente vamos usar Serial1 (18 e 19) para o shield bluetooth
- * e Serial (0 e 1) para monitoraçao/depuraçao
- */
+
+// define how many cycles to a full rotation
+#define CYCLES_PER_ROTATION 512
+
+#define MAX_TIME_MOVING 2000   // 2 seconds
+
+unsigned long moveTimeX = 0L;
+unsigned long moveTimeY = 0L;
+unsigned long currentTime = 0L;
+
+boolean movingX = false;
+boolean movingY = false;
+boolean clockwiseX;
+boolean clockwiseY;

 int stpXPins[] = {8,9,10,11};
 int stpYPins[] = {2,3,4,5};
+
+int xPhase = 0;
+int yPhase = 0;
+

 void setup() {
   Serial1.begin(9600); // Pins 19 (RX) and 18 (TX), Serial2 on 17 and 16, Serial3 on 15 and 14
@@ -24,100 +53,127 @@
 }

 void loop() {
-
-  int xPhase = 0;
-  int yPhase = 0;
-
   if (Serial1.available() > 0) {
     char c = Serial1.read();
+    // Detect X axis movement
+    if(c == 'l') { // Move left
+      movingX = true;
+      clockwiseX = false;
+    }
+    if(c == 'r') { // Move right
+      movingX = true;
+      clockwiseX = true;
+    }
     // Detect Y axis movement
-    if (c == 't') { // Move top
-      phaseSelect(stpYPins, yPhase);
-      ++yPhase %= 8;
-      goto skip;
+    if(c == 't') { // Move top
+      movingY = true;
+      clockwiseY = true;
     }
-    if (c == 'b') { // Move bottom
-      phaseSelect(stpYPins, 7 - yPhase);
-      ++yPhase %= 8;
-      goto skip;
+    if(c == 'b') { // Move bottom
+      movingY = true;
+      clockwiseY = false;
     }
-
-    // Detect X axis movement
-    if (c == 'l') { // Move left
-      phaseSelect(stpXPins, 7 - xPhase);
-      ++xPhase %= 8;
-      goto skip;
+    if(c == 's') {
+      phaseSelect(stpXPins, 8); // Stop X movement
+      phaseSelect(stpYPins, 8); // Stop Y movement
+      movingX = movingY = false;
+      moveTimeX = moveTimeY = 0;
     }
-    if (c == 'r') { // Move right
-      phaseSelect(stpXPins, xPhase);
-      ++xPhase %= 8;
-      goto skip;
+  } else {
+    currentTime = millis();
+    if(movingX && (currentTime - moveTimeX) > MAX_TIME_MOVING) {
+      phaseSelect(stpXPins, 8); // Stop X movement
+      movingX = false;
+      moveTimeX = 0;
+    }
+    if(movingY && (currentTime - moveTimeY) > MAX_TIME_MOVING) {
+      phaseSelect(stpYPins, 8); // Stop X movement
+      movingY = false;
+      moveTimeY = 0;
     }
   }
-  phaseSelect(stpXPins, 8); // Stop X movement
-  phaseSelect(stpYPins, 8); // Stop Y movement
-
-skip:
-  delay(DELAY);
+  if(movingX) {
+    if(clockwiseX) {
+      phaseSelect(stpXPins, xPhase);
+    } else {
+      phaseSelect(stpXPins, 7 - xPhase);
+    }
+    ++xPhase %= 8;
+    if(moveTimeX == 0) {
+      moveTimeX = millis();
+    }
+  }
+  if(movingY) {
+    if(clockwiseY) {
+      phaseSelect(stpYPins, yPhase);
+    } else {
+      phaseSelect(stpYPins, 7 - yPhase);
+    }
+    ++yPhase %= 8;
+    if(moveTimeY == 0) {
+      moveTimeY = millis();
+    }
+  }
 }

 void phaseSelect(int *pins, int phase) {
   switch(phase) {
-     case 0:
-       digitalWrite(pins[0], LOW);
-       digitalWrite(pins[1], LOW);
-       digitalWrite(pins[2], LOW);
-       digitalWrite(pins[3], HIGH);
-       break;
-     case 1:
-       digitalWrite(pins[0], LOW);
-       digitalWrite(pins[1], LOW);
-       digitalWrite(pins[2], HIGH);
-       digitalWrite(pins[3], HIGH);
-       break;
-     case 2:
-       digitalWrite(pins[0], LOW);
-       digitalWrite(pins[1], LOW);
-       digitalWrite(pins[2], HIGH);
-       digitalWrite(pins[3], LOW);
-       break;
-     case 3:
-       digitalWrite(pins[0], LOW);
-       digitalWrite(pins[1], HIGH);
-       digitalWrite(pins[2], HIGH);
-       digitalWrite(pins[3], LOW);
-       break;
-     case 4:
-       digitalWrite(pins[0], LOW);
-       digitalWrite(pins[1], HIGH);
-       digitalWrite(pins[2], LOW);
-       digitalWrite(pins[3], LOW);
-       break;
-     case 5:
-       digitalWrite(pins[0], HIGH);
-       digitalWrite(pins[1], HIGH);
-       digitalWrite(pins[2], LOW);
-       digitalWrite(pins[3], LOW);
-       break;
-     case 6:
-       digitalWrite(pins[0], HIGH);
-       digitalWrite(pins[1], LOW);
-       digitalWrite(pins[2], LOW);
-       digitalWrite(pins[3], LOW);
-       break;
-     case 7:
-       digitalWrite(pins[0], HIGH);
-       digitalWrite(pins[1], LOW);
-       digitalWrite(pins[2], LOW);
-       digitalWrite(pins[3], HIGH);
-       break;
-     default:
-       digitalWrite(pins[0], LOW);
-       digitalWrite(pins[1], LOW);
-       digitalWrite(pins[2], LOW);
-       digitalWrite(pins[3], LOW);
-       break;
+  case 0:
+    digitalWrite(pins[0], LOW);
+    digitalWrite(pins[1], LOW);
+    digitalWrite(pins[2], LOW);
+    digitalWrite(pins[3], HIGH);
+    break;
+  case 1:
+    digitalWrite(pins[0], LOW);
+    digitalWrite(pins[1], LOW);
+    digitalWrite(pins[2], HIGH);
+    digitalWrite(pins[3], HIGH);
+    break;
+  case 2:
+    digitalWrite(pins[0], LOW);
+    digitalWrite(pins[1], LOW);
+    digitalWrite(pins[2], HIGH);
+    digitalWrite(pins[3], LOW);
+    break;
+  case 3:
+    digitalWrite(pins[0], LOW);
+    digitalWrite(pins[1], HIGH);
+    digitalWrite(pins[2], HIGH);
+    digitalWrite(pins[3], LOW);
+    break;
+  case 4:
+    digitalWrite(pins[0], LOW);
+    digitalWrite(pins[1], HIGH);
+    digitalWrite(pins[2], LOW);
+    digitalWrite(pins[3], LOW);
+    break;
+  case 5:
+    digitalWrite(pins[0], HIGH);
+    digitalWrite(pins[1], HIGH);
+    digitalWrite(pins[2], LOW);
+    digitalWrite(pins[3], LOW);
+    break;
+  case 6:
+    digitalWrite(pins[0], HIGH);
+    digitalWrite(pins[1], LOW);
+    digitalWrite(pins[2], LOW);
+    digitalWrite(pins[3], LOW);
+    break;
+  case 7:
+    digitalWrite(pins[0], HIGH);
+    digitalWrite(pins[1], LOW);
+    digitalWrite(pins[2], LOW);
+    digitalWrite(pins[3], HIGH);
+    break;
+  default:
+    digitalWrite(pins[0], LOW);
+    digitalWrite(pins[1], LOW);
+    digitalWrite(pins[2], LOW);
+    digitalWrite(pins[3], LOW);
+    break;
   }
   delay(1);
 }

+


Update FlappyBird.ino

Update FlappyBird.ino

--- examples/Games/FlappyBird/FlappyBird.ino
+++ examples/Games/FlappyBird/FlappyBird.ino
@@ -1,4 +1,5 @@
 // By Ponticelli Domenico.
+// 12NOV2020 EEPROM Fix added, modified by Zontex
 // https://github.com/pcelli85/M5Stack_FlappyBird_game

 #include <M5Stack.h>
@@ -27,7 +28,8 @@
 // grass size
 #define GRASSH            4     // grass height (inside floor, starts at floor y)

-int maxScore = 0;
+int address = 0;
+int maxScore = EEPROM.readInt(address);
 const int buttonPin = 2;
 // background
 const unsigned int BCKGRDCOL = M5.Lcd.color565(138,235,244);
@@ -92,10 +94,12 @@

 void setup() {
   // put your setup code here, to run once:
-M5.begin();
-M5.Power.begin();
-resetMaxScore();
-
+  M5.begin();
+  M5.Power.begin();
+  EEPROM.begin(1000);
+  //resetMaxScore();
+  Serial.println("last score:");
+  Serial.println(EEPROM.readInt(address));
 }

 void loop() {
@@ -323,11 +327,12 @@
 // ---------------
 void game_over() {
   M5.Lcd.fillScreen(TFT_BLACK);
-  EEPROM_Read(&maxScore,0);
+  maxScore = EEPROM.readInt(address);

   if(score>maxScore)
   {
-    EEPROM_Write(&score,0);
+    EEPROM.writeInt(address, score);
+    EEPROM.commit();
     maxScore = score;
     M5.Lcd.setTextColor(TFT_RED);
     M5.Lcd.setTextSize(2);
@@ -360,31 +365,7 @@

 void resetMaxScore()
 {
-  EEPROM_Write(&maxScore,0);
-}
-
-
-
-void EEPROM_Write(int *num, int MemPos)
-{
- byte ByteArray[2];
- memcpy(ByteArray, num, 2);
- for(int x = 0; x < 2; x++)
- {
-   EEPROM.write((MemPos * 2) + x, ByteArray[x]);
- }
-}
-
-
-
-void EEPROM_Read(int *num, int MemPos)
-{
- byte ByteArray[2];
- for(int x = 0; x < 2; x++)
- {
-   ByteArray[x] = EEPROM.read((MemPos * 2) + x);
- }
- memcpy(num, ByteArray, 2);
-}
-
-
+  EEPROM.writeInt(address, 0);
+  EEPROM.commit();
+}
+


Fixing a typo

Fixing a typo


Format Code (Remove Extra Whitespace)

Format Code (Remove Extra Whitespace)

--- OpenCTD_Feather_Adalogger/OpenCTD_master_m0/OpenCTD_master_m0.ino
+++ OpenCTD_Feather_Adalogger/OpenCTD_master_m0/OpenCTD_master_m0.ino
@@ -8,8 +8,8 @@
 #include <SD.h> //library for SD card reader

 //communication protocols for temperature sensors
-#include <OneWire.h>
-#include <DallasTemperature.h>
+#include <OneWire.h>
+#include <DallasTemperature.h>

 //Software libary for the pressure sensor
 #include <MS5803_14.h>
@@ -36,289 +36,289 @@
 float tempC;

 //Declare global variables for eletrical conductivity
-float EC_float = 0;
-char EC_data[48]; // A 48 byte character array to hold incoming data from the conductivity circuit.
+float EC_float = 0;
+char EC_data[48]; // A 48 byte character array to hold incoming data from the conductivity circuit.
 char *EC; // Character pointer for string parsing.
 byte received_from_sensor = 0; // How many characters have been received.
 byte string_received = 0; // Whether it received a string from the EC circuit.

 void setup () {

-// comment the following three lines out for final deployment
-  #ifndef ESP8266
-    while (!Serial);   //for Leonardo/Micro/Zero
- #endif
+  // comment the following three lines out for final deployment
+#ifndef ESP8266
+  while (!Serial);   //for Leonardo/Micro/Zero
+#endif

   Serial.begin(9600);

-//Initialize SD card reader
+  //Initialize SD card reader
   Serial.print("Initializing SD card...");

   if (!SD.begin(chipSelect)) {
-
+
     Serial.println("Card failed, or not present");
     return;
-
-  }
-
+
+  }
+
   Serial.println("card initialized.");

-  delay(1000);
+  delay(1000);

   if (! rtc.begin()) {
-
+
     Serial.println("Couldn't find RTC");
     while (1);
-
+
   }

   File dataFile = SD.open("datalog.txt", FILE_WRITE);
-
+
   if (dataFile) {
-
+
     dataFile.println("");
     dataFile.println("=== New Cast ===");
     dataFile.println("");
     dataFile.close();
-
-  }
-
-//Initialize real-time clock
+
+  }
+
+  //Initialize real-time clock
   if (rtc.lostPower()) {

     //reset RTC with time when code was compiled if RTC loses power
-    Serial.println("RTC lost power, lets set the time!");
+    Serial.println("RTC lost power, lets set the time!");
     rtc.adjust(DateTime(F(__DATE__), F(__TIME__)));
-
-  }
-
+
+  }
+
   delay(250);       // Wait a quarter second to continue.

-//Initialize sensors
-  sensor.initializeMS_5803(); // Initialize pressure sensor
-
+  //Initialize sensors
+  sensor.initializeMS_5803(); // Initialize pressure sensor
+
   sensors.begin();  // Intialize the temperature sensors.

-  ecSerial.begin(9600); // Set baud rate for conductivity circuit.
+  ecSerial.begin(9600); // Set baud rate for conductivity circuit.

 }

 void loop () {
-
+
   DateTime now = rtc.now(); //check RTC

   sensor.readSensor(); //read pressure sensor
   pressure_abs = sensor.pressure();

-//read temperature sensor
+  //read temperature sensor
   sensors.requestTemperatures();
   tempA = sensors.getTempCByIndex(0);
   tempB = sensors.getTempCByIndex(1);
   tempC = sensors.getTempCByIndex(2);

-//Read electrical conductivity sensor
+  //Read electrical conductivity sensor
   if (ecSerial.available() > 0) {

     received_from_sensor = ecSerial.readBytesUntil(13, EC_data, 48);
     EC_data[received_from_sensor] = 0; // Null terminate the data by setting the value after the final character to 0.
-
-  }
-
-  if ((EC_data[0] >= 48) && (EC_data[0] <=57)) { // Parse data, if EC_data begins with a digit, not a letter (testing ASCII values).
+
+  }
+
+  if ((EC_data[0] >= 48) && (EC_data[0] <= 57)) { // Parse data, if EC_data begins with a digit, not a letter (testing ASCII values).

     parse_data();
-
-  }
-
-//output readings to serial monitor. A whole mess of if/else statements to keep numbers formatted correctly
+
+  }
+
+  //output readings to serial monitor. A whole mess of if/else statements to keep numbers formatted correctly
   Serial.print(now.year(), DEC);
   Serial.print('/');

-  if (now.month()<10) {
-
+  if (now.month() < 10) {
+
     Serial.print(0);
     Serial.print(now.month(), DEC);
-
-  }
-
-  else {
-
-  Serial.print(now.month(), DEC);
-
-  }
-
+
+  }
+
+  else {
+
+    Serial.print(now.month(), DEC);
+
+  }
+
   Serial.print('/');
-
-  if (now.day()<10) {
-
+
+  if (now.day() < 10) {
+
     Serial.print(0);
     Serial.print(now.day(), DEC);
-
-  }
-
-  else {
-
-  Serial.print(now.day(), DEC);
-
-  }
-
-  Serial.print("  ");
-
-  if (now.hour()<10) {
-
+
+  }
+
+  else {
+
+    Serial.print(now.day(), DEC);
+
+  }
+
+  Serial.print("  ");
+
+  if (now.hour() < 10) {
+
     Serial.print(0);
     Serial.print(now.hour(), DEC);
-
-  }
-
-  else {
-
-  Serial.print(now.hour(), DEC);
-
-  }
-
+
+  }
+
+  else {
+
+    Serial.print(now.hour(), DEC);
+
+  }
+
   Serial.print(':');
-
-  if (now.minute()<10) {
-
+
+  if (now.minute() < 10) {
+
     Serial.print(0);
     Serial.print(now.minute(), DEC);
-
-  }
-
-  else {
-
-  Serial.print(now.minute(), DEC);
-
-  }
+
+  }
+
+  else {
+
+    Serial.print(now.minute(), DEC);
+
+  }

   Serial.print(':');
-
-  if (now.second()<10) {
-
+
+  if (now.second() < 10) {
+
     Serial.print(0);
     Serial.print(now.second(), DEC);
-
-  }
-
-  else {
-
-  Serial.print(now.second(), DEC);
-
-  }
-
+
+  }
+
+  else {
+
+    Serial.print(now.second(), DEC);
+
+  }
+
   Serial.print("  ");
   Serial.print(pressure_abs);
-  Serial.print("  ");
+  Serial.print("  ");
   Serial.print(tempA);
   Serial.print("  ");
   Serial.print(tempB);
   Serial.print("  ");
-  Serial.print(tempC);
-  Serial.print("  ");
+  Serial.print(tempC);
+  Serial.print("  ");
   Serial.println(EC);

   //output readings to data file. A whole mess of if/else statements to keep numbers formatted correctly
   File dataFile = SD.open("datalog.txt", FILE_WRITE);
-
+
   if (dataFile) {
-
+
     dataFile.print(now.year(), DEC);
     dataFile.print('/');
-
-    if (now.month()<10) {
-
-    dataFile.print(0);
-    dataFile.print(now.month(), DEC);
-
-    }
-
-    else {
-
-     dataFile.print(now.month(), DEC);
-
-    }
-
+
+    if (now.month() < 10) {
+
+      dataFile.print(0);
+      dataFile.print(now.month(), DEC);
+
+    }
+
+    else {
+
+      dataFile.print(now.month(), DEC);
+
+    }
+
     dataFile.print('/');
-
-    if (now.day()<10) {
-
+
+    if (now.day() < 10) {
+
       dataFile.print(0);
       dataFile.print(now.day(), DEC);
-
-    }
-
-    else {
-
+
+    }
+
+    else {
+
       dataFile.print(now.day(), DEC);
-
-    }
-
-    dataFile.print("  ");
-
-    if (now.hour()<10) {
-
+
+    }
+
+    dataFile.print("  ");
+
+    if (now.hour() < 10) {
+
       dataFile.print(0);
       dataFile.print(now.hour(), DEC);
-
-    }
-
-    else {
-
+
+    }
+
+    else {
+
       dataFile.print(now.hour(), DEC);
-
-    }
-
+
+    }
+
     dataFile.print(':');
-
-    if (now.minute()<10) {
-
+
+    if (now.minute() < 10) {
+
       dataFile.print(0);
       dataFile.print(now.minute(), DEC);
-
-    }
-
-    else {
-
+
+    }
+
+    else {
+
       dataFile.print(now.minute(), DEC);
-
-    }
+
+    }

     dataFile.print(':');
-
-    if (now.second()<10) {
-
+
+    if (now.second() < 10) {
+
       dataFile.print(0);
       dataFile.print(now.second(), DEC);
-
-    }
-
-    else {
-
-     dataFile.print(now.second(), DEC);
-
-    }
-
+
+    }
+
+    else {
+
+      dataFile.print(now.second(), DEC);
+
+    }
+
     dataFile.print("  ");
     dataFile.print(pressure_abs);
-    dataFile.print("  ");
+    dataFile.print("  ");
     dataFile.print(tempA);
     dataFile.print("  ");
     dataFile.print(tempB);
     dataFile.print("  ");
     dataFile.print(tempC);
-    dataFile.print("  ");
+    dataFile.print("  ");
     dataFile.println(EC);
-    dataFile.close();
-
-  }
-
+    dataFile.close();
+
+  }
+
   delay(50);

 }

 void parse_data() { // Parses data from the EC Circuit.

-  EC = strtok(EC_data, ",");
+  EC = strtok(EC_data, ",");

 }


tracker: no loop for unlockSIM

tracker: no loop for unlockSIM

--- CarTracker/CarTracker.ino
+++ CarTracker/CarTracker.ino
@@ -127,10 +127,10 @@
     fona.setGPRSNetworkSettings(F(APN));

 #ifdef SIM_PIN
-    while (! fona.unlockSIM(SIM_PIN))
+    if (! fona.unlockSIM(SIM_PIN))
     {
         console.println(F("Unlock Failed"));
-        delay(1000);
+        HALT();
     }
     console.println(F("Unlock  OK!"));
 #endif


More dumps added to the test

More dumps added to the test

--- Code/Tests/NetworkV1/Test_RouteCache/Test_RouteCache.ino
+++ Code/Tests/NetworkV1/Test_RouteCache/Test_RouteCache.ino
@@ -18,18 +18,21 @@
  * Free Software Foundation, Inc., 59 Temple Place, Suite 330,
  * Boston, MA  02111-1307  USA
  */
+#ifndef __TESTS_ROUTECACHE_H__
+#define __TESTS_ROUTECACHE_H__
+
 #include <stdlib.h>
-#include "Cosa/Trace.hh"
-#include "Cosa/Types.h"
-#include "Cosa/IOStream.hh"
-#include "Cosa/IOStream/Driver/UART.hh"
-#include "Cosa/Watchdog.hh"
-#include "Cosa/RTC.hh"
+#include <Cosa/Trace.hh>
+#include <Cosa/Types.h>
+#include <Cosa/IOStream.hh>
+#include <Cosa/IOStream/Driver/UART.hh>
+#include <Cosa/Watchdog.hh>
+#include <Cosa/RTC.hh>
 #include <Meshwork.h>
-#include "Meshwork/L3/Network.h"
-#include "Meshwork/L3/NetworkV1/NetworkV1.h"
-#include "Meshwork/L3/NetworkV1/RouteCache.h"
-#include "Meshwork/L3/NetworkV1/RouteCache.cpp"
+#include <Meshwork/L3/Network.h>
+#include <Meshwork/L3/NetworkV1/NetworkV1.h>
+#include <Meshwork/L3/NetworkV1/RouteCache.h>
+#include <Meshwork/L3/NetworkV1/RouteCache.cpp>

 using Meshwork::L3::Network;
 using Meshwork::L3::NetworkV1::NetworkV1;
@@ -346,26 +349,33 @@
 		for ( int j = 0; j < RouteCache::MAX_DST_ROUTES; j ++ )
 			route_cache->add_route_entry(&route[i][j], false);
 	//Setup: add QoS:
-	//	route[0]: reach max
-	//	route[1]: reach min
-	//	route[2]: stay at zero
+	//	route[0][0]: reach max
+	//	route[0][1]: reach min
+	//	route[0][2]: stay at zero
+	trace	<< PSTR("[testQoS] Adding route entry with QOS_LEVEL_MAX") << endl;
+	trace	<< PSTR("[testQoS] ... Adding QOS_LEVEL_MAX") << endl;
 	for ( int k = 0; k < Network::QOS_LEVEL_MAX + 10; k ++ )//exceeding max on purpose
 		result &= route_cache->update_QoS(&route[0][0], true);
-	trace	<< PSTR("[testQoS] Route entry with QOS_LEVEL_MAX: ");
+	trace	<< PSTR("[testQoS] ... Route entry: ");//+100
 	route_cache->print(trace, *route_cache->get_route_entry(route[0][0].dst, 0), 2);
 	trace << endl;

+	trace	<< PSTR("[testQoS] Adding route entry with QOS_LEVEL_MIN") << endl;
+	trace	<< PSTR("[testQoS] ... Adding QOS_LEVEL_MIN") << endl;
 	for ( int k = 0; k > Network::QOS_LEVEL_MIN - 10; k -- )//exceeding min on purpose
 		result &= route_cache->update_QoS(&route[0][1], false);
-	trace	<< PSTR("[testQoS] Route entry with QOS_LEVEL_MIN: ");
+	trace	<< PSTR("[testQoS] ... Route entry: ");//-100
 	route_cache->print(trace, *route_cache->get_route_entry(route[0][1].dst, 1), 2);
 	trace << endl;

+	trace	<< PSTR("[testQoS] Adding route entry with QOS_LEVEL_AVERAGE") << endl;
+	trace	<< PSTR("[testQoS] ... Adding QOS_LEVEL_MAX") << endl;
 	for ( int k = 0; k < Network::QOS_LEVEL_MAX + 10; k ++ )//exceeding max on purpose
 		result &= route_cache->update_QoS(&route[0][2], true);
+	trace	<< PSTR("[testQoS] ... Adding QOS_LEVEL_MIN") << endl;
 	for ( int k = 0; k < Network::QOS_LEVEL_MAX; k ++ )//should net to zero
 		result &= route_cache->update_QoS(&route[0][2], false);
-	trace	<< PSTR("[testQoS] Route entry with QOS_LEVEL_AVERAGE: ");
+	trace	<< PSTR("[testQoS] ... Route entry: ");//0
 	route_cache->print(trace, *route_cache->get_route_entry(route[0][2].dst, 2), 2);
 	trace << endl;

@@ -374,24 +384,34 @@

 	int8_t qos;

+	trace << endl;
 	//Phase 1: check QoS calculation Network::QOS_CALCULATE_BEST
 	if ( (qos = route_cache->get_QoS(route[0][0].dst, Network::QOS_CALCULATE_BEST)) != Network::QOS_LEVEL_MAX ) {
 		trace	<< PSTR("[testQoS] QOS_CALCULATE_BEST wrong for dst: ") << route[0][0].dst << PSTR(", equals: ") << qos << endl;
 		result = false;
-	}
-
+	} else {
+		trace	<< PSTR("[testQoS] QOS_CALCULATE_BEST is correct") << endl;
+	}
+
+	trace << endl;
 	//Phase 2: check QoS calculation Network::QOS_CALCULATE_WORST
 	if ( (qos = route_cache->get_QoS(route[0][1].dst, Network::QOS_CALCULATE_WORST)) != Network::QOS_LEVEL_MIN ) {
 		trace	<< PSTR("[testQoS] QOS_CALCULATE_WORST wrong for dst: ") << route[0][1].dst << PSTR(", equals: ") << qos << endl;
 		result = false;
-	}
-
+	} else {
+		trace	<< PSTR("[testQoS] QOS_CALCULATE_WORST is correct") << endl;
+	}
+
+	trace << endl;
 	//Phase 3: check QoS calculation Network::QOS_CALCULATE_AVERAGE
 	if ( (qos = route_cache->get_QoS(route[0][2].dst, Network::QOS_CALCULATE_AVERAGE)) != Network::QOS_LEVEL_AVERAGE ) {
 		trace	<< PSTR("[testQoS] QOS_CALCULATE_AVERAGE wrong for dst: ") << route[0][2].dst << PSTR(", equals: ") << qos << endl;
 		result = false;
-	}
-
+	} else {
+		trace	<< PSTR("[testQoS] QOS_CALCULATE_AVERAGE is correct") << endl;
+	}
+
+	trace << endl;
 	trace << PSTR("[testQoS] Finished: ") << (result ? PSTR("PASSED") : PSTR("FAILED")) << endl << endl;
 	printDelimiter2();
 	return result;
@@ -555,29 +575,35 @@
 	//Setup: default route data
 	setupDefaultRouteData((void*)routes, (void*)route_hops);

-	//Test 1: verify that the route cache is empty by default
-	result &= testEmptyCache(&route_cache);
-	route_cache.remove_all();//ok, must assume that this works in order to use it as a cleanup
-
-	//Test 2: add all routes, remove them, then verify route cache is empty
-	result &= testRemove(&route_cache, (void*)routes);
-	route_cache.remove_all();
-
-	//Test 3: verify that getters1 return correct data
-	result &= testGetters1(&route_cache, (void*)routes);
-	route_cache.remove_all();
-
-	//Test 4: verify that getters2 return correct data
-	result &= testGetters2(&route_cache, (void*)routes);
-	route_cache.remove_all();
+//	//Test 1: verify that the route cache is empty by default
+//	trace << PSTR("[TestSuite][Test_RouteCache] Test 1: verify that the route cache is empty by default") << endl;
+//	result &= testEmptyCache(&route_cache);
+//	route_cache.remove_all();//ok, must assume that this works in order to use it as a cleanup
+//
+//	//Test 2: add all routes, remove them, then verify route cache is empty
+//	trace << PSTR("[TestSuite][Test_RouteCache] Test 2: add all routes, remove them, then verify route cache is empty") << endl;
+//	result &= testRemove(&route_cache, (void*)routes);
+//	route_cache.remove_all();
+//
+//	//Test 3: verify that getters1 return correct data
+//	trace << PSTR("[TestSuite][Test_RouteCache] Test 3: verify that getters1 return correct data") << endl;
+//	result &= testGetters1(&route_cache, (void*)routes);
+//	route_cache.remove_all();
+//
+//	//Test 4: verify that getters2 return correct data
+//	trace << PSTR("[TestSuite][Test_RouteCache] Test 4: verify that getters2 return correct data") << endl;
+//	result &= testGetters2(&route_cache, (void*)routes);
+//	route_cache.remove_all();

 	//Test 5: verify that QoS functions return correct data
+	trace << PSTR("[TestSuite][Test_RouteCache] Test 5: verify that QoS functions return correct data") << endl;
 	result &= testQoS(&route_cache, (void*)routes);
 	route_cache.remove_all();

-	//Test 6: verify that add and replace works correctly
-	result &= testAddAndReplace(&route_cache, (void*)routes);
-	route_cache.remove_all();
+//	//Test 6: verify that add and replace works correctly
+//	trace << PSTR("[TestSuite][Test_RouteCache] Test 6: verify that add and replace works correctly") << endl;
+//	result &= testAddAndReplace(&route_cache, (void*)routes);
+//	route_cache.remove_all();

 	////////////////////// END //////////////////////

@@ -585,13 +611,14 @@
 	trace << PSTR("Run time (ms): ") << time << PSTR("\r\n");
 	trace << PSTR("[TestSuite][Test_RouteCache] Finished: ") << (result ? PSTR("PASSED") : PSTR("FAILED")) << endl;
 	printDelimiter1();
+
+	return result;
 }

 void setup()
 {
 	uart.begin(115200);
-	uint8_t mode = SLEEP_MODE_IDLE;
-	Watchdog::begin(16, mode);
+	Watchdog::begin();
 	RTC::begin();
 	trace.begin(&uart, PSTR(__FILE__));

@@ -600,5 +627,7 @@

 void loop()
 {
-}
-
+	Watchdog::delay(60000);
+}
+
+#endif


Update version_info.ino

Update version_info.ino

--- Arduino/McLighting/version_info.ino
+++ Arduino/McLighting/version_info.ino
@@ -31,4 +31,7 @@
  * - rethink ESP.getChipId implementaion
  * - check ArduinoJSON version
  * - Try restting prevmode as suggested in #276
+ *
+ * 11 Dec 2018 v 2.1.8
+ * - Fix Auto-Discovery for HA version >= 0.84 #286
  */


Added super bright green LED as CS num 7

--- Arduino/private/ledpuff/ledpuff.ino
+++ Arduino/private/ledpuff/ledpuff.ino
@@ -4,6 +4,7 @@
  */

 // Outputs
+int greenled = 7;
 int camera = 8;
 int led = 9;
 int whisker = 10;
@@ -35,6 +36,7 @@
   pinMode(puff, OUTPUT);
   pinMode(whisker, OUTPUT);
   pinMode(tonech, OUTPUT);
+  pinMode(greenled, OUTPUT);

   // Default all output pins to LOW - for some reason they were floating high on the Due before I (Shane) added this
   digitalWrite(camera, LOW);
@@ -42,6 +44,7 @@
   digitalWrite(puff, LOW);
   digitalWrite(whisker, LOW);
   digitalWrite(tonech, LOW);
+  digitalWrite(greenled, LOW);

   Serial.begin(9600);
 }
@@ -213,6 +216,9 @@
       case 6:
         tone(tonech, tonefreq5, cs);   // turn the LED on (HIGH is the voltage level)
         break;
+      case  7:
+        digitalWrite(greenled, HIGH); // turn the green LED on (HIGH is the voltage level)
+        break;
     }
   }
 }
@@ -227,6 +233,9 @@
       case 2:
         digitalWrite(whisker, LOW);   // turn the LED on (HIGH is the voltage level)
         break;
+      case 7:
+        digitalWrite(greenled, LOW); //  turn the green LED off (LOW is the voltage level)
+        break;
     }
   }
 }
@@ -243,6 +252,9 @@
         break;
       case 3:
         usout = puff;
+        break;
+      case 7:
+        usout = greenled;
         break;
       default:
         usout = 0;