[lmr] Add LMREMOTE_SERIAL define, wait for RF12 transmit in SLEEP_MODE_IDLE, disable stabilizeAdc()

--- arduino/lmremote/lmremote.ino
+++ arduino/lmremote/lmremote.ino
@@ -2,6 +2,8 @@
 #include <avr/sleep.h>
 #include <RF12.h>
 #include <Ports.h>
+
+#define LMREMOTE_SERIAL 115200

 // Node Idenfier for the RFM12B (2-30)
 const unsigned char _rfNodeId = 2;
@@ -39,10 +41,9 @@
 static unsigned char _sameCount;
 static unsigned char _seqNo;

-ISR(WDT_vect) {
-  // The WDT is used solely to wake us from sleep
-  wdt_disable();
-}
+// The WDT is used solely to wake us from sleep
+ISR(WDT_vect) { wdt_disable(); }
+//ISR(WDT_vect) { Sleepy::watchdogEvent(); }

 void sleep(uint8_t wdt_period) {
   set_sleep_mode(SLEEP_MODE_PWR_DOWN);
@@ -76,9 +77,9 @@

 void sleepSeconds(unsigned char secs)
 {
-  while (secs >= 8) { sleep(WDTO_8S);  secs -=8; }
-  if (secs >= 4) { sleep(WDTO_4S);  secs -= 4; }
-  if (secs >= 2) { sleep(WDTO_2S);  secs -= 2; }
+  while (secs >= 8) { sleep(WDTO_8S); secs -=8; }
+  if (secs >= 4) { sleep(WDTO_4S); secs -= 4; }
+  if (secs >= 2) { sleep(WDTO_2S); secs -= 2; }
   if (secs >= 1) { sleep(WDTO_1S); }
 }

@@ -146,9 +147,9 @@

     // HDR=0 means to broadcast, no ACK requested
     rf12_sendStart(0, outbuf, len);
-    rf12_sendWait(0);
-  }  /* while txCount */
-
+    rf12_sendWait(1);
+  }  /* while txCount */
+
   rf12_sleep(RF12_SLEEP);
   if (_pinLedTx != 0xff) digitalWrite(_pinLedTx, LOW);
 }
@@ -222,13 +223,16 @@

 void setup(void)
 {
-  //Serial.begin(115200);
-
   // Turn off the units we never use (this only affects non-sleep power)
   PRR = bit(PRUSART0) | bit(PRTWI) | bit(PRTIM1) | bit(PRTIM2);
   // Disable digital input buffers on the analog in ports
   DIDR0 = bit(ADC5D) | bit(ADC4D) | bit(ADC3D) | bit(ADC2D) | bit(ADC1D) | bit(ADC0D);
   DIDR1 = bit(AIN1D) | bit(AIN0D);
+
+#ifdef LMREMOTE_SERIAL
+  PRR &= ~bit(PRUSART0);
+  Serial.begin(115200);  Serial.println("$UCID,lmremote");
+#endif

   rf12_initialize(_rfNodeId, _rfBand);

@@ -256,15 +260,23 @@
     do {
       ++cnt;
       last = curr;
+#ifdef LMREMOTE_SERIAL
+      Serial.print(curr,DEC);
+      Serial.print(' ');
+#endif
       curr = analogRead(_pinBattery);
     } while ((cnt < 10) && (abs(last - curr) > 2));
   }
+#ifdef LMREMOTE_SERIAL
+  Serial.println();
+#endif
 }

 void loop(void)
 {
+  //Sleepy::loseSomeTime(_sleepInterval * 1000);
   sleepSeconds(_sleepInterval);
-  stabilizeAdc();
+  //stabilizeAdc();
   checkTemps();
 }


buoy: Use habduino float printing method.

--- arduino_buoy/arduino_buoy.ino
+++ arduino_buoy/arduino_buoy.ino
@@ -91,21 +91,7 @@
     nolock=0;
   }

-  char* latStr;
-  char tempStrLat[18];
-  latStr = dtostrf(lat,9,5,tempStrLat);
-  while( (strlen(latStr) > 0) && (latStr[0] == 32) )
-  {
-     strcpy(latStr,&latStr[1]);
-  }
-  char* lonStr;
-  char tempStrLon[18];
-  lonStr = dtostrf(lon,9,5,tempStrLon);
-  while( (strlen(lonStr) > 0) && (lonStr[0] == 32) )
-  {
-     strcpy(lonStr,&lonStr[1]);
-  }
-  sprintf(data,"%sL%s,%sS%d",data,latStr,lonStr,sats);
+  sprintf(data,"%sL%s%i.%05d,%s%i.%05d,%ldS%d",data,lat < 0 ? "-" : "",lat_int,lat_dec,lon < 0 ? "-" : "",lon_int,lon_dec,maxalt,sats);

   sensors.setWaitForConversion(false);
   sensors.requestTemperatures();


Fixed a typo

Fixed a typo


firmware: improve code readability

firmware: improve code readability

--- firmware/firmware.ino
+++ firmware/firmware.ino
@@ -21,11 +21,15 @@
     char buf[64];
 }roboSetup;

-float curX,curY,curZ;
-float tarX,tarY,tarZ; // target xyz position
-int tarA,tarB,posA,posB; // target stepper position
-int8_t motorAfw,motorAbk;
-int8_t motorBfw,motorBbk;
+int stepAuxDelay = 0;
+int stepdelay_min = 250;
+int stepdelay_max = 1000;
+
+#define MS_BEFORE_SERVO_SLEEP 100
+#define SPEED_STEP 1
+#define WIDTH 310
+#define HEIGHT 380
+#define STEPS_PER_MM 87.58 // the same as 3d printer

 int ylimit_pin1 = 12;
 int ylimit_pin2 = 13;
@@ -34,101 +38,80 @@
 int servopin = A1;
 Servo servoPen;

-/************** motor movements ******************/
-void stepperMoveA(int dir)
-{
-  if(dir>0){
-    digitalWrite(11, LOW);
-  }else{
-    digitalWrite(11, HIGH);
-  }
+float curX, curY, curZ;
+float tarX, tarY, tarZ; // target xyz position
+int tarA, tarB, posA, posB; // target stepper position
+int8_t motorAfw, motorAbk;
+int8_t motorBfw, motorBbk;
+
+
+
+// ----------------------------------------
+// XY MOVES
+
+void stepperMoveA(int dir) {
+  if (dir > 0) digitalWrite(11, LOW);
+  else digitalWrite(11, HIGH);
   digitalWrite(10, HIGH);
   digitalWrite(10, LOW);
 }

-void stepperMoveB(int dir)
-{
-  if(dir>0){
-    digitalWrite(3, LOW);
-  }else{
-    digitalWrite(3, HIGH);
-  }
+void stepperMoveB(int dir) {
+  if (dir > 0) digitalWrite(3, LOW);
+  else digitalWrite(3, HIGH);
   digitalWrite(9, HIGH);
   digitalWrite(9, LOW);
 }

-/************** calculate movements ******************/
-int stepAuxDelay=0;
-int stepdelay_min=250;
-int stepdelay_max=1000;
-#define SPEED_STEP 1
-
-void doMove()
-{
-  int mDelay=stepdelay_max;
+void doMove() {
+  int mDelay = stepdelay_max;
   int speedDiff = -SPEED_STEP;
-  int dA,dB,maxD;
-  float stepA,stepB,cntA=0,cntB=0;
+  int dA, dB, maxD;
+  float stepA, stepB, cntA = 0, cntB = 0;
   int d;
   dA = tarA - posA;
   dB = tarB - posB;
-  maxD = max(abs(dA),abs(dB));
-  stepA = (float)abs(dA)/(float)maxD;
-  stepB = (float)abs(dB)/(float)maxD;
-  for(int i=0;(posA!=tarA)||(posB!=tarB);i++){
+  maxD = max(abs(dA), abs(dB));
+  stepA = (float) abs(dA) / (float)maxD;
+  stepB = (float) abs(dB) / (float)maxD;
+  for (int i = 0; (posA != tarA) || (posB != tarB); i++) {
     // move A
-    if(posA!=tarA){
-      cntA+=stepA;
-      if(cntA>=1){
-        d = dA>0?motorAfw:motorAbk;
-        posA+=(dA>0?1:-1);
+    if (posA != tarA) {
+      cntA += stepA;
+      if (cntA >= 1) {
+        d = dA > 0 ? motorAfw : motorAbk;
+        posA += (dA > 0 ? 1 : -1);
         // don't move passed limit !
-        if(
-           (d>0 && digitalRead(xlimit_pin2)==1)
-           || (d<0 && digitalRead(xlimit_pin1)==1)){
-          stepperMoveA(d);
-        }
-        cntA-=1;
+        if ((d > 0 && digitalRead(xlimit_pin2) == 1) || (d < 0 && digitalRead(xlimit_pin1) == 1)) stepperMoveA(d);
+        cntA -= 1;
       }
     }
     // move B
-    if(posB!=tarB){
-      cntB+=stepB;
-      if(cntB>=1){
-        d = dB>0?motorBfw:motorBbk;
-        posB+=(dB>0?1:-1);
+    if (posB != tarB) {
+      cntB += stepB;
+      if (cntB >= 1) {
+        d = dB > 0 ? motorBfw : motorBbk;
+        posB += (dB > 0 ? 1 : -1);
         // don't move passed limit !
-        if(
-           (d>0 && digitalRead(ylimit_pin2)==1)
-           || (d<0 && digitalRead(ylimit_pin1)==1)){
-          stepperMoveB(d);
-        }
-        cntB-=1;
+        if ((d > 0 && digitalRead(ylimit_pin2) == 1) || (d < 0 && digitalRead(ylimit_pin1) == 1)) stepperMoveB(d);
+        cntB -= 1;
       }
     }
-    mDelay=constrain(mDelay+speedDiff,stepdelay_min,stepdelay_max)+stepAuxDelay;
+    mDelay = constrain(mDelay + speedDiff, stepdelay_min, stepdelay_max) + stepAuxDelay;
     delayMicroseconds(mDelay);
-    if((maxD-i)<((stepdelay_max-stepdelay_min)/SPEED_STEP)){
-      speedDiff=SPEED_STEP;
-    }
+    if ((maxD - i) < ((stepdelay_max - stepdelay_min) / SPEED_STEP)) speedDiff = SPEED_STEP;
   }
   posA = tarA;
   posB = tarB;
 }

-/******** mapping xy position to steps ******/
-#define WIDTH 310
-#define HEIGHT 380
-#define STEPS_PER_MM 87.58 // the same as 3d printer
-void prepareMove()
-{
+void prepareMove() {
   float dx = tarX - curX;
   float dy = tarY - curY;
-  float distance = sqrt(dx*dx+dy*dy);
-  if (distance < 0.001)
-    return;
-  tarA = tarX*STEPS_PER_MM;
-  tarB = tarY*STEPS_PER_MM;
+  float distance = sqrt(dx * dx + dy * dy);
+  if (distance < 0.001) return;
+  tarA = tarX * STEPS_PER_MM;
+  tarB = tarY * STEPS_PER_MM;
   doMove();
   curX = tarX;
   curY = tarY;
@@ -144,187 +127,113 @@
   initPosition();
 }

-void initPosition() {
-  curX = 0;
-  curY = 0;
-  posA = 0;
-  posB = 0;
-}
-
-/************** calculate movements ******************/
-void parseCoordinate(char * cmd)
-{
+void initPosition() { curX = 0; curY = 0; posA = 0; posB = 0; }
+
+
+
+// ----------------------------------------
+// PARSING
+
+void parseCoordinate(char * cmd) {
   char * tmp;
   char * str;
   str = strtok_r(cmd, " ", &tmp);
   tarX = curX;
   tarY = curY;
-  while(str!=NULL){
+  while (str!=NULL) {
     str = strtok_r(0, " ", &tmp);
-    if(str[0]=='X'){
-      tarX = atof(str+1);
-    }else if(str[0]=='Y'){
-      tarY = atof(str+1);
-    }else if(str[0]=='Z'){
-      tarZ = atof(str+1);
-    }else if(str[0]=='A'){
-      stepAuxDelay = atoi(str+1);
-    }
+    if (str[0] == 'X') tarX = atof(str + 1);
+    else if (str[0] == 'Y') tarY = atof(str + 1);
+    else if (str[0] == 'Z') tarZ = atof(str + 1);
+    else if (str[0] == 'A') stepAuxDelay = atoi(str + 1);
   }
   prepareMove();
 }

-void echoRobotSetup()
-{
-  Serial.print("M10 XY ");
-  Serial.print(roboSetup.data.width);Serial.print(' ');
-  Serial.print(roboSetup.data.height);Serial.print(' ');
-  Serial.print(curX);Serial.print(' ');
-  Serial.print(curY);Serial.print(' ');
-  Serial.print("A");Serial.print((int)roboSetup.data.motoADir);
-  Serial.print(" B");Serial.print((int)roboSetup.data.motoBDir);
-  Serial.print(" H");Serial.print((int)roboSetup.data.motorSwitch);
-  Serial.print(" S");Serial.print((int)roboSetup.data.speed);
-  Serial.print(" U");Serial.print((int)roboSetup.data.penUpPos);
-  Serial.print(" D");Serial.println((int)roboSetup.data.penDownPos);
-}
-
-void echoEndStop()
-{
-  Serial.print("M11 ");
-  Serial.print(digitalRead(xlimit_pin1)); Serial.print(" ");
-  Serial.print(digitalRead(xlimit_pin2)); Serial.print(" ");
-  Serial.print(digitalRead(ylimit_pin1)); Serial.print(" ");
-  Serial.println(digitalRead(ylimit_pin2));
-}
-
-void syncRobotSetup()
-{
-  int i;
-  for(i=0;i<64;i++){
-    EEPROM.write(i,roboSetup.buf[i]);
-  }
-}
-
-void parseRobotSetup(char * cmd)
-{
+void parseRobotSetup(char * cmd) {
   char * tmp;
   char * str;
   str = strtok_r(cmd, " ", &tmp);
   while(str!=NULL){
     str = strtok_r(0, " ", &tmp);
-    if(str[0]=='A'){
-      roboSetup.data.motoADir = atoi(str+1);
-    }else if(str[0]=='B'){
-      roboSetup.data.motoBDir = atoi(str+1);
-    }else if(str[0]=='H'){
-      roboSetup.data.height = atoi(str+1);
-    }else if(str[0]=='W'){
-      roboSetup.data.width = atoi(str+1);
-    }else if(str[0]=='S'){
-      roboSetup.data.speed = atoi(str+1);
+    if (str[0] == 'A') roboSetup.data.motoADir = atoi(str + 1);
+    else if (str[0] == 'B') roboSetup.data.motoBDir = atoi(str + 1);
+    else if (str[0] == 'H') roboSetup.data.height = atoi(str + 1);
+    else if (str[0] == 'W') roboSetup.data.width = atoi(str + 1);
+    else if (str[0] == 'S'){
+      roboSetup.data.speed = atoi(str + 1);
+      // stepdelay_min = atoi(str + 1);
     }
   }
   syncRobotSetup();
 }

-void parseAuxDelay(char * cmd)
-{
+void parseAuxDelay(char * cmd) {
   char * tmp;
   strtok_r(cmd, " ", &tmp);
   stepAuxDelay = atoi(tmp);
 }

-void parsePen(char * cmd)
-{
+void parsePen(char * cmd) {
   char * tmp;
   strtok_r(cmd, " ", &tmp);
   int pos = atoi(tmp);
   servoPen.write(pos);
 }

-void parsePenPosSetup(char * cmd)
-{
+void parsePenPosSetup(char * cmd) {
   char * tmp;
   char * str;
   str = strtok_r(cmd, " ", &tmp);
   while(str!=NULL){
     str = strtok_r(0, " ", &tmp);
-    if(str[0]=='U'){
-      roboSetup.data.penUpPos = atoi(str+1);
-    }else if(str[0]=='D'){
-      roboSetup.data.penDownPos = atoi(str+1);
-    }
+    if (str[0] == 'U') roboSetup.data.penUpPos = atoi(str + 1);
+    else if (str[0] == 'D') roboSetup.data.penDownPos = atoi(str + 1);
   }
   syncRobotSetup();
 }

-void parseMcode(char * cmd)
-{
-  int code;
-  code = atoi(cmd);
+void parseMcode(char * cmd) {
+  int code = atoi(cmd);
   switch(code){
-    case 1:
-      parsePen(cmd);
-      break;
-    case 2:
-      parsePenPosSetup(cmd);
-      break;
-    case 3:
-      parseAuxDelay(cmd);
-      break;
-    case 5:
-      parseRobotSetup(cmd);
-      break;
-    case 10:
-      echoRobotSetup();
-      break;
-    case 11:
-      echoEndStop();
-      break;
-  }
-}
-
-void parseGcode(char * cmd)
-{
-  int code;
-  code = atoi(cmd);
+    case 1:   parsePen(cmd); break;
+    case 2:   parsePenPosSetup(cmd); break;
+    case 3:   parseAuxDelay(cmd); break;
+    case 5:   parseRobotSetup(cmd); break;
+    case 10:  echoRobotSetup(); break;
+    case 11:  echoEndStop(); break;
+  }
+}
+
+void parseGcode(char * cmd) {
+  int code = atoi(cmd);
   switch(code){
     case 0:
-    case 1:
-      parseCoordinate(cmd);
-      break;
-    case 28:
-      tarX=0; tarY=0;
-      goHome();
-      break;
+    case 1: parseCoordinate(cmd); break;
+    case 28: tarX=0; tarY=0; goHome(); break;
   }
 }

 void parseCmd(char * cmd) {
   Serial.println("Command received.");
-  if (cmd[0]=='G') parseGcode(cmd+1);
-  else if (cmd[0]=='M') parseMcode(cmd+1);
-  else if (cmd[0]=='P') {
-    Serial.print("POS X");
-    Serial.print(curX);
-    Serial.print(" Y");
-    Serial.println(curY);
-  }
-}
-
-// local data
-void initRobotSetup()
-{
-  int i;
-  for(i=0;i<64;i++){
-    roboSetup.buf[i] = EEPROM.read(i);
-  }
-  if(strncmp(roboSetup.data.name,"XY4",3)!=0){
+  if (cmd[0] == 'G') parseGcode(cmd+1);
+  else if (cmd[0] == 'M') parseMcode(cmd+1);
+  else if (cmd[0] == 'P') echoPosition();
+}
+
+
+
+// ----------------------------------------
+// LOCAL DATA
+
+void initRobotSetup() {
+  for(int i = 0; i < 64; i++) roboSetup.buf[i] = EEPROM.read(i);
+
+  if (strncmp(roboSetup.data.name,"XY4", 3) != 0) {
     Serial.println("set to default setup");
     // set to default setup
-    memset(roboSetup.buf,0,64);
-    memcpy(roboSetup.data.name,"XY4",3);
+    memset(roboSetup.buf, 0, 64);
+    memcpy(roboSetup.data.name, "XY4", 3);
     roboSetup.data.motoADir = 0;
     roboSetup.data.motoBDir = 0;
     roboSetup.data.width = WIDTH;
@@ -335,88 +244,131 @@
     roboSetup.data.penDownPos = 90;
     syncRobotSetup();
   }
+
   // init motor direction
   // yzj, match to standard connection of xy
   // A = x, B = y
-  if(roboSetup.data.motoADir==0){
-    motorAfw=-1;motorAbk=1;
-  }else{
-    motorAfw=1;motorAbk=-1;
-  }
-  if(roboSetup.data.motoBDir==0){
-    motorBfw=-1;motorBbk=1;
-  }else{
-    motorBfw=1;motorBbk=-1;
-  }
-  int spd = 100 - roboSetup.data.speed;
-//  stepdelay_min = spd*10;
-//  stepdelay_max = spd*100;
-}
-
-
-/************** arduino ******************/
+  if (roboSetup.data.motoADir == 0) {
+    motorAfw = -1;
+    motorAbk = 1;
+  } else {
+    motorAfw = 1;
+    motorAbk = -1;
+  }
+  if (roboSetup.data.motoBDir == 0) {
+    motorBfw = -1;
+    motorBbk = 1;
+  } else {
+    motorBfw = 1;
+    motorBbk = -1;
+  }
+}
+
+void syncRobotSetup() {
+  for (int i = 0; i < 64; i++) EEPROM.write(i, roboSetup.buf[i]);
+}
+
+
+// ----------------------------------------
+// ARDUINO
+
+char buf[64];
+int8_t bufindex;
+boolean isAsleep = false;
+
 void setup() {
   pinMode(11, OUTPUT);
   pinMode(10, OUTPUT);
   pinMode(3, OUTPUT);
   pinMode(9, OUTPUT);
-  pinMode(ylimit_pin1,INPUT_PULLUP);
-  pinMode(ylimit_pin2,INPUT_PULLUP);
-  pinMode(xlimit_pin1,INPUT_PULLUP);
-  pinMode(xlimit_pin2,INPUT_PULLUP);
+  pinMode(ylimit_pin1, INPUT_PULLUP);
+  pinMode(ylimit_pin2, INPUT_PULLUP);
+  pinMode(xlimit_pin1, INPUT_PULLUP);
+  pinMode(xlimit_pin2, INPUT_PULLUP);
   Serial.begin(115200);
   initRobotSetup();
   initPosition();
+
   servoPen.write(roboSetup.data.penUpPos);
   delay(100);
   servoPen.attach(servopin);
+
   goHome();
   Serial.println("ready");
 }

-char buf[64];
-int8_t bufindex;
-
-// -------------------------------------------------------------------------
-
-int no_data = 0;
-boolean isAsleep = false;
-
 void loop() {
-  // echoEndStop();
-  if(Serial.available()){
-    if (isAsleep) {
-      no_data = 0;
-      wakeUp();
-    }
+  if (Serial.available()) {
+    if (isAsleep) wakeUp();

     char c = Serial.read();
-    buf[bufindex++]=c;
-    if(c=='\n'){
-      buf[bufindex]='\0';
+    buf[bufindex++] = c;
+    if (c == '\n') {
+      buf[bufindex] = '\0';
       parseCmd(buf);
-      memset(buf,0,64);
+      memset(buf, 0, 64);
       bufindex = 0;
     }
-    if(bufindex>=64){
-      bufindex=0;
-    }
-  } else if(!isAsleep) {
-    no_data++;
-    delay(100);
-    if (no_data > 100) {
-      sleep();
-    }
-  }
-}
+    if(bufindex >= 64) bufindex=0;
+  } else if (!isAsleep) {
+    sleep();
+  }
+}
+
+
+
+// ----------------------------------------
+// SERVO SLEEP
+
+int sleep_timer = 0;

 void sleep() {
-  isAsleep = true;
-  servoPen.detach();
-  Serial.print('good night !');
+  sleep_timer++;
+  delay(100);
+  if (sleep_timer > MS_BEFORE_SERVO_SLEEP) {
+    isAsleep = true;
+    servoPen.detach();
+    Serial.print('good night !');
+  }
 }

 void wakeUp() {
+  sleep_timer = 0;
   isAsleep = false;
   servoPen.attach(servopin);
+}
+
+
+
+
+// ----------------------------------------
+// ECHO
+
+void echoPosition() {
+  Serial.print("POS X");
+  Serial.print(curX);
+  Serial.print(" Y");
+  Serial.println(curY);
+}
+
+void echoRobotSetup() {
+  Serial.print("M10 XY ");
+  Serial.print(roboSetup.data.width); Serial.print(' ');
+  Serial.print(roboSetup.data.height); Serial.print(' ');
+  Serial.print(curX); Serial.print(' ');
+  Serial.print(curY); Serial.print(' ');
+  Serial.print("A"); Serial.print((int)roboSetup.data.motoADir);
+  Serial.print(" B"); Serial.print((int)roboSetup.data.motoBDir);
+  Serial.print(" H"); Serial.print((int)roboSetup.data.motorSwitch);
+  Serial.print(" S"); Serial.print((int)roboSetup.data.speed);
+  Serial.print(" U"); Serial.print((int)roboSetup.data.penUpPos);
+  Serial.print(" D"); Serial.println((int)roboSetup.data.penDownPos);
+}
+
+void echoEndStop() {
+  Serial.print("M11 ");
+  Serial.print(digitalRead(xlimit_pin1)); Serial.print(" ");
+  Serial.print(digitalRead(xlimit_pin2)); Serial.print(" ");
+  Serial.print(digitalRead(ylimit_pin1)); Serial.print(" ");
+  Serial.println(digitalRead(ylimit_pin2));
 }


firmware: minor tweak to the sleep/wakeup servo

--- firmware/firmware.ino
+++ firmware/firmware.ino
@@ -25,7 +25,7 @@
 int stepdelay_min = 250;
 int stepdelay_max = 1000;

-#define MS_BEFORE_SERVO_SLEEP 100
+#define MS_BEFORE_SERVO_SLEEP 1000
 #define SPEED_STEP 1
 #define WIDTH 310
 #define HEIGHT 380
@@ -274,7 +274,6 @@

 char buf[64];
 int8_t bufindex;
-boolean isAsleep = false;

 void setup() {
   pinMode(11, OUTPUT);
@@ -299,7 +298,7 @@

 void loop() {
   if (Serial.available()) {
-    if (isAsleep) wakeUp();
+    wakeUp();

     char c = Serial.read();
     buf[bufindex++] = c;
@@ -310,9 +309,8 @@
       bufindex = 0;
     }
     if(bufindex >= 64) bufindex=0;
-  } else if (!isAsleep) {
-    sleep();
-  }
+
+  } else sleep();
 }

@@ -321,21 +319,26 @@
 // SERVO SLEEP

 int sleep_timer = 0;
+boolean isAsleep = false;

 void sleep() {
-  sleep_timer++;
-  delay(100);
-  if (sleep_timer > MS_BEFORE_SERVO_SLEEP) {
-    isAsleep = true;
-    servoPen.detach();
-    Serial.print('good night !');
+  if (!isAsleep) {
+    sleep_timer++;
+    delay(100);
+    if (sleep_timer > MS_BEFORE_SERVO_SLEEP / 100) {
+      isAsleep = true;
+      servoPen.detach();
+      Serial.print('good night !');
+    }
   }
 }

 void wakeUp() {
-  sleep_timer = 0;
-  isAsleep = false;
-  servoPen.attach(servopin);
+  if (isAsleep) {
+    sleep_timer = 0;
+    isAsleep = false;
+    servoPen.attach(servopin);
+  }
 }


use HT1632 customized arduino library

use HT1632 customized arduino library

Use library lightened from gauravmm/HT1632-for-Arduino with bitbanging spi code, instead of using the esp8266 arduino SPI library.

--- Woodstation.ino
+++ Woodstation.ino
@@ -4,14 +4,16 @@
 #include <WiFiUdp.h>
 #include <ArduinoOTA.h>

-#include "ht1632c.h"
-
-/// framebuffer
-static uint8_t** ht1632c_framebuffer = 0;
-static uint8_t ht1632c_framebuffer_len = 96;
-
-const char* ssid = "********";
-const char* password = "********";
+#include "HT1632.h"
+
+#define ESP8266
+#define HT1632_CS   D1
+#define HT1632_CLK  D5
+#define HT1632_MOSI D7
+
+
+const char* ssid = "**************";
+const char* password = "*************";

 // NTP Servers:
 static const char ntpServerName[] = "europe.pool.ntp.org";
@@ -87,10 +89,10 @@
   setSyncInterval(300);

   Serial.println("Setting up SPI display");
-  ht1632c_init(HT1632_CMD_8PMOS);
-  ht1632c_clear();
-  ht1632c_pwm(15);
-  ht1632c_sendframe();
+  HT1632.begin(HT1632_CS, HT1632_CLK, HT1632_MOSI);
+  HT1632.clear();
+  HT1632.setPixel(0,7); // ':' on time display
+  HT1632.setPixel(20,7); // ':' on time display
 }

 time_t prevDisplay = 0; // when the digital clock was displayed
@@ -116,47 +118,41 @@
   delay(100);
 }

-void digitalClockDisplay()
-{
-  char buffer[7];
-  sprintf(buffer, "%02d%02d%02d", hour(), minute(), second());
-  Serial.println(buffer);
-}
-
-void printDigits(int digits)
-{
-  // utility for digital clock display: prints preceding colon and leading 0
-  Serial.print(":");
-  if (digits < 10)
-    Serial.print('0');
-  Serial.print(digits);
-}
-
-
-
-
 //------------------ Woodstation related data -------------------

+static int humidityDisplayBaseAddresses[2][2]=
+{
+    {0,0},
+    {7,0}
+};
+
+static int temperatureDisplayBaseAddresses[3][2]=
+{
+    {0,1},
+    {7,1},
+    {14,1}
+};
+
 static int timeDisplayBaseAddresses[6][2]=
 {
     {0,2},  //H
-    {14,2}, //H
-    {28,2}, //m
+    {7,2}, //H
+    {14,2}, //m
     {0,3},  //m
-    {14,3}, //s
-    {28,3}  //s
+    {7,3}, //s
+    {14,3}  //s
 };

 static int dateDisplayBaseAddresses[8][2]=
 {
-    {1,0},  //D
-    {15,0}, //D
-    {29,0}, //M
-    {1,1},  //M
-    {15,1}, //Y
-    {29,1}, //Y
+    {0,4},  //D
+    {7,4}, //D
+    {14,4}, //M
+    {0,5},  //M
+    {7,5}, //Y
+    {14,5}, //Y
     {1,2},  //Y
-    {29,1}  //Y
+    {7,6}  //Y
 };

 static int sevenSegmentDigits[10][7]=
@@ -180,26 +176,28 @@
     return;
   int writeAddr = baseAddr;
   for (int i = 0; i < 7; ++i) {
-    ht1632c_update_framebuffer(writeAddr, bitIndex, sevenSegmentCharBitSequence[i]);
-    Serial.print(sevenSegmentCharBitSequence[i]);
-    writeAddr = writeAddr + 2;
-  }
-  Serial.println();
+    if (sevenSegmentCharBitSequence[i]) {
+      HT1632.setPixel(writeAddr, bitIndex);
+    } else {
+      HT1632.clearPixel(writeAddr, bitIndex);
+    }
+    writeAddr++;
+  }
 }

 void updateTimeDisplay(char* newTime){
   int characterMap[7] = {0, 0, 0, 0, 0, 0, 0};
   int iValue = 0;
   char cValue = '0';
+  //HT1632.clear();
   for(int timeDigitIndex = 0; timeDigitIndex < 6; timeDigitIndex++){
     cValue = newTime[timeDigitIndex];
     iValue = atoi(&cValue);
-    Serial.println(iValue);
     int baseAddr = timeDisplayBaseAddresses[timeDigitIndex][0];
     int bitIndex = timeDisplayBaseAddresses[timeDigitIndex][1];
     writeDisplayCharacterAtIndex(sevenSegmentDigits[iValue], baseAddr, bitIndex);
   }
-  Serial.println();
+  HT1632.render();
 }

@@ -285,190 +283,3 @@
   Udp.write(packetBuffer, NTP_PACKET_SIZE);
   Udp.endPacket();
 }
-
-
-//------------------- HT1632 Related data ------------
-
-void ht1632c_chipselect(const int value)
-{
-  digitalWrite(SS, toBit(value));
-}
-
-void ht1632c_sendcmd(const uint8_t cmd) {
-  uint16_t data = HT1632_ID_CMD;
-  data <<= HT1632_CMD_LEN;
-  data |= cmd;
-  data <<= 5;
-  //reverse_endian(&data, sizeof(data));
-
-  ht1632c_chipselect(1);
-  SPI.write16(data);
-  ht1632c_chipselect(0);
-
-}
-
-void ht1632c_update_framebuffer(const int addr, const uint8_t bitIndex, const uint8_t bitValue)
-{
-  if(addr <0 || addr > (ht1632c_framebuffer_len-1) || bitIndex > 3)
-    return;
-  ht1632c_framebuffer[addr][bitIndex] = toBit(bitValue);
-}
-
-uint8_t ht1632c_get_framebuffer(const int addr, const uint8_t bitIndex)
-{
-  if(addr <0 || addr > (ht1632c_framebuffer_len-1) || bitIndex > 3)
-      return 0;
-  return ht1632c_framebuffer[addr][bitIndex];
-}
-
-//
-// public functions
-//
-
-int ht1632c_init(const uint8_t commonsMode)
-{
-  // init SPI
-  pinMode(SS, OUTPUT);
-  SPI.begin();
-  SPI.setBitOrder(MSBFIRST);
-  SPI.setClockDivider(SPI_CLOCK_DIV64);
-  SPI.setDataMode(SPI_MODE0);
-
-
-  switch (commonsMode) {
-    case HT1632_CMD_8NMOS:
-    case HT1632_CMD_8PMOS:
-      ht1632c_framebuffer_len = 64;
-      break;
-    case HT1632_CMD_16NMOS:
-    case HT1632_CMD_16PMOS:
-      ht1632c_framebuffer_len = 96;
-      break;
-    default:
-      break;
-  }
-
-
-  ht1632c_framebuffer = (uint8_t**) malloc(ht1632c_framebuffer_len*sizeof(uint8_t*));
-  if (!ht1632c_framebuffer) {
-    Serial.println( "Framebuffer allocation failed.");
-    return 3;
-  }
-
-  for (int i = 0; i < ht1632c_framebuffer_len; ++i) {
-    ht1632c_framebuffer[i] = (uint8_t*) malloc(4*sizeof(uint8_t));
-    if (!ht1632c_framebuffer[i]) {
-        Serial.println( "Framebuffer allocation failed.");
-        return 3;
-      }
-    ht1632c_framebuffer[i][0] = ht1632c_framebuffer[i][1] = ht1632c_framebuffer[i][1] = ht1632c_framebuffer[i][3] = 0;
-  }
-
-  // init display
-  ht1632c_sendcmd(HT1632_CMD_SYSDIS);
-  ht1632c_sendcmd(commonsMode);
-  ht1632c_sendcmd(HT1632_CMD_MSTMD);
-  ht1632c_sendcmd(HT1632_CMD_RCCLK);
-  ht1632c_sendcmd(HT1632_CMD_SYSON);
-  ht1632c_sendcmd(HT1632_CMD_LEDON);
-  ht1632c_sendcmd(HT1632_CMD_BLOFF);
-  ht1632c_sendcmd(HT1632_CMD_PWM);
-
-  ht1632c_clear();
-  ht1632c_sendframe();
-
-  return 0;
-}
-
-int ht1632c_close()
-{
-  SPI.end();
-  if (ht1632c_framebuffer) {
-    for (int i = 0; i < ht1632c_framebuffer_len; ++i) {
-      if (ht1632c_framebuffer[i]) {
-        free(ht1632c_framebuffer[i]);
-        ht1632c_framebuffer[i] = 0;
-      }
-    }
-    free(ht1632c_framebuffer);
-    ht1632c_framebuffer = 0;
-  }
-}
-
-void ht1632c_pwm(const uint8_t value)
-{
-  ht1632c_sendcmd(HT1632_CMD_PWM | (value & 0x0f));
-}
-
-void ht1632c_sendframe()
-{
-  uint16_t data = HT1632_ID_WR;
-  data <<= HT1632_ADDR_LEN;
-  data <<= 6;
-
-  //We append the first 1.5 addresses values, to fill the 16bit buffer
-  uint8_t bitValues = 0;
-  for (int j = 0; j < 4; ++j) {
-    bitValues <<= 1;
-    bitValues |= toBit(ht1632c_framebuffer[0][j]);
-  }
-  for (int j = 0; j < 2; ++j) {
-    bitValues <<= 1;
-    bitValues |= toBit(ht1632c_framebuffer[1][j]);
-  }
-  data |= bitValues;
-  //reverse_endian(&data, sizeof(data));
-
-  ht1632c_chipselect(1);
-  SPI.write16(data);
-
-
-  //Loop to write the frame buffer
-  int i = 1;
-  while (i < ht1632c_framebuffer_len) {
-    bitValues = 0;
-    //we copy the last 2 bits of the previous address,
-    //as they are truncated due to message size of 16b
-    //
-    //(format of bit values : AABB BBCC)
-    for (int j = 2; j < 4; ++j) {
-      bitValues <<= 1;
-      bitValues |= toBit(ht1632c_framebuffer[i][j]);
-    }
-    i++;
-    if (i == ht1632c_framebuffer_len) {
-      bitValues <<=6;
-    }else {
-      for (int j = 0; j < 4; ++j) {
-        bitValues <<= 1;
-        bitValues |= toBit(ht1632c_framebuffer[i][j]);
-      }
-      i++;
-      if (i == ht1632c_framebuffer_len) {
-        bitValues <<= 2;
-      }else {
-        for (int j = 0; j < 2; ++j) {
-          bitValues <<= 1;
-          bitValues |= toBit(ht1632c_framebuffer[i][j]);
-        }
-      }
-
-    }
-    SPI.write(bitValues);
-  }
-
-  ht1632c_chipselect(0);
-}
-
-void ht1632c_clear()
-{
-  // clear buffer
-  if (ht1632c_framebuffer) {
-    for (int i = 0; i < ht1632c_framebuffer_len; ++i) {
-      if (ht1632c_framebuffer[i]) {
-        ht1632c_framebuffer[i][0] = ht1632c_framebuffer[i][1] = ht1632c_framebuffer[i][1] = ht1632c_framebuffer[i][3] = 0;
-      }
-    }
-  }
-
-}


Elro versie

Elro versie

--- Arduino/ELROSender/ELROSender.ino
+++ Arduino/ELROSender/ELROSender.ino
@@ -1,73 +1,228 @@
+#include <RemoteTransmitter.h>
 #include <RemoteReceiver.h>
 #include "SocketIOClient.h"
 #include "Ethernet.h"
 #include "SPI.h"
+#include <Time.h>
 #include <string.h>

-// Used for the ElRO remote functionality
-const int transmitterAddress = 12;
-const int transmitterPin = 7;
-const int transmitterPeriod = 320;
-const int transmitterTimes = 320;
-
-NewRemoteTransmitter transmitter(transmitterPin, transmitterPeriod, transmitterTimes);
+// Used for the KAKU remote functionality
+const long transmitterAddress = 12;
+const byte transmitterPin = 7;
+const unsigned int transmitterPeriod = 320;
+const byte transmitterRepeats = 3;
+
+// Used for smart lights
+const byte ldrPin = A0;
+const short numValues = 4;
+const short timeFrameBefore = 30; // 0.5 Hour before
+const short timeFrameAfter = 150; // 2.5 Hour after
+const unsigned long interval = 1000;
+
+// Smart learning variables
+short lightThresholds[numValues];
+short lightThreshold = 200;
+
+short minutes[numValues];
+short minutesThreshold = 18 * 60; // The time to start, 18:00
+
+byte timeArrayPosition = 0;
+unsigned long lastCheck;
+
+unsigned short lastDay = 0;
+
+// KAKU Transmitter
+ElroTransmitter transmitter(transmitterPin, transmitterPeriod, transmitterRepeats);

 // Ethernet details
-byte mac[] = { 0xDE, 0xAD, 0xBE, 0xEF, 0xFE, 0xED };
-char hostname[] = "ardnmtn.barthopster.nl";
+byte mac[] = {
+  0xDE, 0xAD, 0xBE, 0xEF, 0xFE, 0xED };
+char hostname[] = "192.168.0.203";
+//char hostname[] = "ardnmtn.barthopster.nl";
 int port = 8181;

 SocketIOClient client;

 void setup() {
   Serial.begin(57600);
-
+
   // Init the Ethernet shield
   Ethernet.begin(mac);
-
+
   // Connect!
   if (!client.connect(hostname, port))
     Serial.println("Not connected.");
-
+
   // Catch any received data
   client.setDataArrivedDelegate(onData);
-
+
   // Second handshake
   client.send("Say welcome");
+
+  // Init the receiver
+  RemoteReceiver::init(0, 2, catchReceivedCode);
 }

 void loop() {
+  smartCheck();
   client.monitor();
 }

 // Websocket message handler
 void onData(SocketIOClient client, char *data) {
-  char lightChar;
-
-  // Light 1
-  if(strstr(data, "1")) {
-    lightChar = 'A';
+  if (strstr(data, "time")) {
+    timeUpdate(data + 5);
+  }
+  else {
+    char lightChar;
+
+    // Light 1
+    if (strstr(data, "0")) {
+      lightChar = 'A';
+    }
+
+    // Light 2
+    if (strstr(data, "1")) {
+      lightChar = 'B';
+    }
+
+    // Light 3
+    if (strstr(data, "2")) {
+      lightChar = 'C';
+    }
+
+    // Light 4
+    if (strstr(data, "3")) {
+      lightChar = 'D';
+    }
+
+    // First disable the receiver
+    RemoteReceiver::disable();
+
+    // Turn on the light
+    if (strstr(data, "on")) {
+      transmitter.sendSignal(transmitterAddress, lightChar, true);
+      // Enable this to update SmartValue updating, untested
+      // updateSmartValues();
+    }
+    else { // Turn off
+      transmitter.sendSignal(transmitterAddress, lightChar, true);
+    }
+
+    // Enable the receiver again
+    RemoteReceiver::enable();
   }
-
-  // Light 2
-  if(strstr(data, "2")) {
-    lightChar = 'B';
+}
+
+// Callback function is called only when a valid code is received.
+void catchReceivedCode(unsigned long receivedCode, unsigned int period) {
+  Serial.println("catchReceivedCode");
+
+  // Disable the receiver
+  RemoteReceiver::disable();
+
+  /* This does work nice for the NetRemoteReciever, but not for the older RemoteReciever
+  /* Currently nothing is done with the intercepted code, it will work, but less nice
+   // Take action only if the transmitter address is correct
+   if (receivedCode.address == transmitterAddress) {
+   char lightCommand[16];
+   sprintf(lightCommand, "light%01u:%s", receivedCode.unit, receivedCode.switchType == NewRemoteCode::off ? "false" : "true");
+
+   client.send(lightCommand);
+
+   // Enable this to update SmartValue updating, untested
+   // updateSmartValues();
+   }
+   */
+
+  // Enable the receiver again
+  RemoteReceiver::enable();
+}
+
+// Check for turing on the light using the smart function
+void smartCheck() {
+  unsigned long curTime = millis();
+  if ((day() != lastDay)&&(curTime > (lastCheck + interval) || lastCheck < curTime)) {
+    lastCheck = curTime;
+    //Serial.println("Check");
+    short currentLightValue = analogRead(ldrPin);
+    /*
+    Serial.print("LightValue: ");
+     Serial.println(currentLightValue);
+     */
+    if (currentLightValue <= lightThreshold) {
+      short curTimeMinutes = hour() * 60 + minute();
+      /*
+      Serial.print("Day: ");
+       Serial.println(day());
+       Serial.print("CurTime: ");
+       Serial.println(curTimeMinutes);
+       Serial.print("WantTime: ");
+       Serial.println(minutesThreshold);
+       */
+      if (curTimeMinutes > (minutesThreshold - timeFrameBefore) && curTimeMinutes < (minutesThreshold + timeFrameAfter)) {
+        Serial.println("Lights on");
+        lastDay = day();
+        RemoteReceiver::disable();
+        for (char i = 0; i < 4; i++) {
+          transmitter.sendSignal(transmitterAddress, i + 'A', true);
+          char lightCommand[16];
+          sprintf(lightCommand, "light%01u:%s", i, "true");
+          client.send(lightCommand);
+        }
+        RemoteReceiver::enable();
+      }
+    }
   }
-
-  // Light 3
-  if(strstr(data, "3")) {
-    lightChar = 'C';
+}
+
+// Adds current values to the smartlearning, currently not used because of lack of time
+void updateSmartValues() {
+  short timeMinutes = hour() * 60 + minute();
+  short LDRLight = analogRead(ldrPin);
+
+  // Add the new values
+  if (timeArrayPosition >= numValues)
+    timeArrayPosition = 0;
+
+  minutes[timeArrayPosition] = timeMinutes;
+  lightThresholds[timeArrayPosition] = LDRLight;
+
+  timeArrayPosition++;
+
+  // Calculate new on/off moments
+  for (int i = 0; i < numValues; i++) {
+    minutesThreshold += minutes[i];
+    lightThreshold += lightThresholds[i];
   }
-
-  // Light 4
-  if(strstr(data, "4")) {
-    lightChar = 'D';
-  }
-
-  // Turn on the light
-  if(strstr(data, "on")) {
-    transmitter.sendUnit(lightNumber, true);
-  } else { // Turn off
-    transmitter.sendUnit(lightNumber, false);
-  }
-}
+  minutesThreshold /= numValues;
+  lightThreshold /= numValues;
+}
+
+// Sets the current date to the data in the string
+// The used format is "hours,minutes,seconds,day,month,year"
+void timeUpdate(char *timeString) {
+  Serial.println("timeUpdate");
+  Serial.print("Update time to: ");
+  Serial.println(timeString+28);
+
+  char *p = timeString+28;
+  char *str;
+  byte second, minute, hour, day, month;
+  short year;
+  if ((str = strtok_r(p, ",", &p)) != NULL)
+    hour = atoi(str);
+  if ((str = strtok_r(p, ",", &p)) != NULL)
+    minute = atoi(str);
+  if ((str = strtok_r(p, ",", &p)) != NULL)
+    second = atoi(str);
+  if ((str = strtok_r(p, ",", &p)) != NULL)
+    day  = atoi(str);
+  if ((str = strtok_r(p, ",", &p)) != NULL)
+    month = atoi(str);
+  if ((str = strtok_r(p, ",", &p)) != NULL)
+    year = atoi(str);
+
+  setTime(hour, minute, second, day, month, year);
+}
+


Added highscore reset to stacker game

Added highscore reset to stacker game

--- examples/ArduinOLED_u8g2_StackerGame/ArduinOLED_u8g2_StackerGame.ino
+++ examples/ArduinOLED_u8g2_StackerGame/ArduinOLED_u8g2_StackerGame.ino
@@ -189,6 +189,13 @@
   display.print(F("Press any button"));
 }

+void resetScreen() {
+  display.setCursor(0, 2*10+5);
+  display.print(F("Highscore Reset"));
+  display.setCursor(0, 5*10);
+  display.print(F("Press any button"));
+}
+
 void setup() {
   ArduinOLED.begin(); //start the ArduinOLED library, which controls the buttons and joystick
   display.begin(); //start the u8g2 library, which controls the display
@@ -198,11 +205,17 @@
   display.setDrawColor(1);
   display.setFontPosTop();
   display.setFontDirection(0);
+
+  //hold down the R button to reset the stacker highscore
+  if(ArduinOLED.isPressed(BTN_R)) {
+    EEPROM.write(STACKER_EEPROM_ADDR, 0);
+    render(resetScreen); //display the "highscore reset" message
+    ArduinOLED.pause(BTN_ANY); //wait for any button to be pressed
+  }
+
   render(setupScreen); //display the menu
-
-  while (ArduinOLED.isPressed(BTN_ANY)); //wait for a button to be pressed
-  while (!ArduinOLED.isPressed(BTN_ANY)); //wait for a button to be pressed
-  while (ArduinOLED.isPressed(BTN_ANY)); //wait for a button to be pressed
+
+  ArduinOLED.pause(BTN_ANY); //wait for any button to be pressed
 //  display.setFont(u8g2_font_unifont_t_symbols); //set the font to allow unicode later
 }


web server for initiating reboot

web server for initiating reboot

First draft of a web server. It's not good at all, but it seems to work.

--- ArduinoWeatherStation.ino
+++ ArduinoWeatherStation.ino
@@ -8,15 +8,15 @@
  Much of this is based on Mike Grusin's USB Weather Board code: https://www.sparkfun.com/products/10586

  */
-const String wxVersion = "L17eB2";
-const String wxOwner = "-LR-";
+const String wxVersion = "L18cB1";
+const String wxOwner = "-WX-";
 const byte ina219a_HWaddr = 0x40;  //0x40 for everyone but Lance. 0x44 for Lance.
 const byte ina219b_HWaddr = 0x41;  //
 const byte bme280a_HWaddr = 0x76;  //Default may be 0x77 depending on mfgr
 const byte bme280b_HWaddr = 0x77;
 const bool disableNTP = false;      //Set to false to allow NTP, but it can cause crashes if it doesn't get a response.
-const bool enableEthDump2Serial = true;  //Set to false to suppress spitting Ethernet output to serial. Sometimes unprintable characters mess up the terminal.
-const String startupMessage = "UM Weather Station (ver L17eB2 2017/09/30 add solar pause reporting) starting at ms ";
+const bool enableEthDump2Serial = false;  //Set to false to suppress spitting Ethernet output to serial. Sometimes unprintable characters mess up the terminal.
+const String startupMessage = "UM Weather Station (ver L18cB1 2017/09/30 Solar Panel 1/1 minute) starting at ms ";
 //#define FOURMINUTEDAY              // Switch from day to night every four minutes for DEBUG

@@ -121,9 +121,11 @@
 bool powerSave = false;     //Set a flag when we're in power save mode. Do some stuff different.
 bool ethEnabled = false;    //Set once Eth is enabled because enabling incurs a 30 second pause that we don't want to repeat.
 bool pauseSolar = false;    //We need to charge pausing when it gets hot or if charging too fast. It == battery, box, outside, etc...
-byte pauseSolarMinutes = 5; //How long to leave solar off when we turn it off.
+byte pauseSolarMinutes = 2; //How long to leave solar off when we turn it off.
+byte resumeSolarMinutes = 3;//How long to leave solar ON even if charge rate is high.
 float pauseSolarChargeCurrent;  //Store the battery charging rate that resulted in a solar panel "pause" so we can report it.
 time_t pauseSolarStartTime; //Keep track of when we paused the solar panel so we can leave it off for a set time.
+time_t resumeSolarStartTime;//Similarly, what time we resumed so we don't cut it off too fast.
 time_t reportWatchdog = 0;  //Do we need to report a watchdog reset?
 time_t recentTime = 0;      //Set the current time periodically so we can use it in the Watchdog Interrupt
 time_t lastCrashTime = 0;
@@ -278,12 +280,16 @@
 IPAddress dnsServer(8, 8, 8, 8);
 IPAddress gateway(192, 168, IPq3, IPgw);  // Must be 254 for Marshall, set at TOP of sketch since we need to check/change often.
 IPAddress subnet(255, 255, 255, 0);
+EthernetClient client;          // For outgoing connections, uploading to the CSS webserver
+EthernetClient incomingClient;  // For incoming connections. Initially this is just to prompt a reboot for new code upload.
+EthernetServer server(23537);
+EthernetUDP Udp;

 // if you don't want to use DNS (and reduce your sketch size)
 // use the numeric IP instead of the name for the server:
 //IPAddress server(74,125,232,128);    // numeric IP for Google (no DNS)
 //char server[] = "www.google.com";    // name address for Google (using DNS)
-char server[] = "www.crestlinesoaring.org"; // Web server to connect to.
+char CSSserver[] = "www.crestlinesoaring.org"; // Web server to connect to.
 // [MarshallProprietary]

 // Some debugging and record keeping variables
@@ -315,12 +321,6 @@
 unsigned long msNTPrequest;          // miliseconds at which NTP request was made (so we can see how long it took)

-// Initialize the Ethernet client library
-// with the IP address and port of the server
-// that you want to connect to (port 80 is default for HTTP):
-EthernetClient client;
-EthernetUDP Udp;
-
 // Turns on power for components needed for network connectivity
 void enableEthernet() {

@@ -342,6 +342,9 @@
     Serial.write(8);
     if (i > 9) {
       Serial.write(8);
+    }
+    if (i == 10) {
+      Serial.write("0");
     }
     Serial.print(i - 1);

@@ -356,7 +359,8 @@
   // ETH takes 5 seconds to be ready to send when turned on
   // This a poor way to accomplish this task; better would be to ping
   Serial.println();
-  Serial.print(": Eth startup delay, 5 more seconds:    ");
+  Serial.print(getTimeWithZeros());
+  Serial.print(": Eth startup delay, 5 more seconds:  0");
   for (int i=5; i>0; i--) {

     // Count down the seconds on Serial. Character 8 is the backspace.
@@ -369,8 +373,10 @@
     wdt_reset();
     delay(1000);
   }
+  Serial.println();

   Ethernet.begin(mac, ip, dnsServer, gateway, subnet); // Eth must be initialized after each power up
+  server.begin();
   ethEnabled = true;

   Serial.print(millis());
@@ -384,7 +390,9 @@
 void disableEthernet() {
   Serial.println();
   Serial.print(getTimeWithZeros());
-  Serial.println(": disableEthernet() called. Shutting everything down.");
+  Serial.println(F(": disableEthernet() called. Shutting everything down."));
+  incomingClient.stop();
+  client.stop();

   pinMode(PIN_UBIQUITI_DISABLE, OUTPUT);                  // prepares Ubiquiti power control pin
   digitalWrite(PIN_UBIQUITI_DISABLE, UBIQUITI_DISABLED);  // turns Ubiquiti off
@@ -490,7 +498,7 @@
     wdt_enable(WDTO_8S);

     if (EEPROM.read(eePowerSave) == 255) {
-      Serial.println("EEPROM eePowerSave was 255, is this a new Arduino? Setting to false (0).");
+      Serial.println(F("EEPROM eePowerSave was 255, is this a new Arduino? Setting to false (0)."));
       EEPROM.update(eePowerSave, false);
     }

@@ -499,15 +507,15 @@
     pinMode(30, OUTPUT);                       //             common GND source for "YYD-3" FET switches.

     // Check EEPROM to see if we should be in power save mode. If so, shut some stuff off immediately.
-    Serial.print("Reading EEPROM to see power save state: ");
+    Serial.print(F("Reading EEPROM to see power save state: "));
     if (EEPROM.read(eePowerSave)) {
-      Serial.print("Power Save. Shutting off Eth and Ubiquiti... ");
+      Serial.print(F("Power Save. Shutting off Eth and Ubiquiti... "));
       powerSave = true;

       disableEthernet();

     } else {
-      Serial.print("No power save. Turning on Eth and Ubiquiti... ");
+      Serial.print(F("No power save. Turning on Eth and Ubiquiti... "));
       powerSave = false;

       enableEthernet();
@@ -764,7 +772,50 @@

 void loop()
-{
+{
+  //First check for incoming Ethernet connections. So far, this is only "connecing to reset". Not much happens.
+  if (!powerSave) {
+    msTemp = millis();
+    incomingClient = server.available();
+    if (incomingClient) {
+      Serial.println(F("  --=Ethernet client connected!!=-- "));
+      Serial.println(F("    -= Going down for reboot =-  "));
+      // Probably just waiting here is enough to cause a WatchDog reset, which is all we really need.
+      while (incomingClient.connected()) {
+        //Serial.print(F("Entering While incomingClient.connected() at ms: "));
+        //Serial.println(millis());
+        if (incomingClient.available()) {
+          char c = incomingClient.read();
+          Serial.write(c);
+          incomingClient.print(c);
+          if (c == 'R') {
+            wdt_reset();
+            Serial.println(F("---===---===--- Client hit R and [enter], which causes the reboot ---===---===---"));
+            incomingClient.println(F("R and Enter detected. Rebooting and disconnecting."));
+            delay(100);
+            Serial.println(); Serial.print(" ");
+            int i = 0;
+            while(true) { // this will surely cause a reboot.
+              Serial.print(8);
+              Serial.print(i);
+              incomingClient.print(" ");
+              incomingClient.print(i);
+              i++;
+            }
+            break;
+          }
+        }
+      }
+      delay(5);
+      incomingClient.stop();
+      Serial.println();
+      Serial.print(F("Incoming client disconnected after "));
+      Serial.print(millis() - msTemp);
+      Serial.println("ms.");
+    }
+  }
+
+
   //Do "once a second stuff", mostly weather. Also keep track of which minute it is.
   if(millis() - lastSecond >= 1000)
   {
@@ -919,16 +970,16 @@
       int minutesToday = hour() * 60 + minute();

 #ifdef FOURMINUTEDAY
-      Serial.println("   !!DEBUG: Cycling to NIGHT every SIX minutes because of ""#define FOURMINUTEDAY""");
+      Serial.println(F("   !!DEBUG: Cycling to NIGHT every SIX minutes because of ""#define FOURMINUTEDAY"""));
       if ( (minute() / 6) % 2 ) {
-        Serial.println("The time of day is: ");
+        Serial.println(F("The time of day is: "));

 #else
-      Serial.print("The time of day is: ");
+      Serial.print(F("The time of day is: "));
       Serial.print(hour()); Serial.print(":"); Serial.print(minute());
       if ( (minutesToday < sunrise - 15) or (minutesToday > sunset - 15) ) {

-        Serial.print(", which is Night time. We will switch to daytime at ");
+        Serial.print(F(", which is Night time. We will switch to daytime at "));
         Serial.print((sunrise - 15) / 60); Serial.print(":"); Serial.println((sunrise - 15) % 60);
 #endif
         // We're not between "half an hour before sunrise" and sunset, so turn stuff off.
@@ -941,7 +992,7 @@
         disableEthernet();

       } else {
-        Serial.print(", which is Day time. We will switch to night at ");
+        Serial.print(F(", which is Day time. We will switch to night at "));
         Serial.print((sunset - 15) / 60); Serial.print(":"); Serial.println((sunset - 15) % 60);
         // Otherwise, make sure things are TURNED ON
         if (powerSave) {
@@ -965,14 +1016,15 @@
       *  B A T T E R Y   P R O T E C T I O N
       * * * * * * * * * * * * * * * * * * * * * * * * */

-      if (ina219b_current > 700) {
+      //If the charge rate is too high, cut it off. Unless we just resumed.. then let it soak up a little sun first.
+      if ((ina219b_current > 2000) and ( (resumeSolarStartTime + resumeSolarMinutes * 60) <= now() )) {

         // Charging too fast. Poor man's slowdown: turn off the solar panel for a bit. 8-o
         Serial.println();
         Serial.print(getTimeWithZeros());
-        Serial.print(F(": Pausing Solar Panels because charge rate"));
+        Serial.print(F(": Pausing Solar Panels because charge rate "));
         Serial.print(ina219b_current, 0);
-        Serial.println(F(" was > 700ma."));
+        Serial.println(F(" was > 1000mA."));
         pauseSolar = true;
         pauseSolarChargeCurrent = ina219b_current;
         pauseSolarStartTime = now();
@@ -989,13 +1041,14 @@
           Serial.print(" = ");
           Serial.println((pauseSolarStartTime + pauseSolarMinutes * 60) - now());
           if ( (pauseSolarStartTime + pauseSolarMinutes * 60) <= now() ) {
-            //It's been enough minutes with the Panels off. Turn them back on.
+            //It's been enough time with the Panels off. Turn them back on.
             Serial.println();
             Serial.print(getTimeWithZeros());
             Serial.println(F(": RESUMING Solar Panels, it's been long enough with them turned off"));
             pauseSolarChargeCurrent = 0;
             pauseSolar = false;
             enableSolar();
+            resumeSolarStartTime = now();
           }
         }
       } // END of charging-too-fast check
@@ -1089,8 +1142,9 @@
   //INA 219 averaging. Gets about 60-70 readings a second at time of writing.
   if (ina219a_MMAmillis + 8 < millis()) {

-    shuntvoltage = ina219a.getShuntVoltage_mV();
-    busvoltage = ina219a.getBusVoltage_V();
+    // * -1 because this one's wired backwards for convenience.
+    shuntvoltage = -1.0 * ina219a.getShuntVoltage_mV();
+    busvoltage = -1.0 * ina219a.getBusVoltage_V();
     ina219_MMAtemp = busvoltage + (shuntvoltage / 1000.0);

     ina219a_MMAvoltSum -= ina219a_MMAvoltAvg;
@@ -1102,7 +1156,7 @@
     ina219a_MMAcurrentSum -= ina219a_MMAcurrentAvg;
     ina219a_MMAcurrentSum += ina219_MMAtemp;
     ina219a_MMAcurrentAvg  = ina219a_MMAcurrentSum / ina219a_MMAcount;
-    ina219a_current = ina219a_MMAcurrentAvg * -2.0; // * -2.0 because a resistor was added and this one's wired backwards for convenience.
+    ina219a_current = ina219a_MMAcurrentAvg * 2.0; // * 2.0 because a resistor was added.

     ina219a_MMAloops++;

@@ -1123,7 +1177,6 @@
       ina219b_MMAcurrentSum += ina219_MMAtemp;
       ina219b_MMAcurrentAvg  = ina219b_MMAcurrentSum / ina219b_MMAcount;
       ina219b_current = ina219b_MMAcurrentAvg * 2.0; // double because a resistor was added
-

     }

@@ -1148,9 +1201,9 @@
   }
   sunriseDay = day();
   Serial.println();
-  Serial.print("Sunrise today is at  "); Serial.print(sunrise / 60); Serial.print(":"); Serial.println(sunrise % 60);
-  Serial.print("Sunset  today is at " ); Serial.print(sunset  / 60); Serial.print(":"); Serial.println(sunset  % 60);
-  Serial.print("  Took "); Serial.print(micros() - usTemp);  Serial.println("us to calculate.");
+  Serial.print(F("Sunrise today is at  ")); Serial.print(sunrise / 60); Serial.print(":"); Serial.println(sunrise % 60);
+  Serial.print(F("Sunset  today is at " )); Serial.print(sunset  / 60); Serial.print(":"); Serial.println(sunset  % 60);
+  Serial.print(F("  Took ")); Serial.print(micros() - usTemp);  Serial.println(F("us to calculate."));
   Serial.println();
 }

@@ -1647,7 +1700,7 @@

   client.setTimeout(600);
   int clientConnectStatus;
-  clientConnectStatus = client.connect(server, 80);
+  clientConnectStatus = client.connect(CSSserver, 80);
   if (clientConnectStatus) {
     logSome(F("Ether client connected for uploadWeather. Mem: "));
     logSome(freeRam());
@@ -1797,9 +1850,9 @@
     weatherString += String(ina219a_current * -1, 0);
   } else {
     //positive numbers
-    if (ina219a_current < 1000) weatherString += "0";
-    if (ina219a_current < 100)  weatherString += "0";
-    if (ina219a_current < 10)   weatherString += "0";
+    if (ina219a_current < 999.5) weatherString += "0";
+    if (ina219a_current < 99.5)  weatherString += "0";
+    if (ina219a_current < 9.5)   weatherString += "0";
     weatherString += String(ina219a_current, 0);
   }
   //weatherString += String("mA");
@@ -1826,9 +1879,9 @@
     weatherString += String(ina219b_current * -1, 0);
   } else {
     //positive numbers
-    if (ina219b_current < 1000) weatherString += "0";
-    if (ina219b_current < 100)  weatherString += "0";
-    if (ina219b_current < 10)   weatherString += "0";
+    if (ina219b_current < 999.5) weatherString += "0";
+    if (ina219b_current < 99.5)  weatherString += "0";
+    if (ina219b_current < 9.5)   weatherString += "0";
     weatherString += String(ina219b_current, 0);
   }
   //weatherString += String("mA");
@@ -1892,7 +1945,7 @@
   // add socket status as 8 hex chars
   bool reportSockets = false;
   for (int i = 0; i < MAX_SOCK_NUM; i++) {
-    if (ethSockStatus[i] > 0) reportSockets = true;
+    if ((ethSockStatus[i] > 0) and (ethSockStatus[i] != 0x14)) reportSockets = true;  // 0x14 == listen. We know one is listening always.
   }
   if (reportSockets) {
     weatherString += String(charComma);


Changed analog read pin for random seed

Changed analog read pin for random seed

--- Pan_Tilt_laser/Pan_Tilt_laser.ino
+++ Pan_Tilt_laser/Pan_Tilt_laser.ino
@@ -153,7 +153,7 @@
   }

 if(millis() - timePassed >= 1000){
-    randomSeed(analogRead(0));
+    randomSeed(analogRead(4));
     changeVal = getMarkovSpeed(changeVal);
     markovShakeState = markovState(10, 20);


#32 unit test coverage of the onRelease function

--- tests/switchesTests/switchesTests.ino
+++ tests/switchesTests/switchesTests.ino
@@ -5,6 +5,7 @@
 #include "SwitchInput.h"

 bool pressed;
+bool keyReleased;
 uint8_t key;
 bool held;
 int callsMade;
@@ -36,6 +37,11 @@
     pressed = true;
 }

+void onSwitchReleased(uint8_t k, bool h) {
+    keyReleased = true;
+    held = h;
+}
+
 class SwitchesFixture : public TestOnce {
 protected:
     MockedIoAbstraction mockIo;
@@ -48,6 +54,7 @@
         taskManager.reset();

         pressed = false;
+        keyReleased = false;
         held = false;
         callsMade = 0;
         encoderCurrentVal = 0;
@@ -62,6 +69,7 @@
         }
         // now check if we are pressed, and if there are any errors.
         assertEqual(pressed, shouldBePressed);
+        assertFalse(keyReleased);
         assertEqual(mockIo.getErrorMode(), NO_ERROR);
     }

@@ -73,7 +81,17 @@

         // now check if we are held and for any errors
         assertEqual(held, shouldBeHeld);
+        assertFalse(keyReleased);
         assertEqual(mockIo.getErrorMode(), NO_ERROR);
+    }
+
+    void assertReleasedState(bool expectedHeldState) {
+        int loopCount = 0;
+        while(!keyReleased && ++loopCount < 500) {
+            taskManager.yieldForMicros(1000);
+        }
+        assertTrue(keyReleased);
+        assertEqual(held, expectedHeldState);
     }

     void runInterruptLoopTimes(int times) {
@@ -87,6 +105,7 @@
 testF(SwitchesFixture, testPressingASingleButton) {
     switches.initialise(&mockIo, true);
     switches.addSwitch(2, onSwitchPressed, NO_REPEAT);
+    switches.onRelease(2, onSwitchReleased);
     assertFalse(switches.isInterruptDriven());

     // simulate the button being pressed (with a bounce).
@@ -98,6 +117,7 @@
     // we now simulate the button being pressed down.
     for(int i=3; i<25;i++)  mockIo.setValueForReading(i, 0x0000);
     assertPressedState(true);
+    assertFalse(keyReleased);

     long millisStart = millis();

@@ -105,6 +125,12 @@
     mockIo.resetIo();
     for(int i=0; i<25;i++)  mockIo.setValueForReading(i, 0x0000);
     assertHeldState(true);
+
+    // we now simulate the button being released.
+    mockIo.resetIo();
+    for(int i=0; i<25;i++)  mockIo.setValueForReading(i, 0x0004);
+    assertReleasedState(true);
+

     // make sure getting to held took near to 400 millis.
     assertMoreOrEqual(millis() - millisStart, (uint32_t)380);


Fixed a typo

Fixed a typo

--- Metro/examples/blinking_2_instances/blinking_2_instances.ino
+++ Metro/examples/blinking_2_instances/blinking_2_instances.ino
@@ -11,7 +11,7 @@
 int state1 = HIGH;

 // Instantiate a metro object and set the interval to 250 milliseconds (0.25 seconds).
-Metro metro0 = Metro(500);
+Metro metro0 = Metro(250);

 // Instantiate another metro object and set the interval to 125 milliseconds (0.125 seconds).
 Metro metro1 = Metro(125);


copied app controller example from spark repo

--- application_controller/serial_interface/serial_interface.ino
+++ application_controller/serial_interface/serial_interface.ino
@@ -39,197 +39,127 @@

 #include "rbc_mesh_interface.h"

-static aci_pins_t pins;
+#define ACCESS_ADDR     (0xA541A68F)

-static uint8_t         uart_buffer[20];
-static uint8_t         dummychar = 0;
+// defining the state of the system for communication
+enum state_t{
+    STATE_INIT,           // not yet initialized
+    STATE_READY,          // no external command in work
+    STATE_WAITING_FOR_EVT // external command in work, waiting for answer from SPI slave
+};

-// access address in our example mesh application
-//uint32_t accAddr = 0x8FA641A5;
-uint32_t accAddr = 0xA541A68F;
+int state = STATE_INIT;

-void __ble_assert(const char *file, uint16_t line)
-{
-  Serial.print("ERROR ");
-  Serial.print(file);
-  Serial.print(": ");
-  Serial.print(line);
-  Serial.print("\n");
-  while(1);
+// buffer for the last value send by the SPI slave
+int lastResponse;
+
+int initState = 0;
+
+// callback function for http command to set a handle value
+int set_val(String args){
+
+    if(state != ready){
+        return -1;
+    }
+    state = waitingForEvent;
+
+    uint8_t handle = args[0] - '0';
+    uint8_t value  = args[1] - '0';
+
+    return rbc_mesh_value_set(handle, &value, (uint8_t) 1);
 }

+// callback function for http command to get a handle value
+int get_val_req(String args){

+    if(state != ready){
+        return -1;
+    }
+    state = waitingForEvent;
+
+    uint8_t handle = args[0] - '0';
+
+    return rbc_mesh_value_get(handle);
+}
+
+aci_pins_t pins;
+
+// arduino conform init function
 void setup(void)
 {
-  Serial.begin(115200);
-  //Wait until the serial port is available (useful only for the Leonardo)
-  //As the Leonardo board is not reseted every time you open the Serial Monitor
-  #if defined (__AVR_ATmega32U4__)
-    while(!Serial)
-    {}
-    delay(1000);  //5 seconds delay for enabling to see the start up comments on the serial board
-  #elif defined(__PIC32MX__)
-    delay(1000);
-  #endif
+  Serial.begin(9600);

   pins.board_name = BOARD_DEFAULT; //See board.h for details REDBEARLAB_SHIELD_V1_1 or BOARD_DEFAULT
-  pins.reqn_pin   = SS;
-  pins.rdyn_pin   = 8;
-  pins.mosi_pin   = MOSI;
-  pins.miso_pin   = MISO;
-  pins.sck_pin    = SCK;
+  pins.reqn_pin   = A2;
+  pins.rdyn_pin   = D5;
+  pins.mosi_pin   = A5;
+  pins.miso_pin   = A4;
+  pins.sck_pin    = A3;

   pins.spi_clock_divider      = SPI_CLOCK_DIV8;
-  pins.reset_pin              = UNUSED; //4 for Nordic board, UNUSED for REDBEARLAB_SHIELD_V1_1
-  pins.active_pin             = UNUSED;
-  pins.optional_chip_sel_pin  = UNUSED;
+
+  pins.reset_pin              = D2;
+  pins.active_pin             = NRF_UNUSED;
+  pins.optional_chip_sel_pin  = NRF_UNUSED;

   pins.interface_is_interrupt = false; //Interrupts still not available in Chipkit
   pins.interrupt_number       = 1;

-  // initialize mesh_interface
   rbc_mesh_hw_init(&pins);
-
-  Serial.println("Local setup done");
-  Serial.println("Starting connection setup");
-  return;
-
 }

-bool stringComplete = false;  // whether the string is complete
-uint8_t stringIndex = 0;      //Initialize the index to store incoming chars
-
-enum state_t{
-    starting,
-    ready,
-    waitingForEvent
-};
-
-int state = starting;
-
-
-int initState = 0;
-bool newMessage = false;
-
+// sending intialization commands to SPI slave
+// alternating sending of commands and waiting for response
 void initConnectionSlowly(){
     switch(initState) {
         case 0:
-            Serial.print(".");
-            rbc_mesh_init(accAddr, (uint8_t) 38, (uint8_t) 2, (uint32_t) 100);
+            rbc_mesh_init(ACCESS_ADDR, (uint8_t) 38, (uint8_t) 2, (uint32_t) 100);
             initState++;
+            Serial.println("Sent init command");
             break;
         case 1:
-            if(newMessage){
-                Serial.print(".");
-                rbc_mesh_value_enable((uint8_t) 1);
-                initState++;
-            }
+            rbc_mesh_value_enable((uint8_t) 1);
+            initState++;
+            Serial.println("Enabled value 1");
             break;
         case 2:
-            if(newMessage){
-                Serial.println(".");
-                rbc_mesh_value_enable((uint8_t) 2);
-                initState++;
-            }
+            rbc_mesh_value_enable((uint8_t) 2);
+            initState++;
+            Serial.println("Enabled value 2");
             break;
         case 3:
-            if(newMessage){
-                state = ready;
-                Serial.println("connection setup done");
-                Serial.println("possible commands are");
-                Serial.println(" 1 - red off");
-                Serial.println(" 2 - red on");
-                Serial.println(" 3 - green off");
-                Serial.println(" 4 - green on");
-            }
+            state = ready;
+            Serial.println("init done");
     }
 }

-void actions_loop() {
-  if (stringComplete){
-    Serial.print("");
-    Serial.print("running, state is ");
-    Serial.println(state);
-
-    uint8_t handle = 1;
-    uint8_t value = 1;
-    if(uart_buffer[0] == '1'){
-      Serial.println("got 1: red off");
-      handle = 1;
-      value = 0;
-    }
-    if(uart_buffer[0] == '2'){
-      Serial.println("got 2: red on");
-      handle = 1;
-      value = 1;
-    }
-    if(uart_buffer[0] == '3'){
-      Serial.println("got 3: green off");
-      handle = 2;
-      value = 0;
-    }
-    if(uart_buffer[0] == '4'){
-      Serial.println("got 4: green on");
-      handle = 2;
-      value = 1;
-    }
-    if(state == ready){
-      Serial.println("sending now");
-      state = waitingForEvent;
-      rbc_mesh_value_set(handle, &value, (uint8_t) 1);
-    }
-    stringIndex = 0;
-    stringComplete = false;
-  }
-  if (Serial.available()) {
-      serialEvent();
-  }
-}
-
+// arduino conform main loop
 void loop() {
-
-    if(state == starting){
+    static bool newMessage = false;
+    // send next initialization command to SPI slave until we leave init state
+    if (state == STATE_INIT && newMessage) {
         initConnectionSlowly();
     }
+
     //Process any ACI commands or events
     serial_evt_t evnt;
     newMessage = rbc_mesh_evt_get(&evnt);

-    if(state == waitingForEvent && newMessage){
-        state = ready;
-    }
-
-  // react to command line interaction
-  actions_loop();
+    if(newMessage && evnt.opcode == SERIAL_EVT_OPCODE_CMD_RSP){
+        if (evnt.params.cmd_rsp.status != ACI_STATUS_SUCCESS)
+        {
+            Serial.print("Error response on cmd ");
+            Serial.print(evnt.params.cmd_rsp.command_opcode, HEX);
+            Serial.print(": ");
+            Serial.print(evnt.params.cmd_rsp.status, HEX);
+            Serial.println();
+        }

+        if (state == STATE_WAITING_FOR_EVT) {
+            state = STATE_READY;
+            // save the response value of SPI slave into buffer
+            // can be read via callback function
+            lastResponse = evnt.params.cmd_rsp.response.val_get.data[0];
+        }
+    }
 }
-
-// handle incoming UART messages
-void serialEvent() {
-
-  while(Serial.available() > 0){
-    // get the new byte:
-    dummychar = (uint8_t)Serial.read();
-    if(stringComplete){
-      continue;
-    }
-    if (dummychar == '\n'){
-      // if the incoming character is a newline, set a flag
-      // so the main loop can do something about it
-      uart_buffer[stringIndex] = 0;
-      stringIndex--;
-      stringComplete = true;
-      continue;
-    }
-
-    if(stringIndex > 19){
-      Serial.println("Serial input truncated");
-      stringIndex--;
-      stringComplete = true;
-      return;
-    }
-    // add it to the uart_buffer
-    uart_buffer[stringIndex] = dummychar;
-    stringIndex++;
-  }
-}


one stepper and 5 on off functinos

one stepper and 5 on off functinos

--- SBR/SBR.ino
+++ SBR/SBR.ino
@@ -14,25 +14,24 @@
 int en1 = 2; //1 is fill
 int step1 = 3;
 int dir1 = 4;
-int en2 = 5;//2 is decant
-int step2 = 6;
-int dir2 = 7;
+int decantpump = 5;
+int fillpump = 6;
+int skimmer =7;
 int air = 9;
 int stir = 8;
 int depth = A0;
 float tank;
 void setup() {
   pinMode(en1, OUTPUT);
-  pinMode(en2, OUTPUT);
+  pinMode(decantpump, OUTPUT);
   pinMode(step1, OUTPUT);
-  pinMode(step2, OUTPUT);
+  pinMode(fillpump, OUTPUT);
   pinMode(dir1, OUTPUT);
-  pinMode(dir2, OUTPUT);
+  pinMode(skimmer, OUTPUT);
   pinMode(air, OUTPUT);
   pinMode(stir, OUTPUT);
   pinMode(depth, INPUT);
   digitalWrite(en1, HIGH);
-  digitalWrite(en2, HIGH);
   lcd.begin(16, 2);
    if (! rtc.begin()) {
     lcd.print("Couldn't find RTC");
@@ -61,7 +60,7 @@
   lcd.print(now.unixtime());
   lcd.setCursor(0, 1);
   lcd.print(millis()/1000);
-delay(1000);
+delay(100);
   uint8_t buttons = lcd.readButtons();

   if (buttons) {
@@ -109,7 +108,10 @@
   measurevol();
   lcd.setCursor(0,1);
   lcd.print(tank);
-  stepper(400, 1, 2);
+  int starttime = millis();
+   while ((millis()-starttime)<10000){
+    digitalWrite(fillpump, HIGH);}
+    digitalWrite(fillpump, LOW);
 }
 void aeration(){//check depth and keep air on and pumps off for time period
   lcd.clear();
@@ -133,6 +135,19 @@
   lcd.setCursor(0,1);
   lcd.print(tank);
 }
+void skim(){//skim during settle
+  lcd.clear();
+  lcd.setCursor(0,0);
+  lcd.print("Skim ");
+  lcd.setBacklight(YELLOW);
+  measurevol();
+  lcd.setCursor(0,1);
+  lcd.print(tank);
+  int starttime = millis();
+  while ((millis()-starttime)<10000){
+    digitalWrite(skimmer, HIGH);}
+    digitalWrite(skimmer, LOW);
+}
 void decant(){ // empty through decant pump checking volume
   lcd.clear();
   lcd.setCursor(0,0);
@@ -141,7 +156,10 @@
   measurevol();
   lcd.setCursor(0,1);
   lcd.print(tank);
-  stepper(20000, 2, 1);
+  int starttime = millis();
+ while ((millis()-starttime)<10000){
+    digitalWrite(decantpump, HIGH);}
+    digitalWrite(decantpump, LOW);
 }
 void rest(){ //everything off except maybe stir
   lcd.clear();
@@ -151,6 +169,10 @@
   measurevol();
   lcd.setCursor(0,1);
   lcd.print(tank);
+  int starttime = millis();
+   while ((millis()-starttime)<10000){
+    digitalWrite(stir, HIGH);}
+    digitalWrite(stir, LOW);
 }
 void stepper(int num, int motor, int direct){
   if (motor == 1){
@@ -167,30 +189,17 @@
   }
   digitalWrite(en1, HIGH);
 }
-else if (motor ==2){
-    digitalWrite(en2, LOW);
-    if (direct == 1){
-      digitalWrite(dir2, HIGH);}//empty
-      else if (direct ==2){
-        digitalWrite(dir2, LOW);}// fill
-    for (int i=0; i<=num; i++){
-      digitalWrite(step2, HIGH);
-      delay(2);
-      digitalWrite(step2, LOW);
-      delay(2);
-  }
-  digitalWrite(en2, HIGH);
-}
-}
+}
+
 void measurevol(){
   int junk = analogRead(depth);
   float tank1 = analogRead(depth)*0.438596-30.7018;
   float tank2 = analogRead(depth)*0.438596-30.7018;
   float tank3 = analogRead(depth)*0.438596-30.7018;
   float tank4 = analogRead(depth)*0.438596-30.7018;
-  float tank5 =analogRead(depth)*0.438596-30.7018;
+  float tank5 = analogRead(depth)*0.438596-30.7018;
   float tank6 = analogRead(depth)*0.438596-30.7018;
-  float tank7 =analogRead(depth)*0.438596-30.7018;
+  float tank7 = analogRead(depth)*0.438596-30.7018;
   float tank8 = analogRead(depth)*0.438596-30.7018;
   tank = (tank1 + tank2 + tank3 + tank4 + tank5 + tank6 + tank7 + tank8)/8;
 }


Clean up of config defines to use fixed IP and bring config to top of sketch

--- examples/Ethernet/CosaSNMP/CosaSNMP.ino
+++ examples/Ethernet/CosaSNMP/CosaSNMP.ino
@@ -9,19 +9,19 @@
  * modify it under the terms of the GNU Lesser General Public
  * License as published by the Free Software Foundation; either
  * version 2.1 of the License, or (at your option) any later version.
- *
+ *
  * This library is distributed in the hope that it will be useful,
  * but WITHOUT ANY WARRANTY; without even the implied warranty of
  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
  * Lesser General Public License for more details.
- *
+ *
  * @section Description
  * W5100 Ethernet Controller device driver example code; SNMP agent
- * with support for GET/GETNEXT/SET for MIB-2 SYSTEM and Arduino MIB.
+ * with support for GET/GETNEXT/SET for MIB-2 SYSTEM and Arduino MIB.
  *
  * @section Circuit
  * This sketch is designed for the Ethernet Shield.
- *
+ *
  *                       W5100/ethernet
  *                       +------------+
  * (D10)--------------29-|CSN         |
@@ -53,15 +53,40 @@
 #include "Cosa/IOStream/Driver/UART.hh"
 #define PRINT_PDU // Comment this out to remove some tracing and reduce memory usage

+// Network configuration
+// If WS5100 board has a MAC sticker then use here instead of this default
+static const uint8_t mac[6] __PROGMEM = { 0xde, 0xad, 0xbe, 0xef, 0xfe, 0xed };
+// If no DHCP on network set these
+// #define USE_FIXED_IP 192,168,1,100
+// #define SUBNET 255,255,255,0
+
+// Disable SD on Ethernet Shield
+#define USE_ETHERNET_SHIELD
+#if defined(USE_ETHERNET_SHIELD)
+#include "Cosa/OutputPin.hh"
+OutputPin sd(Board::D4, 1);
+#endif
+
+W5100 ethernet(mac);
+
+// SNMP MIB-2 System configuration
+static const char descr[] __PROGMEM = "<service description>";
+static const char contact[] __PROGMEM = "<contact information>";
+static const char name[] __PROGMEM = "<device name>";
+static const char location[] __PROGMEM = "<device location>";
+
+SNMP::MIB2_SYSTEM mib2(descr, contact, name, location);
+SNMP snmp;
+
 /**
  * Arduino MIB OID(1.3.6.1.4.1.36582)
  */
 class ARDUINO_MIB : public SNMP::MIB {
 private:
   enum {
-    ardDigitalPin = 1,	      // Digital pin[0..19](0..1), read-only
-    ardAnalogPin = 2,	      // Analog pin[0..5](0..1023), read-only
-    ardVcc = 3,		      // Power supply[0](0..VCC), mV, read-only
+    ardDigitalPin = 1,        // Digital pin[0..19](0..1), read-only
+    ardAnalogPin = 2,         // Analog pin[0..5](0..1023), read-only
+    ardVcc = 3,               // Power supply[0](0..VCC), mV, read-only
   } __attribute__((packed));

 public:
@@ -73,7 +98,7 @@
   {
     return (SNMP::ARDUINO_MIB_OID);
   }
-
+
   /**
    * @override SNMP::MIB
    * Handle Arduino MIB objects SNMP requests. Returns true and
@@ -84,7 +109,7 @@
   virtual bool is_request(SNMP::PDU& pdu);
 };

-bool
+bool
 ARDUINO_MIB::is_request(SNMP::PDU& pdu)
 {
   uint8_t mib_baselen = pgm_read_byte(SNMP::ARDUINO_MIB_OID);
@@ -107,18 +132,18 @@
       break;
     case ardDigitalPin:
       if (index < 19)
-	index += 1;
-      else {
-	index = 0;
-	sys = ardAnalogPin;
-      }
+        index += 1;
+      else {
+        index = 0;
+        sys = ardAnalogPin;
+      }
       break;
     case ardAnalogPin:
       if (index < 5)
-	index += 1;
-      else {
-	index = 0;
-	sys = ardVcc;
+        index += 1;
+      else {
+        index = 0;
+        sys = ardVcc;
       }
       break;
     case ardVcc:
@@ -132,33 +157,33 @@

   // Check request type
   if (sys < ardDigitalPin || sys > ardVcc) return (false);
-
+
   // Get value for digital or analog pin, or power supply voltage
   if (pdu.type == SNMP::PDU_GET) {
     switch (sys) {
     case ardDigitalPin:
       if (index > 19)
-	pdu.error_status = SNMP::NO_SUCH_NAME;
-      else {
-	Board::DigitalPin pin;
-	pin = (Board::DigitalPin) pgm_read_byte(&digital_pin_map[index]);
-	pdu.value.encode(SNMP::SYNTAX_INT, (int16_t) InputPin::read(pin));
+        pdu.error_status = SNMP::NO_SUCH_NAME;
+      else {
+        Board::DigitalPin pin;
+        pin = (Board::DigitalPin) pgm_read_byte(&digital_pin_map[index]);
+        pdu.value.encode(SNMP::SYNTAX_INT, (int16_t) InputPin::read(pin));
       }
       break;
     case ardAnalogPin:
       if (index > 5)
-	pdu.error_status = SNMP::NO_SUCH_NAME;
-      else {
-	Board::AnalogPin pin;
-	pin = (Board::AnalogPin) pgm_read_byte(&analog_pin_map[index]);
-	pdu.value.encode(SNMP::SYNTAX_INT, (int16_t) AnalogPin::sample(pin));
+        pdu.error_status = SNMP::NO_SUCH_NAME;
+      else {
+        Board::AnalogPin pin;
+        pin = (Board::AnalogPin) pgm_read_byte(&analog_pin_map[index]);
+        pdu.value.encode(SNMP::SYNTAX_INT, (int16_t) AnalogPin::sample(pin));
       }
       break;
     case ardVcc:
       if (index > 0)
-	pdu.error_status = SNMP::NO_SUCH_NAME;
+        pdu.error_status = SNMP::NO_SUCH_NAME;
       else
-	pdu.value.encode(SNMP::SYNTAX_INT, (int16_t) AnalogPin::bandgap());
+        pdu.value.encode(SNMP::SYNTAX_INT, (int16_t) AnalogPin::bandgap());
       break;
     }
   }
@@ -170,35 +195,22 @@
   return (true);
 }

-// Disable SD on Ethernet Shield
-#define USE_ETHERNET_SHIELD
-#if defined(USE_ETHERNET_SHIELD)
-#include "Cosa/OutputPin.hh"
-OutputPin sd(Board::D4, 1);
-#endif
-
-// Network configuration
-// If WS5100 board has a MAC sticker then use here instead of this default
-static const uint8_t mac[6] __PROGMEM = { 0xde, 0xad, 0xbe, 0xef, 0xfe, 0xed };
-// If no DHCP set these, uncomment in var definitions, and switch to ethernet.begin() below
-//#define IP 192,168,1,100
-//#define SUBNET 255,255,255,0
-
-// SNMP MIB-2 System configuration
-static const char descr[] __PROGMEM = "<service description>";
-static const char contact[] __PROGMEM = "<contact information>";
-static const char name[] __PROGMEM = "<device name>";
-static const char location[] __PROGMEM = "<device location>";
-
-W5100 ethernet(mac);
-SNMP::MIB2_SYSTEM mib2(descr, contact, name, location);
 ARDUINO_MIB arduino;
-SNMP snmp;

 void setup()
 {
-  uint8_t ip[4]; // = { IP };
-  uint8_t subnet[4]; // = { SUBNET };
+  uint8_t ip[4]
+#if defined(USE_FIXED_IP)
+    = { USE_FIXED_IP };
+#else
+    ;
+#endif
+  uint8_t subnet[4]
+#if defined(SUBNET)
+    = { SUBNET };
+#else
+    ;
+#endif

   // Start watchdog and uart. Use uart for trace output
   uart.begin(9600);
@@ -206,18 +218,18 @@
   Watchdog::begin();

   // Start ethernet controller and request network address for hostname
+#if defined(USE_FIXED_IP)
+  ASSERT(ethernet.begin(ip, subnet);
+#else
   ASSERT(ethernet.begin_P(PSTR("CosaSNMPAgent")));
-//ASSERT(ethernet.begin(ip, subnet); // If no DHCP
-
-  // Alternative give network address and subnet mask
-  // ASSERT(ethernet.begin(ip, subnet));
+#endif

   // Print the given or default network address
   ethernet.get_addr(ip, subnet);
   trace << PSTR("IP = ");
   INET::print_addr(trace, ip);
   trace << endl;
-
+
   // Print some memory statistics
   TRACE(free_memory());
   TRACE(sizeof(W5100));


fix for hostname

fix for hostname

git-svn-id: d8bfcd070c2c81762cca1b3912331324182919ba@20619 0d6f1817-ed0e-0410-87c9-987e46238f29

--- zimodem/zcommand.ino
+++ zimodem/zcommand.ino
@@ -468,6 +468,7 @@
          ||(argn==CFG_TIMEFMT)
          ||(argn==CFG_TIMEURL)
          ||(argn==CFG_PRINTSPEC)
+         ||(argn==CFG_HOSTNAME)
          ||(argn==CFG_TERMTYPE)))
         {
           char hex[256];


Updated to version 1.0.2

Updated to version 1.0.2

--- examples/Input-String-on-LCD-1602/Input-String-on-LCD-1602.ino
+++ examples/Input-String-on-LCD-1602/Input-String-on-LCD-1602.ino
@@ -106,6 +106,7 @@
     }
     tone(BEEP, 4000, 100);
   }
+  waitUntilUnpressed();
   Serial.print(F("Your choice: "));
   Serial.println(chr);

@@ -144,6 +145,14 @@
     key = kpd.getKey();
     if (key.state == KEY_DOWN || key.state == MULTI_KEY_DOWN)
       return key.character;
+  }
+}
+
+void waitUntilUnpressed() {
+  while(true) {
+    key = kpd.getKey();
+    if (key.state == KEY_UP)
+      return;
   }
 }

@@ -156,6 +165,7 @@
   setCursorPos();
   chrCtr = 0;
   displayInputMode();
+  boolean isCompleted = false;
   while (true) {
     key = kpd.getKey();
     switch (key.state) {
@@ -190,10 +200,13 @@
             break;
           case KEY_D:
             strBuffer[chrCtr] = 0;
-            return;
+            isCompleted = true;
+            break;
           default:
             chr = alphaMode ? getAlphabet(key.character, key.tapCounter) : key.character;
         }
+        if (isCompleted)
+          break;
         if (!upperCaseMode && chr >= 'A')
           chr += 32; // makes lower case
         if (key.state == MULTI_TAP && alphaMode && key.character >= '1' && key.character <= '9') {
@@ -251,6 +264,8 @@
         digitalWrite(LED_BUILTIN, LOW);
         backlightTimeout = millis() + BACKLIGHT_PERIODS;
         autoOffBacklight = true;
+        if (isCompleted)
+          return;
     }
   }
 }


отправка D8,D10

отправка D8,D10

--- serialracoon.ino
+++ serialracoon.ino
@@ -1,3 +1,5 @@
+#include <SFE_BMP180.h>
+
 /* YourDuino.com Example: BlueTooth HC-05 Setup
  - WHAT IT DOES:
    - Sets "Key" pin on HC-05 HIGH to enable command mode
@@ -114,6 +116,9 @@
   pinMode(HC_05_SETUPKEY, OUTPUT);  // this pin will pull the HC-05 pin 34 (key pin) HIGH to switch module to AT mode
   pinMode(HC_05_PWR1, OUTPUT);      // Connect in parallel to HC-05 VCC
   pinMode(HC_05_PWR2, OUTPUT);      // Connect in parallel to HC-05 VCC
+
+  pinMode(10, INPUT);
+  pinMode(8, INPUT);

 //  digitalWrite(HC_05_SETUPKEY, HIGH);  // Set command mode when powering up

@@ -147,7 +152,9 @@
 int v0 = 0;
 int v1 = 0;
 int v2 = 0;
-int v3 = 0;
+int v3 = 0;
+int d10 = 0;
+int d8 = 0;

 void loop()
 {
@@ -184,9 +191,12 @@
   v2 = analogRead(A2);
   v3 = analogRead(A3);

+  d10 = digitalRead(10);
+  d8 = digitalRead(8);
+
   if (board == 0) {
     //sprintf(out, "seqid %d;%d;;;\r\n", cnt++, val);
-    sprintf(out, "%d;%d;%d;%d;%d\r\n", cnt, v0, v1, v2, v3);
+    sprintf(out, "seqid=%d;A0=%d;A1=%d;D8=%d;D10=%d\r\n", cnt, v0, v1, d8, d10);
     Serial.println(out);
     BTSerial.write(out);
     delay(100);


fine tune the bpm detector

fine tune the bpm detector

--- Arduino/spectrum_i2c/spectrum_i2c.ino
+++ Arduino/spectrum_i2c/spectrum_i2c.ino
@@ -7,13 +7,13 @@
 byte spectrum[9];

-#define SIZE 1024
-#define SLICE 32
+#define SIZE 512
+#define SLICE 16

 byte huge[SIZE];
 long energy[SIZE/SLICE];
 int p = 0;
-long t;
+volatile long t;
 long start;
 long last_beat;
 long beat_length;
@@ -50,6 +50,8 @@
   digitalWrite(spectrumReset,LOW);
   delay(5);
   // Reading the analyzer now will read the lowest frequency.
+
+  //Serial.println("INITIALIZED");
 }

 //just loop and read - need to add normalization
@@ -92,7 +94,7 @@
   if (modifier < MIN_MODIFIER){
   modifier = MIN_MODIFIER;
   }
-  captureBeat(spectrum[0]);
+  captureBeat((spectrum[0]+spectrum[0])>>1);
 }

 void sendSpectrum() {
@@ -100,12 +102,15 @@
   if (!offBeat && !sentBeat) {
     spectrum[8] = 1;
     sentBeat = true;
+ //   Serial.println("!!!!!!!!!");
   } else {
     spectrum[8] = 0;
     sentBeat = false;
+ //   Serial.print(beat_length);
+ //   Serial.print("\t");
+ //   Serial.println(bpm);
   }
   Wire.write(spectrum, 9);
-  //Serial.println(modifier);
 }

@@ -130,19 +135,24 @@
     sumEnergy/=SIZE;
     energy[(SIZE/SLICE)-1] = newEnergy;
     long diff = millis()-t;
-    if (newEnergy > 1.3 * sumEnergy && diff > .9*beat_length) {
+    if (newEnergy > 1.2 * sumEnergy && diff > .8*beat_length) {
       if (offBeat) {
-        float newBPM = 60000/(float)diff;
-        bpm = bpm*.9 + newBPM*.1;
+        t = millis();
         beat_length = beat_length*.9 + diff*.1;
-        t = millis();
+        if (beat_length < 375) beat_length = 375; //160bpm
+        if (beat_length > 600) beat_length = 600; //100bpm
+
+        bpm = 60000/(float)beat_length;
       }
       offBeat = false;
     }
     else {
       offBeat = true;
     }
-  }

+//Serial.println(bpm);
+          }
+
+
 }


Coco the rest of the packet parser code

Coco the rest of the packet parser code

--- Arduino/BlueCube/BlueCube.ino
+++ Arduino/BlueCube/BlueCube.ino
@@ -196,27 +196,52 @@
     }

     while (ble->available()) {
+      // Loop while there are characters available to read from the bluetooth connection
+
+      // Get the next available character
       char c =  ble->read();
-      serial->print(c);
+
+      // Add it to our buffer, and increment the index
       packetbuffer[bufferIndex] = c;
       bufferIndex++;
+
+      // Print the character we have received to the USB serial output
+      serial->print(c);
+
+      // Reset the timeout counter to our original timeout value
       timeout = origtimeout;
+
+      // Look for the character we use to indicate the end of a message
       if (c == ';') {
+        // We have reached the end of the message, so print a new line
         serial->println();
+
+        // Set the timeout to zero as we don't need to wait any longer for characters
         timeout = 0;
+
+        // Break out of the inner characters available loop
         break;
       }
     }
-
-    if (timeout == 0) break;
+
+    // Check what the current timeout value is
+    if (timeout == 0) {
+      // Timeout has been reached, break out of loop
+      break;
+    }
+
+    // Delay for 1ms and try again, as no (more) data was available to read
+    // and we haven't hit the timeout.
     delay(1);
   }

   packetbuffer[bufferIndex] = 0;  // null term

-  if (!bufferIndex)  // no data or timeout
-    return;
-
+  if (!bufferIndex) {
+    return;               // no data or we hit the timeout, so exit the function
+  }
+
+  // We have data, so pass it to the cube's parser to read the message and act upon it
   bytecode_t bytecode = {};
   byte errorCode = parser(packetbuffer, sizeof(packetbuffer), & bytecode);
 }


Updated some code formatting

Updated some code formatting


Update Output.ino

Update Output.ino

--- sandbox/Razor_AHRS/Output.ino
+++ sandbox/Razor_AHRS/Output.ino
@@ -94,42 +94,44 @@
   Serial.write((byte*) gyro, 12);
 }

-void output_sensor_angles()
+void output_sensors_and_angles()
 {
   if (output_format == OUTPUT__FORMAT_BINARY)
-    output_sensor_angles_binary();
+    output_sensors_and_angles_binary();
   else if (output_format == OUTPUT__FORMAT_TEXT)
-    output_sensor_angles_text();
+    output_sensors_and_angles_text();
 }

-void output_sensor_angles_binary()
+void output_sensors_and_angles_binary()
 {
-  Serial.write((byte*) accel, 12);
-  Serial.write((byte*) gyro, 12);
+  Serial.write((byte*) Accel_Vector, 12);
+  Serial.write((byte*) Gyro_Vector, 12);

   float ypr[3];
   ypr[0] = TO_DEG(yaw);
   ypr[1] = TO_DEG(pitch);
   ypr[2] = TO_DEG(roll);
   Serial.write((byte*) ypr, 12);
+
 }

-void output_sensor_angles_text()
+void output_sensors_and_angles_text()
 {
   Serial.print("#A-"); Serial.print('C'); Serial.print('=');
-  Serial.print(accel[0]); Serial.print(",");
-  Serial.print(accel[1]); Serial.print(",");
-  Serial.print(accel[2]); Serial.println();
+  Serial.print(GRAVITY_MS_REF(Accel_Vector[0])); Serial.print(",");
+  Serial.print(GRAVITY_MS_REF(Accel_Vector[1])); Serial.print(",");
+  Serial.print(GRAVITY_MS_REF(Accel_Vector[2])); Serial.println();

   Serial.print("#G-"); Serial.print('C'); Serial.print('=');
-  Serial.print(gyro[0]); Serial.print(",");
-  Serial.print(gyro[1]); Serial.print(",");
-  Serial.print(gyro[2]); Serial.println();
+  Serial.print(Gyro_Vector[0]); Serial.print(",");
+  Serial.print(Gyro_Vector[1]); Serial.print(",");
+  Serial.print(Gyro_Vector[2]); Serial.println();

   Serial.print("#YPR=");
   Serial.print(TO_DEG(yaw)); Serial.print(",");
   Serial.print(TO_DEG(pitch)); Serial.print(",");
   Serial.print(TO_DEG(roll)); Serial.println();
+
 }

 void output_sensors()


Reduce starfield count to 15, from 30. This promoted a net savings of *165 bytes* of RAM.


commit

commit

--- watermeter/time.ino
+++ watermeter/time.ino
@@ -106,7 +106,7 @@
       secsSince1900 |= (unsigned long)packetBuffer[41] << 16;
       secsSince1900 |= (unsigned long)packetBuffer[42] << 8;
       secsSince1900 |= (unsigned long)packetBuffer[43];
-      return secsSince1900 - 2208988800UL;
+      return secsSince1900 - 2208988800UL;/* + timeZone * SECS_PER_HOUR; Excluded timeZone, now() return time_t with timeZone=0 */
     }
   }
   if (DEBUG) Serial.println("No NTP Response :-(");


Corrected a lot of bugs

Corrected a lot of bugs

--- src/cyclop_plus_plus/cyclop_plus_plus.ino
+++ src/cyclop_plus_plus/cyclop_plus_plus.ino
@@ -109,7 +109,6 @@
 void          buttonPressInterrupt();
 void          drawAutoScanScreen(void);
 void          drawBattery(unsigned char xPos, unsigned char yPos, unsigned char value, bool showNumbers = false );
-void          drawChannelScreen( unsigned char channel);
 void          drawLeftInfoLine( void );
 void          drawLogo( unsigned char xPos, unsigned char yPos);
 void          drawOptionsScreen(unsigned char option, unsigned char in_edit_state );
@@ -131,6 +130,7 @@
 void          resetOptions(void);
 char         *shortNameOfChannel(unsigned char channel, char *name);
 void          setOptions( void );
+void          updateScannerScreen(unsigned char position, unsigned char value1, unsigned char value2 );

 //******************************************************************************
 //* Positions in the frequency table for the 48 channels
@@ -204,9 +204,6 @@
 rtc6715 receiver( SPI_CLOCK_PIN, SLAVE_SELECT_PIN, SPI_DATA_PIN );
 unsigned char softPositions[48];

-
-
-
 //******************************************************************************
 //* function: setup
 //******************************************************************************
@@ -254,35 +251,6 @@
     }
   }
   osd( CMD_CLEAR_SCREEN );
-
-  // Mark blocked channels in the softPositions array
-  for (i = 0; i < 48; i++)
-    softPositions[i] = positions[i];
-
-  if (!options[A_BAND_OPTION]) {
-    for (i = 0; i < 8; i++)
-      softPositions[getReversePosition( i )] = 255;
-  }
-  if (!options[B_BAND_OPTION]) {
-    for (i = 8; i < 16; i++)
-      softPositions[getReversePosition( i )] = 255;
-  }
-  if (!options[E_BAND_OPTION]) {
-    for (i = 16; i < 24; i++)
-      softPositions[getReversePosition( i )] = 255;
-  }
-  if (!options[F_BAND_OPTION]) {
-    for (i = 24; i < 32; i++)
-      softPositions[getReversePosition( i )] = 255;
-  }
-  if (!options[R_BAND_OPTION]) {
-    for (i = 32; i < 40; i++)
-      softPositions[getReversePosition( i )] = 255;
-  }
-  if (!options[L_BAND_OPTION]) {
-    for (i = 40; i < 48; i++)
-      softPositions[getReversePosition( i )] = 255;
-  }

   // Set delay time before entering screen save mode
   forceDisplayTimer = millis() + FORCED_SCREEN_UPDATE_MS;
@@ -314,13 +282,11 @@
           currentChannel = bestChannelMatch(autoScan(getFrequency(currentChannel)));
           break;
         case 3:
+          osd( CMD_CLEAR_SCREEN );
           setOptions();
           writeEeprom();
           break;
       }
-      osd( CMD_CLEAR_SCREEN );
-      drawChannelScreen(currentChannel);
-      delay(4000);
       screenCleaning = 1;
       break;

@@ -397,26 +363,6 @@
   }
   else
     analogWrite( ALARM_PIN, 0 );
-}
-
-//******************************************************************************
-//* function: resetOptions
-//*         : Resets all configuration settings to their default values
-//******************************************************************************
-void resetOptions(void) {
-  options[BATTERY_ALARM_OPTION]    = BATTERY_ALARM_DEFAULT;
-  options[ALARM_LEVEL_OPTION]      = ALARM_LEVEL_DEFAULT;
-  options[BATTERY_TYPE_OPTION]     = BATTERY_TYPE_DEFAULT;
-  options[BATTERY_CALIB_OPTION]    = BATTERY_CALIB_DEFAULT;
-  options[SHOW_STARTSCREEN_OPTION] = SHOW_STARTSCREEN_DEFAULT;
-  options[INFO_LINE_OPTION]        = INFO_LINE_DEFAULT;
-  options[INFO_LINE_POS_OPTION]    = INFO_LINE_POS_DEFAULT;
-  options[A_BAND_OPTION]           = A_BAND_DEFAULT;
-  options[B_BAND_OPTION]           = B_BAND_DEFAULT;
-  options[E_BAND_OPTION]           = E_BAND_DEFAULT;
-  options[F_BAND_OPTION]           = F_BAND_DEFAULT;
-  options[R_BAND_OPTION]           = R_BAND_DEFAULT;
-  options[L_BAND_OPTION]           = L_BAND_DEFAULT;
 }

 //******************************************************************************
@@ -580,7 +526,7 @@
   osd(CMD_DISABLE_VIDEO);

   // Cycle through the band
-  while ((clickType = getClickType(BUTTON_PIN)) == NO_CLICK) {
+  while (digitalRead(BUTTON_PIN) != BUTTON_PRESSED) {
     for (i = 0; i < 2; i++) {
       scanFrequency += SCANNING_STEP;
       if (scanFrequency > FREQUENCY_MAX)
@@ -596,8 +542,8 @@
     updateScannerScreen(29 - ((FREQUENCY_MAX - scanFrequency) / FREQUENCY_DIVIDER), rssiDisplayValue1, rssiDisplayValue2 );
   }
   // Fine tuning
-  scanFrequency = scanFrequency - 20;
-  for (i = 0; i < 20; i++, scanFrequency += 2) {
+  scanFrequency = scanFrequency - SCANNING_STEP*4;
+  for (i = 0; i < SCANNING_STEP*4; i++, scanFrequency += 2) {
     receiver.setFrequency(scanFrequency);
     delay( RSSI_STABILITY_DELAY_MS );
     scanRssi = averageAnalogRead(RSSI_PIN);
@@ -648,9 +594,9 @@
     }
   }
   // Fine tuning
-  scanFrequency = bestFrequency - 20;
+  scanFrequency = bestFrequency - SCANNING_STEP*4;
   bestRssi = 0;
-  for (i = 0; i < 20; i++, scanFrequency += 2) {
+  for (i = 0; i < SCANNING_STEP*4; i++, scanFrequency += 2) {
     receiver.setFrequency(scanFrequency);
     delay( RSSI_STABILITY_DELAY_MS );
     scanRssi = averageAnalogRead(RSSI_PIN);
@@ -731,8 +677,6 @@
   return name;
 }

-
-
 //******************************************************************************
 //* function: getVoltage
 //*         : returns battery voltage as an unsigned integer.
@@ -798,6 +742,64 @@
     alarmOffPeriod = 0;
   }
   drawBattery(x, y, value, showNumbers);
+}
+
+//******************************************************************************
+//* function: updateSoftPositions
+//******************************************************************************
+void updateSoftPositions( void ) {
+  unsigned char i;
+
+  // Mark blocked channels in the softPositions array
+  for (i = 0; i < 48; i++)
+    softPositions[i] = positions[i];
+
+  if (!options[A_BAND_OPTION]) {
+    for (i = 0; i < 8; i++)
+      softPositions[getReversePosition( i )] = 255;
+  }
+  if (!options[B_BAND_OPTION]) {
+    for (i = 8; i < 16; i++)
+      softPositions[getReversePosition( i )] = 255;
+  }
+  if (!options[E_BAND_OPTION]) {
+    for (i = 16; i < 24; i++)
+      softPositions[getReversePosition( i )] = 255;
+  }
+  if (!options[F_BAND_OPTION]) {
+    for (i = 24; i < 32; i++)
+      softPositions[getReversePosition( i )] = 255;
+  }
+  if (!options[R_BAND_OPTION]) {
+    for (i = 32; i < 40; i++)
+      softPositions[getReversePosition( i )] = 255;
+  }
+  if (!options[L_BAND_OPTION]) {
+    for (i = 40; i < 48; i++)
+      softPositions[getReversePosition( i )] = 255;
+  }
+}
+
+//******************************************************************************
+//* function: resetOptions
+//*         : Resets all configuration settings to their default values
+//******************************************************************************
+void resetOptions(void) {
+  options[BATTERY_ALARM_OPTION]    = BATTERY_ALARM_DEFAULT;
+  options[ALARM_LEVEL_OPTION]      = ALARM_LEVEL_DEFAULT;
+  options[BATTERY_TYPE_OPTION]     = BATTERY_TYPE_DEFAULT;
+  options[BATTERY_CALIB_OPTION]    = BATTERY_CALIB_DEFAULT;
+  options[SHOW_STARTSCREEN_OPTION] = SHOW_STARTSCREEN_DEFAULT;
+  options[INFO_LINE_OPTION]        = INFO_LINE_DEFAULT;
+  options[INFO_LINE_POS_OPTION]    = INFO_LINE_POS_DEFAULT;
+  options[A_BAND_OPTION]           = A_BAND_DEFAULT;
+  options[B_BAND_OPTION]           = B_BAND_DEFAULT;
+  options[E_BAND_OPTION]           = E_BAND_DEFAULT;
+  options[F_BAND_OPTION]           = F_BAND_DEFAULT;
+  options[R_BAND_OPTION]           = R_BAND_DEFAULT;
+  options[L_BAND_OPTION]           = L_BAND_DEFAULT;
+
+  updateSoftPositions();
 }

 //******************************************************************************
@@ -896,6 +898,7 @@
       drawOptionsScreen( menuSelection, in_edit_state );
     }
   }
+  updateSoftPositions();
 }

 //******************************************************************************
@@ -905,25 +908,14 @@
 void testAlarm( void ) {
   unsigned char i;

-  for ( i = 0; i < 3; i++) {
-    analogWrite( ALARM_PIN, 1 << options[ALARM_LEVEL_OPTION] );
-    delay(ALARM_MIN_ON);
-    analogWrite( ALARM_PIN, 0 );
-    delay(ALARM_MIN_OFF);
-  }
-  for (i = 0; i < 3; i++) {
-    analogWrite( ALARM_PIN, 1 << options[ALARM_LEVEL_OPTION] );
-    delay(ALARM_MED_ON);
-    analogWrite( ALARM_PIN, 0 );
-    delay(ALARM_MED_OFF);
-  }
-  for (i = 0; i < 3; i++) {
-    analogWrite( ALARM_PIN, 1 << options[ALARM_LEVEL_OPTION] );
-    delay(ALARM_MAX_ON);
-    analogWrite( ALARM_PIN, 0 );
-    delay(ALARM_MAX_OFF);
-  }
-  analogWrite( ALARM_PIN, 0 );
+  while (getClickType(BUTTON_PIN) == NO_CLICK) {
+    for (i = 0; i < 3; i++) {
+      analogWrite( ALARM_PIN, 1 << options[ALARM_LEVEL_OPTION] );
+      delay(ALARM_MAX_ON);
+      analogWrite( ALARM_PIN, 0 );
+      delay(ALARM_MAX_OFF);
+    }
+  }
 }

 //******************************************************************************
@@ -1055,57 +1047,15 @@
 }

 //******************************************************************************
-//* function: drawChannelScreen
-//*         : draws the standard screen with channel information
-//******************************************************************************
-void drawChannelScreen( unsigned char channel) {
-  char buffer[22];
-  unsigned char answer;
-
-  drawLogo(1, 0);
-  batteryMeter(25, 0);
-
-  osd( CMD_ENABLE_FILL );
-  osd( CMD_ENABLE_INVERSE );
-
-  osd( CMD_SET_X, 1 );
-  osd( CMD_SET_Y, 3 );
-  osd_string("                         ");
-
-  osd( CMD_SET_X, 1 );
-  osd( CMD_SET_Y, 4 );
-  osd_string(" Frequency:              ");
-  osd( CMD_SET_X, 13 );
-  osd_int(getFrequency(channel));
-  osd_string( " MHz" );
-
-  osd( CMD_SET_X, 1 );
-  osd( CMD_SET_Y, 5 );
-  osd_string(" Channel  :              ");
-  osd( CMD_SET_X, 13 );
-  osd_string(shortNameOfChannel(channel, buffer));
-
-  osd( CMD_SET_X, 1 );
-  osd( CMD_SET_Y, 6 );
-  osd_string(" Name     :              ");
-  osd( CMD_SET_X, 13 );
-  osd_string( longNameOfChannel(channel, buffer));
-
-  osd( CMD_SET_X, 1 );
-  osd( CMD_SET_Y, 7 );
-  osd_string("                         ");
-
-  osd( CMD_DISABLE_INVERSE );
-  osd( CMD_DISABLE_FILL );
-}
-
-//******************************************************************************
 //* function: drawFunctionScreen
 //******************************************************************************
 #define XPOS  5
 #define YPOS  4
 uint8_t drawFunctionScreen( uint8_t function )
 {
+  drawLogo(1, 0);
+  batteryMeter(25, 0);
+
   osd(CMD_SET_X, XPOS);
   osd(CMD_SET_Y, YPOS);
   function == 0 ? osd(CMD_ENABLE_INVERSE) : osd(CMD_DISABLE_INVERSE);
@@ -1113,19 +1063,19 @@
   osd_string(" Exit            ");

   osd(CMD_SET_X, XPOS);
-  osd(CMD_SET_Y, YPOS+1);
+  osd(CMD_SET_Y, YPOS + 1);
   function == 1 ? osd(CMD_ENABLE_INVERSE) : osd(CMD_DISABLE_INVERSE);
   function == 1 ? osd(CMD_ENABLE_FILL) : osd(CMD_DISABLE_FILL);
   osd_string(" Graphic Scanner ");

   osd(CMD_SET_X, XPOS);
-  osd(CMD_SET_Y, YPOS+2);
+  osd(CMD_SET_Y, YPOS + 2);
   function == 2 ? osd(CMD_ENABLE_INVERSE) : osd(CMD_DISABLE_INVERSE);
   function == 2 ? osd(CMD_ENABLE_FILL) : osd(CMD_DISABLE_FILL);
   osd_string(" Auto Scanner    ");

   osd(CMD_SET_X, XPOS);
-  osd(CMD_SET_Y, YPOS+3);
+  osd(CMD_SET_Y, YPOS + 3);
   function == 3 ? osd(CMD_ENABLE_INVERSE) : osd(CMD_DISABLE_INVERSE);
   function == 3 ? osd(CMD_ENABLE_FILL) : osd(CMD_DISABLE_FILL);
   osd_string(" Options         ");
@@ -1135,8 +1085,21 @@
 //* function: drawAutoScanScreen
 //******************************************************************************
 void drawAutoScanScreen( void ) {
+  char buffer[22];
+  unsigned char answer;
+
   drawLogo(1, 0);
   batteryMeter(25, 0);
+
+  osd( CMD_ENABLE_FILL );
+  osd( CMD_ENABLE_INVERSE );
+
+  osd( CMD_SET_X, 1 );
+  osd( CMD_SET_Y, 5 );
+  osd_string("      Auto Scanning      ");
+
+  osd( CMD_DISABLE_INVERSE );
+  osd( CMD_DISABLE_FILL );
 }

 //******************************************************************************
@@ -1272,7 +1235,7 @@
     }
     switch (j) {
       case BATTERY_ALARM_OPTION:     osd_string("battery alarm      "); break;
-      case ALARM_LEVEL_OPTION:       osd_string("alarm level        "); break;
+      case ALARM_LEVEL_OPTION:       osd_string("alarm sound level  "); break;
       case BATTERY_TYPE_OPTION:      osd_string("battery type       "); break;
       case BATTERY_CALIB_OPTION:     osd_string("volt calibration   "); break;
       case SHOW_STARTSCREEN_OPTION:  osd_string("show start screen  "); break;
@@ -1300,7 +1263,7 @@
     if (j < MAX_OPTIONS) {
       switch (j) {
         case BATTERY_ALARM_OPTION:    osd_string(options[j] ? "yes    " : "no     "); break;
-        case ALARM_LEVEL_OPTION:      osd_int(options[j]); osd_string("      "); break;
+        case ALARM_LEVEL_OPTION:      osd_int(options[j]);      osd_string("      "); break;
         case BATTERY_TYPE_OPTION:     osd_string(options[j] ? "2s lipo" : "3s lipo"); break;
         case BATTERY_CALIB_OPTION:    osd_int(voltage / 10); osd_string("."); osd_int(voltage % 10);  osd_string("   "); break;
         case SHOW_STARTSCREEN_OPTION: osd_string(options[j] ? "yes    " : "no     "); break;


Added debounce check

Added debounce check

--- RFIDreader/RFIDreader.ino
+++ RFIDreader/RFIDreader.ino
@@ -69,30 +69,36 @@
   unsigned long startTime, endTime = 0;
   int signalState;
   int previousState = NULL;
-
   while(standby == false) {
     // read signal state
     signalState = digitalRead(signalPin);
+    delay(100);

-    // check for new ON signal
-    if (previousState == LOW && signalState == HIGH) {
-      startTime = millis();
-      previousState = signalState;
+    // debounce check
+    if (signalState == digitalRead(signalPin)) {
+
+      // check for new ON signal
+      if (previousState == LOW && signalState == HIGH) {
+        startTime = millis();
+        previousState = signalState;
+      }
+      // check for OFF signal
+      else if (previousState == HIGH && signalState == LOW) {
+        endTime = (millis() - startTime)/1000;
+        if (endTime != 0) {
+          Serial.print("Elapsed time: ");
+          Serial.println(endTime);
+        }
+        previousState = signalState;
+        standby = true;
+      }
+      // no event
+      else {
+        previousState = signalState;
+      }
+
     }
-    // check for OFF signal
-    else if (previousState == HIGH && signalState == LOW) {
-      endTime = (millis() - startTime)/1000;
-      if (endTime != 0) {
-        Serial.print("Elapsed time: ");
-        Serial.println(endTime);
-      }
-      previousState = signalState;
-      standby = true;
-    }
-    // no event
-    else {
-      previousState = signalState;
-    }
+
   }
 }