* 150906 마무리

* 150906 마무리

--- Arduino/Arduino.ino
+++ Arduino/Arduino.ino
@@ -420,15 +420,6 @@
   EEPROM.write(offset++, _config.tailVersion);
 }

-/*typedef struct Config {
-  uint8_t version = VER;
-  uint8_t mode = MODE_BOOT;
-  char ssid[32] = "unknown";
-  char pass[32] = "unknown";
-  char serverAddr[64] = "unknown";
-  int port = 80;
-  uint8_t tailVersion = VER;
-} CONFIG;*/

 bool checkConfig(CONFIG* config) {
@@ -446,135 +437,3 @@
 }

-
-
-/*
-  byte buffer[256];
-  SwSerial.print("AT+CIPSTART=\"TCP\",\"httpbin.org\",80\r\n");
-  delay(2000);
-  while(!SwSerial.available());
-  while(SwSerial.available()) {
-      Serial.print((char)SwSerial.read());
-  }
-  String cmd = "GET /ip HTTP/1.0\r\n\r\n";
-  SwSerial.print("AT+CIPSEND=");
-  SwSerial.print(cmd.length());
-  SwSerial.print("\r\n");
-
-  if (SwSerial.find(">")) {
-    Serial.print(">");
-  }
-  else {
-    SwSerial.print("AT+CIPCLOSE=AT+CIPCLOSE\r\n");
-    Serial.println("connect timeout");
-    delay(1000);
-    return;
-  }
-
-  SwSerial.print(cmd);
-  long lastMs = millis();
-  while(!SwSerial.available());
-  while(millis() - lastMs < 5000) {
-      if(SwSerial.available()) {
-        byte data = SwSerial.read();
-        Serial.print((char)data);
-      }
-  }
-  Serial.println("====");
-  delay(1000);
-
-
-
-  SwSerial.print("AT+CIPCLOSE=AT+CIPCLOSE\r\n");
-
-  while(!SwSerial.available());
-  while(millis() - lastMs < 5000) {
-      if(SwSerial.available()) {
-        byte data = SwSerial.read();
-        Serial.print((char)data);
-      }
-  }*/
-  /*
-   // 시리얼 버퍼를 비운다.
-    int delayt = 0;
-   Serial.flush();
-   byte buffer[10];
-   int idx = 0;
-   Serial.print("dealy : ");
-   // 버퍼에 값이 들어올 때 까지 대기.
-   while(!Serial.available());
-   // HC-06 으로 명령어를 날린다.
-   while(Serial.available()) {
-      Serial.readBytes(buffer, 10);
-   }
-   String aa = "";
-   aa += (char*)buffer;
-   delayt = aa.toInt();
-   Serial.println(delayt);
-   Serial.print("cmd : ");
-   // 버퍼에 값이 들어올 때 까지 대기.
-   while(!Serial.available());
-   // HC-06 으로 명령어를 날린다.
-   while(Serial.available()) {
-      data = Serial.read();
-      if(data == -1) break;
-      SwSerial.print(data);
-      Serial.print(data);
-      // 시리얼 통신에서는 9600bps 기준으로
-      // read 를 사용할 때 1ms 의 딜레이를 줘야 한다.
-      delayMicroseconds(84);
-   }
-   SwSerial.print("\r\n");
-   Serial.println();
-   // HC-06에서 처리할 시간을 준다.
-   Serial.print("return : ");
-   // HC-06 으로 부터 받아온 리턴 값을 출력한다.
-   while(!SwSerial.available()) {}
-   delayMicroseconds(84);
-   boolean isO = false;
-   boolean isK = false;
-   long lastMs = millis();
-   while((!isO || !isK) && millis() - lastMs < delayt) {
-      data = SwSerial.read();
-      if(data == -1) continue;
-      Serial.print(data);
-      //delayMicroseconds(84);
-
-
-      if(data == 'O') {
-        isO = true;
-      }
-      else if(isO && data == 'K') {
-        isK = true;
-      }
-      else {
-        isO = false;
-        isK = false;
-      }
-   }
-   Serial.print("\n\n");*/
-   /*
-   analogWrite(9,255);
-   analogWrite(6,255);
-  SwSerial.println("OKOK + 1\r\n");
-   // 데이터가 들어올때 까지 대기.
-  while(!SwSerial.available());
-  digitalWrite(ledPin, HIGH);
-  while(SwSerial.available()) {
-    data = SwSerial.read();
-    buffer[index++] = data;
-    // 버퍼가 꽉 찼거나 문자열이 끝났을 때,
-    // 루프에서 나간다.
-    if(index == BUFF_SIZE || data == '\0') break;
-    // 9600bps 기준으로 delay 를 1ms 을 줘야 한다.
-    delay(1);
-  }
-  // 블루투스를 통하여 받은 데이터를 되돌려준다.
-  for(uint8_t i = 0; i < index; ++i) {
-    SwSerial.write(buffer[i]);
-  }
-  SwSerial.print("\r\n");
-  index = 0;
-  int val = analogRead(1);
-  SwSerial.println(val);*/
-


revise circuit description

revise circuit description

--- vfobox.ino
+++ vfobox.ino
@@ -12,19 +12,43 @@
 https://www.circuitsathome.com/mcu/rotary-encoder-interrupt-service-routine-for-avr-micros

-  The circuit:
+ The circuit:
+
+ Power
+ * nominal 12V supply to amplifier
  * 5V to Arduino 5V pin
  * GND to Arduino GND pin

+ Reserve For Serial Debugging
+ * Leave digital #0 (RXD) and #1 (TXD) available for serial debugging
+
+ Rotary Encoder
+ * Rotary Encoder right tab to digital #2
+ * Rotary Encoder left tab to digital #3
+ * Rotary Encoder middle tab to ground
+ * Rotary Switch to digital #17
+
+ AD9850
  * CLK to digital #4
  * FQ to digital #5
- * DAT to digital #6
- * RST to digital #7
-
- * Rotary Encoder left tab to digital #3
- * Rotary Encoder right tab to digital #2
- * Rotary Encoder middle tab to ground
- * Rotary Switch to digital #1
+ * DAT to digital #8
+ * RST to digital #9
+
+ Reserve For Comparator
+ * Leave digital #6 and #7 available for future use of analog comparator
+
+ Memory Buttons
+ * Up to four memory buttons can be added, starting at d10..d13
+
+ RF Output Warning
+ * Sense rectified RF output on digital #14 (ADC 0)
+ * Warning LED on digital #16
+
+ I2C bus
+ * Built-in SDA on digital #18
+ * Built-in SCL on digital #19
+
+ AREF is not connected; we use ATmega328 1.1V internal analog reference

 */


* changes in version 0.14:            * debouncing target temp and fan status

--- minimalistthermostat.ino
+++ minimalistthermostat.ino
@@ -26,7 +26,7 @@
 #include "blynkAuthToken.h"

 #define APP_NAME "Thermostat"
-String VERSION = "Version 0.13";
+String VERSION = "Version 0.14";
 /*******************************************************************************
  * changes in version 0.09:
        * reorganized code to group functions
@@ -48,9 +48,16 @@
  * changes in version 0.13:
            * removing endOfCycleState since my HVAC does not need it
            * adding time in notifications
+ * changes in version 0.14:
+           * debouncing target temp and fan status
+
+TODO list:
+ * take few samples and average them
+
 *******************************************************************************/

 #define PUSHBULLET_NOTIF "pushbulletGUST"
+const int TIME_ZONE = -4;

 /*******************************************************************************
  initialize FSM states with proper enter, update and exit functions
@@ -77,8 +84,6 @@
 // to protect the fan and the heating/cooling elements
 #define MINIMUM_IDLE_TIMEOUT 180000
 elapsedMillis minimumIdleTimer;
-
-const int TIME_ZONE = -4;

 /*******************************************************************************
  IO mapping
@@ -134,6 +139,12 @@
 //fan status: false=off, true=on
 bool fanStatus = false;

+#define DEBOUNCE_SETTINGS 5000
+float newTargetTemp = 19.0;
+elapsedMillis setNewTargetTempTimer;
+bool newFanStatus = false;
+elapsedMillis setNewFanStatusTimer;
+
 //TESTING_HACK
 // this allows me to system test the project
 bool testing = false;
@@ -189,7 +200,7 @@
   if (Particle.function("setTargetTmp", setTargetTemp)==false) {
      Particle.publish(APP_NAME, "ERROR: Failed to register function setTargetTemp", 60, PRIVATE);
   }
-  if (Particle.function("setFan", setFan)==false) {
+  if (Particle.function("setFan", setFanStatus)==false) {
      Particle.publish(APP_NAME, "ERROR: Failed to register function setFan", 60, PRIVATE);
   }
   //TESTING_HACK
@@ -234,6 +245,9 @@
     //all the Blynk magic happens here
     Blynk.run();
   }
+
+  updateTargetTemp();
+  updateFanStatus();

 }

@@ -243,24 +257,108 @@
                     newTargetTemp has to be a valid float value, or no new target temp will be set
  * Return         : 0, or -1 if it fails to convert the temp to float
  *******************************************************************************/
-int setTargetTemp(String newTargetTemp)
-{
-  float tmpFloat = newTargetTemp.toFloat();
+int setTargetTemp(String temp)
+{
+  float tmpFloat = temp.toFloat();
   //update the target temp only in the case the conversion to float works
   // (toFloat returns 0 if there is a problem in the conversion)
   // sorry, if you wanted to set 0 as the target temp, you can't :)
   if ( tmpFloat > 0 ) {
-    targetTemp = tmpFloat;
-    targetTempString = String(targetTemp);
-    //Particle.publish(APP_NAME, "New target temp: " + targetTempString, 60, PRIVATE);
-    Particle.publish(PUSHBULLET_NOTIF, "New target temp: " + targetTempString + getTime(), 60, PRIVATE);
+    //newTargetTemp will be copied to targetTemp moments after in function updateTargetTemp()
+    // this is to 1-debounce blynk and 2-debounce the user changing his/her mind quickly
+    newTargetTemp = tmpFloat;
+    //start timer to debounce this new setting
+    setNewTargetTempTimer = 0;
     return 0;
+  }
+
+  //if the execution reaches here then the value was invalid
+  //Particle.publish(APP_NAME, "ERROR: Failed to set new target temp to " + temp, 60, PRIVATE);
+  Particle.publish(PUSHBULLET_NOTIF, "ERROR: Failed to set new target temp to " + temp + getTime(), 60, PRIVATE);
+  return -1;
+}
+
+/*******************************************************************************
+ * Function Name  : updateTargetTemp
+ * Description    : updates the value of target temperature of the thermostat
+                    moments after it was set with setTargetTemp
+ * Return         : none
+ *******************************************************************************/
+void updateTargetTemp()
+{
+  //debounce the new setting
+  if (setNewTargetTempTimer < DEBOUNCE_SETTINGS) {
+    return;
+  }
+  //is there anything to update?
+  if (targetTemp == newTargetTemp) {
+    return;
+  }
+
+  targetTemp = newTargetTemp;
+  targetTempString = String(targetTemp);
+  //Particle.publish(APP_NAME, "New target temp: " + targetTempString, 60, PRIVATE);
+  Particle.publish(PUSHBULLET_NOTIF, "New target temp: " + targetTempString + getTime(), 60, PRIVATE);
+}
+
+/*******************************************************************************
+ * Function Name  : setFanStatus
+ * Description    : sets the status of the Fan on or off
+ * Return         : 0, or -1 if the parameter does not match on or off
+ *******************************************************************************/
+int setFanStatus(String status)
+{
+  //update the fan status only in the case the status is on or off
+  if ( status == "on" ) {
+    //newFanStatus will be copied to fanStatus moments after in function updateTargetTemp()
+    // this is to 1-debounce blynk and 2-debounce the user changing his/her mind quickly
+    newFanStatus = true;
+    //start timer to debounce this new setting
+    setNewFanStatusTimer = 0;
+    return 0;
+  }
+  if ( status == "off" ) {
+    //newFanStatus will be copied to fanStatus moments after in function updateTargetTemp()
+    // this is to 1-debounce blynk and 2-debounce the user changing his/her mind quickly
+    newFanStatus = false;
+    //start timer to debounce this new setting
+    setNewFanStatusTimer = 0;
+    return 0;
+  }
+
+  return -1;
+}
+
+/*******************************************************************************
+ * Function Name  : updateFanStatus
+ * Description    : updates the status of the fan of the thermostat
+                    moments after it was set with setFan
+ * Return         : none
+ *******************************************************************************/
+void updateFanStatus()
+{
+  //debounce the new setting
+  if (setNewFanStatusTimer < DEBOUNCE_SETTINGS) {
+    return;
+  }
+  //is there anything to update?
+  if (fanStatus == newFanStatus) {
+    return;
+  }
+
+  //update the fan status only in the case the status is on or off
+  if (newFanStatus) {
+    fanStatus = true;
+    Particle.publish(PUSHBULLET_NOTIF, "Fan on" + getTime(), 60, PRIVATE);
+    return;
   } else {
-    //Particle.publish(APP_NAME, "ERROR: Failed to set new target temp to " + newTargetTemp, 60, PRIVATE);
-    Particle.publish(PUSHBULLET_NOTIF, "ERROR: Failed to set new target temp to " + newTargetTemp + getTime(), 60, PRIVATE);
-    return -1;
-  }
-}
+    fanStatus = false;
+    Particle.publish(PUSHBULLET_NOTIF, "Fan off" + getTime(), 60, PRIVATE);
+    return;
+  }
+
+}
+

 /*******************************************************************************
  * Function Name  : readTemperature
@@ -409,7 +507,7 @@

 void heatingEnterFunction(){
   //Particle.publish(APP_NAME, "heatingEnterFunction", 60, PRIVATE);
-  Particle.publish(PUSHBULLET_NOTIF, "Heat on", 60, PRIVATE);
+  Particle.publish(PUSHBULLET_NOTIF, "Heat on" + getTime(), 60, PRIVATE);
   myDigitalWrite(fan, HIGH);
   myDigitalWrite(heat, HIGH);
   myDigitalWrite(cold, LOW);
@@ -426,13 +524,13 @@

   if ( currentTemp >= (targetTemp + margin) ) {
     //Particle.publish(APP_NAME, "Desired temperature reached", 60, PRIVATE);
-    Particle.publish(PUSHBULLET_NOTIF, "Desired temperature reached", 60, PRIVATE);
+    Particle.publish(PUSHBULLET_NOTIF, "Desired temperature reached" + getTime(), 60, PRIVATE);
     thermostatStateMachine.transitionTo(idleState);
   }
 }
 void heatingExitFunction(){
   //Particle.publish(APP_NAME, "heatingExitFunction", 60, PRIVATE);
-  Particle.publish(PUSHBULLET_NOTIF, "Heat off", 60, PRIVATE);
+  Particle.publish(PUSHBULLET_NOTIF, "Heat off" + getTime(), 60, PRIVATE);
   myDigitalWrite(fan, LOW);
   myDigitalWrite(heat, LOW);
   myDigitalWrite(cold, LOW);
@@ -520,28 +618,6 @@
   }
 }

-/*******************************************************************************
- * Function Name  : setFan
- * Description    : sets the status of the Fan on or off
- * Return         : 0, or -1 if the parameter does not match on or off
- *******************************************************************************/
-int setFan(String status)
-{
-  //update the fan status only in the case the status is on or off
-  if ( status == "on" ) {
-    fanStatus = true;
-    Particle.publish(PUSHBULLET_NOTIF, "Fan on" + getTime(), 60, PRIVATE);
-    return 0;
-  }
-  if ( status == "off" ) {
-    fanStatus = false;
-    Particle.publish(PUSHBULLET_NOTIF, "Fan off" + getTime(), 60, PRIVATE);
-    return 0;
-  }
-
-  return -1;
-}
-
 /*******************************************************************************/
 /*******************************************************************************/
 /*******************************************************************************/


moved serlcd include to display ino

moved serlcd include to display ino

--- SlotCar.ino
+++ SlotCar.ino
@@ -1,5 +1,4 @@

-#include <serLCD.h>
 #include <EnableInterrupt.h>
 #include "Pins.h"
 #include "Events.h"


clean version with debug test

clean version with debug test

--- src/rabbitclock/ds1307/ds1307.ino
+++ src/rabbitclock/ds1307/ds1307.ino
@@ -6,27 +6,65 @@

 RTC_DS1307 RTC;

-int hour_day = 7;
-int minu_day = 0;
-int hour_night = 19;
-int minu_night = 30;
-
+int ledDay = 12;
+int ledNight = 13;
+boolean night = true;
+int minutes;
+boolean debug = false;

 void setup () {
-    pinMode(13, OUTPUT);
-    pinMode(12, OUTPUT);
+    pinMode(ledDay, OUTPUT);
+    pinMode(ledNight, OUTPUT);
+    digitalWrite(ledNight, LOW);
+    digitalWrite(ledDay, LOW);
     Serial.begin(57600);
-    Wire.begin();
-    //RTC.adjust(DateTime(__DATE__, __TIME__));
-    RTC.begin();
+    Wire.begin();
+    if (! RTC.isrunning()) {
+      Serial.println("RTC stopped !");
+      RTC.adjust(DateTime(__DATE__, __TIME__));
+      // following line sets the RTC to the date & time this sketch was compiled
+      RTC.begin();
+    } else {
+      Serial.println("RTC is running !");
+    }

-    // following line sets the RTC to the date & time this sketch was compiled
-    digitalWrite(13, LOW);
 }

 void loop () {
+   //print2SerialDate();
+   DateTime now = RTC.now();
+   if ( debug) {
+     minutes += 20 ;
+     if (minutes > 24 * 60)
+       minutes = 0 ;
+   } else {
+     minutes = now.hour() * 60 +  now.minute();
+   }
+
+   print2SerialMinutes(minutes);
+   night = true;
+   if ( minutes >=  7 * 60 + 10 )
+     night = false;
+   if ( minutes >= 13 * 60 + 30 )
+     night = true;
+   if ( minutes >= 16 * 60 )
+     night = false ;
+   if ( minutes >= 19 * 60 )
+     night = true;
+
+   if (night) {
+      digitalWrite(ledNight, HIGH);
+      digitalWrite(ledDay, LOW);
+   } else {
+      digitalWrite(ledDay, HIGH);
+      digitalWrite(ledNight, LOW);
+   }
+   delay(1000);
+   test();
+}
+
+void print2SerialDate(){
     DateTime now = RTC.now();
-
     Serial.print(now.year(), DEC);
     Serial.print('/');
     Serial.print(now.month(), DEC);
@@ -38,29 +76,29 @@
     Serial.print(now.minute(), DEC);
     Serial.print(':');
     Serial.print(now.second(), DEC);
+    Serial.print(' ');
+    Serial.print((now.hour() * 60 + now.minute()), DEC);
     Serial.println();
-
-    if ( now.hour() <= hour_day && now.minute() < minu_day ) {
-      digitalWrite(12, HIGH);
-      digitalWrite(13, LOW);
-      Serial.print("debug1");
-    } else if ( now.hour() >= hour_day && now.minute() >= minu_day && now.hour() < hour_night && now.minute() < minu_night ) {
-      digitalWrite(13, HIGH);
-      digitalWrite(12, LOW);
-      Serial.print("debug2");
-    } else if ( now.hour() >= hour_night && now.minute() >= minu_night ) {
-      digitalWrite(12, HIGH);
-      digitalWrite(13, LOW);
-      Serial.print("debug3");
-    }
-
-
-    Serial.print(" since 2000 = ");
-    Serial.print(now.get());
-    Serial.print("s = ");
-    Serial.print(now.get() / 86400L);
-    Serial.println("d");
-
-    Serial.println();
-    delay(3000);
 }
+
+void print2SerialMinutes(int minutes){
+  Serial.print(minutes / 60, DEC);
+  Serial.print(":");
+  Serial.print(minutes % 60, DEC);
+  Serial.println();
+}
+
+void test(){
+  DateTime now = RTC.now();
+  if ( now.year() == 2000 || now.year() == 2165){
+      print2SerialDate();
+      for ( int i = 0 ; i < 5 ; i++){
+        digitalWrite(ledDay, HIGH);
+        digitalWrite(ledNight, LOW);
+        delay(100);
+        digitalWrite(ledDay, LOW);
+        digitalWrite(ledNight, HIGH);
+        delay(100);
+     }
+  }
+}


Adds a time interpolation function for more accurate tf timestamps, as well as fixes the odom topic's child frame.


Bug fixes

Bug fixes

--- IR_Test/IR_Test.ino
+++ IR_Test/IR_Test.ino
@@ -101,7 +101,7 @@
     case 16750695:
       button="100+";
       buttonId = 50695;
-      buttonVal = 143007
+      buttonVal = 143007;
       break;
     case 16756815:
       button="200+";
@@ -136,7 +136,7 @@
     case 16734885:
       button="6";
       buttonId = 34885;
-      buttonVal = 104105
+      buttonVal = 104105;
       break;
     case 16728765:
       button="7";
@@ -168,12 +168,12 @@
   int n4;
   int n5;
   int n6;
-  n6 = x % 10;
-  n5 = floor(x / 10) % 10;
-  n4 = floor(x / 100) % 10;
-  n3 = floor(x / 1000) % 10;
-  n2 = floor(x / 10000) % 10;
-  n1 = floor(x / 100000) % 10;
+  n6 = int(x) % 10;
+  n5 = int(floor(x / 10)) % 10;
+  n4 = int(floor(x / 100)) % 10;
+  n3 = int(floor(x / 1000)) % 10;
+  n2 = int(floor(x / 10000)) % 10;
+  n1 = int(floor(x / 100000)) % 10;
   int nums[6] = {n1,n2,n3,n4,n5,n6};
 }

@@ -498,24 +498,40 @@
 }

 void patternPicker(int x) {
-  separate(x)
+  separate(x);
   for (int i = 0; i < 6; i++) {
     if (nums[i] = 0) {
       p0();
+      Serial.println(nums[i]);
+      delay(200);
     } else if (nums[i] = 1) {
       p1();
+      Serial.println(nums[i]);
+      delay(200);
     } else if (nums[i] = 2) {
       p2();
+      Serial.println(nums[i]);
+      delay(200);
     } else if (nums[i] = 3) {
       p3();
+      Serial.println(nums[i]);
+      delay(200);
     } else if (nums[i] = 4) {
       p4();
+      Serial.println(nums[i]);
+      delay(200);
     } else if (nums[i] = 5) {
       p5();
+      Serial.println(nums[i]);
+      delay(200);
     } else if (nums[i] = 6) {
       p6();
+      Serial.println(nums[i]);
+      delay(200);
     } else if (nums[i] = 7) {
       p7();
+      Serial.println(nums[i]);
+      delay(200);
     }
   }
 }
@@ -537,10 +553,11 @@
     if (buttonVal != 0){
       Serial.println(button);
       Serial.println(buttonId);
-      Serial.println(convertToOct(buttonId));
+      Serial.println(buttonVal);
       Serial.println("");
       patternPicker(buttonVal);
     }
   }
   someNum = someNum + 1;
 }
+


rearranged pins to free up comparator

rearranged pins to free up comparator

--- vfobox.ino
+++ vfobox.ino
@@ -35,18 +35,22 @@

 // set rotary encoder pins
 #define ENC_RD	PIND	//encoder port read
-#define RotEncSwPin 1 // digital pin 4
 #define A_PIN 2  // INT0 vector; digital pin 2
 #define B_PIN 3  // INT1 vector; digital pin 3
+#define RotEncSwPin 17 // digital pin 17 (a3)

 // set up AD9850 pins
-#define W_CLK 4
-#define FQ_UD 5
-#define DATAPIN 6
-#define RESET 7
+#define W_CLK 4 // digital pin 4
+#define FQ_UD 5  // digital pin 5
+#define DATAPIN 8  // digital pin 8
+#define RESET 9  // digital pin 9
+
+// set up comparator inputs
+//
+//

 // set up memory push buttons
-#define MEM_BUTTON_START_PIN  8  // digital pin where mem buttons start
+#define MEM_BUTTON_START_PIN  10  // digital pin where mem buttons start
 #define NUMBER_MEM_BUTTONS    2  // how many mem buttons

 const double bandStart = 100000;  // start of Gnerator at 100 KHZ


clear hw serial receive buffer when emptyQueue

--- a_Queue.ino
+++ a_Queue.ino
@@ -6,6 +6,7 @@
 void emptyQueue()
 {
   queueb = queuee = 0;
+  Serial.flush(); // clear receive buffer
 }

 boolean inputAvailable()


lcd: experiment with eeprom and serial

lcd: experiment with eeprom and serial

--- lcd/lcd.ino
+++ lcd/lcd.ino
@@ -10,6 +10,7 @@
 **************************************************************************************/

 #include <LiquidCrystal.h>
+#include <EEPROM.h>

 LiquidCrystal lcd(8, 9, 4, 5, 6, 7);           // select the pins used on the LCD panel

@@ -50,45 +51,94 @@
     return btnNONE;                // when all others fail, return this.
 }

-void setup(){
+int ee_address = 0;
+
+struct lcdtext {
+    char s[14];
+};
+
+void setup() {
    lcd.begin(16, 2);               // start the library
    lcd.setCursor(0,0);             // set the LCD cursor   position
-   lcd.print("Push the buttons");  // print a simple message on the LCD
+   lcd.print("t:push buttons");  // print a simple message on the LCD
+
+    Serial.begin(9600);
+    delay(1000);
+    Serial.println("type to print on LCD");
+
+    String ee_text = "";
+
+    lcdtext lt_get;
+    EEPROM.get(ee_address, lt_get);
+    Serial.println("current text on EEPROM is");
+    Serial.print("t:");
+    Serial.println(lt_get.s);
+    lcd.setCursor(2,0);
+    lcd.print("              ");
+    lcd.setCursor(2,0);
+    lcd.print(lt_get.s);
+
+    Serial.println("type to print something else on LCD");
 }
+
+int incomingByte = 0;
+String incoming_text = "";

 void loop(){
    lcd.setCursor(9,1);             // move cursor to second line "1" and 9 spaces over
+    lcd.print("s:");
+    lcd.setCursor(11,1);
    lcd.print(millis()/1000);       // display seconds elapsed since power-up

    lcd.setCursor(0,1);             // move to the begining of the second line
    lcd_key = read_LCD_buttons();   // read the buttons

    switch (lcd_key){               // depending on which button was pushed, we perform an action
-
        case btnRIGHT:{             //  push button "RIGHT" and show the word on the screen
-            lcd.print("RIGHT ");
+            lcd.print("b:R");
             break;
        }
        case btnLEFT:{
-             lcd.print("LEFT   "); //  push button "LEFT" and show the word on the screen
+             lcd.print("b:L"); //  push button "LEFT" and show the word on the screen
              break;
        }
        case btnUP:{
-             lcd.print("UP    ");  //  push button "UP" and show the word on the screen
+             lcd.print("b:U");  //  push button "UP" and show the word on the screen
              break;
        }
        case btnDOWN:{
-             lcd.print("DOWN  ");  //  push button "DOWN" and show the word on the screen
+             lcd.print("b:D");  //  push button "DOWN" and show the word on the screen
              break;
        }
        case btnSELECT:{
-             lcd.print("SELECT");  //  push button "SELECT" and show the word on the screen
+             lcd.print("b:S");  //  push button "SELECT" and show the word on the screen
              break;
        }
        case btnNONE:{
-             lcd.print("NONE  ");  //  No action  will show "None" on the screen
+             lcd.print("b:N");  //  No action  will show "None" on the screen
              break;
        }
    }
+
+    if (Serial.available() > 0) {
+        //incomingByte = Serial.read();
+        incoming_text = Serial.readString();
+
+        // say what you got:
+        Serial.print("t:");
+        //Serial.println(incomingByte, DEC);
+        Serial.println(incoming_text);
+        lcd.setCursor(2,0);
+        lcd.print("              ");
+        lcd.setCursor(2,0);
+        lcd.print(incoming_text);
+
+        char c_text[14];
+        lcdtext lt;
+        incoming_text.toCharArray(lt.s, 14);
+        //lt.s = c_text;
+
+        EEPROM.put(ee_address, lt);
+    }
 }


force softAP disconnection as it seems there is a memory kept in the wifi stack, that starts the AP despite not beeing invoked in non-config mode

--- examples/SONOFF/SONOFF.ino
+++ examples/SONOFF/SONOFF.ino
@@ -201,6 +201,10 @@
         MqttConfig tmpConfig = myConfigServer->getMqttConfig();
         sensorNameForCallback = tmpConfig.sensorName;
         if(tmpConfig.mqttPort != ""){
+            WiFi.mode(WIFI_STA);
+            WiFi.softAPdisconnect();
+
+
             bootMode = BOOT_MODE_MQTT;
             myMqtt = new MqttConnection(tmpConfig.sensorName.c_str(), tmpConfig.wifiName.c_str(), tmpConfig.wifiPwd.c_str(), tmpConfig.mqttIp.c_str(), tmpConfig.mqttPort.toInt());

@@ -217,6 +221,8 @@
         }
         else{
             WiFi.mode(WIFI_STA);
+            WiFi.softAPdisconnect();
+
             WiFi.begin(tmpConfig.wifiName.c_str(), tmpConfig.wifiPwd.c_str());

             while (WiFi.status() != WL_CONNECTED) {


clean up dev example a little

clean up dev example a little

--- examples/DEV/OnDemandConfigPortal/OnDemandConfigPortal.ino
+++ examples/DEV/OnDemandConfigPortal/OnDemandConfigPortal.ino
@@ -18,54 +18,7 @@

 unsigned long mtime = 0;

-// OLED TEST , untested
-// // #define MYOLED
-
-// #include <Wire.h>
-// #include <Adafruit_GFX.h>
-// #include <Adafruit_SSD1306.h>
-// #ifdef MYOLED
-
-// #define SCREEN_WIDTH 128 // OLED display width, in pixels
-// #define SCREEN_HEIGHT 32 // OLED display height, in pixels
-
-// // Declaration for an SSD1306 display connected to I2C (SDA, SCL pins)
-// #define OLED_RESET     -1 // Reset pin # (or -1 if sharing Arduino reset pin)
-// Adafruit_SSD1306 display(SCREEN_WIDTH, SCREEN_HEIGHT, &Wire, OLED_RESET);
-
-// void init_oled(){
-//   Wire.begin(SCL,SDA);  // begin(sda, scl) SWAP!
-//   // SSD1306_SWITCHCAPVCC = generate display voltage from 3.3V internally
-//   if(!display.begin(SSD1306_SWITCHCAPVCC, 0x3C)) { // Address 0x3C for 128x32
-//     Serial.println(F("SSD1306 allocation failed"));
-//   }
-
-//   display.clearDisplay();
-//   display.setTextSize(1);             // Normal 1:1 pixepl scale
-//   display.setTextColor(WHITE);        // Draw white text
-//   display.setCursor(0,0);             // Start at top-left corner
-//   display.display();
-// }
-
-// void print_oled(String str,uint8_t size){
-//   display.clearDisplay();
-//   display.setTextSize(size);
-//   display.setTextColor(WHITE);
-//   display.setCursor(0,0);
-//   display.println(str);
-//   display.display();
-// }
-// #else
-//   void print_oled(String str,uint8_t size){
-//     (void)str;
-//     (void)size;
-//   }
-// #endif
-
-void print_oled(String str,uint8_t size){
-  (void)str;
-  (void)size;
-}
+

 WiFiManager wm;

@@ -80,6 +33,20 @@

 // char ssid[] = "*************";  //  your network SSID (name)
 // char pass[] = "********";       // your network password
+
+// OLED TEST , ssd1306
+// #define WM_OLED
+#ifdef WM_OLED
+#include <Wire.h>
+#include <Adafruit_GFX.h>
+#include <Adafruit_SSD1306.h>
+#define SCREEN_WIDTH 128 // OLED display width, in pixels
+#define SCREEN_HEIGHT 32 // OLED display height, in pixels
+
+// Declaration for an SSD1306 display connected to I2C (SDA, SCL pins)
+#define OLED_RESET     -1 // Reset pin # (or -1 if sharing Arduino reset pin)
+Adafruit_SSD1306 display(SCREEN_WIDTH, SCREEN_HEIGHT, &Wire, OLED_RESET);
+#endif

 void saveWifiCallback(){
   Serial.println("[CALLBACK] saveCallback fired");
@@ -104,7 +71,7 @@

 void bindServerCallback(){
   wm.server->on("/custom",handleRoute);
-  // wm.server->on("/info",handleRoute); // can override wm!
+  // wm.server->on("/info",handleRoute); // you can override wm!
 }

 void handleRoute(){
@@ -114,30 +81,32 @@

 void setup() {
   WiFi.mode(WIFI_STA); // explicitly set mode, esp defaults to STA+AP
+
   // put your setup code here, to run once:
   Serial.begin(115200);
   // Serial1.begin(115200);

   // Serial.setDebugOutput(true);
   delay(1000);
-  // Serial1.println("TXD1 Enabled");

   Serial.println("\n Starting");
   // WiFi.setSleepMode(WIFI_NONE_SLEEP); // disable sleep, can improve ap stability

-  #ifdef OLED
-  init_oled();
+  #ifdef WM_OLED
+    init_oled();
   #endif
+
   print_oled(F("Starting..."),2);
   wm.debugPlatformInfo();

-  //Local intialization. Once its business is done, there is no need to keep it around
   //reset settings - for testing
   // wm.resetSettings();
   // wm.erase();

+  // invert theme, dark
   wm.setClass("invert");

+  // setup some parameters
   WiFiManagerParameter custom_html("
This Is Custom HTML
"); // only custom html
   WiFiManagerParameter custom_mqtt_server("server", "mqtt server", "", 40);
   WiFiManagerParameter custom_mqtt_port("port", "mqtt port", "", 6);
@@ -154,7 +123,7 @@
   wm.setSaveConfigCallback(saveWifiCallback);
   wm.setSaveParamsCallback(saveParamCallback);

-  //add all your parameters here
+  // add all your parameters here
   wm.addParameter(&custom_html);
   wm.addParameter(&custom_mqtt_server);
   wm.addParameter(&custom_mqtt_port);
@@ -163,50 +132,63 @@
   wm.addParameter(&custom_ipaddress);
   wm.addParameter(&custom_checkbox);

+  // set values later if you want
   custom_html.setValue("test",4);
   custom_token.setValue("test",4);

-  // Set cutom menu via menu[] or vector
-  // const char* menu[] = {"wifi","wifinoscan","info","param","close","sep","erase","restart","exit"};
-  // wm.setMenu(menu,9); // custom menu array must provide length
+/*
+  Set cutom menu via menu[] or vector
+  const char* menu[] = {"wifi","wifinoscan","info","param","close","sep","erase","restart","exit"};
+  wm.setMenu(menu,9); // custom menu array must provide length
+*/

   std::vector<const char *> menu = {"wifi","wifinoscan","info","param","close","sep","erase","restart","exit"};
   // wm.setMenu(menu); // custom menu, pass vector

   // wm.setParamsPage(true); // move params to seperate page, not wifi, do not combine with setmenu!

-  // set static sta ip
+  // set STA static ip
   // wm.setSTAStaticIPConfig(IPAddress(10,0,1,99), IPAddress(10,0,1,1), IPAddress(255,255,255,0));
   // wm.setShowStaticFields(false);
   // wm.setShowDnsFields(false);

-  // set static ip
+  // set AP static ip
   // wm.setAPStaticIPConfig(IPAddress(10,0,1,1), IPAddress(10,0,1,1), IPAddress(255,255,255,0));
   // wm.setAPStaticIPConfig(IPAddress(10,0,1,99), IPAddress(10,0,1,1), IPAddress(255,255,255,0));

   // set country
-  wm.setCountry("US"); // setting wifi country seems to improve OSX soft ap connectivity, may help others as well
-
-  // set channel
+  // setting wifi country seems to improve OSX soft ap connectivity,
+  // may help others as well, default is CN which has different channels
+  wm.setCountry("US");
+
+  // set Hostname
+  wm.setHostname("WIFIMANAGERTESTING");
+
+  // set custom channel
   // wm.setWiFiAPChannel(13);

   // set AP hidden
   // wm.setAPHidden(true);

-  // show password publicly!
+  // show password publicly in form
   // wm.setShowPassword(true);

   //sets timeout until configuration portal gets turned off
   //useful to make it all retry or go to sleep in seconds
   wm.setConfigPortalTimeout(120);

+  // set connection timeout
   // wm.setConnectTimeout(20);
+
+  // show static ip fields
   // wm.setShowStaticFields(true);

   // wm.startConfigPortal("AutoConnectAP", "password");

-  // wm.setCleanConnect(true); // disconenct before connect, clean connect
-
+  // This is sometimes necessary, it is still unknown when and why this is needed but it may solve some race condition or bug in esp SDK/lib
+  // wm.setCleanConnect(true); // disconnect before connect, clean connect
+
+  //
   wm.setBreakAfterConfig(true);

   // set custom webserver port, automatic captive portal does not work with custom ports!
@@ -216,16 +198,18 @@
   //if it does not connect it starts an access point with the specified name
   //here  "AutoConnectAP"
   //and goes into a blocking loop awaiting configuration
+
   wifiInfo();
+
   print_oled(F("Connecting..."),2);
   if(!wm.autoConnect("WM_AutoConnectAP","12345678")) {
     Serial.println("failed to connect and hit timeout");
     print_oled("Not Connected",2);
   }
   else if(TEST_CP) {
+    // start configportal always
     delay(1000);
     Serial.println("TEST_CP ENABLED");
-    // start configportal always
     wm.setConfigPortalTimeout(TESP_CP_TIMEOUT);
     wm.startConfigPortal("WM_ConnectAP");
   }
@@ -300,7 +284,7 @@
     Serial.print(".");
     now = time(nullptr);
     if((millis() - start) > timeout){
-      Serial.println("[ERROR] Failed to get NTP time.");
+      Serial.println("\n[ERROR] Failed to get NTP time.");
       return;
     }
   }
@@ -332,4 +316,32 @@
   // AP esp_267751
   // 507726A4AE30
   // ESP32 Chip ID = 507726A4AE30
-}+}
+
+#ifdef WM_OLED
+void init_oled(){
+  if(!display.begin(SSD1306_SWITCHCAPVCC, 0x3C)) { // Address 0x3C for 128x32
+    Serial.println(F("SSD1306 allocation failed"));
+  }
+
+  display.clearDisplay();
+  display.setTextSize(1);             // Normal 1:1 pixepl scale
+  display.setTextColor(WHITE);        // Draw white text
+  display.setCursor(0,0);             // Start at top-left corner
+  display.display();
+}
+
+void print_oled(String str,uint8_t size){
+  display.clearDisplay();
+  display.setTextSize(size);
+  display.setTextColor(WHITE);
+  display.setCursor(0,0);
+  display.println(str);
+  display.display();
+}
+#else
+  void print_oled(String str,uint8_t size){
+    (void)str;
+    (void)size;
+  }
+#endif


Fix rx tx pins Change_Baud_Rate Example

Fix rx tx pins Change_Baud_Rate Example

--- examples/Change_Baud_Rate/Change_Baud_Rate.ino
+++ examples/Change_Baud_Rate/Change_Baud_Rate.ino
@@ -1,7 +1,7 @@

 #include<CS5490.h>

-#define rx 13
+#define rx 11
 #define tx 12

 /* Choose your board */


Set hostname; Set mode to standalone

Set hostname; Set mode to standalone

--- MagicMushroom.ino
+++ MagicMushroom.ino
@@ -27,6 +27,9 @@
 void bootstrapWebServer(void);

 void setup() {
+
+  WiFi.hostname("MagicMushroom");
+  WiFi.mode(WIFI_STA);

   sounds.push_back("kranplaetze.mp3");
   sounds.push_back("badumtss.mp3");


Deleted analogWrite calls

Deleted analogWrite calls

--- VeronicaLedLamp.ino
+++ VeronicaLedLamp.ino
@@ -8,9 +8,6 @@

 #define LOCALDOMAIN "veronicalamp"
 #define FACTORY_RESET_PIN 5
-#define R_PIN 13
-#define G_PIN 12
-#define B_PIN 14

 const char json[] = "{\"a\": \"%d\", \"c\": [\"%02x%02x%02x\", \"%02x%02x%02x\", \"%02x%02x%02x\", \"%02x%02x%02x\", \"%02x%02x%02x\", \"%02x%02x%02x\", \"%02x%02x%02x\", \"%02x%02x%02x\"], \"m\": \"%d\", \"n\": \"%s\", \"s\": \"%s\", \"u\": \"%d:%d:%d\", \"w\": \"%d\"}";

@@ -66,9 +63,6 @@

     // Initialise pins
     pinMode( FACTORY_RESET_PIN, INPUT );
-    pinMode( R_PIN, OUTPUT );
-    pinMode( G_PIN, OUTPUT );
-    pinMode( B_PIN, OUTPUT );

     // Attach an interrupt to the Factory Reset Pin for Access Control
     attachInterrupt(FACTORY_RESET_PIN, physicalAccess, RISING);
@@ -92,53 +86,6 @@
 }

 void loop() {
-    if( mode == 0 ) {                       // OFF
-        R(0);
-        G(0);
-        B(0);
-    } else if( mode == 1 ) {                // 2 Color Fade
-    } else if( mode == 2 ) {                // Flash
-    } else if( mode == 3 ) {                // Full Fade
-        switch(stage)
-        {
-        case -1:
-            if( R() == 255 ) R(254);
-            if( G() == 255 ) G(254);
-            if( B() == 255 ) R(254);
-            ++stage;
-            break;
-        case 0:
-            if( G( G()+1 ) == 255 ) ++stage;
-            break;
-        case 1:
-            if( R( R()-1 ) == 0 ) ++stage;
-            break;
-        case 2:
-            if( B( B()+1 ) == 255 ) ++stage;
-            break;
-        case 3:
-            if( G( G()-1 ) == 0 ) ++stage;
-            break;
-        case 4:
-            if( R( R()+1 ) == 255 ) ++stage;
-            break;
-        case 5:
-            if( B( B()-1 ) == 0 ) ++stage;
-            break;
-        }
-        if( stage == 6 ) stage = 0;
-    } else if( mode == 4 ) {                // Static color
-        if( stage == -1 ) {
-            EEPROM.get( 1 + EEPROM.read(25) * 3, color[0] );
-            ++stage;
-        }
-        R(color[0][0]);
-        G(color[0][1]);
-        B(color[0][2]);
-    } else if( mode == 5 ) {                // 3 Color Fade
-    } else if( mode == 6 ) {                // Data Stream
-    }
-
     // Handle services
     mdns.update();
     server.handleClient();
@@ -310,17 +257,20 @@
 }

 byte R(byte r) {
-    analogWrite(R_PIN, r * 4);
+    Serial.print("R ");
+    Serial.println(r);
     return (m_R = r);
 }

 byte G(byte g) {
-    analogWrite(G_PIN, g * 4);
+    Serial.print("G ");
+    Serial.println(g);
     return (m_G = g);
 }

 byte B(byte b) {
-    analogWrite(B_PIN, b * 4);
+    Serial.print("B ");
+    Serial.println(b);
     return (m_B = b);
 }


Add comment

Add comment

--- sketch/sketch.ino
+++ sketch/sketch.ino
@@ -3,51 +3,82 @@

 /* サーボモータの制御クラス */
 class ServoIO{
+
+  Servo servo; /* サーボのピン */
+
+  /* サーボモータが可動範囲外に回転するのを防ぐ関数*/
   int angleCalc(const int currentAngle, const int difference){
     const int sum = currentAngle + difference;
-    if(sum < 5){return 0;}
-    if(sum > 175){return 180;}
+    if(sum < 5){return 0;}      /* 5度以下なら0度を返す */
+    if(sum > 175){return 180;}  /* 175度以上なら180度を返す */
     return currentAngle + difference;
   }
+
   protected:
+
+    /* サーボを回転させる関数 */
+    /* 値は0~180の間で */
     void rotateServo(const int difference){
-      const int currentAngle = servoPin.read();
+      const int currentAngle = servo.read();
       const int changedAngle = angleCalc(currentAngle, difference);
-      servoPin.write(changedAngle);
+      if(currentAngle != changedAngle){
+        servo.write(changedAngle);
+      }
     }
+
   public:
-    Servo servoPin;
+    /* サーボモータのピンを設定する関数 */
+    /* 無くても良いが、あると統一感が生まれる */
+    void servoPin(int pin){
+      servo.attach(pin);
+    }
 };

 /* モータの制御クラス */
 class MotorIO{
+
+  /* モータの状態を表す型 */
   struct MotorState{
-    bool isMoveFoward;
-    bool isStop;
+    bool isMoveFoward; /* 前進するか */
+    bool isStop;       /* 停止するか */
   };
+
+  /* モータの現在の状態
+     もう少し良い方法があれば書き直す */
   MotorState motorState = {true, false};
+
+  /* モータの変更後の状態
+     現在と違う状態がセットされていればmotor関数が状態を変更する */
+  MotorState changedMotorState = {true, false};
+
   void motor(){
-    if(! motorState.isStop){
-      if(motorState.isMoveFoward){
-        // Move Foward code here...
+    if(motorState.isMoveFoward != changedMotorState.isMoveFoward  ||
+       motorState.isStop != changedMotorState.isStop){
+      if(! motorState.isStop){
+        if(motorState.isMoveFoward){
+          // Move Foward code here...
+        } else {
+         // Move backward code here...
+        }
       } else {
-       // Move backward code here...
+        // Stop code here...
       }
-    } else {
-      // Stop code here...
     }
   }
-  protected:
+  public:
+    /* 前進するよう状態を変更 */
     void moveFoward(){
-      motorState = {true,false};
+      changedMotorState = {true,false};
     }
+    /* 後退するよう状態を変更 */
     void moveBackward(){
-      motorState = {false,false};
+      changedMotorState = {false,false};
     }
+    /* 停止するよう状態を変更 */
     void moveStop(){
-      motorState = {true,true};
+      changedMotorState = {true,true};
     }
-  public:
+    /* モータの状態を更新 */
     void updateMotorState(){
       motor();
     }
@@ -55,35 +86,42 @@

 /* 制御のクラス */
 class Control: public ServoIO, public MotorIO{
+  int errorPinNum; /* エラーピンの番号を表す */
   void error(void){
-    digitalWrite(errorPin,HIGH);
+    digitalWrite(errorPinNum,HIGH);
   }
-  void angleMove(int angle, bool isFoward){
+
+  /* moveFooBarの抽象化関数 */
+  void angleMove(const int angle, const bool isFoward){
     rotateServo(angle);
     if(isFoward){moveFoward();}else{moveBackward();}
   }

   public:
-    void leftFoward(){angleMove(-30, true);}
-    void rightFoward(){angleMove(30, true);}
-    void leftBackward(){angleMove(-30, false);}
-    void rightBackward(){angleMove(30, false);}
-    int errorPin;
-    void setup(){
-      pinMode(errorPin,OUTPUT);
+    /* 左前に移動するよう状態を変更 */
+    void moveLeftFoward(){angleMove(-30, true);}
+    /* 右前に移動するよう状態を変更 */
+    void moveRightFoward(){angleMove(30, true);}
+    /* 左後に移動するよう状態を変更 */
+    void moveLeftBackward(){angleMove(-30, false);}
+    /* 右後に移動するよう状態を変更 */
+    void moveRightBackward(){angleMove(30, false);}
+    /* エラーLEDのピンを設定する関数 */
+    void errorPin(const int pin){
+      errorPinNum = pin;
+      pinMode(pin,OUTPUT);
     }
 };

 Control ctrl;

 void setup(){
-  ctrl.errorPin=13;
-  ctrl.servoPin.attach(9);
+  ctrl.errorPin(13);
+  ctrl.servoPin(9);
 }

 void loop(){
-//  rotateServo(90);
-//  rotateServo(-90);
+  ctrl.updateMotorState();
 }


Add log with timestamps

Add log with timestamps

--- led-countdown/led-countdown.ino
+++ led-countdown/led-countdown.ino
@@ -16,12 +16,12 @@
 unsigned long endMillis = 0;

 Adafruit_NeoPixel strip = Adafruit_NeoPixel(60, pixelPin, NEO_GRB + NEO_KHZ800);
-const uint32_t color1 = strip.Color(40, 0, 30);
+const uint32_t color1 = strip.Color(30, 0, 30);

 void setup() {
   // Console
   Serial.begin(serialRate);
-  Serial.println("Let's go");
+  log("Let's go");

   //Clock
   rtc.begin();
@@ -54,7 +54,7 @@
   delay(loopDelay);

   if (lastNumber != number) {
-    Serial.println(String("Set Number to ") + number);
+    log(String("Set Number to ") + number);
   }
 }

@@ -67,8 +67,8 @@
   }

   if ( isRunning == false ) {
-    Serial.println("Manually started countdown");
     isRunning = true;
+    log("Manually started countdown");
   }
 }

@@ -126,7 +126,7 @@
   } else {
     setNumber(0);
     isRunning = false;
-    Serial.write("Stopped countdown\n");
+    log("Stopped countdown\n");
   }
 }

@@ -135,7 +135,7 @@
   TimeTable table(dateTime);
   if ( table.match() ) {
     startCountdownMinutes(60);
-    Serial.println("TimeTable started Countdown");
+    log("TimeTable started Countdown");
   }
 }

@@ -146,3 +146,10 @@
   setNumber(minutes);
 }

+void log(const String& message)
+{
+  String output;
+  rtc.now().addToString(output);
+  Serial.println(output + " " + message);
+}
+


errata corrige

errata corrige

--- arduino.ino
+++ arduino.ino
@@ -209,7 +209,7 @@
   digitalWrite(led, LOW);
   read_value=(read_value*(OPEN-CLOSE)/100)+CLOSE;

-  if(read_value >= CLOSE && read_value <= CLOSE)
+  if(read_value >= CLOSE && read_value <= OPEN)
      set_servo(read_value);

   return 0;


modify MQTT protocoll

modify MQTT protocoll

--- Teensy/Teensy.ino
+++ Teensy/Teensy.ino
@@ -99,24 +99,23 @@
   // handle all mqtt messages
   if (strTopic.startsWith("mumalab")) {
     if (strTopic == "mumalab/fridge/state") {
-      state = strMessage == "on" ? 1 : 0;
+      state = strMessage.toInt();
     } else if (strTopic == "mumalab/fridge/brightness") {
       brightness = strMessage.toInt();
       brightness = min(255, max(brightness, 0));
       FastLED.setBrightness(brightness);
     } else if (strTopic == "mumalab/fridge/mode/animation/effect") {
-      String effectName = strMessage;
-      if (effectName == "twinkle") {
+      if (strMessage == "twinkle") {
         animation.setEffect(1);
-      } else if (effectName == "plasma") {
+      } else if (strMessage == "plasma") {
         animation.setEffect(2);
-      } else if (effectName == "snake") {
+      } else if (strMessage == "snake") {
         animation.setEffect(3);
-      } else if (effectName == "life") {
+      } else if (strMessage == "life") {
         animation.setEffect(4);
-      } else if (effectName == "sprite") {
+      } else if (strMessage == "sprite") {
         animation.setEffect(5);
-      } else if (effectName == "rainbow") {
+      } else if (strMessage == "rainbow") {
         animation.setEffect(6);
       }
       animation.setState(1);


updating code

updating code

--- firmware/beer/beersensor.ino
+++ firmware/beer/beersensor.ino
@@ -7,11 +7,10 @@
   * API endpoints:
     x reset
     x get data
-    x set calibration
     * set tap name
     * animation (beer) type
+
 */
-
 // This #include statement was automatically added by the Particle IDE.
 #include "neopixel/neopixel.h"

@@ -20,7 +19,7 @@
 #define EEPROM_ADDR_PERCENT_FULL 3
 #define PIXEL_PIN D2
 #define PIXEL_TYPE WS2812B
-#define PIXEL_COUNT 7
+#define PIXEL_COUNT 14

 Adafruit_NeoPixel strip = Adafruit_NeoPixel(PIXEL_COUNT, PIXEL_PIN, PIXEL_TYPE);

@@ -202,6 +201,11 @@
   currentSecond = Time.second();
   if(currentSecond != previousSecond)
   {
+      Serial.println("pinVal Next second");
+      Serial.println(previousPulseCount);
+      Serial.println(pulseCount);
+      Serial.println(flowing);
+      Serial.println("-------------");
       // setPixels(instantPulseCount);
       instantPulseCount = 0;
       if(previousPulseCount != pulseCount)
@@ -210,6 +214,10 @@
         flowing = false;
       previousPulseCount = pulseCount;
       previousSecond = currentSecond;
+      Serial.println(previousPulseCount);
+      Serial.println(pulseCount);
+      Serial.println(flowing);
+      Serial.println("================");
   }
 }


Added better support for calibrating

Added better support for calibrating

--- firmware/src/PoolBuddy.ino
+++ firmware/src/PoolBuddy.ino
@@ -23,9 +23,14 @@
 double orp = 0;
 double soc = 0;
 int wifi;
+bool calibrationmode = false;

 void setup() {
   //Serial.begin(9600);
+  temp = 0;
+  ph = 0;
+  orp = 0;
+  soc = 0;
   if (!Wire.isEnabled())
     Wire.begin();
   pinMode(POWER,OUTPUT);
@@ -39,9 +44,12 @@
   Particle.variable("pH", ph);
   Particle.variable("ORP", orp);
   Particle.variable("soc", soc);
+  Particle.variable("calibrating",calibrationmode);
+  Particle.function("switchmode",switchcalibrationmode);
   Particle.function("calibratePh",calibrate_ph);
   Particle.function("calibrateORP",calibrate_orp);
   Particle.function("check",check_calibrated);
+  Particle.function("measure",measure);
   Particle.function("slope",check_slope);
   Particle.variable("wifi",wifi);

@@ -49,33 +57,45 @@
 }

 void loop() {
-  if (millis() > nextSampleTime) {
-    measure_temp();
-    compensate_temp_ph();
-    measure_ph();
-    measure_orp();
-    measure_wifi();
-    nextSampleTime = millis() + SAMPLE_INTERVAL;
-    soc = lipo.getSOC();
-  }
-  if(millis() > nextSleepTime) {
-    Particle.publish("waterdata", water_data(), PRIVATE);
-    if(soc <= 10)
-      sleepInterval = 60 * 15;
-    else if(soc <= 20)
-      sleepInterval = 60 * 10;
-    else
-      sleepInterval = 60 * 5;
-    nextSleepTime = millis() + (sleepInterval * 1000) + WAKE_INTERVAL;
-    executeRequest(PH_ADDRESS,"Sleep");
-    executeRequest(ORP_ADDRESS,"Sleep");
-    digitalWrite(POWER, LOW);
-    System.sleep(SLEEP_MODE_DEEP,sleepInterval);
+  if (!calibrationmode) {
+    if (millis() > nextSampleTime) {
+      measure_temp();
+      compensate_temp_ph();
+      measure_ph();
+      measure_orp();
+      measure_wifi();
+      nextSampleTime = millis() + SAMPLE_INTERVAL;
+      soc = lipo.getSOC();
+    }
+    if(millis() > nextSleepTime) {
+      Particle.publish("waterdata", water_data(), PRIVATE);
+      if(soc <= 10)
+        sleepInterval = 60 * 15;
+      else if(soc <= 20)
+        sleepInterval = 60 * 10;
+      else
+        sleepInterval = 60 * 5;
+      nextSleepTime = millis() + (sleepInterval * 1000) + WAKE_INTERVAL;
+      executeRequest(PH_ADDRESS,"Sleep");
+      executeRequest(ORP_ADDRESS,"Sleep");
+      digitalWrite(POWER, LOW);
+      System.sleep(SLEEP_MODE_DEEP,sleepInterval);
+    }
   }
 }

 String water_data() {
   return String::format("{\"temperature\":%f,\"ph\":%f,\"orp\":%f,\"soc\":%f,\"wifi\":%d}",temp,ph,orp,soc,wifi);
+}
+
+int measure(String arg) {
+  ph = 0;
+  orp = 0;
+  temp = 0;
+  measure_temp();
+  measure_ph();
+  measure_orp();
+  measure_wifi();
 }

 void measure_ph() {
@@ -83,11 +103,11 @@
   //Serial.print("Ph:");
   //Serial.println(pH_data);
   if (isdigit(pH_data[0])) {
-    String(pH_data).toFloat();
+    float current = String(pH_data).toFloat();
     if(ph == 0)
-      ph = String(pH_data).toFloat();
+      ph = current;
     else
-      ph = (ph + String(pH_data).toFloat()) / 2;
+      ph = (ph + current) / 2;
   }
 }

@@ -96,11 +116,11 @@
   //Serial.print("ORP:");
   //Serial.println(orp_data);
   if (isdigit(orp_data[0])) {
-    String(orp_data).toFloat();
+    float current = String(orp_data).toFloat();
     if(orp == 0)
-      orp = String(orp_data).toFloat();
+      orp = current;
     else
-      orp = (orp + String(orp_data).toFloat()) / 2;
+      orp = (orp + current) / 2;
   }
 }

@@ -136,6 +156,10 @@
     wifi = (int)((-wifi_db / 127)*100);
 }

+int switchcalibrationmode(String arg) {
+  calibrationmode = !calibrationmode;
+}
+
 int calibrate_ph(String arg) {
   String commandString = String("Cal");
   commandString.concat(",");
@@ -147,7 +171,7 @@
     commandString.concat("4.00");
   if(arg=="high")
     commandString.concat("10.00");
-  executeRequest(PH_ADDRESS,commandString);
+  Serial.println(executeRequest(PH_ADDRESS,commandString));
   return 0;
 }

@@ -165,10 +189,12 @@
 }

 int check_calibrated(String args) {
-  //Serial.println(executeRequest(PH_ADDRESS,"Cal,?"));
-  //Serial.println(executeRequest(PH_ADDRESS,"Status"));
-  //Serial.println(executeRequest(ORP_ADDRESS,"Cal,?"));
-  //Serial.println(executeRequest(ORP_ADDRESS,"Status"));
+  Serial.println("Ph:");
+  Serial.println(executeRequest(PH_ADDRESS,"Cal,?"));
+  Serial.println(executeRequest(PH_ADDRESS,"Status"));
+  Serial.println("ORP:");
+  Serial.println(executeRequest(ORP_ADDRESS,"Cal,?"));
+  Serial.println(executeRequest(ORP_ADDRESS,"Status"));
   return 0;
 }

@@ -184,28 +210,28 @@
   Wire.beginTransmission(address);
   Wire.write(cmd);
   Wire.endTransmission();
-  if(cmd=="R")
-    delay(800);
+  if(cmd=="R" | cmd.startsWith("Cal"))
+    delay(900);
   else
     delay(300);
   Wire.requestFrom(address, 20);
   int val=Wire.read();
   switch (val) {
     case 1:
-      //Serial.println("Success");
+      Serial.println("Success");
       break;
     case 2:
-      //Serial.println("Failed");
+      Serial.println("Failed");
       return String("Failed");
       break;
     case 254:
-      //Serial.println("Pending");
+      Serial.println("Pending");
       break;
     case 255:
-      //Serial.println("No Data");
+      Serial.println("No Data");
       break;
     default:
-      //Serial.printlnf("Invalid response %d",val);
+      Serial.printlnf("Invalid response %d",val);
       return String("Failed");
   }

@@ -214,5 +240,6 @@
     i+=1;
   }
   Wire.endTransmission();
+  //Serial.println(String(data));
   return String(data);
 }


Set up MAX_COUNT to automatically update itself.

Moved speaker functionality to its own function.

Set up sensor pin to use the internal pull-up resistor (save some money!)

Re-wrote note timing so that all notes have the same(ish) duration.

--- Alarm_Tone/Alarm_Tone.ino
+++ Alarm_Tone/Alarm_Tone.ino
@@ -11,52 +11,65 @@
  *
  * where the different tones are described as in the table:
  *
- * note         frequency       period  PW (timeHigh)
- * c            261 Hz          3830    1915
- * d            294 Hz          3400    1700
- * e            329 Hz          3038    1519
- * f            349 Hz          2864    1432
- * g            392 Hz          2550    1275
- * a            440 Hz          2272    1136
- * b            493 Hz          2028    1014
+ * note         frequency       period  PW (timeHigh)
+ * c            261 Hz          3830    1915
+ * d            294 Hz          3400    1700
+ * e            329 Hz          3038    1519
+ * f            349 Hz          2864    1432
+ * g            392 Hz          2550    1275
+ * a            440 Hz          2272    1136
+ * b            493 Hz          2028    1014
  * C            523 Hz          1912    956
  *
  * (cleft) 2005 D. Cuartielles for K3
  */

 int ledPin = 13;
-int speakerOut = 9;
-byte names[] = {'c', 'd', 'e', 'f', 'g', 'a', 'b', 'C'};
+int speakerOut = 9;
+int sensorPin = 5;
+byte names[] = {'c', 'd', 'e', 'f', 'g', 'a', 'b', 'C'};
 int tones[] = {1915, 1700, 1519, 1432, 1275, 1136, 1014, 956};
-byte melody[] = "9b6d9b6d9b6d9b6d";
+byte melody[] = "3b3d"; //"3b3d3b3d3b3d3b3d";
 // count length: 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0
 //                                10                  20                  30
 int count = 0; //Iterates through the notes in the playlist
 int count2 = 0; //The counter that iterates through the names, looking for a match with the requested note
-int count3 = 0; //Controls how long a "beat" is, via its for loop
-int MAX_COUNT = 8; //How many notes are in the melody
+int MAX_COUNT = (sizeof(melody) - 1) / 2; //How many notes are in the melody
 int statePin = LOW;
+void speaker ();

 void setup() {
- pinMode(ledPin, OUTPUT);
- //Speaker is already set up by default as output
+  pinMode(ledPin, OUTPUT);
+  pinMode(sensorPin, INPUT);
+  digitalWrite(sensorPin, HIGH);
+  //Speaker is already set up by default as output
 }

 void loop() {
-  analogWrite(speakerOut, 0); //Ensure speaker starts off
+  if (digitalRead (sensorPin) == LOW) {
+    speaker();
+  }
+}
+
+void speaker() {
+  analogWrite(speakerOut, 0); //Ensure speaker starts off
   for (count = 0; count < MAX_COUNT; count++) { //Iterates through the notes requested
     statePin = !statePin;
     digitalWrite(ledPin, statePin);
-    for (count3 = 0; count3 <= (melody[count*2] - 48) * 30; count3++) { //controls how long a note plays
-      for (count2=0;count2<8;count2++) { //Iterate through tones
-        if (names[count2] == melody[count*2 + 1]) { //if you find a tone that matches the tone requested
-          analogWrite(speakerOut,255); //pulse speaker accordingly (does not control volume well)
+    for (count2 = 0; count2 < 8; count2++) { //Iterate through tones
+      if (names[count2] == melody[count * 2 + 1]) { //if you find a tone that matches the tone requested
+        unsigned long startTime = millis();
+        while (millis() - startTime <= (melody[count * 2] - 48) * 100) { //rudimentary way of spacing out the length of a tone, and keeps tones at the same length
+          analogWrite(speakerOut, 255); //pulse speaker accordingly (does not control volume well)
           delayMicroseconds(tones[count2]);
           analogWrite(speakerOut, 0);
           delayMicroseconds(tones[count2]); //there is a timing issue here where higher notes are played slightly shorter
-        }
-        if (melody[count*2 + 1] == 'p') {
-          // make a pause of a certain size
+        }
+      }
+      if (melody[count * 2 + 1] == 'p') {
+        // make a pause of a certain size
+        unsigned long startTime = millis();
+        while (millis() - startTime <= (melody[count * 2] - 48) * 30) {
           analogWrite(speakerOut, 0);
           delayMicroseconds(500);
         }
@@ -65,4 +78,4 @@
   }
 }

-//Code from http://www.arduino.cc/en/Tutorial/PlayMelody
+//Base code from http://www.arduino.cc/en/Tutorial/PlayMelody


Update mega_eth_rs485_lcd_mqtt.ino

Update mega_eth_rs485_lcd_mqtt.ino

--- rr/mega_eth_rs485_lcd_mqtt.ino
+++ rr/mega_eth_rs485_lcd_mqtt.ino
@@ -141,7 +141,7 @@
 regs[3] = val4;

-  lcd.setCursor(0,0);
+/*  lcd.setCursor(0,0);
  lcd.print("SA:");
  lcd.setCursor(3,0);
 float val11 = val1 / 100.0;
@@ -161,7 +161,7 @@
   lcd.print(val33, 1);
   lcd.setCursor(19,0);
   lcd.print("%");
-
+  */

 }
  else if (val4 == 2)


Eran corrections

Eran corrections

--- turboencabulator/turboencabulator.ino
+++ turboencabulator/turboencabulator.ino
@@ -1,4 +1,4 @@
-#include <MIDI.h>
+]#include <MIDI.h>

 #include <LiquidCrystal.h>

@@ -45,12 +45,12 @@

 IntervalTimer timer_0, timer_1, timer_2, timer_3;
-LiquidCrystal vfd(3, 4, 5, 6, 7, 8);                // (RS, Enable, D4, D5, D6, D7)
+LiquidCrystal vfd(3, 4, 5, 6, 7, 2);                // (RS, Enable, D4, D5, D6, D7)

 #define midi_mode_switch    10
 #define pulse_mode_switch   9
 #define estop_switch        11
-#define channel_1_out       21
+#define channel_1_out       23
 #define pulsewidth_pot A0
 #define duty_cycle_pot A1


first working version of ESP to reader, needs more cleanup and docs

--- code/esp-rfid/esp-rfid.ino
+++ code/esp-rfid/esp-rfid.ino
@@ -6,44 +6,68 @@

   Single shot read - Ask the reader to tell us what tags it currently sees. And it beeps!

-  If using the Simultaneous RFID Tag Reader (SRTR) shield, make sure the serial slide
-  switch is in the 'SW-UART' position.
 */

-#include <SoftwareSerial.h> //Used for transmitting to the device
-
-SoftwareSerial softSerial(2, 3); //RX, TX
+#include <SoftwareSerial.h> // communication between ESP and RFID reader

 #include "SparkFun_UHF_RFID_Reader.h" //Library for controlling the M6E Nano module
-RFID nano; //Create instance

-#define BUZZER1 9
-//#define BUZZER1 0 //For testing quietly
-#define BUZZER2 10
+#include "util.h"
+
+
+// jumper wires from:
+//   GPIO 13 to shield 2
+//   GPIO 15 to shield 3
+// select "SW-UART" on both RFID board
+// move UART switch to "HW" on the ESP board
+
+// Create instances of the serial driver and the RFID driver
+SoftwareSerial softSerial(13, 15); //RX, TX (from ESP's view)
+RFID nano;
+
+
+// connect these pins between the ESP and RFID reader:
+//   GPIO 12 to shield 9
+//   GPIO 14 to shield 10
+#define BUZZER1 12
+#define BUZZER2 14
+
+

 void setup()
 {
-  Serial.begin(115200);
+  board_init();  // for the functions in util.h

+  Serial.begin(115200);  // Serial monitor must match this rate
+
+  // Setup the pins for the buzzer
   pinMode(BUZZER1, OUTPUT);
   pinMode(BUZZER2, OUTPUT);
-
   digitalWrite(BUZZER2, LOW); //Pull half the buzzer to ground and drive the other half.

   while (!Serial);
+  status(GOOD);  // blink that we are here
+
+
+  // now get the RFID reader setup
   Serial.println();
-  Serial.println("Initializing...");
+  Serial.println("Initializing RFID reader...");

-  if (setupNano(38400) == false) //Configure nano to run at 38400bps
+  // nano defaults to 115200 baud rate, keep it the same!
+
+  if (setupNano(115200) == false)
   {
     Serial.println("Module failed to respond. Please check wiring.");
     while (1); //Freeze!
   }

   nano.setRegion(REGION_NORTHAMERICA); //Set to North America
-
   nano.setReadPower(500); //5.00 dBm. Higher values may cause USB port to brown out
   //Max Read TX Power is 27.00 dBm and may cause temperature-limit throttling
+
+  // Uncomment this to see the commands and responses sent/received
+  //   between the ESP and Reader
+  //nano.enableDebugging(Serial);
 }

 void loop()
@@ -83,6 +107,9 @@
   Serial.println(F("]"));
 }

+
+
+
 //Gracefully handles a reader that is already configured and already reading continuously
 //Because Stream does not have a .begin() we have to do this outside the library
 boolean setupNano(long baudRate)
@@ -96,20 +123,17 @@

   //About 200ms from power on the module will send its firmware version at 115200. We need to ignore this.
   while(softSerial.available()) softSerial.read();
+
+  nano.getVersion();

-  nano.getVersion();
-
-  if (nano.msg[0] == ERROR_WRONG_OPCODE_RESPONSE)
-  {
+  if (nano.msg[0] == ERROR_WRONG_OPCODE_RESPONSE) {
     //This happens if the baud rate is correct but the module is doing a ccontinuous read
     nano.stopReading();

     Serial.println(F("Module continuously reading. Asking it to stop..."));

     delay(1500);
-  }
-  else
-  {
+  } else {
     //The module did not respond so assume it's just been powered on and communicating at 115200bps
     softSerial.begin(115200); //Start software serial at 115200

@@ -120,11 +144,12 @@

   //Test the connection
   nano.getVersion();
-  if (nano.msg[0] != ALL_GOOD) return (false); //Something is not right
+  Serial.print("connection test response: ");
+  Serial.println(nano.msg[0], HEX);
+  //if (nano.msg[0] != ALL_GOOD) return (false); //Something is not right

   //The M6E has these settings no matter what
   nano.setTagProtocol(); //Set protocol to GEN2
-
   nano.setAntennaPort(); //Set TX/RX antenna ports to 1

   return (true); //We are ready to rock


Switch to 115200

Switch to 115200

The bluetooth adapter I'm using (BlueSMiRF) only seems to work with
115200 connections...

--- Arduino/blink_on_serial/blink_on_serial.ino
+++ Arduino/blink_on_serial/blink_on_serial.ino
@@ -8,8 +8,8 @@
   // initialize the digital pin as an output.
   pinMode(led, OUTPUT);

-  // start serial port at 9600 bps:
-  Serial.begin(9600);
+  // start serial port at 115200 bps:
+  Serial.begin(115200);
   while (!Serial) {
     ; // This is only required if you have a Leonardo
   }


Added feature to change and select coils to use

--- ad9833/ad9833.ino
+++ ad9833/ad9833.ino
@@ -16,6 +16,7 @@

 // List of commands goes here.
 const char cmdFreq[] = "FREQ";
+const char cmdFreqReset[] = "FREQR";
 const char cmdRead[] = "READ";
 const char cmdRst[]  = "RESET";

@@ -48,6 +49,17 @@
   7  // Coil 8
 };

+int coilSelect[NUMCOILS] = {
+  15, // Coil 1
+  16, // Coil 2
+  17, // Coil 3
+  19, // Coil 4
+  20, // Coil 5
+  21, // Coil 6
+  22, // Coil 7
+  23  // Coil 8
+};
+
 // Input serial buffer and size holder
 char input[INPUT_SIZE + 1];
 byte cmdsize = 0;
@@ -64,6 +76,8 @@
 	  // Set states for the SPI enable pins
     for (int i = 0; i < NUMCOILS; i++){
     	pinMode(coilEnable[i], INPUT);
+      pinMode(coilSelect[i], OUTPUT);
+      digitalWrite(coilSelect[i], LOW);
     }

     // Start Serial and reduce timeout to 100ms
@@ -211,6 +225,9 @@
 	else if(!strcmp(cmd, cmdRst)){
 		resetAll();
 	}
+  else if(!strcmp(cmd, cmdFreqReset)){
+    processFreqsReset(cmd);
+  }
  else{return NACK;}
 }

@@ -239,6 +256,26 @@
 	}
 }

+int processFreqsReset(char *cmd)
+{
+ resetAll();
+ processFreqs(cmd);
+}
+
+
+void selectCoil(int coilNo)
+{
+  for (int i=0; i<NUMCOILS; i++){
+      if (i == coilNo){
+        digitalWrite(coilSelect[i], LOW); // Set to transmit
+      }
+      else{
+        digitalWrite(coilSelect[i], HIGH); // Set to receive
+      }
+  }
+}
+
+

 int isCoilValid(int coilNo)
 {


initial race band addition. removing references to STATE_SWITCH

--- src/rx5808-pro-diversity/rx5808-pro-diversity.ino
+++ src/rx5808-pro-diversity/rx5808-pro-diversity.ino
@@ -89,19 +89,18 @@
 #define STATE_SEEK 1
 #define STATE_SCAN 2
 #define STATE_MANUAL 3
-#define STATE_SWITCH 4
+#define STATE_DIVERSITY 4
 #define STATE_SAVE 5
 #define STATE_RSSI_SETUP 6
-#define STATE_DIVERSITY 7

 #define START_STATE STATE_SEEK
 #define MAX_STATE STATE_MANUAL

 #define CHANNEL_BAND_SIZE 8
 #define CHANNEL_MIN_INDEX 0
-#define CHANNEL_MAX_INDEX 31
-
-#define CHANNEL_MAX 31
+#define CHANNEL_MAX_INDEX 39
+
+#define CHANNEL_MAX 39
 #define CHANNEL_MIN 0

 #define TV_COLS 128
@@ -126,13 +125,15 @@
 #define EEPROM_ADR_RSSI_MAX_B_L 9
 #define EEPROM_ADR_RSSI_MAX_B_H 10

+
 // Channels to sent to the SPI registers
 const uint16_t channelTable[] PROGMEM = {
   // Channel 1 - 8
   0x2A05,    0x299B,    0x2991,    0x2987,    0x291D,    0x2913,    0x2909,    0x289F,    // Band A
   0x2903,    0x290C,    0x2916,    0x291F,    0x2989,    0x2992,    0x299C,    0x2A05,    // Band B
   0x2895,    0x288B,    0x2881,    0x2817,    0x2A0F,    0x2A19,    0x2A83,    0x2A8D,    // Band E
-  0x2906,    0x2910,    0x291A,    0x2984,    0x298E,    0x2998,    0x2A02,    0x2A0C  // Band F / Airwave
+  0x2906,    0x2910,    0x291A,    0x2984,    0x298E,    0x2998,    0x2A02,    0x2A0C,    // Band F / Airwave
+  0x281D,    0x288F,    0x2902,    0x2914,    0x2978,    0x2999,    0x2A0C,    0x2A1E     // Band R / Immersion Raceband
 };

 // Channels with their Mhz Values
@@ -141,7 +142,8 @@
   5865, 5845, 5825, 5805, 5785, 5765, 5745, 5725, // Band A
   5733, 5752, 5771, 5790, 5809, 5828, 5847, 5866, // Band B
   5705, 5685, 5665, 5645, 5885, 5905, 5925, 5945, // Band E
-  5740, 5760, 5780, 5800, 5820, 5840, 5860, 5880  // Band F / Airwave
+  5740, 5760, 5780, 5800, 5820, 5840, 5860, 5880, // Band F / Airwave
+  5658, 5695, 5732, 5769, 5806, 5843, 5880, 5917  // Band R / Immersion Raceband
 };

 // do coding as simple hex value to save memory.
@@ -149,12 +151,13 @@
   0xA1, 0xA2, 0xA3, 0xA4, 0xA5, 0xA6, 0xA7, 0xA8,
   0xB1, 0xB2, 0xB3, 0xB4, 0xB5, 0xB6, 0xB7, 0xB8,
   0xE1, 0xE2, 0xE3, 0xE4, 0xE5, 0xE6, 0xE7, 0xE8,
-  0xF1, 0xF2, 0xF3, 0xF4, 0xF5, 0xF6, 0xF7, 0xF8
+  0xF1, 0xF2, 0xF3, 0xF4, 0xF5, 0xF6, 0xF7, 0xF8,
+  0xC1, 0xC2, 0xC3, 0xC4, 0xC5, 0xC6, 0xC7, 0xC8
 };

 // All Channels of the above List ordered by Mhz
 const uint8_t channelList[] PROGMEM = {
-  19, 18, 17, 16, 7, 8, 24, 6, 9, 25, 5, 10, 26, 4, 11, 27, 3, 12, 28, 2, 13, 29, 1, 14, 30, 0, 15, 31, 20, 21, 22, 23
+  19, 18, 32, 17, 33, 16, 7, 34, 8, 24, 6, 9, 25, 5, 35, 10, 26, 4, 11, 27, 3, 36, 12, 28, 2, 13, 29, 37, 1, 14, 30, 0, 15, 31, 38, 20, 21, 39, 22, 23
 };

 uint8_t channel = 0;
@@ -357,7 +360,7 @@
                     TV.draw_rect(8,3+3*MENU_Y_SIZE,100,12,  WHITE, INVERT);
                     state=STATE_MANUAL;
                 break;
-                case 3: // DIP mode or diversity
+                case 3: // Diversity
                     TV.draw_rect(8,3+4*MENU_Y_SIZE,100,12,  WHITE, INVERT);
                     state=STATE_DIVERSITY;
                 break;
@@ -479,7 +482,6 @@
             break;
             case STATE_MANUAL: // manual mode
             case STATE_SEEK: // seek mode
-            case STATE_SWITCH: // SWITCH mode
                 TV.select_font(font8x8);
                 TV.draw_rect(0,0,TV_X_MAX,TV_Y_MAX,  WHITE); // outer frame
                 if (state == STATE_MANUAL)
@@ -489,10 +491,6 @@
                 else if(state == STATE_SEEK)
                 {
                     TV.printPGM(10, TV_Y_OFFSET,  PSTR("AUTO MODE SEEK"));
-                }
-                else if(state == STATE_SWITCH)
-                {
-                    TV.printPGM(10, TV_Y_OFFSET,  PSTR("  SWITCH MODE "));
                 }
                 TV.draw_line(0,1*TV_Y_GRID,TV_X_MAX,1*TV_Y_GRID,WHITE);
                 TV.printPGM(5,TV_Y_OFFSET+1*TV_Y_GRID,  PSTR("BAND: "));
@@ -537,13 +535,14 @@
                     case STATE_SEEK: // seek mode
                         TV.printPGM(50,5+1*MENU_Y_SIZE,  PSTR("Search"));
                     break;
-                    case STATE_SWITCH: // SWITCH mode
-                        TV.printPGM(50,5+1*MENU_Y_SIZE,  PSTR("Switch"));
-                    break;
                 }
                 TV.printPGM(10, 5+2*MENU_Y_SIZE, PSTR("Band:"));
                 // print band
-                if(channelIndex > 23)
+                if(channelIndex > 31)
+                {
+                    TV.printPGM(50,5+2*MENU_Y_SIZE,  PSTR("C/Race   "));
+                }
+                else if(channelIndex > 23)
                 {
                     TV.printPGM(50,5+2*MENU_Y_SIZE,  PSTR("F/Airwave"));
                 }
@@ -698,7 +697,7 @@
     /*****************************************/
     /*   Processing MANUAL MODE / SEEK MODE  */
     /*****************************************/
-    if(state == STATE_MANUAL || state == STATE_SEEK || state == STATE_SWITCH)
+    if(state == STATE_MANUAL || state == STATE_SEEK)
     {
         if(state == STATE_MANUAL) // MANUAL MODE
         {
@@ -730,7 +729,11 @@
         if(update_frequency_view) // only updated on changes
         {
             // show current used channel of bank
-            if(channelIndex > 23)
+            if(channelIndex > 31)
+            {
+                TV.printPGM(50,TV_Y_OFFSET+1*TV_Y_GRID,  PSTR("C/Race   "));
+            }
+            else if(channelIndex > 23)
             {
                 TV.printPGM(50,TV_Y_OFFSET+1*TV_Y_GRID,  PSTR("F/Airwave"));
             }
@@ -866,9 +869,9 @@
         rssi_scaled=map(rssi, 1, 100, 5, SCANNER_BAR_SIZE);
         hight = (TV_ROWS - TV_SCANNER_OFFSET - rssi_scaled);
         // clear last bar
-        TV.draw_rect((channel * 4), (TV_ROWS - TV_SCANNER_OFFSET - SCANNER_BAR_SIZE), 3, SCANNER_BAR_SIZE , BLACK, BLACK);
+        TV.draw_rect((channel * 3), (TV_ROWS - TV_SCANNER_OFFSET - SCANNER_BAR_SIZE), 2, SCANNER_BAR_SIZE , BLACK, BLACK);
         //  draw new bar
-        TV.draw_rect((channel * 4), hight, 3, rssi_scaled , WHITE, WHITE);
+        TV.draw_rect((channel * 3), hight, 2, rssi_scaled , WHITE, WHITE);
         // print channelname
         if(state == STATE_SCAN)
         {
@@ -879,7 +882,7 @@
                 TV.print(writePos+10, SCANNER_LIST_Y_POS, pgm_read_word_near(channelFreqTable + channelIndex));
                 writePos += 30;
                 // mark bar
-                TV.print((channel * 4) - 3, hight - 5, pgm_read_byte_near(channelNames + channelIndex), HEX);
+                TV.print((channel * 3) - 3, hight - 5, pgm_read_byte_near(channelNames + channelIndex), HEX);
             }
         }
         // next channel


Sends toilet status on sensor change

Sends toilet status on sensor change

--- sensor/sensor.ino
+++ sensor/sensor.ino
@@ -32,6 +32,7 @@

 void handleInterrupt() {
   wdt_disable(); // Disable watchdog timer
+  sendStatus();
 }

 void sendStatus() {


killMsgSend Added

killMsgSend Added

A statement was added to stop any command-style messages being sent from
the arduino.  This is useful because the laptop freezes after receiving
a certain number of characters through serial comms.

--- embedded/Crossfire_Program/Crossfire_Program.ino
+++ embedded/Crossfire_Program/Crossfire_Program.ino
@@ -54,7 +54,9 @@

 // Parameters
 /*******************************************************************************************/
-#define DEBUG 1 //Defining DEBUG turns ON debugging messages
+#define DEBUG 0 //Defining DEBUG turns ON debugging messages
+
+#define killMsgSend 1 //Prevents the arduino from sending the functional messages to the laptop

 #define commsTimeout 200 //The maximum time that a received serial command can take, in mS

@@ -354,6 +356,7 @@
 /*******************************************************************************************/
 //This function sends commands to the laptop.  It has optional inputs.
 void sendMessage (byte CMD,byte in1, byte in2, byte in3) {
+#if killMsgSend==1
   Serial.print("GO");
   if (commandLength[CMD]>0){
     Serial.print(in1);
@@ -365,6 +368,7 @@
     }
   }
   Serial.println(); //Print a new line character
+#endif
 }


added board initialization and communication methods


replace calls to system millis() with overflow trap wrapper; make all temp vars holding times unsigned long

--- ardesp/waterelf32/waterelf32.ino
+++ ardesp/waterelf32/waterelf32.ino
@@ -227,7 +227,7 @@
   bool gotOverflow = false;     // does the growbed have an overflow?
   int fillLevel = 7;            // cms below the level sensor: drain point
   bool filling = false;         // true when closed / on
-  long lastFlip = -1;           // millis at last state change
+  unsigned long lastFlip = -1;  // millis at last state change
   int floodMins = 18;

   Valve() { number = counter++; }
@@ -252,13 +252,13 @@
     // dbg(valveDBG, "pump Pin = "); dbg(valveDBG, pumpMcpPin);
     // dbg(valveDBG, ", solen = "); dln(valveDBG, solenoidMcpPin);

-    lastFlip = millis();
+    lastFlip = millisWrapper();
   }
   void on()  { stateChange(true); }  // fill time
   void off() { stateChange(false); } // drain time
   void step(monitor_t* now, char cycleMins) {   // check conditions and adjust
     dbg(valveDBG, "\nvalve[].step - number = "); dln(valveDBG, number);
-    int t = millis();
+    unsigned long t = millisWrapper();
     dbg(valveDBG, "t = "); dbg(valveDBG, t);
     dbg(valveDBG, "; filling = "); dln(valveDBG, filling);
     if(filling &&
@@ -312,7 +312,7 @@
     staggerMins = cycleMins / numValves;
     dbg(valveDBG, "cycleMins = "); dbg(valveDBG, cycleMins);
     dbg(valveDBG, " staggerMins = "); dln(valveDBG, staggerMins);
-    long t = millis();
+    unsigned long t = millisWrapper();
     dbg(valveDBG, "millis = "); dln(valveDBG, t);
     long nextCycleStart = t;
     for(int i = 0; i < numValves; i++) {
@@ -386,7 +386,7 @@
     monitor_t* now = &monitorData[monitorCursor];
     if(monitorSize < MONITOR_POINTS)
       monitorSize++;
-    now->timestamp = millis();
+    now->timestamp = millisWrapper();
     if(GOT_TEMP_SENSOR) {
       getTemperature(&now->waterCelsius);               yield();
     }


Update todo

Update todo

--- LoaderTest/LoaderTest.ino
+++ LoaderTest/LoaderTest.ino
@@ -18,11 +18,14 @@
 // For example:
 //   python sendGt1.py life3.gt1

-// XXX Better check if Gigatron is running OK (judge signals better)
 // XXX Try higher than 9600 transfer rates again
 // XXX Wild idea: let the ROM communicate back by modulating vPulse
 // XXX Hardware: Put reset line on the DB9 jack
 // XXX Hardware: Put an output line on the DB9 jack
+// XXX Keyboard: Map Ctrl-Alt-Del to Gigatron reset (instead of PageUp)
+// XXX Keyboard: Map Enter to both newline AND buttonA
+// XXX Keyboard: Delete = buttonA (same code 0x7f). Change delete code?
+// XXX Keyboard: Is it possible to mimic key hold-down properly???
 // XXX Embed a Gigatron Terminal program. Or better: GigaMon

 const byte gt1File[] PROGMEM = {


arduino baru

arduino baru

--- arduino/sensor_suhu/sensor_suhu.ino
+++ arduino/sensor_suhu/sensor_suhu.ino
@@ -35,10 +35,10 @@
  int reading = analogRead(sensorPin);
 EthernetClient client = server.available();

-  float voltage = reading * 5.0;
+  int voltage = reading * 5.0;
  voltage /= 1024.0;
  // now print out the temperature
- float temperatureC = ((voltage - 0.5) * 10) + 7 ;  //converting from 10 mv per degree wit 500 mV offset
+ int temperatureC = ((voltage - 0.5) * 10) + 7 ;  //converting from 10 mv per degree wit 500 mV offset
                                                //to degrees ((voltage - 500mV) times 100)
  Serial.print(temperatureC); Serial.println(" degrees C");


bug fix(es)

bug fix(es)

--- snake.ino
+++ snake.ino
@@ -74,14 +74,16 @@
   myScreen.rect(3,2,screenWidth-6,screenHeight-4);

   /* The snake and food data before the game starts */
-  for (int i = 11; i<=41; i+=6){
-    addFirst(i,4);
+  for (int i = 29; i<=53; i+=6){
+    addFirst(i,52);
     drawSegment(head->x, head->y);
   }
+
   /* TODO: "random placement, not on forbidden tiles"-function */
   foodTile.x = 5;
   foodTile.y = 4;
   drawFood(foodTile.x, foodTile.y);
+  delay(1000);
 }

 /* Input the incremental move using the pushbuttons */
@@ -204,8 +206,7 @@

 void loop(){

-  startScreen(); /* TODO: pause until button is pressed */
-
+  startScreen();
   /* Main brain game frame */
   while(!collision){

@@ -215,14 +216,14 @@

     if (millis()-timestamp > 300){
       /* Update, draw, and check things */
-      temp = head;
-      temp->x += moveTo.x;
-      temp->y += moveTo.y;
-      addFirst(temp->x,temp->y);
+      coord movetemp;
+      movetemp.x = head->x + moveTo.x;
+      movetemp.y = head->y + moveTo.y;
+
+      addFirst(movetemp.x,movetemp.y);

       /* Draw */
       drawSegment(head->x, head->y);
-
       if (growBy){
         growBy--;
         score += 1;


Update Master-board.ino

Update Master-board.ino

--- Firmware/Ball/Master-Board/Master-board.ino
+++ Firmware/Ball/Master-Board/Master-board.ino
@@ -1 +1,185 @@
-kikoo
+String version = "0.1.1";
+/*
+
+ >      FIRMWARE ONLY FOR AN ARDUINO NANO !!    <
+ > IF YOU USE ANOTHER ARDUINO, ADAPT THE PINOUT <
+
+ ###################################################
+  ______  ______     _     _ ______  _____ _______
+ (____  \(____  \   | |   | |  ___ \(_____|_______)
+  ____)  )____)  )__| |   | | |   | | | | | |
+ |  __  (|  __  (___) |   | | |   | | | | | |
+ | |__)  ) |__)  )  | |___| | |   | |_| |_| |_____
+ |______/|______/    \______|_|   |_(_____)\______)
+    A open source project for create you own BB-8!
+ ###################################################
+
+ https://github.com/Gruniek/BB-UNIT
+ Made by Daniel M/Gruniek/MOUS
+
+ Compatible only with an Arduino Nano and the specific PCB.
+ PCB Link : https://github.com/Gruniek/BB-UNIT/
+
+ --------------
+ - Change log -
+ --------------
+
+ 11/2016
+ =========
+ - Start of the code
+
+ To do list
+ ==========
+ - All
+
+
+  Big thanks for http://r2builders.fr/ !
+  Initial project : http://r2builders.fr/forum/viewtopic.php?f=26&t=3928&hilit=BB8+par+MOUS
+
+  ===============
+  EXEMPLE COMMAND
+  ===============
+
+*/
+
+#include "Wire.h"
+#include "MPU6050.h"
+
+#include <SPI.h>
+#include <nRF24L01.h>
+#include <RF24.h>
+#include <RF24_config.h>
+
+int i2cAdress      = 1;
+
+int pinDirA        = 2;      // PIN DIRECTION FOR X
+int pinStepA       = 3;      // PIN STEP FOR X
+int pinEnable      = 4;      // Activation off all stepper
+
+int pinDirB        = 5;      // PIN DIRECTION FOR Y
+int pinStepB       = 6;      // PIN STEP FOR Y
+
+
+
+int PING           = 13;
+int PING_MASTER    = 12;
+
+// MPU6050
+MPU6050 accelgyro;
+
+int16_t ax, ay, az;
+int16_t gx, gy, gz;
+
+
+// RF24
+int msg[1];
+RF24 radio(9,10);
+const uint64_t pipe = 0xE8E8F0F0E1LL;
+int lastmsg = 1;
+String theMessage = "";
+
+void setup()
+{
+    pinMode( pinEnable   , OUTPUT );
+    pinMode( pinDirA     , OUTPUT );
+    pinMode( pinStepA    , OUTPUT );
+    pinMode( pinDirB     , OUTPUT );
+    pinMode( pinStepB    , OUTPUT );
+    pinMode( PING        , OUTPUT );
+    pinMode( PING_MASTER , INPUT  );
+
+	Serial.begin(9600);
+	Serial.println("Booting up...");
+    Serial.println(" ");
+    Serial.println("_ Astromech Industrie _");
+    Serial.print("  BB-8 Version ");
+    Serial.println(version);
+    Serial.println("===================");
+    Serial.println(" ");
+
+
+
+
+    Serial.print("Initializing I2C devices...  I2C ADRESS :");
+    Serial.print(i2cAdress);
+
+    Wire.begin(i2cAdress);
+
+    accelgyro.initialize();
+	Serial.println(" [ OK ]");
+
+    Serial.print("Connect to the MPU6050 : ");
+    Serial.println(accelgyro.testConnection());
+    //Serial.println(accelgyro.testConnection() ? "Connection successful" : "Connection failed");
+
+    Serial.println("Initializing RF24 devices...  ");
+    radio.begin();
+    radio.openWritingPipe(pipe);
+    radio.startListening();
+
+    Serial.println("Booting successful !");
+    Serial.println("====================");
+
+}
+
+void loop()
+{
+	/* SEND
+	String theMessage = "Hello there!";
+	int messageSize = theMessage.length();
+	for (int i = 0; i < messageSize; i++)
+	{
+    	int charToSend[1];
+    	charToSend[0] = theMessage.charAt(i);
+    	radio.write(charToSend,1);
+  	}
+
+	msg[0] = 2;
+    radio.write(msg,1);
+    */
+
+    if (radio.available())
+    {
+    	bool done = false;
+    	done = radio.read(msg, 1);
+    	char theChar = msg[0];
+      	if (msg[0] != 2)
+      	{
+        	theMessage.concat(theChar);
+        }
+      	else
+      	{
+       		Serial.println(theMessage);
+
+			int str_len = theMessage.length() + 1;
+
+			char msg[str_len];
+
+			// Copy it over
+			theMessage.toCharArray(msg, str_len);
+
+    		if (strcmp(strtok(msg, " "), "SET") == 0)
+    		{
+        		Serial.println("UPDATE SETPOINT");
+      			// trouvé le message
+      			char *p;
+      			while ((p = strtok(NULL, " ")) != NULL)
+      			{
+        			int val = atoi(p + 1);
+        			switch (*p)
+        			{
+          			//	case 'x': setpointX  = val; break;
+          			//	case 'y': setpointY  = val; break;
+      	  			//	case 'm': multiplier = val; break;
+      				//	case 'i': invertXY   = val; break;
+      				//	case 'j': invertX    = val; break;
+      				//	case 'k': invertX    = val; break;
+      				//	case 'h': hysteresis = val; break;
+        			}
+      			}
+    		}
+       		theMessage= "";
+      	}
+   }
+
+}


menu: cr/lf fix for ASCII, Hayes: at command always ASCII response output, default phone book entries, non-ascii character fix.

--- MicroView/WiFiModem-Menu/WiFiModem-Menu.ino
+++ MicroView/WiFiModem-Menu/WiFiModem-Menu.ino
@@ -18,7 +18,7 @@

 // Defining HAYES enables Hayes commands and disables the 1) and 2) menu options for telnet and incoming connections.
 // This is required to ensure the compiled code is <= 30,720 bytes
-//#define HAYES
+#define HAYES
 #include <MicroView.h>
 #include <elapsedMillis.h>
 #include <SoftwareSerial.h>
@@ -267,13 +267,13 @@

     //C64Println();
 #ifdef HAYES
-    C64Println(F("\nCommodore Wi-Fi Modem Hayes Emulation"));
+    C64Println(F("\r\nCommodore Wi-Fi Modem Hayes Emulation"));
     ShowPETSCIIMode();
     C64Println();
     ShowInfo(true);
     HayesEmulationMode();
 #else
-    C64Println(F("\nCommodore Wi-Fi Modem"));
+    C64Println(F("\r\nCommodore Wi-Fi Modem"));
     C64Println();
     ShowInfo(true);

@@ -282,11 +282,11 @@
     Display(F("READY."));

     ShowPETSCIIMode();
-    C64Print(F("1. Telnet to host or BBS\n"
-                 "2. Phone Book\n"
-                 "3. Wait for incoming connection\n"
-                 "4. Configuration\n"
-                 "\n"
+    C64Print(F("1. Telnet to host or BBS\r\n"
+                 "2. Phone Book\r\n"
+                 "3. Wait for incoming connection\r\n"
+                 "4. Configuration\r\n"
+                 "\r\n"
                  "Select: "));

     /*C64Println(F("1. Telnet to host or BBS"));
@@ -346,11 +346,11 @@
     while (true)
     {
         char temp[30];
-        C64Print(F("\n"
-                     "Configuration Menu\n"
-                     "\n"
-                     "1. Display Current Configuration\n"
-                     "2. Change SSID\n"));
+        C64Print(F("\r\n"
+                     "Configuration Menu\r\n"
+                     "\r\n"
+                     "1. Display Current Configuration\r\n"
+                     "2. Change SSID\r\n"));
 //        C64Println();
 //        C64Println(F("Configuration Menu"));
 //        C64Println();
@@ -360,9 +360,9 @@
         C64Println(temp);
         sprintf_P(temp,PSTR("4. %s DCD always on"),Modem_DCDFollowsRemoteCarrier == false ? "Disable" : "Enable");
         C64Println(temp);
-        C64Print(F("5. Direct Terminal Mode (Debug)\n"
-                     "6. Return to Main Menu\n"
-                     "\nSelect: "));
+        C64Print(F("5. Direct Terminal Mode (Debug)\r\n"
+                     "6. Return to Main Menu\r\n"
+                     "\r\nSelect: "));
 //        C64Println(F("5. Direct Terminal Mode (Debug)"));
 //        C64Println(F("6. Return to Main Menu"));
 //        C64Println();
@@ -430,13 +430,13 @@

     while (true)
     {
-        C64Println(F("\n"
-                     "Change SSID\n"
-                     "\n"
-                     "1. WEP\n"
-                     "2. WPA / WPA2\n"
-                     "3. Return to Configuration Menu\n"
-                     "\n"
+        C64Println(F("\r\n"
+                     "Change SSID\r\n"
+                     "\r\n"
+                     "1. WEP\r\n"
+                     "2. WPA / WPA2\r\n"
+                     "3. Return to Configuration Menu\r\n"
+                     "\r\n"
                      "Select: "));

 /*        C64Println();
@@ -508,13 +508,13 @@
             if (wifly.join(20000))    // 20 second timeout
             {
                 //C64Println();
-                C64Println(F("\nSSID Successfully changed"));
+                C64Println(F("\r\nSSID Successfully changed"));
                 return;
             }
             else
             {
                 //C64Println();
-                C64Println(F("\nError joining network"));
+                C64Println(F("\r\nError joining network"));
                 continue;
             }
     }
@@ -528,14 +528,14 @@

         C64Println();
         DisplayPhoneBook();
-        C64Print(F("\nSelect: #, m to modify, a to set\nauto-start, 0 to go back: "));
+        C64Print(F("\r\nSelect: #, m to modify, a to set\r\n""auto-start, 0 to go back: "));

         char addressChar = ReadByte(C64Serial);
         C64Serial.println((char)addressChar);

         if (addressChar == 'm' || addressChar == 'M')
         {
-            C64Print(F("\nEntry # to modify? (0 to abort): "));
+            C64Print(F("\r\nEntry # to modify? (0 to abort): "));

             char addressChar = ReadByte(C64Serial);

@@ -550,7 +550,7 @@
                     break;

                     default:
-                    C64Print(F("\nEnter address: "));
+                    C64Print(F("\r\nEnter address: "));
                     String hostName = GetInput();
                     if (hostName.length() > 0)
                     {
@@ -564,7 +564,7 @@
         }
         else if (addressChar == 'a' || addressChar == 'A')
         {
-            C64Print(F("\nEntry # to set to auto-start?\n(0 to disable): "));
+            C64Print(F("\r\nEntry # to set to auto-start?\r\n""(0 to disable): "));

             char addressChar = ReadByte(C64Serial);

@@ -803,12 +803,12 @@
     char mac[20];
     char ip[20];
     char ssid[20];
-    WiFlyLocalPort = wifly.getPort();   // Port WiFly listens on.  0 = disabled.

     wifly.getMAC(mac, 20);    // Sometimes the first time contains garbage..
     wifly.getMAC(mac, 20);
     wifly.getIP(ip, 20);
     wifly.getSSID(ssid, 20);
+    WiFlyLocalPort = wifly.getPort();   // Port WiFly listens on.  0 = disabled.

     //C64Println();
     C64Print(F("MAC Address: "));    C64Println(mac);
@@ -855,7 +855,7 @@
     int localport = WiFlyLocalPort;

     //C64Println();
-    C64Print(F("\nIncoming port ("));
+    C64Print(F("\r\nIncoming port ("));
     C64Serial.print(localport);
     C64Print(F("): "));

@@ -870,7 +870,7 @@

     WiFlyLocalPort = localport;

-    C64Print(F("\nWaiting for connection on port "));
+    C64Print(F("\r\nWaiting for connection on port "));
     C64Serial.println(WiFlyLocalPort);

     /* Force close any connections that were made before we started listening, as
@@ -891,7 +891,7 @@
 {
     int port = lastPort;

-    C64Print(F("\nTelnet host ("));
+    C64Print(F("\r\nTelnet host ("));
     C64Print(lastHost);
     C64Print(F("): "));
     String hostName = GetInput();
@@ -923,7 +923,7 @@

 int getPort(void)
 {
-    C64Print(F("\nPort ("));
+    C64Print(F("\r\nPort ("));
     C64Serial.print(lastPort);
     C64Print(F("): "));

@@ -945,7 +945,7 @@
 void Connect(String host, int port, boolean raw)
 {
     char temp[50];
-    sprintf_P(temp, PSTR("\nConnecting to %s"), host.c_str());
+    sprintf_P(temp, PSTR("\r\nConnecting to %s"), host.c_str());
 #ifdef HAYES
     DisplayP(temp);
 #else
@@ -1293,10 +1293,10 @@

         strncpy(address,readEEPROMPhoneBook(ADDR_HOSTS + ((autoConnectHost-1) * ADDR_HOST_SIZE)).c_str(),ADDR_HOST_SIZE);

-        C64Print(F("Auto-connecting to:\n"));
+        C64Print(F("Auto-connecting to:\r\n"));
         C64Println(address);

-        C64Println(F("\nPress any key to cancel..."));
+        C64Println(F("\r\nPress any key to cancel..."));
         // Wait for user to cancel

         int option = PeekByte(C64Serial, 2000);
@@ -1357,10 +1357,10 @@

         strncpy(address,readEEPROMPhoneBook(ADDR_HOSTS + ((autoConnectHost-1) * ADDR_HOST_SIZE)).c_str(),ADDR_HOST_SIZE);

-        C64Print(F("Auto-connecting to:\n"));
+        C64Print(F("Auto-connecting to:\r\n"));
         C64Println(address);

-        C64Println(F("\nPress any key to cancel..."));
+        C64Println(F("\r\nPress any key to cancel..."));
         // Wait for user to cancel

         int option = PeekByte(C64Serial, 2000);
@@ -1368,13 +1368,21 @@
         if (option != TIMEDOUT)   // Key pressed
         {
             ReadByte(C64Serial);    // eat character
-            DisplayBoth(F("OK"));
+            //DisplayBoth(F("OK"));
+            Display(F("OK"));
+            C64Serial.print(F("OK"));
+            C64Serial.println();
         }
         else
             Modem_Dialout(address);
     }
     else
-        DisplayBoth(F("OK"));
+    {
+        //DisplayBoth(F("OK"));
+        Display(F("OK"));
+        C64Serial.print(F("OK"));
+        C64Serial.println();
+    }

     while (true)
     {
@@ -1393,6 +1401,7 @@
     Modem_PrintResponse("4", F("ERROR"));
 }

+/* Modem response codes should be in ASCII.  Do not translate to PETSCII. */
 void Modem_PrintResponse(const char* code, const __FlashStringHelper * msg)
 {
     //C64Println();  // Moved to top of Modem_ProcessCommandBuffer() so that
@@ -1401,9 +1410,17 @@
     if (!Modem_QuietMode)
     {
         if (Modem_VerboseResponses)
-            C64Println(msg);
+        {
+            //C64Println(msg);
+            C64Serial.print(msg);
+            C64Serial.println();
+        }
         else
-            C64Println(code);
+        {
+            //C64Println(code);
+            C64Serial.print(code);
+            C64Serial.println();
+        }
     }

     // Always show verbose version on OLED, underneath command
@@ -1441,8 +1458,6 @@
     Modem_isConnected = false;
     Modem_isRinging = false;

-    delay(500);
-    Modem_PrintResponse("3", F("NO CARRIER"));
     //sprintf_P(temp, PSTR("\r\nNO CARRIER\r\n"));
     //DisplayBothP(temp);
     //DisplayP(temp);
@@ -1456,6 +1471,9 @@
         wifly.closeForce();      // Incoming connections need to be force closed.  close()
                                  // does not work because WiFlyHQ.cpp connected variable is
                                  // not set for incoming connections.
+
+    //delay(500);
+    Modem_PrintResponse("3", F("NO CARRIER"));

     if (Modem_DCDFollowsRemoteCarrier)
         digitalWriteFast(C64_DCD, Modem_ToggleCarrier(false));
@@ -1658,10 +1676,16 @@
     }
     else if (strstr(Modem_CommandBuffer, ("AT&PBCLEAR")) != NULL)
     {
-        for (int i = 0; i < ADDR_HOST_ENTRIES; i++)
+#define STATIC_PB_ENTRIES  2
+        for (int i = 0; i < ADDR_HOST_ENTRIES - STATIC_PB_ENTRIES; i++)
         {
             updateEEPROMPhoneBook(ADDR_HOSTS + (i * ADDR_HOST_SIZE), "\0");
         }
+
+        // To add static entries, update STATIC_PB_ENTRIES and add entries below increased x: ADDR_HOST_ENTRIES - x
+        updateEEPROMPhoneBook(ADDR_HOSTS + (ADDR_HOST_ENTRIES - 1 * ADDR_HOST_SIZE), F("WWW.COMMODORESERVER.COM:1541"));   // last entry
+        updateEEPROMPhoneBook(ADDR_HOSTS + (ADDR_HOST_ENTRIES - 2 * ADDR_HOST_SIZE), F("WWW.JAMMINGSIGNAL.COM:23"));       // second last entry
+
         updateEEPROMByte(ADDR_HOST_AUTO, 0);
         Modem_PrintOK();
     }
@@ -2132,8 +2156,6 @@
         if (Modem_isCommandMode)
         {
             unsigned char unsignedInbound;
-            boolean isValid = true;
-            char temp[5];

             if (Modem_flowControl)
                 digitalWriteFast(C64_CTS, LOW);
@@ -2142,21 +2164,21 @@

             // Block non-ASCII/PETSCII characters
             unsignedInbound = (unsigned char)inbound;
+
+            // Do not delete this.  Used for troubleshooting...
+            /*char temp[5];
+            sprintf(temp, "-%d-",unsignedInbound);
+            C64Serial.write(temp);*/
+
             if (unsignedInbound == 0x08 || unsignedInbound == 0x0a || unsignedInbound == 0x0d || unsignedInbound == 0x14) {}  // backspace, LF, CR, C= Delete
             else if (unsignedInbound <= 0x1f)
-                isValid = false;
+                break;
             else if (unsignedInbound >= 0x80 && unsignedInbound <= 0xc0)
-                isValid = false;
+                break;
             else if (unsignedInbound >= 0xdb)
-                isValid = false;
-
-            // Do not delete this.  Used for troubleshooting...
-            /*if (!isValid) {
-                sprintf(temp, "-%d-",unsignedInbound);
-                C64Serial.write(temp);
-            }*/
-
-            if (Modem_EchoOn && isValid)
+                break;
+
+            if (Modem_EchoOn)
             {
                 if (!Modem_flowControl)
                   delay(100 / (BAUD_RATE / 2400));     // Slow down command mode to prevent garbage if flow control
@@ -2172,7 +2194,7 @@
                     Modem_CommandBuffer[strlen(Modem_CommandBuffer) - 1] = '\0';
                 }
             }
-            else if (inbound != '\r' && inbound != '\n' && inbound != Modem_S2_EscapeCharacter && isValid)
+            else if (inbound != '\r' && inbound != '\n' && inbound != Modem_S2_EscapeCharacter)
             {
                 if (strlen(Modem_CommandBuffer) >= COMMAND_BUFFER_SIZE) {
                   //Display (F("CMD Buf Overflow"));
@@ -2590,7 +2612,7 @@
         //delay(5000);

         if (WiFly_BAUD_RATE != 2400) {
-            C64Println(F("Reboot Microview & WiFi to set new port."));
+            C64Println(F("Reboot MicroView & WiFi to set new port."));
             return true;
         }
         else {


Hacked virtualwire to use timer2

Hacked virtualwire to use timer2

--- tracker/tracker.ino
+++ tracker/tracker.ino
@@ -14,14 +14,60 @@
 ----------------------------------------------------
 */

+
+/*
+Hacked virtualwire to use 8 bit timer2
+from line 510...
+
+#else // ARDUINO - hacked to timer2 http://forum.arduino.cc/index.php/topic,100371.0.html
+    // figure out prescaler value and counter match value
+    prescaler = vw_timer_calc(speed, (uint8_t)-1, &nticks);
+    if (!prescaler)
+    {
+        return; // fault
+    }
+
+    TCCR2A = 0;
+    TCCR2A = _BV(WGM21); // Turn on CTC mode / Output Compare pins disconnected
+
+    // convert prescaler index to TCCRnB prescaler bits CS00, CS01, CS02
+    TCCR2B = 0;
+    TCCR2B = prescaler; // set CS00, CS01, CS02 (other bits not needed)
+
+    // Number of ticks to count before firing interrupt
+    OCR2A = uint8_t(nticks);
+
+    // Set mask to fire interrupt when OCF0A bit is set in TIFR0
+    TIMSK2 |= _BV(OCIE2A);
+    // Enable interrupt
+#ifdef TIMSK1
+    // atmega168
+    //TIMSK1 |= _BV(OCIE1A);
+#else
+    // others
+    //TIMSK |= _BV(OCIE1A);
+#endif // TIMSK1
+
+
+
+from line 777...
+
+	#else // Assume Arduino Uno (328p or similar) hack to timer2
+		#define VW_TIMER_VECTOR TIMER2_COMPA_vect
+
+
+*/
+
+#define VW_TIMER_VECTOR TIMER2_COMPA_vect
+
 #include <util/delay.h>
 #include <avr/wdt.h>
-#include <Wire.h>
+#include <VirtualWire.h> // hacked version for timer2!!
 #include <Servo.h>

 #define LED_DEBUG 13
-#define PIN_TX 7
+#define PIN_TX 12

 #define PIN_LDR_LEFT  2 // PC2
 #define PIN_LDR_RIGHT 3 // PC3
@@ -29,12 +75,11 @@
 #define MOVE_INTERVAL_MILLIS 60

 #define SERVO_INCREMENT 5 // How much to move each loop
-#define SERVO_PIN_HORZ 8 // PB1
+#define SERVO_PIN_HORZ 9 // PB1
 #define SERVO_HORZ_MAX 2800
 #define SERVO_HORZ_MIN 700
-
-
-#define I2C_SLAVE_ADDR 100
+#define SERVO_PIN_HORZ_POWER 8 // PB0
+

 // When the last move was attempted.
 unsigned long move_last = 0;
@@ -55,19 +100,6 @@
 // Store the current servo positions.
 int servo_horz_pos = 1700;

-// Extend the print class for use with i2c as a serial print.
-class tI2Cserial : public Print
-{
-  public:
-    virtual size_t write (const byte c)  {
-      Wire.beginTransmission(I2C_SLAVE_ADDR);
-      Wire.write(c);
-      Wire.endTransmission();
-    }
-};
-
-// an instance of the I2Cserial object
-tI2Cserial I2Cserial;

 void setup()
 {
@@ -77,13 +109,20 @@

     pinMode(LED_DEBUG, OUTPUT);
     pinMode(PIN_TX, OUTPUT);
+
+    pinMode(SERVO_PIN_HORZ_POWER, OUTPUT);
+    digitalWrite(SERVO_PIN_HORZ_POWER, LOW); // low = 0n (PNP)
+
+
+    //vw_set_ptt_inverted(true); // Required for DR3100
+    vw_setup(2000);      // Bits per sec
+    vw_set_tx_pin(PIN_TX);

     servo_horz.attach(SERVO_PIN_HORZ, SERVO_HORZ_MIN, SERVO_HORZ_MAX);

     servo_horz.writeMicroseconds(servo_horz_pos);

-    // Join the i2c bus as master
-    Wire.begin();
+

 }

@@ -111,12 +150,12 @@
         }
         digitalWrite(LED_DEBUG, ledState);

-        // Send an i2C message.
-        I2Cserial.print(msgId);
-        I2Cserial.print(",");
-        I2Cserial.print(servo_horz_pos);
-        I2Cserial.println();
-
+        // Send a transmission
+        char msg[16];
+        sprintf(msg, "%d,wd=%d,mv=%u", msgId, ledState, readVcc());
+        vw_send((uint8_t *)msg, strlen(msg));
+        vw_wait_tx(); // Wait until the whole message is gone
+        ++msgId;
     }
 }

@@ -152,11 +191,11 @@
     int left = analogRead(PIN_LDR_LEFT);
     int right = analogRead(PIN_LDR_RIGHT);

-    /*
+
     Serial.print(left);
     Serial.print(':');
-    Serial.print(right);
-    */
+    Serial.println(right);
+

     int diff = left - right;
     if (abs(diff) > THRESHOLD_LDR_HORZ) {
@@ -178,5 +217,33 @@
   wdt_enable(WDTO_8S);
 }

-
-
+/**
+ * Read the internal voltage.
+ */
+long readVcc()
+{
+  // Read 1.1V reference against AVcc
+  // set the reference to Vcc and the measurement to the internal 1.1V reference
+  #if defined(__AVR_ATmega32U4__) || defined(__AVR_ATmega1280__) || defined(__AVR_ATmega2560__)
+    ADMUX = _BV(REFS0) | _BV(MUX4) | _BV(MUX3) | _BV(MUX2) | _BV(MUX1);
+  #elif defined (__AVR_ATtiny24__) || defined(__AVR_ATtiny44__) || defined(__AVR_ATtiny84__)
+    ADMUX = _BV(MUX5) | _BV(MUX0);
+  #elif defined (__AVR_ATtiny25__) || defined(__AVR_ATtiny45__) || defined(__AVR_ATtiny85__)
+    ADMUX = _BV(MUX3) | _BV(MUX2);
+  #else
+    ADMUX = _BV(REFS0) | _BV(MUX3) | _BV(MUX2) | _BV(MUX1);
+  #endif
+
+  _delay_ms(2); // Wait for Vref to settle
+  ADCSRA |= _BV(ADSC); // Start conversion
+  while (bit_is_set(ADCSRA,ADSC)); // measuring
+
+  uint8_t low  = ADCL; // must read ADCL first - it then locks ADCH
+  uint8_t high = ADCH; // unlocks both
+
+  long result = (high<<8) | low;
+
+  result = 1125300L / result; // Calculate Vcc (in mV); 1125300 = 1.1*1023*1000
+  return result; // Vcc in millivolts
+}
+


Fixed that FFat was formatted twice.

Fixed that FFat was formatted twice.

--- aquacontrol32.ino
+++ aquacontrol32.ino
@@ -362,7 +362,6 @@
       OLED.display();
     }
     ESP_LOGI( TAG, "%s", formatStr );
-    FFat.format( true, (char*)"ffat" );
     if (!FFat.format( true, (char*)"ffat" ) || !FFat.begin()) {
       ESP_LOGI( TAG, "FFat error while formatting. Halting." );
       const char * errorffatStr = "FFat error.";