Improve format of documentation to allow code folding; add anonymous namespace for global variables and function prototypes; improve documentation on static keyword

--- Dremelfuge.ino
+++ Dremelfuge.ino
@@ -5,95 +5,157 @@
 Compiled and Edited by: Albert Ju, Fu Yang Chin
 */

-#include <LiquidCrystal.h>               // include the library code for display
-                                         // because it's a file inside of the Arduino.app 's library folder, use <> DIRECTIVE
-#include "LEDButton.h"                   // include custom library local to the .ino--within the same sketch folder
-                                         // because it's a relative path in the same directory, use "" LITERAL PATHNAME
-
-//---GLOBAL VARIABLES--//
-//:: ***these variables MUST be global because they're being used by multiple totally separate functions--static local won't do
-LiquidCrystal lcd = LiquidCrystal(12, 11, 5, 4, 3, 6);   // initialize the library with the numbers of the interface pins
-
-// White Pushbutton
-const uint8_t WPB_IN_PIN = 2, WPB_LED_PIN = 13;
-const unsigned int WPB_DEBOUNCE_DELAY = 500;
-LEDButton wpb = LEDButton(WPB_IN_PIN, WPB_LED_PIN, WPB_DEBOUNCE_DELAY);
-
-// PWM (Pulse-Width Modulation) Motor Control and Potentiometer
-const uint8_t MOTOR_PIN = 9;
-const uint8_t POT_PIN = A5;
-
-
-//:: ***No magic numbers! Using case statements, enum will provide readable, self-documenting code for when switching modes
-enum class Mode
-{
-  SETTING_TIME,
-  SETTING_SPEED,
-  SPINNING
-};
-Mode mode = Mode::SETTING_TIME;                       //*** initialization over assignment; set SETTING_TIME to be the first mode!
-
-//---Function prototypes---//
-inline void lcdPrintFormattedSecs(unsigned long seconds);
-
+#include <LiquidCrystal.h>                              // include the library for the display;
+                                                        // because it's inside of Arduino.app use <> DIRECTIVE
+#include "LEDButton.h"                                  // include custom library which is in the same directory as this file
+                                                        // because it's a relative path, use "" LITERAL PATHNAME
+
+//============================GLOBAL VARIABLES=================================//
+/* *** These variables MUST be global because they're being used by multiple
+  totally separate functions--static local won't do
+  i.e., this data NEEDS to be available to ALL of the program at ALL times
+  */
+/* *** The following anonymous namespace ensures internal linkage of all global
+  variables and functions, as if all were declared `static` (see large comment
+  in loop() for details on `static`)
+  */
+
+namespace
+{
+    LiquidCrystal lcd
+    = LiquidCrystal(12, 11, 5, 4, 3, 6);                  // initialize LC object with the numbers of the interface pins
+
+    // White Pushbutton
+    const uint8_t WPB_IN_PIN = 2, WPB_LED_PIN = 13;
+    const unsigned int WPB_DEBOUNCE_DELAY = 500;
+    LEDButton wpb
+    = LEDButton(WPB_IN_PIN, WPB_LED_PIN, WPB_DEBOUNCE_DELAY);
+
+    const uint8_t MOTOR_PIN = 9;
+    const uint8_t POT_PIN = A5;
+
+
+    //Function prototypes
+    /* It's good practice to define the prototypes yourself, rather than letting
+      the compiler auto-generate them for you
+      */
+    inline void lcdPrintFormattedSecs(unsigned long seconds);
+} // namespace
+
+/////////////////////////////////////////////////////////////////////////////////
 void setup()
 {
   const uint8_t LCD_COLUMNS = 20, LCD_ROWS = 4;

   wpb.begin();
-  wpb.turnLEDOn();                //
+  wpb.turnLEDOn();

   pinMode(MOTOR_PIN, OUTPUT);
   pinMode(POT_PIN, INPUT);

   lcd.begin(LCD_COLUMNS, LCD_ROWS);
   lcd.setCursor(0, 0);
-  lcd.print(F("  Dremel Centrifuge"));                //*** Serial or derived functions will store their String arguments in RAM, which is wasteful; F() stores them in flash memory, where the sketch is stored (largest storage)
+  lcd.print(F("  Dremel Centrifuge"));                  //*** Serial or derived functions will store their String arguments in RAM, which is wasteful; F() stores them in flash memory, where the sketch is stored (largest storage)
   lcd.setCursor(0, 2);
   lcd.print(F("Set speed:"));
   lcd.setCursor(0, 3);
   lcd.print(F("   Push to Start!"));

   Serial.begin(9600);
-}
-
+} // void setup()
+
+/////////////////////////////////////////////////////////////////////////////////
 void loop()
 {
-  /* Explanation of static keyword in C++:
-   3 types of things can be static: (local) function variables, & class
-   member data (variables and functions--functions = pointer to address of
-   instructions). But `static` gets implemented the same way in each. There
-   exists special memory segments called DATA and BSS (which is just DATA but
-   for uninitialized data). At compile, global and `static` data are each *given
-   their own addresses within DATA or BSS, addresses where they will live (be
-   stored at) forever.* *When the program first runs, BEFORE main(), global and
-   `static` data are initialized to whatever value you set in source code*--you
-   can see this in the Assembly code. If you only declared global or `static`
-   data, then they will be initialized to 0 and placed in BSS. `static` data is
-   not deallocated when out of scope--*its address is permanent, and though the
-   values that live there may change, those values will never be erased (as long
-   as the program is running).* Of course, that `static` data can only be
-   accessed when it's within scope, making it much safer than similar global data.
-  */
-
-                                                      //*** perform operations with data of the same type, so as to boost performance by not needing to implicitly typecast
-  static unsigned long setDuration;                   // the duration that the centrifuge should run
-  static unsigned long spinningStartTime;             // point on the timeline where the countdown starts, i.e. when wpb is pressed the second time
+  /* Explanation of `static` and statically allocated memory in C++:
+
+    3 types of things can be keyword `static`: (local) function variables & class
+    member data (variables and functions--functions = pointer to address of
+    instructions). But `static` gets implemented the same way in each. Global
+    variables are similar to keyword `static` data in that both are "statically
+    allocated." This means two things: 1. globals and `static`s are *initialized
+    at the start of the program, before main*, and 2. global and `static` data
+    are *given permanent memory addresses in RAM outside of the stack and heap,*
+    so that a) even if a local `static` variable goes out of scope, its memory
+    will not be erased because it is located separately from its collapsed
+    stack frame; b) `static` class member data is shared by all (objects),
+    but owned by none. All objects of that class point to the same data at the
+    same address in DATA/BSS (see below). If a static member is `public`, then it
+    actually becomes truly global in scope and can be accessed anywhere, with the
+    caveat that it needs to be referenced with Class::.
+    As long as the program is running (main() hasn't returned), a value will
+    always exist in these permanent memory addresses.
+
+    Of course, local `static` data can only be accessed when it's within scope,
+    just like regular local data. This is much safer for programmers to use
+    than global data.
+    Additionally, global `static` data is marked to have "internal linkage"--
+    the data will be internal to its "compilation"/"translation" unit (internal
+    to the file it belongs to) and can only be accessed by within that one file.
+    Global data, in contrast, has "external linkage," meaning that it can be
+    accessed by all files linked to the current program. This is both unsafe and
+    has great potential for name collision.
+
+    ~~Static variables will always persist.~~
+    ~~"Old values see the rise and fall of generations of stack frames from their
+    permanent addresses"~~
+    ~~Static and global data are initialized at runtime, even if they're only
+    declared (in which case it will be initialized to 0)~~
+    ~~`static` means either "permanent storage" (local or member data-level) or
+    "internal linkage"~~
+
+    Details of implementation--compiler and processor specific, but generally:
+    The compiler assigns permanent RAM addresses to global & static variables
+    at compile time, creating machine code instructions for the processor to
+    initialize each address with each variable's initial value as written in
+    source code. In particular, these permanent RAM addresses will lie in special
+    segments of RAM: "DATA" (for globals and `static`s initialized in source
+    code) and BSS (for globals and `static`s declared but not initialized in
+    source code, so will be initialized to 0).
+    Furthermore, these initialization instructions are executed before main()--
+    i.e. all global and `static` data are initialized at the start of the
+    program.
+    Specifically for many modern microcontrollers like Atmel AVR, `static` and
+    global data will be initially stored not in SRAM but rather in Flash memory,
+    where the actual program is also stored. Flash memory is non-volatile
+    read/write, meaning that data within it is not erased when the power is off,
+    unlike RAM. For faster processing of this `static` and global data, at
+    runtime it will be copied to RAM, into DATA/BSS.
+    (This is different from most modern PCs, where instructions are stored in the
+    hard drive but loaded into RAM when run).
+    */
+
+  enum class Mode
+  {
+    SETTING_TIME,
+    SETTING_SPEED,
+    SPINNING
+  };
+  static Mode mode = Mode::SETTING_TIME;                // initialization over assignment; set SETTING_TIME as the first mode!
+  /* Perform operations with data of the same type, to
+    boost performance by not needing to implicitly typecast
+    */
+  static unsigned long setDuration;
+  static unsigned long spinningStartTime;               // point in time when countdown starts i.e. when wpb pressed the 2nd time
   static uint8_t motorSpeed;

   switch(mode)
   {
     case Mode::SETTING_TIME:
     {
-      static bool changedUIString = false;            //*** because changedUIString is static, its state will always persist
+      static bool changedUIString = false;              // because changedUIString is static, its state will always persist
       if(!changedUIString)
       {
         lcd.setCursor(0, 1);
         lcd.print(F("Set time: <"));
-        changedUIString = true;                       //*** this block becomes unreachable after this, because this true value is remembered; therefore only done once when case first entered
-      }
-
-      setDuration = map(analogRead(POT_PIN), 0, 1024, 0, 901);
+        changedUIString = true;
+        /* This block becomes unreachable after this, because this true value is
+          remembered; therefore block only done once, when case first entered
+          */
+      } // if(!changedUIString)
+
+      setDuration = map(analogRead(POT_PIN),
+                        0, 1024, 0, 901);

       lcd.setCursor(11, 1);
       lcdPrintFormattedSecs(setDuration);
@@ -101,27 +163,39 @@

       if(wpb.pressed())
       {
-        // then implicitly set in stone the countdown value, change display, and enter next block
-        //*** because mode will change, countdown will no longer be updated by pot, so on case switch countdown will equal its final value, no further updating necessary
-
-        // Erase <> selector braces
+        /* then implicitly set in stone the countdown value, change display,
+          and enter next block.
+          Because mode will change, countdown will no longer be updated by pot, so
+          on switch, countdown will equal its final value, no updating necessary
+          */
+
+        // Erase <> selector braces:
         lcd.setCursor(10, 1);
         lcdPrintFormattedSecs(setDuration);
         lcd.print(F("    "));

-        setDuration*= (long)1000;                     //*** to save space, the ATmega328P chip of UNO uses 2-byte ints, which can hold at max 32 767; operator*(int, int) will still return an int, but in this case an overflowed int;
-                                                      //*** initSetTime, a long, will just be assigned the overflowed value--it won't force operator*(int, int) to return a long.
-                                                      //*** so, by typecasting 1000 or using 1000L, you make the compiler promote analogRead() to a long, so operator*(long, long) will return the expected value, within range of sizeof long
+        /* To save space, the ATmega328P chip of UNO uses 2-byte ints, which can
+          hold at max 32 767; operator*(int, int) will still return an int, but in
+          this case an overflowed int; initSetTime, a long, will just be assigned
+          the overflowed value--it won't force operator*(int, int) to return a long.
+          so, by typecasting 1000 or using 1000L, you make the compiler promote
+          analogRead() to a long, so operator*(long, long) will return the expected
+          value, within range of sizeof long
+          */
+
+        setDuration*= (long)1000;
+
         changedUIString = false;
         mode = Mode::SETTING_SPEED;
-      }
+      } // if(wpb.pressed())
       break;
-    }
+    } // case Mode::SETTING_TIME

     case Mode::SETTING_SPEED:
     {
-      motorSpeed = map(analogRead(POT_PIN), 0, 1024, 0, 255);
+      motorSpeed = map(analogRead(POT_PIN),
+                       0, 1024, 0, 255);

       lcd.setCursor(11, 2);
       lcd.print(F("<"));
@@ -131,9 +205,11 @@

       if(wpb.pressed())
       {
-        // then implicitly set in stone the motorSpeed value, change display, pre-start the countdown, and switch block
-
-        // Erase <> selector braces
+        /* then implicitly set in stone the motorSpeed value, change display,
+          pre-start the countdown, and switch block
+          */
+
+        // Erase <> selector braces:
         lcd.setCursor(11, 2);
         lcd.print(motorSpeed);
         lcd.print(F("  "));
@@ -141,9 +217,9 @@
         spinningStartTime = millis();

         mode = Mode::SPINNING;
-      }
+      } // if(wpb.pressed())
       break;
-    }
+    } // case Mode::SETTING_SPEED

     case Mode::SPINNING:
@@ -151,15 +227,16 @@
       static bool changedUIString = false;
       if(!changedUIString)
       {
-        analogWrite(MOTOR_PIN, motorSpeed);   // set motorSpeed once and you're done--the voltage stays there!
+        analogWrite(MOTOR_PIN, motorSpeed);             // set motorSpeed once and you're done--the voltage stays there!

         lcd.setCursor(0, 1);
         lcd.print(F("Finished in: "));
         changedUIString = true;
         Serial.println("reached only once");
-      }
-
-      unsigned long secondsLeft = (setDuration - (millis() - spinningStartTime))/1000;  //*** save RAM AND flash memory by only doing this calculation once per case in loop()
+      } // if(!changedIUIString)
+
+      unsigned long secondsLeft =                       // save RAM by only doing this calculation only once per loop()::SPINNING
+      (setDuration - (millis() - spinningStartTime))/1000;

       lcd.setCursor(13, 1);
       lcdPrintFormattedSecs(secondsLeft);
@@ -168,15 +245,19 @@
       if(wpb.pressed() || secondsLeft == 0)
       {
         digitalWrite(MOTOR_PIN, LOW);
-        changedUIString = false;              // UI string will be changed back!
+        changedUIString = false;                        // UI string will be changed back!
         mode = Mode::SETTING_TIME;
-      }
+      } // if(wpb.pressed() || secondsLeft == 0)
       break;
-    }
-  }
-}
-
-inline void lcdPrintFormattedSecs(unsigned long seconds) //*** inline = suggestion to the compiler to paste the raw code of this function wherever it's called == performance optimization, no hopping pointers to callers and callbacks
+    } // case Mode::SPINNING
+  } // switch(mode)
+} // void loop()
+
+/* `inline` = suggestion to the compiler to paste the raw code of this function
+  wherever it's called == performance optimization, no hopping pointers to callers
+  and callbacks
+  */
+inline void lcdPrintFormattedSecs(unsigned long seconds)
 {
   lcd.print(seconds/60); lcd.print(F(":")); lcd.print((seconds%60 < 10 ? F("0") : F(""))); lcd.print(seconds%60);
 }


RFID length fix

RFID length fix

--- CardReader.ino
+++ CardReader.ino
@@ -7,11 +7,11 @@

 #include "ps2.h"

+// NOTE: this project must have user RFID write permission to work
 // SET THESE
 #define PUBLIC_KEY ""
 #define PRIVATE_KEY ""
 byte mac[] = { 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF };
-

 // Whiteish for initialized
 #define INITIALIZED_COLOR 50, 50, 50
@@ -147,7 +147,7 @@

         String rfidHex = String(rfidValue, HEX);

-        if(rfidHex.length() == 7) {
+        while(rfidHex.length() < 8) {
           rfidHex = "0" + rfidHex;
         }


add:tutorial

add:tutorial

--- RGB_matrix.ino
+++ RGB_matrix.ino
@@ -41,44 +41,72 @@
 }

 void loop(){
-
+    demo1();
+}
+
+//700[ms]ごとに
+void demo1(){
+    byte pattern[9];
+    for(int i=0;i<9;i++){
+        setAll(pattern,OFF);
+        pattern[i]=WHITE;
+        lighting(pattern,700);
+    }
+}
+
+void tutorial(){
+    byte pattern1[9];
+
+    pattern1[0]=RED;    //[RED,GREEN,BLUE]で色を指定
+    pattern1[1]=GREEN;
+    pattern1[2]=CYAN;    //[CYAN,YELLOW,MAGENTA]から選択可能
+    pattern1[3]=RED|BLUE; //(=MAGENTA)色の合成も可能
+    pattern1[4]=WHITE;   //[WHITE]を選択可能
+    pattern1[5]=RED|GREEN|BLUE;  //(=WHITE)
+    pattern1[6]=OFF;     //光らせない時は[OFF]
+    pattern1[7]=B001;    //２進数で直接指定でも可[RED:B001,GREEN:B010,BLUE:B100]
+    pattern1[8]=B000;    //(=OFF)[0~8]の9個のLEDの色を指定可能
+
+    while(1){
+        lighting(pattern1,1500);  //pattern1を1500[ms]出力し続ける
+
+        byte pattern2;
+        setAll(pattern2,RED);    //すべて同じ色ならsetAll()で設定可能
+        lighting(pattern2,800);     //pattern2を800[ms]出力し続ける
+
+        setAll(pattern2,OFF);     //pattern2に上書き
+        lightning(pattern2,2000);     //pattern2を2000[ms]出力し続ける
+    }
+}
+
+void setAll(byte data[],byte color){
+    for(int i=0;i<9;i++) data[i]=color;
+}
+
+void lighting(byte data[],int wait){
+    unsigned long begin = millis();
+    while( (millis()-begin)>wait ) lighting(data);
 }

-void tutorial(){
-    byte pattern[9];
-
-    pattern[0]=RED;    //[RED,GREEN,BLUE]で色を指定
-    pattern[1]=GREEN;
-    pattern[2]=CYAN;    //[CYAN,YELLOW,MAGENTA]から選択可能
-    pattern[3]=RED|BLUE; //(=MAGENTA)色の合成も可能
-    pattern[4]=WHITE;   //[WHITE]を選択可能
-    pattern[5]=RED|GREEN|BLUE;  //(=WHITE)
-    pattern[6]=OFF;     //光らせない時は[OFF]
-    pattern[7]=B001;    //２進数で直接指定でも可[RED:B001,GREEN:B010,BLUE:B100]
-    pattern[8]=B000;    //(=OFF)[0~8]の9個のLEDの色を指定可能
-
-    while(1) lighting(pattern,10);
-}
-
-
-void lighting(byte data[],int interval){
-    static long last_time=0;
+void lighting(byte data[]){
+    const int INTERVAL=10;
+    static unsigned long last_time=0;

-    //前回実行(青色発光開始時)からinterval[ms]待つ
-    while( (millis()-last_time) > interval );
+    //前回実行(青色発光開始時)からINTERVAL[ms]待つ
+    while( (millis()-last_time) > INTERVAL );

     //red
     colorWrite(OFF);
     ledWrite(data,0);
     colorWrite(RED);
-    delay(interval);
+    delay(INTERVAL);

     //green
     colorWrite(OFF);
     ledWrite(data,1);
     colorWrite(GREEN);
-    delay(interval);
+    delay(INTERVAL);

     //BLUE
     colorWrite(OFF);


Add some delays between setting channels + flash LED

--- WizardView.ino
+++ WizardView.ino
@@ -9,16 +9,22 @@

 void setup() {
     // Wait for modules to settle.
-    delay(1000);
+    delay(2000);

     // Set to race frequencies.
-    rx1.setFrequency(5665);
+    rx1.setFrequency(5805);
+    delay(500);
     rx2.setFrequency(5745);
+    delay(500);
     rx3.setFrequency(5885);
+    delay(500);
     rx4.setFrequency(5945);
 }

 void loop() {
-    // Do nothing.
+    // Flash the LED.
+    digitalWrite(13, HIGH);
+    delay(1000);
+    digitalWrite(13, LOW);
     delay(1000);
 }


changed LED pin

changed LED pin

--- XbmcSwitch.ino
+++ XbmcSwitch.ino
@@ -1,5 +1,5 @@
 int pushButton = 2;
-int mainLed = 6;
+int mainLed = 3;

 int switchState = 1;
 int noSerialCount = 0;


add delay

add delay

--- _07-ac-ir-remote-timer/_07-ac-ir-remote-timer.ino
+++ _07-ac-ir-remote-timer/_07-ac-ir-remote-timer.ino
@@ -4,18 +4,23 @@
 int powerPin = 2;

 void setup() {
-
+  delay(500);
   pinMode(powerPin, OUTPUT);
-  digitalWrite(powerPin, LOW);
+  digitalWrite(powerPin, LOW);
+  delay(500);
 }

 void loop()
 {
+    delay(500);
     togglePower();
+    delay(500);
     sleep30Minutes();
+    delay(500);
     togglePower();
-    //sleep60Minutes();
+    delay(500);
     sleep30Minutes();
+    delay(500);
 }

 // USe 9 sec
@@ -35,6 +40,7 @@
 }

 void togglePower() {
+  delay(100);
   digitalWrite(powerPin, HIGH);
   delay(100);
   digitalWrite(powerPin, LOW);


remove reboot

remove reboot

--- Yun/CheapWatchDog/CheapWatchDog.ino
+++ Yun/CheapWatchDog/CheapWatchDog.ino
@@ -17,7 +17,7 @@

 unsigned long lastHeartbeat = 0;

-void(* reboot) (void) = 0; //declare reset function @ address 0
+//void(* reboot) (void) = 0; //declare reset function @ address 0

 void setup() {
   boot();
@@ -45,7 +45,8 @@
   digitalWrite(RESET_PIN, HIGH);

   // Wait Main arduino to reboot
-  reboot();
+  //reboot();
+  boot();
 }

 void boot(){


power-meter update

power-meter update

--- _06-power-meter/_06-power-meter.ino
+++ _06-power-meter/_06-power-meter.ino
@@ -6,9 +6,9 @@

 // wifi
 #ifdef __IS_MY_HOME
-  #include "/usr/local/src/ap_setting.h"
+#include "/usr/local/src/ap_setting.h"
 #else
-  #include "ap_setting.h"
+#include "ap_setting.h"
 #endif

 // mqtt
@@ -23,18 +23,36 @@

 volatile long startMills ;
-volatile float revMills ;
+volatile long revMills ;
+long oldrevMills ;
+
 long sentMills ;

 volatile int IRSTATUS = LOW ;
 int OLDIRSTATUS ;

 float revValue ;
+float oldrevValue ;
 double VIrms ;

 //
 String clientName ;
 String payload ;
+
+// smoothing
+// https://www.arduino.cc/en/Tutorial/Smoothing
+// Define the number of samples to keep track of.  The higher the number,
+// the more the readings will be smoothed, but the slower the output will
+// respond to the input.  Using a constant rather than a normal variable lets
+// use this value to determine the size of the readings array.
+
+const int numReadings = 10;
+
+int readings[numReadings];      // the readings from the analog input
+int indexof = 0;                  // the indexof of the current reading
+int total = 0;                  // the running total
+int average = 0;                // the average
+

 void callback(const MQTT::Publish& pub) {
 }
@@ -46,7 +64,7 @@
   Serial.begin(38400);
   Serial.println("power meter test!");
   delay(20);
-
+
   Serial.println();
   Serial.println();
   Serial.print("Connecting to ");
@@ -54,12 +72,12 @@

   WiFi.mode(WIFI_STA);

-  #ifdef __IS_MY_HOME
+#ifdef __IS_MY_HOME
   WiFi.begin(ssid, password, channel, bssid);
   WiFi.config(IPAddress(192, 168, 10, 17), IPAddress(192, 168, 10, 1), IPAddress(255, 255, 255, 0));
-  #else
-  WiFi.begin(ssid, password);
-  #endif
+#else
+  WiFi.begin(ssid, password);
+#endif

   while (WiFi.status() != WL_CONNECTED) {
@@ -100,69 +118,99 @@
     Serial.println("MQTT connect failed");
     Serial.println("Will reset and try again...");
     abort();
-  }
-
+  }
+
   startMills = millis();
   sentMills = millis();
   revMills  = 0 ;
+  revValue  = 0 ;
+  oldrevMills = 0 ;
+  oldrevValue = 0 ;

   pinMode(IRPIN, INPUT);
-  attachInterrupt(4, IRCHECKING_START, RISING);
-
-  emon1.current(A0, 74);  // Current: input pin, calibration.
+  attachInterrupt(4, IRCHECKING_START, RISING);
+
+  emon1.current(A0, 70);  // Current: input pin, calibration.

   OLDIRSTATUS = LOW ;

-}
-
-void IRCHECKING_START(){
+  for (int thisReading = 0; thisReading < numReadings; thisReading++)
+    readings[thisReading] = 0 ;
+
+}
+
+void IRCHECKING_START() {
   detachInterrupt(4);
   attachInterrupt(4, count_powermeter, RISING);
   startMills = millis();
+  OLDIRSTATUS = HIGH ;
 }

 void loop()
 {
+  total = total - readings[indexof];
+
+  VIrms = emon1.calcIrms(1480) * 220.0 ;
+  readings[indexof] = VIrms ;
+
+  total = total + readings[indexof];
+  indexof = indexof + 1;
+  if (indexof >= numReadings)
+    indexof = 0;
+
+  average = total / numReadings;
+
+/*
+  Serial.print("revMills ==> ");
+  Serial.print(revMills);
+  Serial.print(" oldrevMills ==> ");
+  Serial.println(oldrevMills);
+*/
+
+  if ( revMills > 0 ) {
+      revValue = float(( 3600  * 1000 ) / ( 600 * float(revMills) ) ) * 1000 ;
+  }
+
+/*
+  Serial.print("revValue ==> ");
+  Serial.println(revValue);
+*/

-  VIrms = emon1.calcIrms(1480) * 220.0 ;
-  revValue = (( 3600  * 1000 )/ ( 600 * revMills ) ) * 1000 ;
-
-  payload = "{\"VIrms\":";
-  payload += VIrms;
-  payload += ",\"revValue\":";
-  payload += revValue;
-  payload += ",\"revMills\":";
-  payload += revMills;
-  payload += "}";
-
-  /*
-  if ( revValue > 0 ) {
-    Serial.print("power => ");
-    Serial.print(VIrms);
-    Serial.print(" ir => ");
-    Serial.print(revMills);
-    Serial.print(" W => ");
-    Serial.println(revValue);
-
-  }
-  */
-
-  if ( ( revMills != 0.00 ) && ( IRSTATUS != OLDIRSTATUS ) ) {
-       sendmqttMsg(payload);
-       OLDIRSTATUS = IRSTATUS;
-       sentMills = millis();
-  }
-
-  if ((millis() - sentMills) > REPORT_INTERVAL ) {
-       sendmqttMsg(payload);
-       sentMills = millis();
-  }
-
-  delay(1000);
-
-}
-
-void sendmqttMsg(String payload)
+  if ( oldrevValue == 0 ) {
+    oldrevValue = revValue ;
+  }
+
+  if ( oldrevMills == 0 ) {
+    oldrevMills = revMills ;
+  }
+
+    payload = "{\"VIrms\":";
+    payload += average;
+    payload += ",\"revValue\":";
+    payload += ( revValue + oldrevValue ) / 2 ;
+    payload += ",\"revMills\":";
+    payload += ( revMills + oldrevMills ) / 2 ;
+    payload += "}";
+
+  if (( IRSTATUS != OLDIRSTATUS ) && ( revMills > 0 )) {
+    sendmqttMsg(payload);
+    sentMills = millis();
+    OLDIRSTATUS = IRSTATUS ;
+    oldrevValue = revValue ;
+    oldrevMills = revMills ;
+  }
+
+
+  if (((millis() - sentMills) > REPORT_INTERVAL ) && ( revMills > 0 )) {
+    sendmqttMsg(payload);
+    sentMills = millis();
+  }
+
+  delay(100);
+
+}
+
+void sendmqttMsg(String payload)
 {
   if (!client.connected()) {
     if (client.connect((char*) clientName.c_str())) {
@@ -181,11 +229,7 @@
     Serial.print("Sending payload: ");
     Serial.println(payload);

-    if (
-      client.publish(MQTT::Publish(topic, (char*) payload.c_str())
-                .set_retain()
-               )
-      ) {
+   if (client.publish(topic, (char*) payload.c_str())) {
       Serial.println("Publish ok");
     }
     else {
@@ -197,9 +241,9 @@

 void count_powermeter()
 {
-// if (( millis() - startMills ) < 600 ) {
+  // if (( millis() - startMills ) < 600 ) {
   if (( millis() - startMills ) < ( revMills / 3 )) {
-       return;
+    return;
   } else {
     revMills   = (millis() - startMills)  ;
     startMills = millis();


No time check unless connection found.

No time check unless connection found.

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

--- zimodem/zcommand.ino
+++ zimodem/zcommand.ino
@@ -421,7 +421,7 @@
     zclock.setFormat(configArguments[CFG_TIMEFMT]);
   if((!zclock.isDisabled())&&(configArguments[CFG_TIMEURL].length()>0))
     zclock.setNtpServerHost(configArguments[CFG_TIMEURL]);
-  if(!zclock.isDisabled())
+  if((!zclock.isDisabled()) && (WiFi.status() == WL_CONNECTED))
     zclock.forceUpdate();
 }

@@ -473,10 +473,15 @@
   hostname = argv[CFG_HOSTNAME];
   if(wifiSSI.length()>0)
   {
+    debugPrintf("Connecting to %s\n",wifiSSI.c_str());
     connectWifi(wifiSSI.c_str(),wifiPW.c_str());
-  }
+    debugPrintf("Done connecting to %s\n",wifiSSI.c_str());
+  }
+  debugPrintf("Reset start.\n");
   doResetCommand();
+  debugPrintf("Reset complete.  Init start\n");
   showInitMessage();
+  debugPrintf("Init complete.\n");
 }

 ZResult ZCommand::doInfoCommand(int vval, uint8_t *vbuf, int vlen, bool isNumber)


Add full MQTT addressing to esp8266 firmware.

--- TestServer.ino
+++ TestServer.ino
@@ -21,6 +21,11 @@
 // Length of name strings. (hostname, room names, lamp names, etc.)
 #define NAME_LEN 32

+// Each device has an address in the form 'role/location1/location2/etc'
+// eg: 'lighting/kitchen/worktop/left'.
+#define ADDRESS_SEGMENTS 6
+#define ADDRESS_SEGMENT_LEN 32
+

 enum Io_Type {
   test,
@@ -29,9 +34,12 @@
   onoff
 };

+typedef struct Address_Segment {
+  char segment[ADDRESS_SEGMENT_LEN];
+} Address_Segment;
+
 typedef struct Connected_device {
-  char name[NAME_LEN];
-  char room[NAME_LEN];
+  Address_Segment address_segment[ADDRESS_SEGMENTS];
   Io_Type io_type;
   int io_pins[3];
   int io_value[3];
@@ -50,20 +58,35 @@

 String mac_address;
 const int led = 12;
-const int led2 = 13;

 // Configuration
 void SetHostname(const char* new_hostname) {
-  strncpy(config.hostname, new_hostname, NAME_LEN);
-}
-
-void SetDevice(const unsigned int index, struct Connected_device device) {
+  strncpy(config.hostname, new_hostname, NAME_LEN -1);
+  config.hostname[NAME_LEN] = '\0';
+}
+
+void SetDevice(const unsigned int index, struct Connected_device& device) {
   if (index < MAX_DEVICES) {
     memcpy(&(config.devices[index]), &device, sizeof(device));
   }
 }

+String DeviceAddress(Connected_device& device) {
+  String return_value = "";
+  for(int i = 0; i < ADDRESS_SEGMENTS; i++){
+    if(strlen(device.address_segment[i].segment) > 0){
+      if(i > 0){
+        return_value += "/";
+      }
+      return_value += device.address_segment[i].segment;
+    } else {
+      break;
+    }
+  }
+  return return_value;
+}
+

 // mDNS
 Brokers brokers(QUESTION_SERVICE);
@@ -72,8 +95,6 @@
   brokers.ParseMDnsAnswer(answer);
 }
 mdns::MDns my_mdns(NULL, NULL, answerCallback);
-
-

 // MQTT
@@ -93,11 +114,11 @@

   // Switch on the LED if an 1 was received as first character
   if ((char)payload[0] == '1') {
-    digitalWrite(led2, LOW);   // Turn the LED on (Note that LOW is the voltage level
+    digitalWrite(led, LOW);   // Turn the LED on (Note that LOW is the voltage level
     // but actually the LED is on; this is because
     // it is acive low on the ESP-01)
   } else {
-    digitalWrite(led2, HIGH);  // Turn the LED off by making the voltage HIGH
+    digitalWrite(led, HIGH);  // Turn the LED off by making the voltage HIGH
   }
 }

@@ -107,15 +128,35 @@
   mqtt_client.setCallback(mqtt_callback);
   if (mqtt_client.connect(config.hostname)) {
     char lamp[255];
-    strncpy(lamp, "_subject : lighting/unconfigured/", 254);
-    strncat(lamp, config.hostname, 254 - strlen(lamp));
-    strncat(lamp, " , _state : off", 254 - strlen(lamp));
-
-    mqtt_client.publish("homeautomation/0/lighting/_announce", lamp);
-    //mqtt_client.subscribe("homeautomation/+/lighting/unconfigured/" + config.hostname);
-    mqtt_client.subscribe("homeautomation/+/lighting/unconfigured/_all");
-    mqtt_client.subscribe("homeautomation/+/lighting/_all");
-    mqtt_client.subscribe("homeautomation/+/_all/_all");
+    char address[255];
+
+    strncpy(address, "homeautomation/+/_all/_all", 254);
+    mqtt_client.subscribe(address);
+
+    for (int i = 0; i < MAX_DEVICES; ++i) {
+      if (strlen(config.devices[i].address_segment[0].segment) > 0) {
+        String announce = "_subject : " + DeviceAddress(config.devices[i]);
+        announce += " , _state : off";
+        announce.toCharArray(lamp, 255);
+
+        mqtt_client.publish("homeautomation/0/lighting/_announce", lamp);
+
+        strncpy(address, "homeautomation/+/_all", 254);
+
+        for(int j = 0; j < ADDRESS_SEGMENTS; j++){
+          if(strlen(config.devices[i].address_segment[j].segment) <= 0) {
+            break;
+          }
+          address[strlen(address) -4] = '\0';
+          strncat(address, config.devices[i].address_segment[j].segment, 254 - strlen(address));
+          if (j < (ADDRESS_SEGMENTS -1) && strlen(config.devices[i].address_segment[j +1].segment) > 0) {
+            strncat(address, "/_all", 254 - strlen(address));
+          }
+          Serial.println(address);
+          mqtt_client.subscribe(address);
+        }
+      }
+    }
   }
   brokers.RateBroker(mqtt_client.connected());
   if (mqtt_client.connected()) {
@@ -162,12 +203,10 @@
   message += "\n";

   for (int i = 0; i < MAX_DEVICES; ++i) {
-    if (strlen(config.devices[i].name)) {
-      message += i;
+    message += i;
+    if (strlen(config.devices[i].address_segment[0].segment) > 0) {
       message += "  ";
-      message += config.devices[i].name;
-      message += "  ";
-      message += config.devices[i].room;
+      message += DeviceAddress(config.devices[i]);
       message += "  ";
       if (config.devices[i].io_type == Io_Type::test) {
         message += "test";
@@ -188,9 +227,8 @@
           message += config.devices[i].io_pins[0];
         }
       }
-
-      message += "\n";
-    }
+    }
+    message += "\n";
   }

   message += brokers.Summary();
@@ -200,25 +238,45 @@
 }

 void handleConfig() {
+  Serial.println("handleConfig()");
   const unsigned int now = millis() / 1000;

   String message = "";
+
+  for(int i = 0; i < http_server.args(); i++){
+    message += http_server.argName(i);
+    message += '\t';
+    message += http_server.arg(i);
+    message += '\n';
+  }
+  message += '\n';

   if (http_server.hasArg("test_arg")) {
     message += "test_arg: " + http_server.arg("test_arg") + "\n";
   }
+
   if (http_server.hasArg("hostname")) {
     char tmp_buffer[NAME_LEN];
     http_server.arg("hostname").toCharArray(tmp_buffer, NAME_LEN);
     SetHostname(tmp_buffer);
     message += "hostname: " + http_server.arg("hostname") + "\n";
   }
-  Serial.println("device");
-  if (http_server.hasArg("device") and http_server.hasArg("name") and http_server.hasArg("room") and http_server.hasArg("io_type") and http_server.hasArg("io_pins")) {
+
+  if (http_server.hasArg("device") and http_server.hasArg("address_segment") and
+      http_server.hasArg("io_type") and http_server.hasArg("io_pins")) {
     unsigned int index = http_server.arg("device").toInt();
     Connected_device device;
-    http_server.arg("name").toCharArray(device.name, NAME_LEN);
-    http_server.arg("room").toCharArray(device.room, NAME_LEN);
+
+    int segment_counter = 0;
+    for(int i = 0; i < http_server.args(); i++){
+      if(http_server.argName(i) == "address_segment"){
+        http_server.arg(i).toCharArray(device.address_segment[segment_counter++].segment, ADDRESS_SEGMENT_LEN);
+      }
+    }
+    for(int i = segment_counter; i < ADDRESS_SEGMENTS; i++){
+      device.address_segment[segment_counter++].segment[0] = '\0';
+    }
+
     if (http_server.arg("io_type") == "test") {
       device.io_type = Io_Type::test;
     } else if (http_server.arg("io_type") == "rgb") {
@@ -238,14 +296,10 @@
       io_pins_buffer[strlen(io_pins_buffer)] = ',';
     }

-    Serial.println(io_pins_buffer);
-    Serial.println();
-
     unsigned int pin_num = 0, pin_buffer_pointer = 0;
     memset(pin_buffer, '\0', 4);
     for (unsigned int i = 0; i < strlen(io_pins_buffer); ++i) {
       if (io_pins_buffer[i] == ',') {
-        Serial.println(pin_buffer);
         device.io_pins[pin_num++] = atoi(pin_buffer);
         memset(pin_buffer, '\0', 4);
         pin_buffer_pointer = 0;
@@ -257,12 +311,14 @@
         break;
       }
     }
-    Serial.println();

     SetDevice(index, device);

     message += "device: " + http_server.arg("device") + "\n";
     Serial.println(message);
+
+    // Force reconnect to MQTT so we subscribe to any new addreses.
+    mqtt_client.disconnect();
   }

   http_server.send(200, "text/plain", message);


Removing duplicate comment from top of KeyboardAndMouseControl example code.

--- build/shared/examples/09.USB/KeyboardAndMouseControl/KeyboardAndMouseControl.ino
+++ build/shared/examples/09.USB/KeyboardAndMouseControl/KeyboardAndMouseControl.ino
@@ -21,8 +21,6 @@
  this code is in the public domain

  */
-
-// set pin numbers for the five buttons:

 // set pin numbers for the five buttons:
 const int upButton = 2;


Using double "0.0" to check the temp/hum readings Check voltage against 3 1.5 batteries

--- ard-dht/ard-dht.ino
+++ ard-dht/ard-dht.ino
@@ -148,8 +148,8 @@
   Serial.flush();
 #endif

-  if ( ( t != 0 ) && ( h != 0 ) )
-    oregon.send(oregon_channel, oregon_id, t, h, Vcc > 1200 * 2 ? 1 : 0); // send the sensor readings
+  if ( ( t != 0.0 ) && ( h != 0.0 ) )
+    oregon.send(oregon_channel, oregon_id, t, h, (Vcc > (1200 * 3)) ? 1 : 0); // send the sensor readings

   blinkLed(); // flash the led
 }


more cleanup, pins a little bit better debounced but not much

--- arduino/due/due.ino
+++ arduino/due/due.ino
@@ -1,5 +1,5 @@
 //#include "sam3xcounter.h"
-Print &dbg(SerialUSB);
+Print &dbg(Serial);

 #include "pinclass.h"

@@ -15,63 +15,39 @@
 const InputPin<6, LOW> button1;
 const InputPin<7, LOW> button2;

-//seeed motor shield v1.0
-template <unsigned e,unsigned f,unsigned b> struct Hbridge {
-const OutputPin<e> Enab;
-const OutputPin<f> Forward;
-const OutputPin<b> Reverse;
-public:
-  /* taking an int for future use in setting a pwm on the enable pin */
-  void operator =(int dir){
-    Enab=false;
-    Forward=dir>0;
-    Reverse=dir<0;
-    Enab=dir!=0;
-  }
-
-  void freeze(){
-     Reverse=true;
-     Forward=true;
-     Enab=true;
-  }
-
-};
+#include "motorshield1.h"

-Hbridge<10,12,13> M2;
-Hbridge<9,8,11> M1;
-//end seeed motor shield v1.0
+#include "timerservice.h"

-#include "polledtimer.h"
-extern "C" int sysTickHook(){
-  PolledTimerServer();//all of our millisecond stuff hangs off of here.
-  return false; //allowed standard code to run
-}
-#include "tableofpointers.h"
 #include "retriggerablemonostable.h"

 RetriggerableMonostable lamprey(red, Ticks(350));
 RegisterTimer(lamprey);
-
 void triggerPulse(){
   lamprey.trigger();
 }

-#define Show(arg) SerialUSB.print("\n" #arg ":");SerialUSB.print(arg)
+#define Show(arg) dbg.print("\n" #arg ":");dbg.print(arg)

 #include "interruptPin.h"
 void greenLight() {
   green = button2;
   RX=green;
-  M2=1*(1-button1);//go forward unless other button is pressed in which case stop
-  Serial.print("G");
+  if(button2){
+    M2=1*(1-button1);//go forward unless other button is pressed in which case stop
+  }
+  dbg.print("G");
+  dbg.print(millis());
 }
 const InterruptPin<greenLight, button2.number, CHANGE> greenirq;

 void redLight(){
   red = button1;
   TX=red;
-  M2=-1*(1-button2);//see greenLight();
-  Serial.print("R");
+  if(button1){
+    M2=-1*(1-button2);//see greenLight();
+  }
+  dbg.print("R");
 }
 const InterruptPin<redLight, button1.number, CHANGE> redirq;
 //const InterruptPin<triggerPulse,button1.number,FALLING> redirq;
@@ -91,7 +67,7 @@
 /**
  * this could have been implemented with two PolledTimer's triggering each other, but that uses more critical resources than coding it directly.
 */
-class SlowPWM: public PolledTimer {
+class SoftPWM: public PolledTimer {
 protected:
   Ticks pair[2];
   bool phase;
@@ -109,7 +85,7 @@
     pair[1]=high;
   }

-  SlowPWM(Ticks low, Ticks high, bool andStart=false){
+  SoftPWM(Ticks low, Ticks high, bool andStart=false){
     setCycle(low,high);
     if(andStart){
       onDone();
@@ -130,20 +106,20 @@
 };

-class SlowPWMdemo: public SlowPWM {
+class SlowPWMdemo: public SoftPWM {
 public:
-  using SlowPWM::SlowPWM;
+  using SoftPWM::SoftPWM;
   //it is a bad idea to do this much in an isr ...
   virtual void onToggle(bool on){
     if(!on){
-      dbg.print("\nSlowpwm:");
+      dbg.print("\nSoftPWM:");
     } else {
       dbg.print(" to ");
     }
     dbg.print(millis());
   }

-} spwmdemo(250,750,true);
+} spwmdemo(250,750,false);

 RegisterTimer(spwmdemo);

@@ -157,7 +133,7 @@
   M1=0;
 }

-char indicator='-';
 void loop() {
   __WFE();
+  //dbg.print("+");
 }


Check if WiFi.hostname() is equal to the variable hostName at boot.

This should fix #2

Signed-off-by: Cellie <eb06271ece6666d2299daf37acf342ab0910d0ad@cellie-Mint-64.lan>

--- aquacontrol.ino
+++ aquacontrol.ino
@@ -147,7 +147,6 @@
 ///////////////////////////////////////////////////////////////////////////////////////////////////////

 void setup() {
-  WiFi.persistent(false);
   system_update_cpu_freq(cpuSpeed);  //todo: make adjustable in web interface AND SAVEable!!!!

   //setup channel names and set OUTPUT pinModes just in case...
@@ -295,6 +294,13 @@
     Serial.print( F("Default NTP sync delay set to: ") );  Serial.println( ntpSyncDelay );
   }

+  //check if hostname is correct
+  if ( hostName != WiFi.hostname() ) {
+    Serial.println( F("Difference between hostnames. Adjusting and reconnecting...") );
+    WiFi.hostname(hostName);
+    WiFi.reconnect();
+  }
+
   //check for channelnames on disk and setup accordingly
   thisFile = SPIFFS.open( channelNamesFile , "r");
   byte thisChannel = 0;


fix indent

fix indent

--- RGB_matrix.ino
+++ RGB_matrix.ino
@@ -1,20 +1,20 @@
 #include "sounds.h"

 void setup() {
-    pinMode(8, OUTPUT);
-    pinMode(9, INPUT_PULLUP);
-    pinMode(5, OUTPUT);//カソード下
-    pinMode(6, OUTPUT);//カソード中
-    pinMode(7, OUTPUT);//カソード上
-    pinMode(0, OUTPUT);//アノード１
-    pinMode(1, OUTPUT);//アノード２
-    pinMode(2, OUTPUT);//アノード３
-    pinMode(3, OUTPUT);//アノード４
-    pinMode(4, OUTPUT);//アノード５
-    pinMode(10, OUTPUT);//アノード６
-    pinMode(11, OUTPUT);//アノード７
-    pinMode(12, OUTPUT);//アノード８
-    pinMode(13, OUTPUT);//アノード９
+    pinMode( 0, OUTPUT);
+    pinMode( 1, OUTPUT);
+    pinMode( 2, OUTPUT);
+    pinMode( 3, OUTPUT);
+    pinMode( 4, OUTPUT);
+    pinMode( 5, OUTPUT);
+    pinMode( 6, OUTPUT);
+    pinMode( 7, OUTPUT);
+    pinMode( 8, OUTPUT);
+    pinMode( 9, INPUT_PULLUP);
+    pinMode(10, OUTPUT);
+    pinMode(11, OUTPUT);
+    pinMode(12, OUTPUT);
+    pinMode(13, OUTPUT);
 }

 void loop() {
@@ -166,21 +166,20 @@
     digitalWrite(13, LOW);

     for (int thisNote = 0; thisNote < 68; thisNote++) {
+        buttonState=digitalRead(9);
+        if (buttonState ==LOW ) {goto start;}
+        digitalWrite(5,HIGH);
+        digitalWrite(6,HIGH);
+        digitalWrite(7,HIGH);
+        int duration = 1000/noteDurations2[thisNote];//発音時間を定める

-    buttonState=digitalRead(9);
-    if (buttonState ==LOW ) {goto start;}
-    digitalWrite(5,HIGH);
-    digitalWrite(6,HIGH);
-    digitalWrite(7,HIGH);
-    int duration = 1000/noteDurations2[thisNote];//発音時間を定める
-
-    tone(8, melody2[thisNote],duration);   //発音
-    digitalWrite(5,LOW);
-    digitalWrite(6,LOW);
-    digitalWrite(7,LOW);
-    int pause = duration * 1.5;  //音符の間で時間をあける
-
-    delay(pause);
+        tone(8, melody2[thisNote],duration);   //発音
+        digitalWrite(5,LOW);
+        digitalWrite(6,LOW);
+        digitalWrite(7,LOW);
+        int pause = duration * 1.5;  //音符の間で時間をあける
+
+        delay(pause);
     }
     goto music2;
 }


trying to free memory

trying to free memory

--- Arduino/Base/Base.ino
+++ Arduino/Base/Base.ino
@@ -6,7 +6,7 @@
 #include "SIMCommunication.h"

 #define XBEE_BAUD 9600
-#define QMAX 10
+#define QMAX 1

 SoftwareSerial xbee(2, 3);
 XBeeCommunication xcomm("00000");//Change here for different bases
@@ -41,20 +41,15 @@
   while (!simcomm.isOn()) {
     simcomm.togglePower();
   }
-  DEBUG_PRINT("Power Status:");DEBUG_PRINTLN(simcomm.isOn() ? "ON" : "OFF");
+  DEBUG_PRINT("Pwr ");DEBUG_PRINTLN(simcomm.isOn() ? "ON" : "OFF");

-  if (simcomm.connectToNetwork()) {
-    DEBUG_PRINTLN(F("Connected!"));
-  } else {
+  if (!simcomm.connectToNetwork()) {
     DEBUG_PRINTLN(F("Network Connection Failed."));
   }

-  DEBUG_PRINTLN("ok..");
 }

 void loop(){
-  DEBUG_PRINTLN(F("====================Beginning of Void Loop===================="));
-
   /*
   This limits the sending of updates to the server by sending a maximum of 10 once every minute
   or once the array of requests reaches its maximum
@@ -65,7 +60,7 @@
       DEBUG_PRINTLN(qCount);
       delay(1000);
       for(int i = 0; i < qCount; i++){
-		DEBUG_PRINTLN(F("Making HTTP POST Request"));
+		//DEBUG_PRINTLN(F("Making HTTP POST Request"));
 		simcomm.HTTPRequest(1, "http://sachleen.com/sachleen/parking/API/nodes/save", "id=" + nodeIds[i] + "&" + "available=" + spacesAvail[i] + "&api_key=" + apiKey);
         //sendResponse = sendRequestServer(nodeIds[i], 'U', spacesAvail[i], totalSpaces[i]);//Sends a message to the server to update the status of the node
 		DEBUG_PRINTLN(response);//Idk what the response is supposed to be yet...
@@ -96,8 +91,8 @@
 		//DEBUG_PRINTLN(identifier.length());
 		identifier.trim();
 		if(identifier=="N"){
-			DEBUG_PRINT(F("Number of sensors request from "));DEBUG_PRINTLN(nodeId);
-			DEBUG_PRINTLN(F("Making HTTP GET Request"));
+			DEBUG_PRINT(F("num req frm "));DEBUG_PRINTLN(nodeId);
+			//DEBUG_PRINTLN(F("Making HTTP GET Request"));
 			response = simcomm.HTTPRequest(0, "http://sachleen.com/sachleen/parking/API/nodes/" + nodeId, "");
 			DEBUG_PRINTLN(response);
 			response.trim();//might not need(?)
@@ -149,7 +144,6 @@
 		}
         delay(2000);
     }
-    DEBUG_PRINTLN(F("====================End of Void Loop===================="));
 }

 /*


Added function to calculate directly the altitude

--- OpenRocket.ino
+++ OpenRocket.ino
@@ -122,6 +122,8 @@
 long b5;
 short temperature;
 long pressure;
+float atm; // "standard atmosphere"
+float alti;

 /*****************************************************************/

@@ -348,8 +350,7 @@
   }
   Serial.println("SD initiated!.");
   dataFile = SD.open("datalog.txt", FILE_WRITE);
-  header = "milliseconds, temperature, pressure";
-  dataFile.println(header);
+  dataFile.println("miliseconds, temperature, pressure");

   turn_output_stream_on();
   //turn_output_stream_off();
@@ -377,20 +378,28 @@
     // BMP085
     temperature = bmp085GetTemperature(bmp085ReadUT());
     pressure = bmp085GetPressure(bmp085ReadUP());
+    atm = pressure / 101325;
+    alti = calcAltitude(pressure);
+    //dtostrf(floatVar, minStringWidthIncDecimalPoint, numVarsAfterDecimal, charBuf);
     Serial.print("Temp: ");
-    Serial.print(temperature, 1);
+    Serial.print(temperature);
     Serial.println(" C");
     Serial.print("Pres: ");
-    Serial.print(pressure, 2);
+    Serial.print(pressure);
     Serial.println(" hPa");
+    Serial.print("Atmophere: ");
+    Serial.println(atm);
+    Serial.print("Altitude: ");
+    Serial.print(alti);
+    Serial.println("M");
     Serial.println();

-    // if the file is available, write to it:
     if (dataFile) {
-      dataString = String(timestamp) + " , " + String(temperature) + ", " + String(pressure);
-      dataFile.println(dataString);
-      // print to the serial port too:
-      //Serial.println(timestamp);
+      dataFile.print(timestamp);
+      dataFile.print(",");
+      dataFile.print(temperature);
+      dataFile.print(",");
+      dataFile.println(pressure);
     }
     // if the file isn't open, pop up an error:
     else {
@@ -533,3 +542,36 @@
   up = (((unsigned long) msb << 16) | ((unsigned long) lsb << 8) | (unsigned long) xlsb) >> (8-OSS);
   return up;
 }
+
+void writeRegisterBMP085(int deviceAddress, byte address, byte val) {
+  Wire.beginTransmission(deviceAddress); // start transmission to device
+  Wire.write(address);       // send register address
+  Wire.write(val);         // send value to write
+  Wire.endTransmission();     // end transmission
+}
+
+int readRegisterBMP085(int deviceAddress, byte address){
+
+  int v;
+  Wire.beginTransmission(deviceAddress);
+  Wire.write(address); // register to read
+  Wire.endTransmission();
+
+  Wire.requestFrom(deviceAddress, 1); // read a byte
+
+  while(!Wire.available()) {
+    // waiting
+  }
+
+  v = Wire.read();
+  return v;
+}
+
+float calcAltitude(float pressure){
+  float A = pressure/101325;
+  float B = 1/5.25588;
+  float C = pow(A,B);
+  C = 1 - C;
+  C = C /0.0000225577;
+  return C;
+}


Able to have light states, plus jungle and ocean

--- board/board.ino
+++ board/board.ino
@@ -7,7 +7,7 @@

 Adafruit_DCMotor *motorA = AFMS.getMotor(1);
 Adafruit_DCMotor *motorB = AFMS.getMotor(2);
-int baseSpeed = 200;
+int baseSpeed = 140;

 #define inPin 3

@@ -30,41 +30,97 @@
 long currentBitOffCount;
 int bits;

-int ledR = 9;
-int ledG = 10;
-int ledB = 11;
-
-int rCycle = 128;
-int gCycle = 255;
-int bCycle = 128;
+int RED = 0;
+int GREEN = 1;
+int BLUE = 2;
+int YELLOW = 3;
+
+int numLeds = 4;
+int leds[] = {9, 10, 11, 5}; // LED pins
+int cycles[] = {0, 0, 0, 0}; // The initial level of the light
+int times[] = {1, 1, 1, 1};
+bool flags[] = {false, false, false, false};
+int increments[] = {0, 0, 0, 0};
+int modders[] = {64, 64, 64, 64};
+
+int timer = 0;
+int timerMax = 500;

 void setup() {
   // put your setup code here, to run once:
   Serial.begin(9600);
-  Serial.println("ok");
-
-  pinMode(ledR,   OUTPUT);
-  pinMode(ledG, OUTPUT);
-  pinMode(ledB,  OUTPUT);
-
-
+  pinMode(leds[RED],   OUTPUT);
+  pinMode(leds[GREEN], OUTPUT);
+  pinMode(leds[BLUE],  OUTPUT);
+  pinMode(leds[YELLOW],  OUTPUT);
+  setOcean();
   AFMS.begin();  // create with the default frequency 1.6KHz
 }

 void loop() {
   // put your main code here, to run repeatedly:
   readInput();
-  analogWrite(ledR, rCycle);
-  analogWrite(ledG, gCycle);
-  analogWrite(ledB, bCycle);
-
-  rCycle = (rCycle + 2) % 256;
-  gCycle = (gCycle + 3) % 256;
-  bCycle = (bCycle + 1) % 256;
+  analogWrite(leds[RED], cycles[RED]);
+  analogWrite(leds[GREEN], cycles[GREEN]);
+  analogWrite(leds[BLUE], cycles[BLUE]);
+  analogWrite(leds[YELLOW], cycles[YELLOW]);
+
+  if (timer >= timerMax) {
+    timer = 0;
+  } else {
+    timer++;
+  }
+
+  for (int i = 0; i < numLeds; i++) {
+    if (flags[i] || !(timer % times[i])) {
+      flags[i] = true;
+      cycles[i] = (cycles[i] + increments[i]) % modders[i];
+      if (!cycles[i]) {
+        flags[i] = false;
+      }
+    }
+  }

   delay(10);
 }

+void resetLights() {
+  for (int i = 0; i < numLeds; i++) {
+    cycles[i] = 0;
+  }
+
+  for (int i = 0; i < numLeds; i++) {
+    times[i] = 1;
+  }
+
+  for (int i = 0; i < numLeds; i++) {
+    increments[i] = 0;
+  }
+
+  for (int i = 0; i < numLeds; i++) {
+    modders[i] = 64;
+  }
+}
+
+void setJungle() {
+  resetLights();
+  cycles[BLUE] = 5;
+  cycles[GREEN] = 255;
+  times[YELLOW] = 350;
+  increments[GREEN] = 1;
+  increments[YELLOW] = 3;
+  modders[GREEN] = 256;
+}
+
+void setOcean() {
+  resetLights();
+  cycles[BLUE] = 15;
+  cycles[GREEN] = 15;
+  times[RED] = 350;
+  times[YELLOW] = 220;
+  increments[YELLOW] = 3;
+  increments[RED] = 3;
+}

 void readInput() {
     bool on = analogRead(inPin) > 400;


Clean up and implemented 'calibrate' submenu

--- DigitalVFO.ino
+++ DigitalVFO.ino
@@ -25,10 +25,11 @@
 #define NUM_COLS        16

 // macro to get number of elements in an array
-#define ARRAY_LEN(a)    (sizeof(a)/sizeof(a[0]))
+#define ALEN(a)    (sizeof(a)/sizeof(a[0]))

 // define one row of blanks
-const char *BlankRow = "                ";
+// FIXME: should be dynamic
+char *BlankRow = NULL;

 // define data pins we connect to the LCD
 const byte lcd_RS = 7;
@@ -43,7 +44,7 @@
 const int re_pinB = 3;     // encoder B pin
 const int re_pinPush = 4;  // encoder pushbutton pin

-// define pin controlling contrast
+// define pin controlling brightness and contrast
 const byte mc_Brightness = 5;
 const byte mc_Contrast = 6;

@@ -60,7 +61,7 @@
 // size of frequency display in chars (30MHz is maximum frequency)
 #define MAX_FREQ_CHARS  8

-// address in display CGRAM for definable characters
+// address in display CGRAM for definable and other characters
 #define SELECT_CHAR     0     // shows 'underlined' decimal digits (dynamic, 0 to 9)
 #define SPACE_CHAR      1     // shows an 'underlined' space character
 #define ALLSET_CHAR     0xff  // the 'all bits set' char in display RAM, used for 'bar' display
@@ -93,9 +94,6 @@
                                10000000,    // 7
                                100000000};  // 8

-// values updated by rotary encoder interrupt routines
-volatile byte encoderCount = 0;
-
 // define the display connections
 LiquidCrystal lcd(lcd_RS, lcd_ENABLE, lcd_D4, lcd_D5, lcd_D6, lcd_D7);

@@ -109,7 +107,7 @@
 #define vfo_HoldClick 6
 #define vfo_DClick    7

-// the "in use" display character, ">"
+// the "in use" display character, "→"
 #define IN_USE_CHAR   0x7e

 // default LCD contrast & brightness
@@ -120,6 +118,12 @@
 #define vfo_Standby   0
 #define vfo_Online    1

+// stuff for the calibrate action
+const int MinClockOffset = -32000;
+const int MaxClockOffset = +32000;
+const int MaxOffsetDigits = 5;
+
+
 //##############################################################################
 // The VFO state variables and typedefs
 //##############################################################################
@@ -135,8 +139,11 @@

 typedef byte VFOEvent;

-int LcdContrast;
-int LcdBrightness = 255;
+int LcdContrast = DefaultLcdContrast;
+int LcdBrightness = DefaultLcdBrightness;
+
+// adjustment value for DDS-60 (set in 'Calibrate' menu)
+int VfoClockOffset = 0;

 //##############################################################################
@@ -238,11 +245,11 @@
   show_credits();
   delay(900);    // wait a bit

-  // do a fade out, clear screen then full brightness
+  // do a fade out, clear screen then normal brightness
   for (int i = LcdBrightness; i; --i)
   {
     analogWrite(mc_Brightness, i);
-    delay(10);
+    delay(15);
   }
   lcd.clear();
   delay(400);
@@ -288,7 +295,7 @@
     case vfo_Online:  return "ONLINE";
   }

-  return "UNKNOWN";
+  return "UNKNOWN MODE";
 }

@@ -299,18 +306,16 @@
 // handler for selection of an item (vfo_Click event)
 typedef void (*ItemAction)(struct Menu *, int);

-// handler for inc/dec of custom item (vfo_RRight, vfo_RLeft events)
+// handler for custom item (vfo_RRight, vfo_RLeft events)
 typedef int (*ItemIncDec)(int item_num, int delta);

 // structure defining a menu item
 struct MenuItem
 {
   const char *title;          // menu item display text
-  struct Menu *menu;          // if not NULL, menu to pass to show_menu()
+  struct Menu *menu;          // if not NULL, submenu to pass to show_menu()
   ItemAction action;          // if not NULL, address of action function
 };
-
-typedef struct MenuItem *MenuItemPtr;

 // A structure defining a menu
 struct Menu
@@ -347,8 +352,9 @@
 }

 //----------------------------------------
-// Draw the menu on the screen
+// Draw the menu on the screen.
 //     menu  pointer to a Menu structure
+// Only draws the top row.
 //----------------------------------------

 void menu_draw(struct Menu *menu)
@@ -386,9 +392,10 @@
 }

 //----------------------------------------
-// Draw a menu page from the passed "menu" structure.
+// Handle a menu.
 //     menu      pointer to a defining Menu structure
 //     unused    unused item number (used by action routines)
+//               (used to be index to initial item to draw)
 // Handle events in the loop here.
 // This code doesn't see events handled in any *_action() routine.
 //----------------------------------------
@@ -444,27 +451,27 @@
             // recurse down to sub-menu
             menu_show(menu->items[item_num]->menu, 0);
           }
-          menu_draw(menu);    // redraw the menu header
+          menu_draw(menu);    // redraw the menu header, item redrawn below
           Serial.printf(F("menu_show: end of vfo_Click handling\n"));
           break;
         case vfo_HoldClick:
           Serial.printf(F("menu_show: vfo_HoldClick, exit menu\n"));
           event_flush();
-          return;
+          return;             // back to the parent menu or main screen
         default:
           Serial.printf(F("menu_show: unrecognized event %d\n"), event);
           break;
       }

-      // update the menu display
+      // update the item display
       menuitem_draw(menu, item_num);
     }
   }
 }

 //----------------------------------------
-// show that *something* happened
-// flashes the menu page in a possibly eye-catching way
+// Show that *something* happened.
+// Flash the screen in a possibly eye-catching way.
 //----------------------------------------

 void display_flash(void)
@@ -492,6 +499,9 @@

 void event_push(VFOEvent event)
 {
+  // Must protect from RE code fiddling with queue
+  noInterrupts();
+
   // put new event into next empty slot
   event_queue[queue_fore] = event;

@@ -506,6 +516,8 @@
       event_dump_queue("ERROR: event queue full:");
       abort("Event queue full");
   }
+
+  interrupts();
 }

 VFOEvent event_pop(void)
@@ -600,10 +612,17 @@
   int index = num_digits - sel_col - 1;
   bool lead_zero = true;

+  // convert value to a buffer of decimal values, [0-9]
   ulong2buff(buf, num_digits, value);

+  // create special underlined selection character including selected digit
   lcd.createChar(SELECT_CHAR, sel_digits[int(buf[index])]);
-  lcd.setCursor(col, row);  // because we lose cursor position after lcd.createChar()!?
+
+  // we set cursor here because we lose cursor position after lcd.createChar()!?
+  // would prefer to set cursor position outside this function, but ไม่เป็นไร.
+  lcd.setCursor(col, row);
+
+  // write each byte of buffer to display, handling leading spaces and selection
   for (int i = 0; i < num_digits; ++i)
   {
     int char_val = buf[i];
@@ -636,6 +655,78 @@
   }
 }

+//----------------------------------------
+// Display an integer with sign on the display with selected column underlined.
+//     value       the number to display
+//     sel_col     the selection offset of digit to underline
+//                 (0 is rightmost digit, increasing to the left)
+//     num_digits  the number of digits to show on the display
+//                 (this does NOT include the +/- initial sign)
+//     col, row    position to display left-most digit at
+// If the value is too long it will be truncated at the left.
+//----------------------------------------
+
+void display_sel_offset(int value, int sel_col, int num_digits, int col, int row)
+{
+  char buf [num_digits];
+  int index = num_digits - sel_col - 1;
+  bool lead_zero = true;
+  char prefix = '+';
+
+  Serial.printf(F("display_sel_offset: value=%d, sel_col=%d, num_digits=%d, col=%d, row=%d\n"),
+                value, sel_col, num_digits, col, row);
+
+  // worry about a negative value
+  if (value < 0)
+    prefix = '-';
+  value = abs(value);
+
+  // convert value to a buffer of decimal values, [0-9]
+  ulong2buff(buf, num_digits, value);
+
+  // create special underlined selection character including selected digit
+  lcd.createChar(SELECT_CHAR, sel_digits[int(buf[index])]);
+
+  // we set cursor here because we lose cursor position after lcd.createChar()!?
+  // would prefer to set cursor position outside this function, but ไม่เป็นไร.
+  lcd.setCursor(col, row);
+
+  // write the leading sign character
+  lcd.write(prefix);
+
+  // write each byte of buffer to display, handling leading spaces and selection
+  for (int i = 0; i < num_digits; ++i)
+  {
+    int char_val = buf[i];
+
+    if (char_val != 0 || i >= num_digits - 1)
+        lead_zero = false;
+
+    if (lead_zero)
+    {
+      if (index == i)
+      {
+        lcd.write(byte(SPACE_CHAR));
+      }
+      else
+      {
+        lcd.write(" ");
+      }
+    }
+    else
+    {
+      if (index == i)
+      {
+        lcd.write(byte(SELECT_CHAR));
+      }
+      else
+      {
+        lcd.write(char_val + '0');
+      }
+    }
+  }
+}
+

 //##############################################################################
 // Interrupt driven rotary encoder interface.
@@ -696,6 +787,8 @@

 void pinPush_isr(void)
 {
+  cli();
+
   re_down = ! (PIND & 0x10);

   if (re_down)
@@ -743,6 +836,8 @@
       }
     }
   }
+
+  sei();
 }

 //----------------------------------------
@@ -751,7 +846,11 @@

 void pinA_isr(void)
 {
-  byte reading = PIND & 0xC;
+  byte reading;
+
+  cli();
+
+  reading = PIND & 0xC;

   if (reading == B00001100 && aFlag)
   { // check that we have both pins at detent (HIGH) and that we are expecting detent on
@@ -773,6 +872,8 @@
     // show we're expecting pinB to signal the transition to detent from free rotation
     bFlag = 1;
   }
+
+  sei();
 }

 //----------------------------------------
@@ -781,7 +882,11 @@

 void pinB_isr(void)
 {
-  byte reading = PIND & 0xC;
+  byte reading;
+
+  cli();
+
+  reading = PIND & 0xC;

   if (reading == B00001100 && bFlag)
   { // check that we have both pins at detent (HIGH) and that we are expecting detent on
@@ -803,6 +908,8 @@
     // show we're expecting pinA to signal the transition to detent from free rotation
     aFlag = 1;
   }
+
+  sei();
 }

@@ -811,55 +918,58 @@
 //##############################################################################

 // start storing at address 0
-const int EEPROMBase = 0;
+#define NEXT_FREE   (0)

 // address for Frequency 'frequency'
-const int AddressFreq = EEPROMBase;
-const int AddressFreqSize = sizeof(AddressFreq);
+const int AddressFreq = NEXT_FREE;
+#define NEXT_FREE   (AddressFreq + sizeof(Frequency))

 // address for int 'selected digit'
-const int AddressSelDigit = AddressFreq + AddressFreqSize;
-const int AddressSelDigitSize = sizeof(int);
+const int AddressSelDigit = NEXT_FREE;
+#define NEXT_FREE   (AddressSelDigit + sizeof(SelOffset))
+
+// address for 'VfoClockOffset' calibration
+const int AddressVfoClockOffset = NEXT_FREE;
+#define NEXT_FREE   (AddressVfoClockOffset + sizeof(VfoClockOffset))

 // address for byte 'contrast'
-const int AddressContrast = AddressSelDigit + AddressSelDigitSize;
-const int AddressContrastSize = sizeof(LcdContrast);
+const int AddressContrast = NEXT_FREE;
+#define NEXT_FREE   (AddressContrast + sizeof(LcdContrast))

 // address for byte 'brightness'
-const int AddressBrightness = AddressContrast + AddressContrastSize;
-const int AddressBrightnessSize = sizeof(LcdBrightness);
+const int AddressBrightness = NEXT_FREE;
+#define NEXT_FREE   (AddressBrightness + sizeof(LcdBrightness))

 // address for int 'hold click time'
-const int AddressHoldClickTime = AddressBrightness + AddressBrightnessSize;
-const int AddressHoldClickTimeSize = sizeof(ReHoldClickTime);
+const int AddressHoldClickTime = NEXT_FREE;
+#define NEXT_FREE   (AddressHoldClickTime + sizeof(ReHoldClickTime))

 // address for int 'double click time'
-const int AddressDClickTime = AddressHoldClickTime + AddressHoldClickTimeSize;
-const int AddressDClickTimeSize = sizeof(ReDClickTime);
+const int AddressDClickTime = NEXT_FREE;
+#define NEXT_FREE   (AddressDClickTime + sizeof(ReDClickTime))

 // number of frequency save slots in EEPROM
 const int NumSaveSlots = 10;

-const int SaveFreqSize = sizeof(long);
-const int SaveFreqBase = AddressDClickTime + AddressDClickTimeSize;
-const int SaveFreqBaseSize = NumSaveSlots * SaveFreqSize;
+const int SaveFreqBase = NEXT_FREE;
+#define NEXT_FREE   (SaveFreqBase + NumSaveSlots * sizeof(Frequency))

 //also save the offset for each frequency
-const int SaveOffsetSize = sizeof(SelOffset);
-const int SaveOffsetBase = SaveFreqBase + SaveFreqBaseSize;
-const int SaveOffsetBaseSize = NumSaveSlots * SaveOffsetSize;
-
-// free slot address
-const int NextFreeAddress = SaveOffsetBase + SaveOffsetBaseSize;
+const int SaveOffsetBase = NEXT_FREE;
+#define NEXT_FREE   (SaveOffsetBase + NumSaveSlots * sizeof(SelOffset);
+
+// additional EEPROM saved items go here

 //----------------------------------------
 // Save VFO state to EEPROM.
+// Everything except slot data.
 //----------------------------------------

 void save_to_eeprom(void)
 {
   EEPROM.put(AddressFreq, VfoFrequency);
   EEPROM.put(AddressSelDigit, VfoSelectDigit);
+  EEPROM.put(AddressVfoClockOffset, VfoClockOffset);
   EEPROM.put(AddressBrightness, LcdBrightness);
   EEPROM.put(AddressContrast, LcdContrast);
   EEPROM.put(AddressHoldClickTime, ReHoldClickTime);
@@ -868,12 +978,14 @@

 //----------------------------------------
 // Restore VFO state from EEPROM.
+// Everything except slot data.
 //----------------------------------------

 void restore_from_eeprom(void)
 {
   EEPROM.get(AddressFreq, VfoFrequency);
   EEPROM.get(AddressSelDigit, VfoSelectDigit);
+  EEPROM.get(AddressVfoClockOffset, VfoClockOffset);
   EEPROM.get(AddressBrightness, LcdBrightness);
   EEPROM.get(AddressContrast, LcdContrast);
   EEPROM.get(AddressHoldClickTime, ReHoldClickTime);
@@ -882,12 +994,14 @@

 //----------------------------------------
 // Given slot number, return freq/offset.
+//     freq    pointer to Frequency item to be updated
+//     offset  pointer to selection offset item to be updated
 //----------------------------------------

 void get_slot(int slot_num, Frequency &freq, SelOffset &offset)
 {
-  int freq_address = SaveFreqBase + slot_num * SaveFreqSize;
-  int offset_address = SaveOffsetBase + slot_num * SaveOffsetSize;
+  int freq_address = SaveFreqBase + slot_num * sizeof(Frequency);
+  int offset_address = SaveOffsetBase + slot_num * sizeof(SelOffset);

   EEPROM.get(freq_address, freq);
   EEPROM.get(offset_address, offset);
@@ -895,12 +1009,14 @@

 //----------------------------------------
 // Put frequency/offset into given slot number.
+//     freq    pointer to Frequency item to be saved in slot
+//     offset  pointer to selection offset item to be saved in slot
 //----------------------------------------

 void put_slot(int slot_num, Frequency freq, SelOffset offset)
 {
-  int freq_address = SaveFreqBase + slot_num * SaveFreqSize;
-  int offset_address = SaveOffsetBase + slot_num * SaveOffsetSize;
+  int freq_address = SaveFreqBase + slot_num * sizeof(Frequency);
+  int offset_address = SaveOffsetBase + slot_num * sizeof(SelOffset);

   EEPROM.put(freq_address, freq);
   EEPROM.put(offset_address, offset);
@@ -912,23 +1028,26 @@

 void dump_eeprom(void)
 {
-  Frequency ulong;
+  Frequency freq;
   SelOffset offset;
+  int clkoffset;
   int brightness;
   int contrast;
   unsigned int hold;
   unsigned int dclick;

-  EEPROM.get(AddressFreq, ulong);
+  EEPROM.get(AddressFreq, freq);
   EEPROM.get(AddressSelDigit, offset);
+  EEPROM.get(AddressVfoClockOffset, clkoffset);
   EEPROM.get(AddressBrightness, brightness);
   EEPROM.get(AddressContrast, contrast);
   EEPROM.get(AddressHoldClickTime, hold);
   EEPROM.get(AddressDClickTime, dclick);

   Serial.printf(F("=================================================\n"));
-  Serial.printf(F("dump_eeprom: VfoFrequency=%ld\n"), ulong);
+  Serial.printf(F("dump_eeprom: VfoFrequency=%ld\n"), freq);
   Serial.printf(F("             AddressSelDigit=%d\n"), offset);
+  Serial.printf(F("             VfoClockOffset=%d\n"), clkoffset);
   Serial.printf(F("             LcdBrightness=%d\n"), brightness);
   Serial.printf(F("             LcdContrast=%d\n"), contrast);
   Serial.printf(F("             ReHoldClickTime=%dmsec\n"), hold);
@@ -936,8 +1055,8 @@

   for (int i = 0; i < NumSaveSlots; ++i)
   {
-    get_slot(i, ulong, offset);
-    Serial.printf(F("Slot %d: freq=%ld, seldig=%d\n"), i, ulong, offset);
+    get_slot(i, freq, offset);
+    Serial.printf(F("Slot %d: freq=%ld, seldig=%d\n"), i, freq, offset);
   }

   Serial.printf(F("=================================================\n"));
@@ -948,10 +1067,12 @@
 //
 // From: http://www.rocketnumbernine.com/2011/10/25/programming-the-ad9851-dds-synthesizer
 // Andrew Smallbone <andrew@rocketnumbernine.com>
+//
+// I've touched this a little bit, so any errors are mine!
 //##############################################################################

 //----------------------------------------
-// pulse the 'pin' high and then low
+// Pulse 'pin' high and then low.
 //----------------------------------------

 void dds_pulse_high(byte pin)
@@ -961,7 +1082,7 @@
 }

 //----------------------------------------
-// transfer a byte a bit at a time, LSB first, to DDS_DATA pin
+// Transfer a 'data' byte a bit at a time, LSB first, to DDS_DATA pin.
 //----------------------------------------

 void dds_tfr_byte(byte data)
@@ -974,14 +1095,18 @@
 }

 //----------------------------------------
-// frequency of signwave (datasheet page 12) will be <sys clock> * <frequency tuning word> / 2^32
+// frequency of sinewave (datasheet page 12) will be <sys clock> * <frequency tuning word> / 2^32
+//
+// 'VfoClockOffset' is the value the 'Calibrate' menu tweaks, initially 0.
 //----------------------------------------

 void dds_update(Frequency frequency)
 {
-  int32_t data = frequency * 4294967296.0 / 180.0e6;
-
-  Serial.printf(F("dds_update: frequency=%ld, data=%ld\n"), frequency, data);
+//  int32_t data = frequency * 4294967296.0 / 180.0e6;
+  unsigned long data = frequency * 4294967296 / (6 * (30000000 - VfoClockOffset));
+
+  Serial.printf(F("dds_update: frequency=%ld, VfoClockOffset=%d, data=%ld\n"),
+                frequency, VfoClockOffset, data);

   for (int b = 0; b < 4; ++b, data >>= 8)
   {
@@ -994,12 +1119,12 @@

 //----------------------------------------
 // Force the DDS into standby mode.
+// There is a standby bit in the control word, but setting frequency to zero works.
 //----------------------------------------

 void dds_standby(void)
 {
   Serial.printf(F("DDS into standby mode.\n"));
-
   dds_update(0L);
 }

@@ -1044,37 +1169,46 @@

 //----------------------------------------
 // The standard Arduino setup() function.
+// Called once on powerup.
 //----------------------------------------

 void setup(void)
 {
+  // initialize the BlankRow global to a blank string length of a display row
+  BlankRow = (char *) malloc(NUM_COLS + 1);     // size of one display row
+  for (int i = 0; i < NUM_COLS; ++i)
+    BlankRow[i] = ' ';
+  BlankRow[NUM_COLS] = '\0';
+
   // initialize the serial console
   Serial.begin(115200);

   // VFO wakes up in standby mode
   VfoMode = vfo_Standby;
+
+  // set brightness/contrast pin state
+  pinMode(mc_Brightness, OUTPUT);
+  pinMode(mc_Contrast, OUTPUT);
+
+  // get state back from EEPROM, set display brightness/contrast
+  restore_from_eeprom();
+  analogWrite(mc_Brightness, LcdBrightness);
+  analogWrite(mc_Contrast, LcdContrast);

   // initialize the display
   lcd.begin(NUM_COLS, NUM_ROWS);      // define display size
   lcd.clear();
   lcd.noCursor();

-  // set brightness/contrast pin state
-  pinMode(mc_Brightness, OUTPUT);
-  pinMode(mc_Contrast, OUTPUT);
-
-  // get state back from EEPROM, set display brightness/contrast
-  restore_from_eeprom();
-  analogWrite(mc_Brightness, LcdBrightness);
-  analogWrite(mc_Contrast, LcdContrast);
-
   // create underlined space for frequency display
   lcd.createChar(SPACE_CHAR, sel_digits[SPACE_INDEX]);

   // set up the DDS device
   dds_setup();

-  // set up the rotary encoder, reset a few things if RE button down
+  // set up the rotary encoder
+  // reset a few things if RE button down during powerup
+  // the aim is to get the user out of an "unusable" VFO state
   if (re_setup())
   {
     LcdBrightness = DefaultLcdBrightness;
@@ -1338,6 +1472,7 @@
   // zero the frequency+selected values
   VfoFrequency = MIN_FREQ;
   VfoSelectDigit = 0;
+  VfoClockOffset = 0;
   LcdBrightness = DefaultLcdBrightness;
   LcdContrast = DefaultLcdContrast;
   ReHoldClickTime = DefaultHoldClickTime;
@@ -1362,7 +1497,7 @@
 // Show the credits.
 //   menu      address of 'calling' menu
 //   item_num  index of MenuItem we were actioned from
-// Wait here until VfoClick.
+// Wait here until any type of RE click.
 //----------------------------------------

 void credits_action(struct Menu *menu, int item_num)
@@ -1571,11 +1706,9 @@
 {
   Serial.printf(F("holdclick_action: entered\n"));

-  unsigned int holdtime = ReHoldClickTime;
-
-// the step time for hold click
-#define HOLD_STEP   100
-
+  unsigned int holdtime = ReHoldClickTime;      // the value we change
+  const unsigned int hold_step = 100;           // step adjustment +/-
+
   // get rid of any stray events to this point
   event_flush();

@@ -1597,20 +1730,20 @@
       switch (event)
       {
         case vfo_RLeft:
-          holdtime -= HOLD_STEP;
+          holdtime -= hold_step;
           if (holdtime < MinHoldClickTime)
             holdtime = MinHoldClickTime;
           Serial.printf(F("holdclick_action: vfo_RLeft, after holdtime=%d\n"), holdtime);
           break;
         case vfo_RRight:
-          holdtime += HOLD_STEP;
+          holdtime += hold_step;
           if (holdtime > MaxHoldClickTime)
             holdtime = MaxHoldClickTime;
           Serial.printf(F("holdclick_action: vfo_RRight, after holdtime=%d\n"), holdtime);
           break;
         case vfo_Click:
           ReHoldClickTime = holdtime;
-          save_to_eeprom();
+          save_to_eeprom();         // save change to EEPROM
           display_flash();
           break;
         case vfo_HoldClick:
@@ -1639,11 +1772,9 @@
 {
   Serial.printf(F("doubleclick_action: entered, ReDClickTime=%dmsec\n"), ReDClickTime);

-  int dctime = ReDClickTime;
-
-// the step time for hold click
-#define DCLICK_STEP   100
-
+  int dctime = ReDClickTime;        // the value we adjust
+  unsigned int dclick_step = 100;   // step adjustment +/-
+
   // get rid of any stray events to this point
   event_flush();

@@ -1665,20 +1796,20 @@
       switch (event)
       {
         case vfo_RLeft:
-          dctime -= DCLICK_STEP;
+          dctime -= dclick_step;
           if (dctime < MinDClickTime)
             dctime = MinDClickTime;
           Serial.printf(F("doubleclick_action: vfo_RLeft, after dctime=%d\n"), dctime);
           break;
         case vfo_RRight:
-          dctime += HOLD_STEP;
+          dctime += dclick_step;
           if (dctime > MaxDClickTime)
             dctime = MaxDClickTime;
           Serial.printf(F("doubleclick_action: vfo_RRight, after dctime=%d\n"), dctime);
           break;
         case vfo_Click:
           ReDClickTime = dctime;
-          save_to_eeprom();
+          save_to_eeprom();         // save changes to EEPROM
           display_flash();
           break;
         case vfo_HoldClick:
@@ -1696,6 +1827,108 @@
 }

 //----------------------------------------
+// Adjust the DDS-60 clock tweak to allow frequency calibration.
+//   menu      address of 'calling' menu
+//   item_num  index of MenuItem we were actioned from
+// Only works if the VFO is online.
+//
+// In line with all other action menuitems we want to observer the effects
+// of changing the value, but also only want to make a permanent change on
+// a 'click' action.
+//----------------------------------------
+
+void calibrate_action(struct Menu *menu, int item_num)
+{
+  Serial.printf(F("calibrate_action: entered, VfoClockOffset=%dmsec\n"), VfoClockOffset);
+
+  int save_offset = VfoClockOffset; // save the existing offset
+  int seldig = 0;                   // the selected digit in the display
+  bool was_standby = false;         // true if we have to set standby when finished
+
+  // if VFO in standby mode, remember that and put into online mode
+  if (VfoMode == vfo_Standby)
+  {
+    was_standby = true;
+    vfo_toggle_mode();
+  }
+
+  // get rid of any stray events to this point
+  event_flush();
+
+  // draw row 0 of menu, get heading from MenuItem
+  lcd.clear();
+  lcd.print(menu->items[item_num]->title);
+
+  // show offset info on row 1
+  display_sel_offset(VfoClockOffset, seldig, 5, 10, 1);
+
+  // handle events in our own little event loop
+  while (true)
+  {
+    // handle any pending event
+    if (event_pending() > 0)
+    {
+      byte event = event_pop(); // get next event and handle it
+
+      switch (event)
+      {
+        case vfo_RLeft:
+          VfoClockOffset -= offset2bump[seldig];
+          if (VfoClockOffset < MinClockOffset)
+            VfoClockOffset = MinClockOffset;
+          Serial.printf(F("calibrate_action: vfo_RLeft, after VfoClockOffset=%d\n"),
+                        VfoClockOffset);
+          break;
+        case vfo_RRight:
+          VfoClockOffset += offset2bump[seldig];
+          if (VfoClockOffset > MaxClockOffset)
+            VfoClockOffset = MaxClockOffset;
+          Serial.printf(F("calibrate_action: vfo_RRight, after VfoClockOffset=%d\n"),
+                        VfoClockOffset);
+          break;
+        case vfo_DnRLeft:
+          Serial.printf(F("calibrate_action: vfo_DnRLeft\n"));
+          ++seldig;
+          if (seldig >= MaxOffsetDigits)
+            seldig = MaxOffsetDigits - 1;
+          Serial.printf(F("calibrate_action: vfo_DnRLeft, after seldig=%d\n"),
+                        seldig);
+          break;
+        case vfo_DnRRight:
+          Serial.printf(F("calibrate_action: vfo_DnRLeft\n"));
+          --seldig;
+          if (seldig < 0)
+            seldig = 0;
+          Serial.printf(F("calibrate_action: vfo_DnRRight, after seldig=%d\n"),
+                        seldig);
+          break;
+        case vfo_Click:
+          save_offset = VfoClockOffset; // for when we exit menuitem
+          display_flash();
+          break;
+        case vfo_HoldClick:
+          // put changed VfoClockOffset into EEPROM
+          VfoClockOffset = save_offset;
+          save_to_eeprom();             // save changes to EEPROM
+          event_flush();
+          if (was_standby)
+            vfo_toggle_mode();
+          return;
+        default:
+          // ignored events we don't handle
+          break;
+      }
+
+      // show hold time value in row 1
+      display_sel_offset(VfoClockOffset, seldig, 5, 10, 1);
+
+      // update the VFO frequency
+      dds_update(VfoFrequency);
+    }
+  }
+}
+
+//----------------------------------------
 // Toggle the VFO mode: vfo_Online or vfo_Standby.
 //----------------------------------------
 void vfo_toggle_mode(void)
@@ -1727,7 +1960,7 @@
 struct MenuItem mi_reset_no = {"No", NULL, &reset_no_action};
 struct MenuItem mi_reset_yes = {"Yes", NULL, &reset_action};
 struct MenuItem *mia_reset[] = {&mi_reset_no, &mi_reset_yes};
-struct Menu reset_menu = {"Reset all", ARRAY_LEN(mia_reset), mia_reset};
+struct Menu reset_menu = {"Reset all", ALEN(mia_reset), mia_reset};

 //----------------------------------------
 // Settings menu
@@ -1737,8 +1970,10 @@
 struct MenuItem mi_contrast = {"Contrast", NULL, &contrast_action};
 struct MenuItem mi_holdclick = {"Hold click", NULL, &holdclick_action};
 struct MenuItem mi_doubleclick = {"Double click", NULL, &doubleclick_action};
-struct MenuItem *mia_settings[] = {&mi_brightness, &mi_contrast, &mi_holdclick, &mi_doubleclick};
-struct Menu settings_menu = {"Settings", ARRAY_LEN(mia_settings), mia_settings};
+struct MenuItem mi_calibrate = {"Calibrate", NULL, &calibrate_action};
+struct MenuItem *mia_settings[] = {&mi_brightness, &mi_contrast, &mi_holdclick,
+                                   &mi_doubleclick, &mi_calibrate};
+struct Menu settings_menu = {"Settings", ALEN(mia_settings), mia_settings};

 //----------------------------------------
 // main menu
@@ -1751,7 +1986,7 @@
 struct MenuItem mi_reset = {"Reset all", &reset_menu, NULL};
 struct MenuItem mi_credits = {"Credits", NULL, &credits_action};
 struct MenuItem *mia_main[] = {&mi_save, &mi_restore, &mi_del, &mi_settings, &mi_reset, &mi_credits};
-struct Menu menu_main = {"Menu", ARRAY_LEN(mia_main), mia_main};
+struct Menu menu_main = {"Menu", ALEN(mia_main), mia_main};

 //----------------------------------------
@@ -1807,7 +2042,7 @@
         Serial.printf(F("loop: Got vfo_HoldClick: calling menu_show()\n"));
         menu_show(&menu_main, 0);    // redisplay the original menu
         show_main_screen();
-        save_to_eeprom();   // save any changes made
+        save_to_eeprom();            // save any changes made in menu
         break;
       case vfo_DClick:
         Serial.printf(F("loop: Got vfo_DClick\n"));
@@ -1818,16 +2053,17 @@
         break;
     }

-    // display frequency if changed, update DDS-60
+    // display frequency if changed, update DDS-60 if online
     if (old_freq != VfoFrequency || old_position != VfoSelectDigit)
     {
       display_sel_value(VfoFrequency, VfoSelectDigit, MAX_FREQ_CHARS, NUM_COLS - MAX_FREQ_CHARS - 2, 0);
       old_freq = VfoFrequency;
       old_position = VfoSelectDigit;

-      save_to_eeprom();
-
-      dds_update(VfoFrequency);
-    }
-  }
-}
+      save_to_eeprom();         // worry about frequent writes?
+
+      if (VfoMode == vfo_Online)
+        dds_update(VfoFrequency);
+    }
+  }
+}


conductivity sensor

conductivity sensor

--- ctd/ctd.ino
+++ ctd/ctd.ino
@@ -16,7 +16,8 @@
 const int rLed = 8;              //
 const int LM35 = A0;             // Temperature sensor
 Adafruit_BMP085 bmp;
-//SoftwareSerial gpsSerial(2, 3); // TX, RX - GPS
+const int sal = A5;
+//SoftwareSerial gpsSerial(2, 3); // TX, RX - GPS

 File dataFile;
 unsigned long int ttime;
@@ -33,7 +34,7 @@
   Serial.begin(9600);

   if (!SD.begin(CS_PIN) and !bmp.begin()) {
-    Serial.println(F("begin failed"));
+    Serial.println("begin failed");
     digitalWrite(rLed, HIGH);
     delay(4000);
     digitalWrite(rLed, LOW);
@@ -133,6 +134,8 @@
   dataFile.print(bmp.readSealevelPressure());
   dataFile.print(",");
   dataFile.print(bmp.readAltitude(101500));
+  dataFile.print(",");
+  dataFile.print(analogRead(sal));
   // if the current sea level pressure is known, it will
   // vary with weather and such. If it is 1015 millibars
   // that is equal to 101500 Pascals.
@@ -146,4 +149,5 @@
   Serial.print("The time is: ");
   Serial.println(ttime);
   Serial.println("");
+  Serial.println(analogRead(sal));
 }


Use Serial.write, not Serial.print to output data

--- arduino_sensors/arduino_sensors.ino
+++ arduino_sensors/arduino_sensors.ino
@@ -45,13 +45,13 @@
     dif = X_CENTER - CenterOfBlocks;
     if (dif < -5) {
       sprintf(buffer, "^%s~%s~%s~", "PIXY", "direction", "right");
-      Serial.print(buffer);
+      Serial.write(buffer);
     } else if (dif > 5) {
       sprintf(buffer, "^%s~%s~%s~", "PIXY", "direction", "left");
-      Serial.print(buffer);
+      Serial.write(buffer);
     } else {
       sprintf(buffer, "^%s~%s~%s~", "PIXY", "direction", "straight");
-      Serial.print(buffer);
+      Serial.write(buffer);
     }
     if (debug) {
       Serial.println("");
@@ -62,7 +62,7 @@

   //LIDAR STUFF
   sprintf(buffer, "^%s~%s~%d~", "LIDAR", "cm", lidar.distance());
-  Serial.print(buffer);
+  Serial.write(buffer);
   if (debug) {
     Serial.println("");
   }
@@ -72,7 +72,7 @@
   {
     dtostrf(orientation.heading, 5, 2 , buf);
     sprintf(buffer, "^%s~%s~%s~", "GYRO", "heading", buf);
-    Serial.print(buffer);
+    Serial.write(buffer);
   }
   if (debug) {
     Serial.println("");


Arduino Code

Arduino Code

Added support for the Arduino Nano

--- Control/Gimbal/gimbal.ino
+++ Control/Gimbal/gimbal.ino
@@ -1,39 +1,45 @@
 /*
- * @author: jstuder
- *
- */
+   @author: jstuder
+
+*/
 #include <Servo.h>
+#include <SoftwareSerial.h>
+
+const byte rxPin = 3;
+const byte txPin = 4;
+
+SoftwareSerial upBoard (rxPin, txPin);  //Creating a software serial for the Arduino Nano

 //the servo to counter the pitch of the drone
 Servo pitch, roll;
 const int PARALLEL = 50; //45 allows for 30 degrees of + and - with ease
-const int PERPENDICULAR = PARALLEL + 90;
+const int PERPENDICULAR = PARALLEL + 90;

 //A constant to control the speed of angle change, lower is faster
 const int SPEED = 10;

 /*
- * @parameters
- *  byte angle -> the angle you want to go to
- *  int speed -> the delay between a move of 1 degree (lower is faster)
- */
+   @parameters
+    byte angle -> the angle you want to go to
+    int speed -> the delay between a move of 1 degree (lower is faster)
+*/
 void goToAngle(byte pitchAngle, byte rollAngle, int speed);

 /*
- * @parameters
- * bool isPLL -> true if gimbal needs to be parallel to the ground, false if it
- *               needs to be perpendicular
- * int xAdj -> pass a positive or negative value to adjust the left-right axis of the gimbal
- *             (modifies servo2)
- * int yAdj -> pass a positive or negative value to adjust the forward-backward axis of the gimbal
- *             (modifies pitch)
- */
+   @parameters
+   bool isPLL -> true if gimbal needs to be parallel to the ground, false if it
+                 needs to be perpendicular
+   int xAdj -> pass a positive or negative value to adjust the left-right axis of the gimbal
+               (modifies servo2)
+   int yAdj -> pass a positive or negative value to adjust the forward-backward axis of the gimbal
+               (modifies pitch)
+*/
 void mntn(bool isPLL, byte rAdj, byte pAdj);

 void setup() {

   //assigns analog pin 0 to output
-  pinMode(A0,OUTPUT);
+  pinMode(A0, OUTPUT);
   pinMode(A2, OUTPUT);
   pitch.attach(A0); //attaches pitch to analog 0
   roll.attach(A2);
@@ -42,26 +48,30 @@
   goToAngle(50, 40, SPEED); //sets the gimbal to parallel as default

   //enables serial
-  Serial1.begin(115200);
+  //SoftwareSerial upBoard (rxPin, txPin);
+  upBoard.begin(115200);
   Serial.begin(115200);
   Serial.println("Ready");
-  Serial1.println("hello??");
+
+  upBoard.println("hello??");
+
 }

-void loop()
+void loop()
 {
+
   //used to track parallel or perpendicular
   static boolean isParallel = true;
-  if (Serial1.available())
+  if (upBoard.available())
   {
     //reads as a string to allow for 'change' to be a condition
     String in;
     int i = 0;
-    in = Serial1.readString();
+    in = upBoard.readString();
     Serial.println(in);
     char inC[in.length()];
     in.toCharArray(inC, in.length());
-
+
     //allows yChange to default to the previous value. If input is invalid the gimbal doesn't move.
     byte pChange = pitch.read();
     byte rChange = roll.read();
@@ -83,13 +93,13 @@
         rString += inC[count];
         count++;
       } while (inC[count] != ' ');
-
+
       do
       {
         pString += inC[count];
         count++;
       } while (inC[count] != ' ');
-
+
       rChange = rString.toInt();
       pChange = pString.toInt();

@@ -100,6 +110,7 @@
     //calls the "maintain" function
     mntn(isParallel, rChange, pChange);
   }
+
 }

 void mntn(bool isPLL, byte rAdj, byte pAdj)
@@ -126,7 +137,7 @@
 {
   byte currentPAngle = pitch.read();
   byte currentRAngle = roll.read();
-  if(pitchAngle > currentPAngle)
+  if (pitchAngle > currentPAngle)
   {
     for (int i = currentPAngle; i < pitchAngle; i++)
     {
@@ -143,7 +154,7 @@
     }
   }

-  if(rollAngle > currentRAngle)
+  if (rollAngle > currentRAngle)
   {
     for (int i = currentRAngle; i < rollAngle; i++)
     {


Reverted to old code to test (left working one in comments)

--- Arduino/Base/Base.ino
+++ Arduino/Base/Base.ino
@@ -87,6 +87,35 @@
     DEBUG_PRINT(F("Message From Node: "));DEBUG_PRINTLN(response);

     if (response != NULL) {
+        // uint8_t start = 0;
+        // uint8_t end = response.indexOf(',');
+        // String nodeId = response.substring(start, end);
+		// DEBUG_PRINTLN(nodeId);
+
+        // start = end + 1;
+		// end = response.indexOf(',', start);
+
+        // xcomm.sendMessage(nodeId, "OK");
+        // start = end + 1;
+        // end = response.indexOf(',', start);
+        // uint8_t total = response.substring(start, end).toInt();
+
+        // start = end + 1;
+        // end = response.indexOf(',', start);
+        // uint8_t available = response.substring(start, end).toInt();
+
+        // DEBUG_PRINTLN("Node:  " + String(nodeId));
+        // DEBUG_PRINTLN("Total: " + String(total));
+        // DEBUG_PRINTLN("Avail: " + String(available));
+
+        // nodeIds[qCount] = nodeId;
+        // totalSpaces[qCount] = total;
+        // spacesAvail[qCount] = available;
+        // qCount++;
+
+        // DEBUG_PRINTLN(F("Storing in queue..."));
+
+
         uint8_t start = 0;
         uint8_t end = response.indexOf(',');
         String nodeId = response.substring(start, end);
@@ -94,95 +123,68 @@

         start = end + 1;
 		end = response.indexOf(',', start);
-
-        xcomm.sendMessage(nodeId, "OK");
-        start = end + 1;
-        end = response.indexOf(',', start);
-        uint8_t total = response.substring(start, end).toInt();
-
-        start = end + 1;
-        end = response.indexOf(',', start);
-        uint8_t available = response.substring(start, end).toInt();
-
-        DEBUG_PRINTLN("Node:  " + String(nodeId));
-        DEBUG_PRINTLN("Total: " + String(total));
-        DEBUG_PRINTLN("Avail: " + String(available));
-
-        nodeIds[qCount] = nodeId;
-        totalSpaces[qCount] = total;
-        spacesAvail[qCount] = available;
-        qCount++;
-
-        DEBUG_PRINTLN(F("Storing in queue..."));
-
-
-
-
-        // start = end + 1;
-		// end = response.indexOf(',', start);
-		// String identifier = response.substring(start, end);
+        String identifier = response.substring(start, end);

 		//DEBUG_PRINTLN(identifier.length());
-		//identifier.trim();
-		// if(identifier=="N"){
-			// DEBUG_PRINT(F("num req frm "));DEBUG_PRINTLN(nodeId);
-			// //DEBUG_PRINTLN(F("Making HTTP GET Request"));
-			// response = simcomm.HTTPRequest(0, "http://sachleen.com/sachleen/parking/API/nodes/" + nodeId, "");
-			// DEBUG_PRINTLN(response);
-			// if(response != NULL){
-				// response.trim();//might not need(?)
-				// //JSON Parsing
-				// start = response.indexOf("id\":\"") + 5;
-				// end = start + 5;
-				// //nodeId = response.substring(responseStart, responseEnd);//for testing
-				// nodeId = response.substring(start, end);
-
-				// start = response.indexOf("total\":\"") + 8;
-				// end = start + 1;
-
-				// String total;
-
-				// uint8_t quoteStart = end;
-				// uint8_t quoteEnd = start + 2;
-				// String quoteCheck = response.substring(quoteStart, quoteEnd);
-
-
-				// if(quoteCheck.equals("\"")){
-					// total = response.substring(start, end);
-				// }
-				// else{
-					// total = response.substring(start, end + 1);
-				// }
-
-				// xcomm.sendMessage(nodeId, total);//Sends reponse from server back to node
-			// }
-			// else{
-				// DEBUG_PRINTLN(F("Get request returned NULL"));
-			// }
-
-		// }
-		//else if(identifier.equals("U")){
-		//if(identifier.equals("U")){
-            // xcomm.sendMessage(nodeId, "OK");
-            // start = end + 1;
-            // end = response.indexOf(',', start);
-            // uint8_t total = response.substring(start, end).toInt();
-
-            // start = end + 1;
-            // end = response.indexOf(',', start);
-            // uint8_t available = response.substring(start, end).toInt();
-
-            // DEBUG_PRINTLN("Node:  " + String(nodeId));
-            // DEBUG_PRINTLN("Total: " + String(total));
-            // DEBUG_PRINTLN("Avail: " + String(available));
-
-            // nodeIds[qCount] = nodeId;
-            // totalSpaces[qCount] = total;
-            // spacesAvail[qCount] = available;
-            // qCount++;
-
-            // DEBUG_PRINTLN(F("Storing in queue..."));
-		//}
+		identifier.trim();
+		if(identifier=="N"){
+			DEBUG_PRINT(F("num req frm "));DEBUG_PRINTLN(nodeId);
+			//DEBUG_PRINTLN(F("Making HTTP GET Request"));
+			response = simcomm.HTTPRequest(0, "http://sachleen.com/sachleen/parking/API/nodes/" + nodeId, "");
+			DEBUG_PRINTLN(response);
+			if(response != NULL){
+				response.trim();//might not need(?)
+				//JSON Parsing
+				start = response.indexOf("id\":\"") + 5;
+				end = start + 5;
+				//nodeId = response.substring(responseStart, responseEnd);//for testing
+				nodeId = response.substring(start, end);
+
+				start = response.indexOf("total\":\"") + 8;
+				end = start + 1;
+
+				String total;
+
+				uint8_t quoteStart = end;
+				uint8_t quoteEnd = start + 2;
+				String quoteCheck = response.substring(quoteStart, quoteEnd);
+
+
+				if(quoteCheck.equals("\"")){
+					total = response.substring(start, end);
+				}
+				else{
+					total = response.substring(start, end + 1);
+				}
+
+				xcomm.sendMessage(nodeId, total);//Sends reponse from server back to node
+			}
+			else{
+				DEBUG_PRINTLN(F("Get request returned NULL"));
+			}
+
+		}
+		else if(identifier.equals("U")){
+            xcomm.sendMessage(nodeId, "OK");
+            start = end + 1;
+            end = response.indexOf(',', start);
+            uint8_t total = response.substring(start, end).toInt();
+
+            start = end + 1;
+            end = response.indexOf(',', start);
+            uint8_t available = response.substring(start, end).toInt();
+
+            DEBUG_PRINTLN("Node:  " + String(nodeId));
+            DEBUG_PRINTLN("Total: " + String(total));
+            DEBUG_PRINTLN("Avail: " + String(available));
+
+            nodeIds[qCount] = nodeId;
+            totalSpaces[qCount] = total;
+            spacesAvail[qCount] = available;
+            qCount++;
+
+            DEBUG_PRINTLN(F("Storing in queue..."));
+		}
         delay(2000);
     }
 	loopCount = loopCount + 1;


espoire espoire

espoire espoire

--- calibrateur.ino
+++ calibrateur.ino
@@ -187,7 +187,13 @@
              etatCalibrateur=14;
              Serial.println("la");

-//             compteurRef=compteur;
+
+
+             break;
+        case 14:
+             Serial.println("lalalal");
+
+               compteurRef=compteur;
 //             objTest=leServo.getMilieu();
 //             while (compteur>compteurRef-3)
 //               {
@@ -200,9 +206,6 @@
 //             leServo.setMax(objTest-DELTA);
 //             leServo.setObjectif(leServo.getMilieu());

-             break;
-        case 14:
-             Serial.println("lalalal");

              break;


bugfix

bugfix

--- RGB_matrix.ino
+++ RGB_matrix.ino
@@ -4,6 +4,7 @@

 #define BUZZER_PIN 8
 #define SWITCH_PIN 9
+#define isPress() digitalRead(SWITCH_PIN)

 PlayMelody song1(BUZZER_PIN);
 PlayMelody song2(BUZZER_PIN);
@@ -21,29 +22,9 @@

 void loop(){

-    //スイッチが押されるまでmodeA
-    while( digitalRead(SWITCH_PIN) ) modeA();
-    song1.stop();
-    delay(50);
-
-    //スイッチが離されるまで待つ
-    while( !digitalRead(SWITCH_PIN) );
-
-    //スイッチが押されるまでmodeB
-    while( digitalRead(SWITCH_PIN) ) modeB();
-    song2.stop();
-    delay(50);
-
-    //スイッチが離されるまで待つ
-    while( !digitalRead(SWITCH_PIN) );
-
-}
-
-
-void modeA(){
     //音が変わるたびに発光箇所が変わる
     song1.play();
-    while( song1.isPlaying() ){
+    while( song1.isPlaying() || !isPress() ){
         static int cnt=0;
         cnt += song1.play();
         Led::setAll(OFF);
@@ -51,55 +32,29 @@
         Led::lighting();
     }
     song1.stop();
-    delay(500);
-}
+    Led::setAll(OFF);
+    Led::lighting();
+    delay(200);
+    while( isPress() );  //スイッチが離されるまで待つ

-void modeB(){
+
+
     //音の高さによって色が変わる
     song2.play();
-    while( song2.isPlaying() ){
+    while( song2.isPlaying() || !isPress()){
         song2.play();
         LedColor color = int2color( song2.getPitch() );
         Led::setAll(color);
         Led::lighting();
     }
     song2.stop();
-    delay(500);
+    Led::setAll(OFF);
+    Led::lighting();
+    delay(200);
+    while( isPress() );  //スイッチが離されるまで待つ
+
 }

-
-void tutorial(){
-    LedColor pattern1[9];
-    pattern1[0]=RED;    //[RED,GREEN,BLUE]で色を指定
-    pattern1[1]=GREEN;
-    pattern1[2]=BLUE;
-    pattern1[3]=CYAN;    //[CYAN,YELLOW,MAGENTA]からも選択可能
-    pattern1[4]=YELLOW;
-    pattern1[5]=MAGENTA;
-    pattern1[6]=WHITE;   //[WHITE]を選択可能
-    pattern1[7]=OFF;     //光らせない時は[OFF]
-    pattern1[8]=OFF;
-    Led::lightingWhile(pattern1,1500);  //pattern1を1500[ms]出力し続ける
-
-    Led::setAll(OFF);
-    Led::set(0,BLUE);    //set(led,color):指定ledを指定色に設定
-    Led::set(3,RED);
-    Led::set(5,GREEN);
-    Led::set(8,BLUE);
-    Led::lightingWhile(800);     //設定済みの色で800[ms]出力し続ける
-
-    Led::setAll(OFF);     //すべて同じ色ならsetAll()で設定可能
-    Led::lightingWhile(2000);     //設定済みの色で2000[ms]出力し続ける
-}
-
-void demo(){
-    //700[ms]ごとに発光LEDを遷移
-    for(int i=0;i<9;i++){
-        Led::setAll(OFF);
-        Led::set(i,WHITE);
-        Led::lightingWhile(700);
-    }
-}

 LedColor int2color(int num){
     switch (num%8) {


Updated TODO list

Updated TODO list

--- Synthduino.ino
+++ Synthduino.ino
@@ -10,7 +10,7 @@
 /* TODO
  *
  * 1) [DONE] Convert pitches to format nXX, instead of NOTE_XX
- * 2) Add support for Constant declarations of notes - EIGHTH instead of 8
+ * 2) [DONE] Add support for Constant declarations of notes - EIGHTH instead of 8
  * 3) [DONE] Add enharmonics
  *   ------- 	All these following classes use memory format note->end, where end is an offset from
  *						the overall start time (instead of just duration), so