LPD8806

LPD8806

with FastLED

--- BlackLED.ino
+++ BlackLED.ino
@@ -4,11 +4,11 @@
 //
 //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
 #define NUM_OF_OUTPUTS 2
-#define MAX_NUM_LED_PER_OUTPUT 384
-#define NUM_CHANNEL_PER_LED 4
-
-//#define _use_FastLED  //for all types of chips but only 3 channel
-#define _use_octoWS2811 //for all WS2811 type chips
+#define MAX_NUM_LED_PER_OUTPUT 121
+#define NUM_CHANNEL_PER_LED 3
+
+#define _use_FastLED  //for all types of chips but only 3 channel !!only LPD8806 implemented in code
+//#define _use_octoWS2811 //for all WS2811 type chips

 //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
 //
@@ -17,7 +17,7 @@
 //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
 #define num_channel_per_output MAX_NUM_LED_PER_OUTPUT*NUM_CHANNEL_PER_LED
 #if num_channel_per_output%512 > 0
-#define NUM_OF_UNIVERSES_PER_OUT (num_channel_per_output/512)+1
+#define num_universes_per_output (num_channel_per_output/512)+1
 #else
 #define num_universes_per_output num_channel_per_output/512
 #endif
@@ -31,10 +31,19 @@
 // settings error check
 //
 //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
-
+#ifdef _use_FastLED
+#if NUM_OF_OUTPUTS > 2
+#error  "max 2 outputs for FastLED. if you want more it is easy to implement"
+#endif
 #ifdef _use_octoWS2811
-#ifdef _use_FastLED
 #error "only use one led controlle type"
+#endif
+#endif
+
+#ifdef _use_octoWS2811
+#warning "using less than 8 outputs, octoWS2811 will stil runs 8 outputs"
+#if NUM_OF_OUTPUTS > 8
+#error "octoWS2811 only runs 8 outputs"
 #endif
 #endif

@@ -66,23 +75,29 @@
 #include <Ethernet.h>
 #include <ArtNode.h>
 #include "ArtNetFrameExtension.h"
+
+#ifdef _use_octoWS2811
 #include "OctoWS2811.h"
-
-#include "TeensyMAC.h"
-#include <EEPROM.h>
-
-#define VERSION_HI 0
-#define VERSION_LO 8
-
-#define PIN_RESET 9
-
-EthernetUDP udp;
-uint8_t udp_buffer[600];
-
-boolean locateMode = 0;
+#endif
+#ifdef _use_FastLED
 uint32_t portSyncFlag;
 uint32_t portSyncFlagCheck = 0;
 uint8_t syncFlag;
+#include "FastLED.h"
+#endif
+
+#include "TeensyMAC.h"
+#include <EEPROM.h>
+
+#define VERSION_HI 0
+#define VERSION_LO 8
+
+#define PIN_RESET 9
+
+EthernetUDP udp;
+uint8_t udp_buffer[600];
+
+boolean locateMode = 0;

 // variables for the node.report
 float tempVal = 0;
@@ -107,7 +122,9 @@

 OctoWS2811 LEDS(num_led_per_output, displayMemory, drawingMemory, LEDconfig);
 #endif
+
 #ifdef _use_FastLED
+CRGB leds[num_led_per_output * NUM_OF_OUTPUTS];
 #endif

 //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
@@ -173,6 +190,11 @@
   delay(100);
   #endif
   #ifdef _use_FastLED
+  FastLED.clear();
+  FastLED.showColor(0xFFFFFF);
+  delay(300);
+  FastLED.clear();
+  delay(100);
   #endif
 }

@@ -234,9 +256,6 @@
 void setup() {
   //saveConfig(); //<-- uncomment to force the EEPROM config to your settings on eatch reboot
   loadConfig();
-  for (int i = 0; i < config.numPorts; i++) {
-    bitSet(portSyncFlagCheck, i);
-  }

 #ifdef PIN_RESET
   pinMode(PIN_RESET, OUTPUT);
@@ -268,8 +287,16 @@
   // Open ArtNet
   node = ArtNodeExtended(config, sizeof(udp_buffer), udp_buffer);

+  #ifdef _use_octoWS2811
   LEDS.begin();
   LEDS.show();
+  #endif
+  #ifdef _use_FastLED
+  FastLED.addLeds<LPD8806, 2, 6, RGB, DATA_RATE_KHZ(12)>(leds, num_led_per_output).setCorrection( UncorrectedColor );
+  #if NUM_OF_OUTPUTS > 1
+  FastLED.addLeds<LPD8806, 14, 20, RGB, DATA_RATE_KHZ(12)>(leds, num_led_per_output, num_led_per_output).setCorrection( UncorrectedColor );
+  #endif
+  #endif

   blink();

@@ -318,13 +345,17 @@
               if (port >= 0 && port < config.numPorts) {
                 uint16_t portOffset = port * 128;
                 //write the dmx data to the Octo frame buffer
+                #ifdef _use_octoWS2811
                 uint32_t* dmxData = (uint32_t*) dmx->Data;
-                #ifdef _use_octoWS2811
                 for (int i = 0; i < 128; i++) {
                   LEDS.dmxPixel(i + portOffset, dmxData[i]);
                 }
                 #endif
+
                 #ifdef _use_FastLED
+                for (int i = 0; i < 128; i++) {
+                  leds[i + portOffset] = CRGB(dmx->Data[i*3], dmx->Data[i*3+1], dmx->Data[i*3+2]);
+                }
                 #endif
                 numUniUpdated++;
               }
@@ -337,6 +368,7 @@
               LEDS.show();
               #endif
               #ifdef _use_FastLED
+              FastLED.show();
               #endif

               // calculate framerate


Fix envelope peak at 10V and add 5V output.

--- examples/adsr/adsr.ino
+++ examples/adsr/adsr.ino
@@ -23,7 +23,7 @@
 #include <du-ino_function.h>
 #include <du-ino_interface.h>

-#define ENV_PEAK              5.0
+#define ENV_PEAK              10.0 // V
 #define ENV_SATURATION        1.581976
 #define ENV_DECAY_COEFF       -2.0
 #define ENV_RELEASE_COEFF     -2.0
@@ -108,6 +108,7 @@
       }

       cv_out(CO1, cv_current);
+      cv_out(CO3, cv_current / 2.0);
     }
     else if(gate)
     {


case14

--- calibrateur.ino
+++ calibrateur.ino
@@ -184,7 +184,7 @@
              //leServo.setObjectif(leServo.getMilieu()+DELTA);
              leServo.setObjectif(1900);
              sleep(TEMPOSLEEP);
-
+             etatCalibrateur=14;
              Serial.println("la");

 //             compteurRef=compteur;
@@ -201,8 +201,10 @@
 //             leServo.setObjectif(leServo.getMilieu());

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

         case 2:
              if (leServo.isMin())


nouvelle constante défini (DEP STAT)

nouvelle constante défini (DEP STAT)

--- calibrateur.ino
+++ calibrateur.ino
@@ -52,8 +52,11 @@
 #define PINVOIEB 3 //la pin surlaquelle est branché la voie B
 #define ERREURCOMPTAGE 6 //la tolérance de comptage avant que l'on estime que le servo est arrivé au bout
 #define NBRCYCLE_AR 10 //nbre de cycle d'aller et retour pour la fin des mesure de caractérisation et nbr de cycle pour la mesure des PWMIN et PWMMAX
-#define TEMPO_STAT 200 // tempo pour laisser le servo avancer lors des mesures
+#define TEMPO_STAT 100 // tempo pour laisser le servo avancer lors des mesures
                        // statistique à la fin de la calibration ATTENTION 100ms semble etre trop court!!!!
+#define DEP_MINI_STAT 5  //correspond au déplacement minimum en nombre d'impulsion que doit faire le servo pour
+						//considérer qu'il n' pas encore atteint sa fin de course et que l'on peut laisser le chronometre en
+						//route (pour mesure de vitesse réeel du servo en °/s)
 #define ADRESSE_EEPROM 42//position de leeprom ou la valeur de reglage de vitesse est stocké
 #define VITESSEMAXSERVO 4000 // vitesse max d'un servo en microsecond de PWM par seconde
 //cette vitesse doit imperativement etre superieure à la vitesse que
@@ -391,7 +394,7 @@
                             leServo.setObjectif(leServo.getMax());
                             sleep(TEMPO_STAT);
                             Serial.print("cmpt="); Serial.println(compteur);
-                            while (abs(compteur)>abs(compteurRef)+10)
+                            while (abs(compteur)>abs(compteurRef)+DEP_MINI_STAT)
                                 {
                                     compteurRef=compteur;
                                     Serial.print("yop");
@@ -415,7 +418,7 @@
                             leServo.setObjectif(leServo.getMin());
                             sleep(TEMPO_STAT);
                             Serial.print("cmpt="); Serial.println(compteur);
-                            while (compteur>compteurRef+10)
+                            while (compteur>compteurRef+DEP_MINI_STAT)
                                 {
                                     compteurRef=compteur;
                                     Serial.print("yup ");


fixed capacitor integration by not doing 2 capacitors

--- readSensors/readSensors.ino
+++ readSensors/readSensors.ino
@@ -19,7 +19,7 @@
 const int capacitorChargePin2 = 4;

 const int imuRate = 10; /* sampling rate in Hz */
-const float capacitorRate = 1; //dedicate to capacitor every  10 seconds
+const float capacitorRate = .5; //dedicate to capacitor every  10 seconds
 const int muxRate = 10;

 int muxChoice = 0;
@@ -77,6 +77,7 @@
       break;
     }
   }
+
   long startTime = micros();
   looptimestart = micros();
   int index = 0;
@@ -102,6 +103,7 @@
       break;
     }
   }
+
   while ( (cap1Value < 800 || cap2Value < 800) && index <= length);

   delay(del);
@@ -117,14 +119,15 @@
   }
   delay(del);

-  Serial.print("], \"capacitor2\": [");
-  Serial.print(capacitor2Data[0]);
-  for (int i = 1; i< index;i++){
-    delay(del);
-    Serial.print(", ");
-    Serial.print(capacitor2Data[i]);
-  }
-  delay(del);
+ // Serial.print("]}");
+//  Serial.print("], \"capacitor2\": [");
+//  Serial.print(capacitor2Data[0]);
+//  for (int i = 1; i< index;i++){
+//    delay(del);
+//    Serial.print(", ");
+//    Serial.print(capacitor2Data[i]);
+//  }
+//  delay(del);
   Serial.print("],");
   Serial.print("\"capacitorIime\": [");
   Serial.print( capacitorTimeData[0]);
@@ -138,7 +141,7 @@
   /* dicharge the capacitor  */
   digitalWrite(capacitorChargePin1, LOW);             // set charge pin to  LOW
   digitalWrite(capacitorChargePin2, LOW);             // set charge pin to  LOW
-}
+}

 void samplePorts() /*sample ports and send over serial according to rates*/

@@ -181,17 +184,17 @@

     switch(muxChoice){
     case 0:
-      printf("{\"temperature\": %d, \"time\": ", muxVal);
+      p("{\"temperature\": %d, \"time\": ", muxVal);
       Serial.print(millis());
       Serial.println("}");
       break;
     case 1:
-      printf("{\"conductance\": %d, \"time\": ", muxVal);
+      p("{\"conductance\": %d, \"time\": ", muxVal);
       Serial.print(millis());
       Serial.println("}");
       break;
     case 2:
-      printf("{\"pressure\": %d, \"time\": ", muxVal);
+      p("{\"pressure\": %d, \"time\": ", muxVal);
       Serial.print(millis());
       Serial.println("}");
       break;


Use define for freqPlan

Use define for freqPlan

--- examples/Node/Node.ino
+++ examples/Node/Node.ino
@@ -1,13 +1,17 @@
 #include <TheThingsNetwork.h>
 #include <TheThingsNode.h>

+// Set your AppEUI and AppKey
 const char *appEui = "0000000000000000";
 const char *appKey = "00000000000000000000000000000000";

 #define loraSerial Serial1
 #define debugSerial Serial

-TheThingsNetwork ttn(loraSerial, debugSerial, TTN_FP_EU868);
+// Replace REPLACE_ME with TTN_FP_EU868 or TTN_FP_US915
+#define freqPlan REPLACE_ME
+
+TheThingsNetwork ttn(loraSerial, debugSerial, freqPlan);
 TheThingsNode *node;

 enum port : byte


Add more comments to the ADSR logic.

Add more comments to the ADSR logic.

--- examples/adsr/adsr.ino
+++ examples/adsr/adsr.ino
@@ -157,9 +157,14 @@
   {
     if (retrigger_)
     {
+      // update the currently selected envelope (we use the same envelope for the duration of a curve)
       env_ = selected_env_;
+
+      // reset the gate and release times so that the curve logic can execute
       gate_time_ = 0;
       release_time_ = 0;
+
+      // reset to wait for another retrigger
       retrigger_ = false;
     }

@@ -167,6 +172,7 @@
     {
       if (gate_)
       {
+        // if the gate is active, we are in the attack, decay, or sustain part of the curve, depending on elapsed time
         uint16_t elapsed = millis() - gate_time_;
         if (elapsed < adsr_values_[env_].A)
         {
@@ -175,7 +181,7 @@
         }
         else
         {
-          // decay/sustain
+          // decay/sustain (no dedicated sustain; the decay curve approaches the sustain value after the decay time)
           cv_current_ = adsr_values_[env_].S + (ENV_PEAK - adsr_values_[env_].S)
               * exp(ENV_DECAY_COEFF * (float(elapsed - adsr_values_[env_].A) / float(adsr_values_[env_].D)));
         }
@@ -192,6 +198,7 @@
           }
           else
           {
+            // release curve has finished; zero output and reset gate and release times
             cv_current_ = 0.0;
             release_time_ = 0;
             gate_time_ = 0;
@@ -199,16 +206,20 @@
         }
         else
         {
+          // initial release step; record the release time and the initial CV value at release
           release_time_ = millis();
           cv_released_ = cv_current_;
         }
       }

+      // output the 10V and 5V envelope outputs on CO1 and CO3
       cv_out(CO1, cv_current_);
       cv_out(CO3, cv_current_ / 2.0);
     }
     else if (gate_)
     {
+      // set the gate time to the time when the attack curve would have started for the current CV output value, so that
+      // subsequent curve calculations are correct for retrigger (this will just be the current time if current CV is 0)
       gate_time_ = millis()
           - (unsigned long)(-float(adsr_values_[env_].A) * log(1 - (cv_current_ / (ENV_PEAK * ENV_SATURATION))));
     }


Repaired example

Repaired example

Signed-off-by: Roman3349 <6b7cbc66756660b4790b3af1ec1507653acaa035@centrum.cz>

--- examples/Init/Init.ino
+++ examples/Init/Init.ino
@@ -22,7 +22,7 @@

 // LOCAL PROTOTYPES
 void MyIqrfRxHandler(void);
-void MyIqrfTxHandler(UINT8 txPktId, UINT8 txPktResult);
+void MyIqrfTxHandler(uint8_t txPktId, uint8_t txPktResult);
 void AppTimerHandler(void);
 void cb_timer1ms(void);

@@ -128,6 +128,6 @@
  * @param txPktId Paket ID
  * @param txPktResult Paket writing result
  */
-void MyIqrfTxHandler(UINT8 txPktId, UINT8 txPktResult) {
+void MyIqrfTxHandler(uint8_t txPktId, uint8_t txPktResult) {
   Serial.println("IQRF send done");
 }


Blynk RTC changes

Blynk RTC changes

--- hvacMonitor.ino
+++ hvacMonitor.ino
@@ -1,7 +1,6 @@
 #include <SimpleTimer.h>        // Timer library
 #define BLYNK_PRINT Serial      // Turn this on to see basic Blynk activities
 //#define BLYNK_DEBUG           // Turn this on to see *everything* Blynk is doing... really fills up serial monitor!
-#include <ESP8266WiFi.h>
 #include <ESP8266mDNS.h>        // Required for OTA
 #include <WiFiUdp.h>            // Required for OTA
 #include <ArduinoOTA.h>         // Required for OTA
@@ -31,7 +30,6 @@
 SimpleTimer timer;

 WidgetRTC rtc;
-BLYNK_ATTACH_WIDGET(rtc, V8);
 WidgetTerminal terminal(V26);

 const int blowerPin = 13;  // WeMos pin D7.
@@ -71,10 +69,24 @@

 long todaysAccumRuntimeSecCooling;    // Seconds that system has been cooling.
 long todaysAccumRuntimeSecHeating;    // Seconds that system has been heating.
-bool dominantMode;                    // FALSE = Cooling. TRUE = Heating.
+bool heatingMode;                     // FALSE = Cooling. TRUE = Heating.
 bool hvacMode;                        // FALSE = Cooling. TRUE = Heating.

 double tempRA, tempSA;                // Return and supply air temperatures
+
+int coolingRelay = 5;   // WeMos pin D1.
+int heatingRelay = 4;   // WeMos pin D2.
+int fanRelay = 16;      // WeMos pin D0.
+int bypassRelay = 14;   // WeMos pin D5.
+
+int controlSplit = 1;   // Predefined value of how much I want to heat or cool above trigger point.
+int controllingTemp;
+int setpointTemp;
+String controllingSpace;
+bool coolingMode;       // 1 = cooling. 0 = heating.
+bool controlMode;
+int tempKK, tempLK;
+

 void setup()
 {
@@ -91,6 +103,20 @@
   while (Blynk.connect() == false) {
     // Wait until connected
   }
+
+  pinMode(coolingRelay, OUTPUT);
+  pinMode(heatingRelay, OUTPUT);
+  pinMode(fanRelay, OUTPUT);
+  pinMode(bypassRelay, OUTPUT);
+
+  // Default all HVAC relays to off
+  digitalWrite(coolingRelay, HIGH);
+  digitalWrite(heatingRelay, HIGH);
+  digitalWrite(fanRelay, HIGH);
+  digitalWrite(bypassRelay, HIGH);
+  Blynk.setProperty(V39, "label", "Setpoint");
+  Blynk.setProperty(V39, "color", "#27292D");  // Gray that blends into Blynk tool background rending invisible.
+  Blynk.setProperty(V40, "color", "#696969");

   // START OTA ROUTINE
   ArduinoOTA.setHostname("HVAC-WeMosD1mini");     // Name that is displayed in the Arduino IDE.
@@ -127,12 +153,16 @@
   timer.setInterval(1234L, sendStatus);       // Unit run status polling interval (for app Current Status display only).
   timer.setInterval(1000L, countRuntime);     // Counts blower runtime for daily accumulation displays.
   timer.setInterval(1000L, totalRuntime);     // Counts blower runtime.
+  timer.setInterval(1000L, modeTracking);     // Tracks if unit has been mostly cooling or heating during the day.
   timer.setInterval(1000L, setClockTime);     // Creates a current time with leading zeros.
   //timer.setInterval(500L, alarmTimer);      // Alarms for low SA/RA split in heating or cooling.
   timer.setInterval(15432L, phantSend);       // ~15 sec run status updates to Phant runnting on a local Raspberry Pi.
   timer.setTimeout(100, vsync1);              // Syncs back vPins to survive hardware reset.
   timer.setTimeout(2000, vsync2);             // Syncs back vPins to survive hardware reset.
   timer.setTimeout(4000, vsync3);             // Syncs back vPins to survive hardware reset.
+  timer.setInterval(30000L, tempUpdater);      // When bypass on, this evaluates controlling space against setpoint.
+  timer.setInterval(30000L, tempControl);     // Temps (controlling space) that can control HVAC are synced.
+
 }

 void loop()  // To keep Blynk happy, keep most tasks out of the loop.
@@ -142,6 +172,191 @@
   ArduinoOTA.handle();
 }

+// ******************************************************** HVAC CTRL START **********************************************
+BLYNK_WRITE(V40) {
+  switch (param.asInt())
+  {
+    // **************************************** IN ALL CASES BELOW: LOW == ON/CLOSED, HIGH == OFF/OPEN
+    case 1: {                         // House t-stat controlling (bypass off)
+        controlMode = 0;
+        Blynk.setProperty(V39, "label", "Setpoint");
+        Blynk.setProperty(V39, "color", "#27292D");   // Blynk widget background gray
+        Blynk.setProperty(V40, "color", "#696969");   // DimGray
+        digitalWrite(fanRelay, HIGH);
+        digitalWrite(coolingRelay, HIGH);
+        digitalWrite(heatingRelay, HIGH);
+        digitalWrite(bypassRelay, HIGH);
+        break;
+      }
+    case 2: {                         // House t-stat bypass (Blynk-controlling, but nothing running)
+        controlMode = 0;
+        Blynk.setProperty(V39, "label", "Setpoint");
+        Blynk.setProperty(V39, "color", "#27292D");   // Blynk widget background gray
+        Blynk.setProperty(V40, "color", "#FFFFFF");   // White
+        digitalWrite(fanRelay, HIGH);
+        digitalWrite(coolingRelay, HIGH);
+        digitalWrite(heatingRelay, HIGH);
+        digitalWrite(bypassRelay, LOW);
+        break;
+      }
+    case 3: {                         // Manual fan (blower only)
+        controlMode = 0;
+        Blynk.setProperty(V39, "label", "Setpoint");
+        Blynk.setProperty(V39, "color", "#27292D");   // Blynk widget background gray
+        Blynk.setProperty(V40, "color", "#23C48E");   // Blynk green
+        digitalWrite(fanRelay, LOW);
+        digitalWrite(coolingRelay, HIGH);
+        digitalWrite(heatingRelay, HIGH);
+        digitalWrite(bypassRelay, LOW);
+        break;
+      }
+    case 4: {                         // Manual cooling
+        controlMode = 0;
+        Blynk.setProperty(V39, "label", "Setpoint");
+        Blynk.setProperty(V39, "color", "#27292D");   // Blynk widget background gray
+        Blynk.setProperty(V40, "color", "#04C0F8");   // Blynk blue
+        digitalWrite(fanRelay, HIGH);
+        digitalWrite(coolingRelay, LOW);
+        digitalWrite(heatingRelay, HIGH);
+        digitalWrite(bypassRelay, LOW);
+        break;
+      }
+    case 5: {                         // Manual heating
+        controlMode = 0;
+        Blynk.setProperty(V39, "label", "Setpoint");
+        Blynk.setProperty(V39, "color", "#27292D");   // Blynk widget background gray
+        Blynk.setProperty(V40, "color", "#D3435C");   // Blynk red
+        digitalWrite(fanRelay, HIGH);
+        digitalWrite(coolingRelay, HIGH);
+        digitalWrite(heatingRelay, LOW);
+        digitalWrite(bypassRelay, LOW);
+        break;
+      }
+    case 6: {                                         // Keaton-controlled cooling
+        controlMode = 1;
+        controllingSpace = "KK";                      // Here's the room that we're watching
+        coolingMode = 1;                              // This sets the HVAC in correct mode and decides tstat logic
+        controllingTemp = tempKK;
+        Blynk.setProperty(V39, "label", String("Setpoint - Controlled by KK (currently ") + tempKK + "F).");
+        Blynk.setProperty(V39, "color", "#04C0F8");   // Blynk blue
+        Blynk.setProperty(V40, "color", "#04C0F8");   // Blynk blue
+        digitalWrite(fanRelay, HIGH);
+        digitalWrite(coolingRelay, HIGH);
+        digitalWrite(heatingRelay, HIGH);
+        digitalWrite(bypassRelay, LOW);
+        break;
+      }
+    case 7: {                             // Keaton-controlled heating
+        controlMode = 1;
+        controllingSpace = "KK";
+        coolingMode = 0;
+        controllingTemp = tempKK;
+        Blynk.setProperty(V39, "label", String("Setpoint - Controlled by KK (currently ") + tempKK + "F).");
+        Blynk.setProperty(V39, "color", "#D3435C");
+        Blynk.setProperty(V40, "color", "#D3435C");
+        digitalWrite(fanRelay, HIGH);
+        digitalWrite(coolingRelay, HIGH);
+        digitalWrite(heatingRelay, HIGH);
+        digitalWrite(bypassRelay, LOW);
+        break;
+      }
+    case 8: {                             // Liv-controlled cooling
+        controlMode = 1;
+        controllingSpace = "LK";
+        coolingMode = 1;
+        controllingTemp = tempLK;
+        Blynk.setProperty(V39, "label", String("Setpoint - Controlled by LK (currently ") + tempLK + "F).");
+        Blynk.setProperty(V39, "color", "#04C0F8");
+        Blynk.setProperty(V40, "color", "#04C0F8");
+        digitalWrite(fanRelay, HIGH);
+        digitalWrite(coolingRelay, HIGH);
+        digitalWrite(heatingRelay, HIGH);
+        digitalWrite(bypassRelay, LOW);
+        break;
+      }
+    case 9: {                             // Liv-controlled heating
+        controlMode = 1;
+        controllingSpace = "LK";
+        coolingMode = 0;
+        controllingTemp = tempLK;
+        Blynk.setProperty(V39, "label", String("Setpoint - Controlled by LK (currently ") + tempLK + "F).");
+        Blynk.setProperty(V39, "color", "#D3435C");
+        Blynk.setProperty(V40, "color", "#D3435C");
+        digitalWrite(fanRelay, HIGH);
+        digitalWrite(coolingRelay, HIGH);
+        digitalWrite(heatingRelay, HIGH);
+        digitalWrite(bypassRelay, LOW);
+        break;
+      }
+    default: {
+        controlMode = 0;
+        Blynk.setProperty(V39, "label", "Setpoint");
+        Blynk.setProperty(V39, "color", "#27292D");   // Blynk widget background gray
+        Blynk.setProperty(V40, "color", "#696969");   // DimGray
+        digitalWrite(fanRelay, HIGH);
+        digitalWrite(coolingRelay, HIGH);
+        digitalWrite(heatingRelay, HIGH);
+        digitalWrite(bypassRelay, HIGH);
+        break;
+      }
+  }
+}
+
+void tempControl() {
+
+  if (controlMode == 1)                            // If we're in bypass mode, proceed:
+  {
+
+    if (coolingMode == 0 && controllingTemp != 0 && controllingTemp < setpointTemp)       // If mode is heat and room falls equal or below the target temp...
+    {
+      digitalWrite(heatingRelay, LOW);                            // turn on the heat. But when
+    }
+    else if (coolingMode == 0 && controllingTemp != 0 && controllingTemp >= (setpointTemp + controlSplit))   // If mode is heat and room is warmer then target temp...
+    {
+      digitalWrite(heatingRelay, HIGH);                           // everything is turned off.
+    }
+    else if (coolingMode == 1 && controllingTemp != 0 && controllingTemp > setpointTemp)  // If mode is cool and room rises equal or above the target temp...
+    {
+      digitalWrite(coolingRelay, LOW);                            // turn on cooling. Then,
+    }
+    else if (coolingMode == 1 && controllingTemp != 0 && controllingTemp <= (setpointTemp - controlSplit))   // when mode is cool and room is cooler then target temp...
+    {
+      digitalWrite(coolingRelay, HIGH);                           // turn everything off.
+    }
+
+  }
+}
+
+void tempUpdater() {
+  Blynk.syncVirtual(V4);
+  Blynk.syncVirtual(V6);
+
+  if (controllingSpace == "KK")
+  {
+    controllingTemp = tempKK;
+    Blynk.setProperty(V39, "label", String("Setpoint - Controlled by KK (currently ") + tempKK + "F)");
+  }
+  else if (controllingSpace == "LK")
+  {
+    controllingTemp = tempLK;
+    Blynk.setProperty(V39, "label", String("Setpoint - Controlled by LK (currently ") + tempLK + "F)");
+  }
+}
+
+BLYNK_WRITE(V4) {
+  tempKK = param.asInt();
+}
+
+BLYNK_WRITE(V6) {
+  tempLK = param.asInt();
+}
+
+BLYNK_WRITE(V39)  // Input from slider in app to set setpoint
+{
+  setpointTemp = param.asInt();
+}
+// ******************************************************** HVAC CTRL END **********************************************
+
 void vsync2()
 {
   Blynk.syncVirtual(V110);    // hvacTodaysStartCount
@@ -157,6 +372,7 @@
 void vsync1()
 {
   Blynk.syncVirtual(V16);    // currentStatus
+  Blynk.syncVirtual(V38);    // heatingMode (kind of)
 }

 BLYNK_WRITE(V110)
@@ -182,6 +398,20 @@
 BLYNK_WRITE(V16)
 {
   currentStatus = param.asStr();
+}
+
+BLYNK_WRITE(V38)
+{
+  String blah = param.asStr();
+
+  if (blah == "COOL")
+  {
+    heatingMode = FALSE;
+  }
+  else if (blah == "HEAT")
+  {
+    heatingMode = TRUE;
+  }
 }

 void phantSend() {
@@ -406,16 +636,29 @@
       Blynk.setProperty(V1, "color", "#ff0000");    // Supply is RED
       Blynk.setProperty(V0, "color", "#04C0F8");    // Return is BLUE
       hvacMode = TRUE;                              // FALSE = cooling, TRUE =  heating.
-
-      todaysAccumRuntimeSecHeating = todaysAccumRuntimeSecHeating + 2.5;
     }
     else if (tempSA <= tempRA && hvacMode == TRUE)
     {
       Blynk.setProperty(V1, "color", "#04C0F8");    // Supply is BLUE
       Blynk.setProperty(V0, "color", "#ff0000");    // Return is RED
       hvacMode = FALSE;                             // FALSE = cooling, TRUE =  heating.
-
-      todaysAccumRuntimeSecCooling = todaysAccumRuntimeSecCooling + 2.5;
+    }
+  }
+}
+
+void modeTracking()
+{
+  if (digitalRead(blowerPin) == LOW)  // If the blower is running...
+  {
+    if (tempSA > tempRA)              // and it looks like we're heating, then...
+    {
+      hvacMode = TRUE;                // TRUE = heating, and...
+      ++todaysAccumRuntimeSecHeating; // count each heating second, but...
+    }
+    else if (tempSA < tempRA)         // if it looks like we're coolng, then...
+    {
+      hvacMode = FALSE;               // FALSE = cooling, and...
+      ++todaysAccumRuntimeSecCooling; // count each cooling second.
     }
   }

@@ -426,10 +669,12 @@
   else if (todaysAccumRuntimeSecHeating < todaysAccumRuntimeSecCooling)
   {
     Blynk.virtualWrite(38, "COOL");
+    heatingMode = FALSE;
   }
   else if (todaysAccumRuntimeSecHeating > todaysAccumRuntimeSecCooling)
   {
     Blynk.virtualWrite(38, "HEAT");
+    heatingMode = TRUE;
   }
 }


Initial functionality for new input format

Accepts "V#00FF00" style input, parsing hex to ints with strtol.  Not
tested yet.

--- csarc/csarc.ino
+++ csarc/csarc.ino
@@ -4,7 +4,6 @@
  *  make gradient pulses between two colors: "G#000000:#FFFFFF:pulseTime"
  *  ???
  */
-

 #include "RGBdriver.h"
@@ -29,7 +28,25 @@
   if (input!="") { // if connected
     switch (input[0]) {
       case 'V': {
-        // set value specified in rest of V#FFFFFF inpupt
+        // set value specified in rest of V#FFFFFF input
+
+        // function strtol() returns a long when given (string,end pointer,radix)
+        char redV[2] = {input[2],input[3]};
+        char greenV[2] = {input[4],input[5]};
+        char blueV[2] = {input[6],input[7]};
+
+        red = strtol(redV, NULL, 16);
+        green = strtol(greenV, NULL, 16);
+        blue = strtol(blueV, NULL, 16);
+
+        Driver.begin();
+        Driver.SetColor(red, green, blue);
+        Driver.end();
+
+        // report back hex values
+        Serial.print(red, HEX);
+        Serial.print(green, HEX);
+        Serial.println(blue, HEX);
         break;
       }
     case 'G' : {


um, let's fill until start time not the other way around...

--- ardesp/waterelf/waterelf.ino
+++ ardesp/waterelf/waterelf.ino
@@ -225,7 +225,7 @@
     if(newState == true){
       mcp.digitalWrite(pumpMcpPin, HIGH);
       mcp.digitalWrite(solenoidMcpPin, HIGH);
-      filling = true;
+      filling = true; // TODO if set from UI will interfere with timing?
       dln(valveDBG, " on");
     } else {
       mcp.digitalWrite(pumpMcpPin, LOW);
@@ -241,14 +241,14 @@
   void on()  { stateChange(true); }  // fill time
   void off() { stateChange(false); } // drain time
   void step(monitor_t* now, char cycleMins) {   // check conditions and adjust
-    dbg(valveDBG, "valve[].step - number = "); dln(valveDBG, number);
-    if(!filling && ( startTime >= millis() )) { // time to start filling
+    dbg(valveDBG, "\nvalve[].step - number = "); dln(valveDBG, number);
+    if(!filling && ( startTime <= millis() )) { // time to start filling
       on();
       startTime += (cycleMins * 60 * 1000);
       dbg(valveDBG, "startTime = "); dln(valveDBG, startTime);
-    }
-    if(full(now))                    // we're full
+    } else if(filling && full(now)) {           // we're full
       off();
+    } // TODO if cycleMins - dryMins ...?
   }
   bool full(monitor_t *now) {
     int l = -1;


Fixed statistics printout.

Fixed statistics printout.

--- examples/VWI/CosaVWItempmonitor/CosaVWItempmonitor.ino
+++ examples/VWI/CosaVWItempmonitor/CosaVWItempmonitor.ino
@@ -104,7 +104,7 @@
   next += 1;

   // Print message count and errors every 256 messages
-  if (next & 0xff == 0) {
+  if ((next & 0xff) == 0) {
     trace << PSTR("count = ") << cnt << endl;
     trace << PSTR("errors = ") << err << endl;
   }


Modif code Arduino

Modif code Arduino

--- Arduino/humidite/humidite.ino
+++ Arduino/humidite/humidite.ino
@@ -35,7 +35,11 @@
   input = "0";
   if (input == "0") {
     mode = 0;
-  }
+  }
+  else if (input == "1") {
+    mode = 1;
+  }
+
   switch(mode) {
     case 0:
       break;


Minor changes to arduino scheme to get readings with 1s period and to use Vcal EU value

--- utils/emontxv3_firmware/raspimon_firmware/DiscreteSampling/DiscreteSampling.ino
+++ utils/emontxv3_firmware/raspimon_firmware/DiscreteSampling/DiscreteSampling.ino
@@ -63,7 +63,7 @@

 //----------------------------emonTx V3 Settings---------------------------------------------------------------------------------------------------------------
 const byte Vrms=                  230;                               // Vrms for apparent power readings (when no AC-AC voltage sample is present)
-const byte TIME_BETWEEN_READINGS = 10;            //Time between readings
+const byte TIME_BETWEEN_READINGS = 1000;            // Time between readings in ms (10s before raspimon)

 //http://openenergymonitor.org/emon/buildingblocks/calibration

@@ -72,15 +72,15 @@
 const float Ical3=                90.9;                                 // (2000 turns / 22 Ohm burden) = 90.9
 const float Ical4=                16.67;                               // (2000 turns / 120 Ohm burden) = 16.67

-float Vcal=                       268.97;                             // (230V x 13) / (9V x 1.2) = 276.9 Calibration for UK AC-AC adapter 77DB-06-09
+//float Vcal=                       268.97;                             // (230V x 13) / (9V x 1.2) = 276.9 Calibration for UK AC-AC adapter 77DB-06-09
 //float Vcal=276.9;
-//const float Vcal=               260;                             //  Calibration for EU AC-AC adapter 77DE-06-09
+float Vcal=               260;                             //  Calibration for EU AC-AC adapter 77DE-06-09
 const float Vcal_USA=             130.0;                             //Calibration for US AC-AC adapter 77DA-10-09
 boolean USA=FALSE;

 const float phase_shift=          1.7;
 const int no_of_samples=          1662;
-const int no_of_half_wavelengths= 30;
+const int no_of_half_wavelengths= 10;                          // 30 before raspimon. 10 half are 5 cycles, with 50Hz, and 4 CT sensors = 400ms for power reading
 const int timeout=                2000;                               //emonLib timeout
 const int ACAC_DETECTION_LEVEL=   3000;
 const byte min_pulsewidth= 110;                                // minimum width of interrupt pulse (default pulse output meters = 100ms)
@@ -111,7 +111,7 @@

 //-----------------------RFM12B / RFM69CW SETTINGS----------------------------------------------------------------------------------------------------
 #define RF_freq RF12_433MHZ                                              // Frequency of RF69CW module can be RF12_433MHZ, RF12_868MHZ or RF12_915MHZ. You should use the one matching the module you have.
-byte nodeID = 8;                                                        // emonTx RFM12B node ID
+byte nodeID = 10;                                                        // emonTx RFM12B node ID
 const int networkGroup = 210;

 typedef struct {
@@ -142,7 +142,7 @@

   Serial.begin(9600);

-  Serial.print("emonTx V3.4 Discrete Sampling V"); Serial.print(version*0.1);
+  Serial.print("raspimon - emonTx V3.4 Discrete Sampling V"); Serial.print(version*0.1);
   #if (RF69_COMPAT)
     Serial.println(" RFM69CW");
   #else
@@ -422,7 +422,7 @@
   send_rf_data();                                                           // *SEND RF DATA* - see emontx_lib

   unsigned long runtime = millis() - start;
-  unsigned long sleeptime = (TIME_BETWEEN_READINGS*1000) - runtime - 100;
+  unsigned long sleeptime = max( 20, TIME_BETWEEN_READINGS - runtime - 100 ); // raspimon: added max(20,value) to avoid negative times

   if (ACAC) {                                                               // If powered by AC-AC adaper (mains power) then delay instead of sleep
     delay(sleeptime);


Update EPROM_Dumper.ino

Update EPROM_Dumper.ino

--- EPROM_Dumper/EPROM_Dumper.ino
+++ EPROM_Dumper/EPROM_Dumper.ino
@@ -5,7 +5,11 @@
 {
    Serial.begin(9600); // Opens Serial Port to receive data

-   DDRL = B00000000;  //Sets up L-pins as 8-bit input A + C as 16 bit output
+   /*
+    *Sets up L-pins as 8-bit input A + C as 16 bit output
+    */
+
+   DDRL = B00000000;
    DDRA = B11111111;  //Lower address
    DDRC = B11111111;  //Upper address


Added support for ids and packet types and added color array packet type

--- firmware/node/node.ino
+++ firmware/node/node.ino
@@ -1,11 +1,20 @@
 #include <util/crc16.h>
+#include <EEPROM.h>
 #include <Adafruit_NeoPixel.h>

 const uint8_t NUM_PIXELS = 8;
 const uint8_t OUT_PIN = 2;
 const uint8_t MAX_PACKET_LEN = 32;

+const uint8_t BROADCAST = 255;
+const uint8_t PACKET_SINGLE_COLOR = 0;
+const uint8_t PACKET_COLOR_ARRAY= 1;
+
 Adafruit_NeoPixel pixels = Adafruit_NeoPixel(NUM_PIXELS, OUT_PIN, NEO_GRB + NEO_KHZ800);
+
+// where in EEPROM our node id is stored
+const int id_address = 0;
+uint8_t g_node_id = 0;

 void show_color(uint8_t r, uint8_t g, uint8_t b)
 {
@@ -53,14 +62,33 @@
     startup_animation();

     Serial.begin(38400);
+
+    g_node_id = EEPROM.read(id_address);
 }

-void handle_packet(uint8_t len, uint8_t *data)
+void handle_packet(uint8_t len, uint8_t *packet)
 {
-    uint8_t            j;
+    uint8_t j, type, target;
+    uint8_t *data;

-    for(int j=0; j < NUM_PIXELS; j++)
-        pixels.setPixelColor(j, pixels.Color(data[0], data[1], data[2]));
+    target = packet[0];
+    if (target != BROADCAST && target != g_node_id)
+         return;
+
+    type = packet[1];
+    data = &packet[2];
+    switch(type)
+    {
+        case PACKET_SINGLE_COLOR:
+            for(int j=0; j < NUM_PIXELS; j++)
+                pixels.setPixelColor(j, pixels.Color(data[0], data[1], data[2]));
+            break;
+
+        case PACKET_COLOR_ARRAY:
+            for(int j=0; j < NUM_PIXELS; j++, data += 3)
+                pixels.setPixelColor(j, pixels.Color(data[0], data[1], data[2]));
+            break;
+    }

     pixels.show();
 }


maybe last?

maybe last?

--- little-switches/arduino/galoppo/galoppo.ino
+++ little-switches/arduino/galoppo/galoppo.ino
@@ -13,6 +13,9 @@
 #define piede A0
 #define tamburo 2

+int volo = 400;
+int ciclo = 200;
+

 PS2Keyboard keyboard;

@@ -25,6 +28,8 @@

 int tempo = 78;
 float w = 0;
+
+

 float mapfloat(float x, float in_min, float in_max, float out_min, float out_max)
 {
@@ -93,60 +98,21 @@
 }

 void galoppo(float v) {
-  int aa = 0;
-  long ps,pd,as,ad;
-  bool bps = true;
-  bool bpd = true;
-  bool bas = true;
-  bool bad = true;
-
-
-  bool fine=false;
-  long ii = millis();
-  while (!fine) {
-    if (bps) {
-      digitalWrite(zampaPS,HIGH);
-      ps = millis();
-      bps = false;
-    }
-    if (((millis() - ii) > (75*v)) && bpd)  {
-      digitalWrite(zampaPD,HIGH);
-      pd = millis();
-      bpd = false;
-    }
-    if (((millis() - ii) > (75+125)*v) && bas) {
-      digitalWrite(zampaAS,HIGH);
-      as = millis();
-      bas = false;
-    }
-    if ((millis() - ii) > (75+125+75)*v) && bad) {
-      digitalWrite(zampaAD,HIGH);
-      ad = millis();
-      bad = false;
-    }
-
-    if ((millis() - ii) > ((ps+200)*v)) {
-      digitalWrite(zampaPS,LOW);
-    }
-    if ((millis() - ii) > ((pd+200)*v)) {
-      digitalWrite(zampaPD,LOW);
-    }
-    if ((millis() - ii) > ((as+200)*v)) {
-      digitalWrite(zampaAS,LOW);
-    }
-    if ((millis() - ii) > ((ad+200)*v)) {
-      digitalWrite(zampaAD,LOW);
-      ii = millis();
-      bps = true;
-      bpd = true;
-      bas = true;
-      bad = true;
-      aa++;
-    }
-
-    if (aa > 10) {
-      fine = true;
-    }
-
+  for (int i=0; i<10; i++) {
+  digitalWrite(zampaPS,HIGH);
+  delay(75);
+  digitalWrite(zampaPD,HIGH);
+  delay(150);
+  digitalWrite(zampaAS,HIGH);
+  delay(75);
+  digitalWrite(zampaAD,HIGH);
+  delay(400);
+  digitalWrite(zampaPS,LOW);
+  delay(75);
+  digitalWrite(zampaPD,LOW);
+  delay(150);
+  digitalWrite(zampaAS,LOW);
+  delay(150);
+  digitalWrite(zampaAD,LOW);
   }
 }


Removed redundant #include

Removed redundant #include

--- examples/OnDemandConfigPortal/OnDemandConfigPortal.ino
+++ examples/OnDemandConfigPortal/OnDemandConfigPortal.ino
@@ -1,8 +1,6 @@
 #include <ESP8266WiFi.h>          //https://github.com/esp8266/Arduino

 //needed for library
-#include <DNSServer.h>
-#include <ESP8266WebServer.h>
 #include <WiFiManager.h>          //https://github.com/tzapu/WiFiManager


varidation string send waiting until I2CINT becomes HIGH

--- d_BacpacCommands.ino
+++ d_BacpacCommands.ino
@@ -21,8 +21,6 @@
   switch (command) {
   case GET_BACPAC_PROTOCOL_VERSION: // vs
     ledOff();
-    memcpy_P(buf, validationString, sizeof validationString);
-    SendBufToCamera();
 #ifdef USE_GENLOCK
     if (1) { // send to Dongle
       Serial.println("");
@@ -30,6 +28,11 @@
       Serial.flush();
     }
 #endif
+    while (digitalRead(I2CINT) != HIGH) { // wait until camera pullups I2CINT
+      ;
+    }
+    memcpy_P(buf, validationString, sizeof validationString);
+    SendBufToCamera();
     delay(200); // need a short delay the validation string to be read by camera
     queueIn(F("cv"));
     return;


Fixed myModes[] bug in esp8266_webinterface example sketch (#245)

Co-authored-by: Keith Lord <fe8316594e497b43c77d3f99f323d966d0e18ebf@Keiths-Mac-mini.local>

--- examples/esp8266_webinterface/esp8266_webinterface.ino
+++ examples/esp8266_webinterface/esp8266_webinterface.ino
@@ -228,7 +228,8 @@

     if(server.argName(i) == "m") {
       uint8_t tmp = (uint8_t) strtol(server.arg(i).c_str(), NULL, 10);
-      ws2812fx.setMode(tmp % ws2812fx.getModeCount());
+      uint8_t new_mode = sizeof(myModes) > 0 ? myModes[tmp % sizeof(myModes)] : tmp % ws2812fx.getModeCount();
+      ws2812fx.setMode(new_mode);
       Serial.print("mode is "); Serial.println(ws2812fx.getModeName(ws2812fx.getMode()));
     }


Updates server root and loop functions.

Updates server root and loop functions.

--- njmakerday_20160318/njmakerday_20160318.ino
+++ njmakerday_20160318/njmakerday_20160318.ino
@@ -45,12 +45,12 @@

 void handleRoot() {
 	digitalWrite ( led, 1 );
-	char temp[400];
+	char temp[600];
 	int sec = millis() / 1000;
 	int min = sec / 60;
 	int hr = min / 60;

-	snprintf ( temp, 400,
+	snprintf ( temp, 600,

 "<html>\
   <head>\
@@ -160,6 +160,7 @@
 }

 void loop ( void ) {
-	server.handleClient();
   readMonitors();
+  server.handleClient();
+  delay(5000);
 }


Demo program: Store two more strings in program memory.

--- examples/Demo/Demo.ino
+++ examples/Demo/Demo.ino
@@ -455,11 +455,11 @@
         // Cycle the instructions every 2 seconds.
         if (instructCount == 0)
         {
-          lcd.print("Hold=run");
+          lcd.print(F("Hold=run"));
         }
         else if (instructCount == 40)
         {
-          lcd.print("Tap=flip");
+          lcd.print(F("Tap=flip"));
         }
         if (++instructCount == 80) { instructCount = 0; }
       }


refactor into separate method

refactor into separate method

--- monitoring-temp-arduino-code/monitoring/monitoring.ino
+++ monitoring-temp-arduino-code/monitoring/monitoring.ino
@@ -57,6 +57,23 @@
     return avg / (float)counter;
 }

+void sendValuesToHost() {
+    unsigned long currentMillis = millis();
+    if ((currentMillis - lastSend) > SEND_TO_HOST_INTERVALL_IN_MILLIS) {
+        lastSend = currentMillis;
+
+        Serial.print("(1) ");
+        Serial.print(averageValues(&tempRingBuf_1), 1);
+        Serial.println("Grad Celsius");
+
+        Serial.print("(2) ");
+        Serial.print(averageValues(&tempRingBuf_2), 1);
+        Serial.println("Grad Celsius");
+
+        Serial.println("");
+    }
+}
+
 void setup() {
     if (SEND_TEMP_VALUES_TO_HOST) {
         Serial.begin(9600);
@@ -69,24 +86,12 @@
 }

 void loop() {
-
     buffer_write(&tempRingBuf_1, readTemperatureInCelcius(LM35_1_PIN));
     buffer_write(&tempRingBuf_2, readTemperatureInCelcius(LM35_2_PIN));
     delay(WAIT_MILLIS);

-    unsigned long currentMillis = millis();
-    if (SEND_TEMP_VALUES_TO_HOST && (currentMillis - lastSend) > SEND_TO_HOST_INTERVALL_IN_MILLIS) {
-        lastSend = currentMillis;
-
-        Serial.print("(1) ");
-        Serial.print(averageValues(&tempRingBuf_1), 1);
-        Serial.println("Grad Celsius");
-
-        Serial.print("(2) ");
-        Serial.print(averageValues(&tempRingBuf_2), 1);
-        Serial.println("Grad Celsius");
-
-        Serial.println("");
+    if (SEND_TEMP_VALUES_TO_HOST) {
+        sendValuesToHost();
     }

     analogWrite(FAN_PWM_PIN, 255);


Started work on addresses

Started work on addresses

--- firmware/node/node.ino
+++ firmware/node/node.ino
@@ -18,6 +18,7 @@
 const uint8_t PACKET_CLEAR_NEXT   = 6;
 const uint8_t PACKET_POSITION     = 7;
 const uint8_t PACKET_DELAY        = 8;
+const uint8_t PACKET_ADDR         = 9;

 // where in EEPROM our node id is stored
 const int id_address = 0;
@@ -56,6 +57,8 @@

 // location in space
 int32_t g_pos[3];
+int8_t  g_ring = -1;
+int8_t  g_arm = -1;

 // Gamma correction table in progmem
 const uint8_t PROGMEM gamma[] = {


Broadcast LoRa data via UDP

Broadcast LoRa data via UDP

--- experiments/esp8266_monitor/esp8266_monitor.ino
+++ experiments/esp8266_monitor/esp8266_monitor.ino
@@ -1,21 +1,24 @@
-
-#include "config.h"
-#include "SSD1306.h" // alias for `#include "SSD1306Wire.h"`
-#include "Payload.h"
-#include <ESP8266WiFi.h>
-
-//how many clients should be able to telnet to this ESP8266
-#define MAX_SRV_CLIENTS 2

-WiFiServer server(23);
-WiFiClient serverClients[MAX_SRV_CLIENTS];
+#include <ESP8266WiFi.h>
+#include <WiFiUdp.h>
+#include "config.h"
+#include "SSD1306.h"
+#include "Payload.h"
+
+
+// A UDP instance to let us send and receive packets over UDP
+WiFiUDP Udp;
+
+// Multicast declarations
+IPAddress ipMulti(239, 0, 0, 57);
+unsigned int portMulti = 12345;      // local port to listen on
+

 // Initialize the OLED display using Wire library
 SSD1306  display(0x3c, 4, 5);

 Payload rx_payload = Payload();
-Payload ping_payload = Payload();
 uint8_t input_string[Payload_SIZE];
 uint8_t payload_state = 0;
 uint8_t serial_byte_count = 0;
@@ -25,7 +28,7 @@

 const long ping_interval = 3000;
 unsigned long ping_last = 0;
-uint8_t ping_msg_id = 0;
+

 void setup() {
   Serial.begin(115200);
@@ -35,8 +38,6 @@
   display.init();
   display.flipScreenVertically();
   display.setFont(ArialMT_Plain_16);
-
-  ping_payload.setDeviceId(254);

   rx_payload.setMsgId(254);
   rx_payload.setA(1234);
@@ -58,23 +59,17 @@
     while(1) delay(500);
   }

-  // Socket server.
-  server.begin();
-  server.setNoDelay(true);
-
-  Serial.print("Ready! Use 'netcat ");
-  Serial.print(WiFi.localIP());
-  Serial.println(" 23' to connect");
+  Serial.print("Connected to: ");
+  Serial.println(WiFi.localIP());
+  Serial.println("Ready! Listen for UDP broadcasts on 239.0.0.57 port 12345");
 }

 void loop() {
-

   // Read the data from the LoRa receiver.
   while (Serial.available()) {
     // get the new byte:
     uint8_t in = (uint8_t) Serial.read();
-

     if (payload_state == 0) {
       // Check for the start of the payload
@@ -96,55 +91,11 @@
         serial_byte_count = 0;
         payload_state = 2;
         rx_payload.unserialize(input_string);
-//        Serial.println();
-//        Serial.print(rx_payload.getDeviceId()); Serial.print(", ");
-//        Serial.print(rx_payload.getMsgId()); Serial.print(", ");
-//        Serial.print(rx_payload.getA()); Serial.print(", ");
-//        Serial.print(rx_payload.getB()); Serial.print(", ");
-//        Serial.print(rx_payload.getC()); Serial.print(", ");
-//        Serial.print(rx_payload.getD()); Serial.print(", ");
-//        Serial.print(rx_payload.getE()); Serial.print(", ");
-//        Serial.println(rx_payload.getF());
-
       }
     } else {
       // Passthru other serial messages.
       //Serial.print(char(in));

-    }
-  }
-
-  uint8_t i;
-  // check if there are any new TCP clients
-  if (server.hasClient()) {
-    uint8_t allocated = 0;
-    for (i = 0; i < MAX_SRV_CLIENTS; i++) {
-      if (allocated == 0) {
-        //find free/disconnected spot
-        if (!serverClients[i] || !serverClients[i].connected()) {
-          if (serverClients[i]) {
-            serverClients[i].stop();
-          }
-          serverClients[i] = server.available();
-          serverClients[i].setNoDelay(true);
-          serverClients[i].setTimeout(100);
-          Serial.print("New client: "); Serial.println(i);
-          allocated = 1;
-        }
-      }
-    }
-    //no free/disconnected spot so reject
-    WiFiClient serverClient = server.available();
-    serverClient.stop();
-  }
-
-  // check clients for data
-  for (i = 0; i < MAX_SRV_CLIENTS; i++) {
-    if (serverClients[i] && serverClients[i].connected()) {
-      if (serverClients[i].available()) {
-        // Ignore client input
-        serverClients[i].flush();
-      }
     }
   }

@@ -156,51 +107,13 @@

     // No need to ping if we're sending real data.
     ping_last = currentMillis;
-
-    size_t len = Payload_SIZE;
-    uint8_t sbuf[len];
-    rx_payload.serialize(sbuf);
-
-    // push payload data to all connected clients
-    for(i = 0; i < MAX_SRV_CLIENTS; i++){
-      if (serverClients[i] && serverClients[i].connected()) {
-        if (!serverClients[i].write('\t')) { // Payload start byte
-          serverClients[i].stop();
-        }
-        else {
-          serverClients[i].write(sbuf, len);
-          serverClients[i].write('\n');
-        }
-      }
-    }
+    broadcast_udp();
   }
-  // Keep TCP clients connected with a ping.
+  // Send the data continually, as its UDP some may get missed.
   else if (currentMillis - ping_last >= ping_interval) {
     ping_last = currentMillis;
-
-    ping_payload.setMsgId(++ping_msg_id);
-    //ping_payload.setF(1234);
-    // Send a ping message.
-    size_t len = Payload_SIZE;
-    uint8_t sbuf[len];
-    ping_payload.serialize(sbuf);
-
-    // push payload data to all connected clients
-    for(i = 0; i < MAX_SRV_CLIENTS; i++){
-      if (serverClients[i] && serverClients[i].connected()) {
-        if (!serverClients[i].write('\t')) { // Payload start byte
-          serverClients[i].stop();
-          Serial.print("Stopped: ");
-          Serial.println(i);
-        }
-        else {
-          serverClients[i].write(sbuf, len);
-          serverClients[i].write('\n');
-        }
-      }
-    }
+    broadcast_udp();
   }
-

   // Update the display
   if (currentMillis - previousMillis >= interval) {
@@ -220,3 +133,15 @@

 }

+void broadcast_udp() {
+    size_t len = Payload_SIZE;
+    uint8_t sbuf[len];
+    rx_payload.serialize(sbuf);
+    Udp.beginPacketMulticast(ipMulti, portMulti, WiFi.localIP());
+    Udp.write('\t'); // Payload start byte
+    Udp.write(sbuf, len);
+    Udp.write('\n');
+    Udp.endPacket();
+    Udp.stop();
+}
+


Add conversion from serial string to actual values functionality

--- Arduino_Code/Arduino_Code.ino
+++ Arduino_Code/Arduino_Code.ino
@@ -18,6 +18,7 @@

  String recString = "";
  boolean newAvail = false;
+ String recMessage = "";

 void setup() {
  Serial.begin(9600);
@@ -90,14 +91,43 @@
       {
         endIndex = recString.indexOf("/n");
       }
-      //PROCESS STRING
+      //PROCESS MESSAGE
       if (recString.charAt(0) == 'm') {
-        //Message Processing
-        Serial.println("I have recieved a message");
+        recMessage= recString.substring(2, endIndex);
+        Serial.print("Received Message:");
+        Serial.println(recMessage);
+
+      //PROCESS SEQUENCE
       }
       if (recString.charAt(0) == 's') {
-        //Sequence Processing
         Serial.println("I have received a sequence");
+        Serial.print("It contains this many digits: ");
+        int digits = (recString.length()-1)/2;
+        Serial.println(digits);
+        /*
+        int* seq = new int[(recString.length()-1)/2];
+        Serial.println(sizeof(*seq));
+        for (int i = 2; i < recString.length(); i++)
+        {
+        }
+        */
+        int seqArr[digits];
+        for (int i = 2; i <= (digits*2); i += 2)
+        {
+          seqArr[i/2 -1] = recString.charAt(i) - '0';
+        }
+        /*Verify that you can actually create arrays of variable size
+        Serial.print("Created array size: ");
+        Serial.println(sizeof(seqArr) / sizeof(int));
+        */
+        //Test Sequence Array
+        for (int i = 0; i < digits; i ++)
+        {
+          Serial.println(seqArr[i]);
+        }
+
+
+
       }


BabelFish: Also accept bare CR (\r, 0x0D, ^M) as newline for commands

Using picoterm on OSX sends just '\r' (CR, ^M, 0x0D) when hitting the
enter/return key. (Unless picoterm's output mapping changes it with
"--omap crlf". But that is annoying.)

This isn't picoterm's fault but how the Terminal window behaves in
"raw" mode. Same behavior on Linux. Just let BabelFish accept these.

If both CR and LF are sent, the second will be an empty line for
doCommand() and nothing is done with that.

--- Utils/BabelFish/BabelFish.ino
+++ Utils/BabelFish/BabelFish.ino
@@ -291,7 +291,7 @@
       byte next = Serial.read();
       if (lineIndex < sizeof line)
         line[lineIndex++] = next;
-      if (next == '\n') {
+      if (next == '\r' || next == '\n') {
         line[lineIndex-1] = '\0';
         doCommand(line);
         lineIndex = 0;


get rid of - in SSID

get rid of - in SSID

--- WS2812ArtNet/WS2812ArtNet.ino
+++ WS2812ArtNet/WS2812ArtNet.ino
@@ -273,7 +273,7 @@
   WiFi.softAPmacAddress(mac);

-  String macID = String(mac[WL_MAC_ADDR_LENGTH - 2], HEX) + String("-") + String(mac[WL_MAC_ADDR_LENGTH - 1], HEX);
+  String macID = String(mac[WL_MAC_ADDR_LENGTH - 2], HEX) + String(mac[WL_MAC_ADDR_LENGTH - 1], HEX);

   macID.toUpperCase();
   String UniqueSystemName = String(AP_PREFIX) + macID;


Add color view signals

Add color view signals

--- skittle-color-sorter.ino
+++ skittle-color-sorter.ino
@@ -18,6 +18,9 @@
 //    Color View Red pin to diginal pin 7
 //    Color View Green pin to diginal pin 9
 //    Color View Blue pin to diginal pin 6
+#define PIN_COLOR_RED 7
+#define PIN_COLOR_GREEN 9
+#define PIN_COLOR_BLUE 6
 // * LCD
 //    RS pin to digital pin 12
 #define PIN_LCD_RS 12
@@ -40,12 +43,16 @@

 #define C_HOLE_CLEAR 300 // The clear value used to determine the hole's arrival
 #define C_IDEAL_CLEAR 96 // The ideal clear value for color detection
-#define C_ALLOWED_COLOR_VARIANCE 64 // The allowed color variance
+#define C_ALLOWED_COLOR_VARIANCE 64 // Allowed color variance for color detection
+
+#define F_TOP_SERVO_TIMEOUT_ENABLED true // Enable the timeout for the top servo
+#define C_TOP_SERVO_TIMEOUT 6000 // Timeout to determine if the top servo is stuck
+
+#define C_COLOR_SIGNAL_TIME 1000 // Each Skittle gets 1s color view signal

 #define F_CALIBRATING false // Is calibration in progress

-const boolean topServoTimeoutEnable = true; // Enable the timeout for the top servo
-const int topServoTimeout = 6000; // Timeout to determine if the top servo is stuck
+

 // Include libraries
 #include <LiquidCrystal.h>      // LCD display
@@ -73,10 +80,10 @@
 // Create the color sensor object
 Adafruit_TCS34725 tcs = Adafruit_TCS34725(C_ATIME, TCS34725_GAIN_1X);

-// The number of skittles sorted
-int skittleCount = 0;
-// Time when the last skittle was being sorted
-unsigned long lastSkittleTime = 0;
+
+int skittleCount = 0; // The number of skittles sorted
+unsigned long lastSkittleTime = 0; // Time when the last skittle was being sorted
+int sortingResult = -1; // The sorting result, this number is the index for colorList

 void setup() {
   // Set up the serial for debugging purposes
@@ -104,10 +111,9 @@
   // Set the speed of the top servo
   // with 0 being full-speed in one direction, 180 being full speed in the other, and a value near 90 being no movement.
   servoTop.write(reverseDirection ? 180 : 0);
-  // servoTop.write(180);

   // If the top servo gets stuck
-  if (topServoTimeoutEnable && millis() - lastSkittleTime > topServoTimeout) {
+  if (F_TOP_SERVO_TIMEOUT_ENABLED && millis() - lastSkittleTime > C_TOP_SERVO_TIMEOUT) {
     Serial.println("Top servo is stuck; Direction reversed.");
     // Reserve the top servo's direction
     reverseDirection = true;
@@ -115,8 +121,8 @@
     lastSkittleTime = millis();
   }

-  if (topServoTimeoutEnable && reverseDirection && millis() - lastSkittleTime > 500) {
-    // Set direction back to normal after .5s
+  if (F_TOP_SERVO_TIMEOUT_ENABLED && reverseDirection && millis() - lastSkittleTime > 1000) {
+    // Set direction back to normal after 1s
     reverseDirection = false;
   }

@@ -188,9 +194,9 @@
     }

     if (colors.c > C_HOLE_CLEAR) {
-
+
       best_color.maximize(); // Maximize color
-
+
       if (best_color.compare(C_COLOR_EMPTY).aggregate() < 16) {
         // If this is an empty hole.
         Serial.println("Empty hole");
@@ -206,35 +212,14 @@
         } else {

           int min_diff = C_ALLOWED_COLOR_VARIANCE;
-          int result = -1;
+          sortingResult = -1;
           for (int i = 0; i < sizeof(colorList) / 8; i++) {
             C_Color diff = best_color.compare(colorList[i]);
             int agg = diff.aggregate();
             if (agg < min_diff) {
               min_diff = agg;
-              result = i;
+              sortingResult = i;
             }
-          }
-
-          switch(result){
-            case 0:
-              Serial.println("RED");
-              break;
-            case 1:
-              Serial.println("GREEN");
-              break;
-            case 2:
-              Serial.println("YELLOW");
-              break;
-            case 3:
-              Serial.println("PURPLE");
-              break;
-            case 4:
-              Serial.println("ORANGE");
-              break;
-            default:
-              Serial.println("Unknown color");
-              break;
           }

         }
@@ -252,6 +237,59 @@
   // printColors(r, g, b, c);

+}
+
+void updateColorView() {
+  static int oldSortingResult = -1;
+  if (sortingResult != oldSortingResult) {
+    oldSortingResult = sortingResult;
+    switch (sortingResult) {
+      case 0:
+        Serial.println("RED");
+        analogWrite(PIN_COLOR_RED, 255);
+        analogWrite(PIN_COLOR_GREEN, 0);
+        analogWrite(PIN_COLOR_BLUE, 0);
+        break;
+      case 1:
+        Serial.println("GREEN");
+        analogWrite(PIN_COLOR_RED, 0);
+        analogWrite(PIN_COLOR_GREEN, 255);
+        analogWrite(PIN_COLOR_BLUE, 0);
+        break;
+      case 2:
+        Serial.println("YELLOW");
+        analogWrite(PIN_COLOR_RED, 255);
+        analogWrite(PIN_COLOR_GREEN, 255);
+        analogWrite(PIN_COLOR_BLUE, 0);
+        break;
+      case 3:
+        Serial.println("PURPLE");
+        analogWrite(PIN_COLOR_RED, 128);
+        analogWrite(PIN_COLOR_GREEN, 32);
+        analogWrite(PIN_COLOR_BLUE, 128);
+        break;
+      case 4:
+        Serial.println("ORANGE");
+        analogWrite(PIN_COLOR_RED, 255);
+        analogWrite(PIN_COLOR_GREEN, 128);
+        analogWrite(PIN_COLOR_BLUE, 32);
+        break;
+      default:
+        Serial.println("Unknown color");
+        analogWrite(PIN_COLOR_RED, 0);
+        analogWrite(PIN_COLOR_GREEN, 0);
+        analogWrite(PIN_COLOR_BLUE, 0);
+        break;
+    }
+  } else {
+    // Check if the color view signal has lasted enough time
+    if (millis() - lastSkittleTime > C_COLOR_SIGNAL_TIME) {
+      // Set it back to black
+      analogWrite(PIN_COLOR_RED, 0);
+      analogWrite(PIN_COLOR_GREEN, 0);
+      analogWrite(PIN_COLOR_BLUE, 0);
+    }
+  }
 }

 void loop() {
@@ -268,4 +306,7 @@
   // Update the color sensor
   updateColorSensor();

-}
+  // Update the color view LED output
+  updateColorView();
+
+}


fixed the file format descriptions

fixed the file format descriptions

--- Elcano_C4_Planner/Elcano_C4_Planner.ino
+++ Elcano_C4_Planner/Elcano_C4_Planner.ino
@@ -38,19 +38,19 @@
 -----------------------

 This file provides the latitude and longitude coordinates for each of the maps, followed
-by the file name for that map. A newline is created after each map.
+by the file name for that map. Commas also separate each map.

 The format should be as follows:

-latitude_0,longitude_0,filename_0.txt\n
-...\n
-latitude_n,longitude_n,filename_n.txt\n
+latitude_0,longitude_0,filename_0.txt,
+...,
+latitude_n,longitude_n,filename_n.txt

 A practical example would look like this:

-47.758949,-122.190746,map_47_758949_-122_190746.txt\n
-47.6213,-122.3509,map_47_6213_-122_3509.txt\n
+47.758949,-122.190746,map_47_758949_-122_190746.txt,
+47.6213,-122.3509,map_47_6213_-122_3509.txt

 -----------------------
@@ -70,18 +70,18 @@
 Distance is an array of longs holding the distances from this node to each of the destinations
   in millimeters.

-The file format is a comma delimited list of the values in the struct, with a newline after each.
+The file format is a comma delimited list of the values in the struct, with a comma after each junction.
 It should be formated as follows:

-east_mm_0,north_mm_0,destination_0[0],destination_0[1],destination_0[2],destination_0[3],Distance_0[0],Distance_0[1],Distance_0[2],Distance_0[3]\n
-...\n
-east_mm_n,north_mm_n,destination_n[0],destination_n[1],destination_n[2],destination_n[3],Distance_n[0],Distance_n[1],Distance_n[2],Distance_n[3]\n
+east_mm_0,north_mm_0,destination_0[0],destination_0[1],destination_0[2],destination_0[3],Distance_0[0],Distance_0[1],Distance_0[2],Distance_0[3],
+...,
+east_mm_n,north_mm_n,destination_n[0],destination_n[1],destination_n[2],destination_n[3],Distance_n[0],Distance_n[1],Distance_n[2],Distance_n[3],

 A practical example would look like this:

--183969,380865,1,2,END,END,1,1,1,1\n
--73039,380865,0,3,7,END,1,1,1,1\n
--182101,338388,0,3,4,5,1,1,1,1\n
+-183969,380865,1,2,END,END,1,1,1,1,
+-73039,380865,0,3,7,END,1,1,1,1,
+-182101,338388,0,3,4,5,1,1,1,1

 /*---------------------------------------------------------------------------------------


LED制御の変更

LED制御の変更

--- 2_example/example16_ir_in/example16_ir_in.ino
+++ 2_example/example16_ir_in/example16_ir_in.ino
@@ -18,7 +18,6 @@
 void setup(){                               // 起動時に一度だけ実行する関数
     pinMode(PIN_IR_IN, INPUT);              // IRセンサの入力ポートの設定
     pinMode(PIN_LED,OUTPUT);                // LEDを接続したポートを出力に
-    digitalWrite(PIN_LED,HIGH);             // LEDを点灯状態に
     Serial.begin(9600);                     // 動作確認のためのシリアル出力開始
     Serial.println("Example 16 ir_in");     // 「Example 16」をシリアル出力表示
     WiFi.mode(WIFI_STA);                    // 無線LANをSTAモードに設定
@@ -35,8 +34,10 @@
     byte data[DATA_LEN];                    // リモコン信号データ用
     int len,len8;                           // 信号長 len(bits),len8（bytes）
     byte i;
-
+
+    digitalWrite(PIN_LED,LOW);              // LEDを消灯状態に
     len = ir_read(data, DATA_LEN, 255);     // 赤外線信号を読み取る
+    digitalWrite(PIN_LED,HIGH);             // LEDを点灯状態に
     len8 = len / 8;                         // ビット長を8で割った値をlen8へ代入
     if(len%8) len8++;                       // 余りがあった場合に1バイトを加算
     if(len8>=2){                            // 2バイト以上の時に以下を実行


bugfix ongedaan. was niet fout

bugfix ongedaan. was niet fout


debug

debug

--- glass/glass.ino
+++ glass/glass.ino
@@ -100,7 +100,7 @@
   // monitor the user input all the time
   // so everytime when loop executes, or at least in some states
   // we will see the results
-  if (state == IDLE || state == CONNECTED) {
+  if (state == IDLE || state == CONNECTED || state == VERIFY) {
     g = sliderEvent(&sliderDelta, &sliderVal);
     if (g!= 0) {
       printGesture(g, &sliderDelta, &sliderVal);


Added comments, grouped like functions.

Added comments, grouped like functions.

--- arduboy-game/arduboy-game.ino
+++ arduboy-game/arduboy-game.ino
@@ -25,6 +25,10 @@
 #include <avr/pgmspace.h>
 #include <EEPROM.h>

+/*******************************************************************************
+ * GLOBALS (OTHERS IN globals.h                                                *
+ *******************************************************************************/
+
 // Bullet array
 Bullet playerBullets[MAX_PLAYER_BULLETS];

@@ -32,18 +36,11 @@
 Enemy enemies[MAX_ENEMIES],
       boss;

-void resetPlayer() {
-    playerX = MIN_PLAYER_X;
-    playerY = 32;
-    playerFrame = 2;
-    playerDying = 0;
-    playerGunCharge = MAX_GUN_CHARGE;
-}
-
 /*******************************************************************************
- * MUSIC / SOUNDS                                                              *
+ * MUSIC / SOUND FUNCTIONS                                                     *
  *******************************************************************************/

+// Play the specified song.
 void playMusic(byte song) {
     if (! soundOn) {
       return;
@@ -78,69 +75,44 @@
     }
 }

+// Stop any music that is currently playing.
 void stopMusic(){
   arduboy.tunes.stopScore();
 }

+// Determine whether to play A button shoot tone.
 bool shouldPlayAButtonTone() {
   return (inGameAButtonLastPress > (inGameFrame - 20));
 }

+// Determine whether to play B button shoot tone.
 bool shouldPlayBButtonTone() {
   return (inGameBButtonLastPress > (inGameFrame - 50));
-}
-
-void redAlert() {
-  arduboy.clear();
-
-  drawChrs(5, 30, playerWon2, 125);
-  delay(3000);
-  for (byte i = 1; i < 7; i++) {
-    byte color = i % 2;
-    arduboy.fillRect(0,0,128,64, color);
-    display();
-
-    for (byte z = 1; z < 150 ; z++) {
-      playTone(z, 10);
-      delay(3);
-    }
-  }
-
-  delay(250);
-}
-
-void explode(byte x, byte y, byte dying) {
-  byte rnd = random(1, 15),
-       _dying = dying + rnd;
-
-  playTone(_dying * 5, 10);
-
-  if (inGameFrame % 2 == 0) {
-    arduboy.drawCircle(x, y, dying + rnd, 1);
-    arduboy.drawCircle(x, y, _dying - rnd, 1);
-    arduboy.drawCircle(x, y, _dying - rnd + 5, 1);
-  }
 }

 /*******************************************************************************
  * UTILITY FUNCTIONS                                                           *
  *******************************************************************************/

+// Redraw the screen.
 void display() {
   arduboy.display();
 }

+// Display message at specified location in specified font size.
 void printText(char *message, byte x, byte y, byte textSize) {
   arduboy.setCursor(x, y);
   arduboy.setTextSize(textSize);
   arduboy.print(message);
 }

+// Redraw the screen after a short delay.
 void delayAndDisplay() {
   delay(250);
   display();
 }

+// Use a typewriter effect to display characters from the bitmap font.
 void drawChrs(byte cPos, byte yPos, const uint8_t *letters, unsigned long delayTimer) {
   byte curs = cPos,
        strLen = pgm_read_byte(letters),
@@ -174,7 +146,11 @@
   }
 }

-
+/*******************************************************************************
+ * PRE-GAME SCREENS AND SUPPORTING FUNCTIONS                                   *
+ *******************************************************************************/
+
+// Display the intro screen (Modus Logo) shown once on power on.
 void introScreen() {
   arduboy.clear();
   drawBitmap(2, 8, modusLogo, 0);
@@ -187,11 +163,7 @@
   delay(2750);
 }

-void drawRectAroundPlayMenuOption(byte color) {
-  arduboy.drawRect(2, 48, 28, 12, color);
-}
-
-
+// Display the main title screen, time out if user doesn't choose an option
 byte titleScreen() {
   arduboy.clear();

@@ -211,10 +183,10 @@
     isInitialTitleScreen = false;
   }

-  byte selectedItem = TITLE_PLAY_GAME;
+  byte selectedItem = TITLE_PLAY_GAME,
+       shipTone = 100;
   unsigned long totalDelay = 0;
   long lastDebounceTime = millis();  // the last time the button was pressed
-  byte shipTone = 100;
   float earthY = 56;

   for (float y = 64; y > 16; y -= 0.2f) {
@@ -269,15 +241,18 @@
   return (totalDelay >= ATTRACT_MODE_TIMEOUT ? TITLE_TIMEOUT : selectedItem);
 }

+// Select (color = 1) / deselect (color = 0) title screen Play option.
+void drawRectAroundPlayMenuOption(byte color) {
+  arduboy.drawRect(2, 48, 28, 12, color);
+}
+
+// Select (color = 1) / deselect (color = 0) title screen Settings option.
 void drawRectAroundSettingsMenuOption(byte color) {
   arduboy.drawRect(32, 48, 42, 12, color);
 }

+// Handle clicks on left button to navigate title screen items.
 byte titleMenuLeftButton(byte selectedItem) {
-  /**
-     Handle clicks on the left button
-     to navigate through main menu items.
-  */
   switch (selectedItem) {
     case TITLE_SETTINGS:
       arduboy.drawRect(77, 48, 50, 12, 0);
@@ -297,12 +272,8 @@
   }
 }

+// Handle clicks on right button to navigate title screen items.
 byte titleMenuRightButton(byte selectedItem) {
-  /**
-     Handle clicks on the right button
-     to navigate through main menu items.
-  */
-
   switch (selectedItem) {
     case TITLE_PLAY_GAME:
       drawRectAroundPlayMenuOption(0);
@@ -322,6 +293,7 @@
   }
 }

+// Display the high score screen (used in attract loop and after game over).
 void highScoreScreen() {
   unsigned short totalDelay = 0;
   char hiInitials[4];
@@ -362,6 +334,7 @@
   }
 }

+// Display the credits screen using typewriter / bitmap font effect.
 void creditsScreen() {
   byte creditsDelay = 30;

@@ -388,10 +361,7 @@
   delay(2000);
 }

-void drawBoxAroundSoundSetting(byte color) {
-   arduboy.drawRect(17, 22, 35, 13, color);
-}
-
+// Display the settings screen.
 void settingsScreen() {
   long lastDebounceTime = millis();  // the last time the button was pressed
   bool exit_settings_menu = false;
@@ -486,11 +456,22 @@
   }
 }

+// Select (color = 1) / deselect (color = 0)  the sound item for the settings screen.
+void drawBoxAroundSoundSetting(byte color) {
+   arduboy.drawRect(17, 22, 35, 13, color);
+}
+
+// Toggle the sound on / off message for the settings screen.
 void printsoundOnOff() {
   printText(soundOn ? "SOUND ON " : "SOUND OFF", 20, 25, 1);
   drawBoxAroundSoundSetting(1);
 }

+/*******************************************************************************
+ * IN GAME SCREENS AND SUPPORTING FUNCTIONS                                    *
+ *******************************************************************************/
+
+// Play the game!
 void playGame() {
   stopMusic();

@@ -504,8 +485,8 @@
   isBossAlive = false;
   currentKills = 0;

-  byte spawnedBoss = 0;
-  byte currentIteration = 0;
+  byte spawnedBoss = 0,
+       currentIteration = 0;
   bool iterationEnding = false;

   resetEnemies();
@@ -620,22 +601,69 @@
   stopMusic();
 }

+// Run initial red alert screen flash / sound effect.
+void redAlert() {
+  arduboy.clear();
+
+  drawChrs(5, 30, playerWon2, 125);
+  delay(3000);
+  for (byte i = 1; i < 7; i++) {
+    byte color = i % 2;
+    arduboy.fillRect(0,0,128,64, color);
+    display();
+
+    for (byte z = 1; z < 150 ; z++) {
+      playTone(z, 10);
+      delay(3);
+    }
+  }
+
+  delay(250);
+}
+
+// Reset the player to initial state after they lose a life.
+void resetPlayer() {
+    playerX = MIN_PLAYER_X;
+    playerY = 32;
+    playerFrame = 2;
+    playerDying = 0;
+    playerGunCharge = MAX_GUN_CHARGE;
+}
+
+// Draw circles for explosion centered at x, y with radius determined by 'dying'.
+void explode(byte x, byte y, byte dying) {
+  byte rnd = random(1, 15),
+       _dying = dying + rnd;
+
+  playTone(_dying * 5, 10);
+
+  if (inGameFrame % 2 == 0) {
+    arduboy.drawCircle(x, y, dying + rnd, 1);
+    arduboy.drawCircle(x, y, _dying - rnd, 1);
+    arduboy.drawCircle(x, y, _dying - rnd + 5, 1);
+  }
+}
+
+// Display the player's gun temperature as a bar.
 void drawGunTemp() {
   arduboy.drawRect(40, 1, 40, 5, 1);
   arduboy.fillRect(40, 1, (playerGunCharge), 5, 1);
 }

+// Display the current score with leading 0 padding.
 void drawScore() {
   sprintf(textBuf, "%06lu", score);
   printText(textBuf, 0, 0, 1);
 }

+// Display the starfield.
 void drawStarLayer() {
   for (byte i = 0; i < NUM_STARS; i++) {
     arduboy.drawFastHLine(starX[i], starY[i], starWidth[i], 1);
   }
 }

+// Display one icon per player life remaining.
 void drawLives() {
   for (byte i = 0; i < MAX_LIVES; i++) {
     if (i < livesRemaining) {
@@ -644,6 +672,7 @@
   }
 }

+// Display the player's ship and update its position.
 void drawPlayerShip() {
   if (playerDying == 0) {
     if (arduboy.pressed(RIGHT_BUTTON) && (playerX < MAX_PLAYER_X)) {
@@ -743,6 +772,7 @@
   }
 }

+// Perform calculations required for enemy bullets.
 void handleEnemyBullets() {
   for (byte i = 0; i < MAX_ENEMIES; i++) {
     if ((enemies[i].bullets[0].isVisible()) && (enemies[i].bullets[0].isHittingObject(playerX, playerY, PLAYER_SIZE, PLAYER_SIZE))) {
@@ -758,6 +788,7 @@
   }
 }

+// Perform calculations required for boss bullets.
 void handleBossBullets() {
   if (isBossAlive) {
     for (byte i = 0; i < MAX_BOSS_BULLETS; i++) {
@@ -775,6 +806,8 @@
   }
 }

+// Perform calculations required for player bullets.  Returns true if
+// player kills the 3rd boss to end the wave.
 bool handlePlayerBullets() {
   for (byte i = 0; i < MAX_PLAYER_BULLETS; i++) {
     if (playerBullets[i].isVisible()) {
@@ -825,6 +858,69 @@
   return false;
 }

+// Reset the enemies to the initial state.
+void resetEnemies() {
+  for (byte i = 0; i < MAX_ENEMIES; i++) {
+    enemies[i].health = 0;
+    enemies[i].bullets[0].hide();
+  }
+}
+
+// Reset the boss to the initial state.
+void resetBoss() {
+  boss.health = 0;
+  boss.dying = 0;
+  for (byte i = 0; i < MAX_BOSS_BULLETS; i++) {
+    boss.bullets[i].hide();
+  }
+}
+
+// Reset the player bullets to the initial state.
+void resetPlayerBullets() {
+  for (byte i = 0; i < MAX_PLAYER_BULLETS; i++) {
+    playerBullets[i].hide();
+  }
+}
+
+// Set initial starfield values.
+void createStarFieldVals() {
+  for (byte i = 0; i < NUM_STARS; i++) {
+      setStarValuesForIndex(i);
+  }
+}
+
+// Utility function for setting start field data.
+void setStarValuesForIndex(byte i) {
+  starX[i] = random(250);
+  starY[i] = random(11, 64);
+  starWidth[i] = random(1, 4);
+
+  if (starWidth[i] >= 3) {
+    starSpeed[i] = random(30, 40) * 0.01f;
+  }
+  else if (starWidth[i] >= 2) {
+    starSpeed[i] = random(18, 25) * 0.01f;
+  }
+  else {
+    starSpeed[i] = random(7, 12) * 0.01f;
+  }
+}
+
+// Set the starfield values for the next frame.
+void updateStarFieldVals() {
+  for (byte i = 0; i < NUM_STARS; i++) {
+    if (starX[i] < -1) {
+      setStarValuesForIndex(i);
+      starX[i] = 128 + random(20);
+      starY[i] = random(11, 64);
+    }
+    else {
+      starX[i] -= starSpeed[i];
+    }
+  }
+}
+
+// Player has completed a wave, show message and resume game.
 void playerWinsScreen() {
   byte creditsDelay = 40;

@@ -838,6 +934,11 @@
   redAlert();
 }

+/*******************************************************************************
+ * POST GAME SCREENS AND SUPPORTING FUNCTIONS                                  *
+ *******************************************************************************/
+
+// Game has ended.
 void gameOverScreen() {
   stopMusic();
   arduboy.clear();
@@ -853,12 +954,7 @@
   delay(4500);
 }

-void drawHighScoreEntryCursor(byte pos) {
-  arduboy.fillRect(44, 62, 10, 2, (pos == 0 ? 1 : 0));
-  arduboy.fillRect(56, 62, 10, 2, (pos == 1 ? 1 : 0));
-  arduboy.fillRect(68, 62, 10, 2, (pos == 2 ? 1 : 0));
-}
-
+// Has the game ended with a top 3 high score?
 byte isNewHighScore() {
   char hiScore[7];

@@ -872,6 +968,7 @@
   return NOT_NEW_HI_SCORE;
 }

+// Display the new high score screen and let player enter initials.
 void newHighScoreScreen(byte newHiPos) {
   long lastDebounceTime = millis();
   bool allDone = false;
@@ -967,6 +1064,14 @@
   persistHighScoreTable(false);
 }

+// Draw a cursor under currently selected high score letter.
+void drawHighScoreEntryCursor(byte pos) {
+  arduboy.fillRect(44, 62, 10, 2, (pos == 0 ? 1 : 0));
+  arduboy.fillRect(56, 62, 10, 2, (pos == 1 ? 1 : 0));
+  arduboy.fillRect(68, 62, 10, 2, (pos == 2 ? 1 : 0));
+}
+
+// Store the high score table in EEPROM, set initial data if none present.
 void persistHighScoreTable(bool firstTime) {
   for (byte i = 0; i < 27; i++) {
     EEPROM.write(i + 2, highScoreTable[i]);
@@ -977,6 +1082,7 @@
   }
 }

+// Wipe the high score table from EEPROM, revert to initial data.
 void resetHighScoreTable() {
   // Read it back into memory and overwrite what's in EEPROM
   // with data frem reset location
@@ -988,66 +1094,11 @@
   persistHighScoreTable(false);
 }

-void createStarFieldVals() {
-  for (byte i = 0; i < NUM_STARS; i++) {
-      setStarValuesForIndex(i);
-  }
-}
-
-void resetEnemies() {
-  for (byte i = 0; i < MAX_ENEMIES; i++) {
-    enemies[i].health = 0;
-    enemies[i].bullets[0].hide();
-  }
-}
-
-void resetBoss() {
-  boss.health = 0;
-  boss.dying = 0;
-  for (byte i = 0; i < MAX_BOSS_BULLETS; i++) {
-    boss.bullets[i].hide();
-  }
-}
-
-void resetPlayerBullets() {
-  for (byte i = 0; i < MAX_PLAYER_BULLETS; i++) {
-    playerBullets[i].hide();
-  }
-}
-
-void setStarValuesForIndex(byte i) {
-  starX[i] = random(250);
-  starY[i] = random(11, 64);
-  starWidth[i] = random(1, 4);
-
-  if (starWidth[i] >= 3) {
-    starSpeed[i] = random(30, 40) * 0.01f;
-  }
-  else if (starWidth[i] >= 2) {
-    starSpeed[i] = random(18, 25) * 0.01f;
-  }
-  else {
-    starSpeed[i] = random(7, 12) * 0.01f;
-  }
-}
-
-void updateStarFieldVals() {
-  for (byte i = 0; i < NUM_STARS; i++) {
-    if (starX[i] < -1) {
-      setStarValuesForIndex(i);
-      starX[i] = 128 + random(20);
-      starY[i] = random(11, 64);
-    }
-    else {
-      starX[i] -= starSpeed[i];
-    }
-  }
-}
-
 /*******************************************************************************
  * ENTRY POINTS                                                                *
  *******************************************************************************/

+// Runs once, initialization.
 void setup() {
   arduboy.beginNoLogo();

@@ -1099,6 +1150,7 @@
   alphabet[28] = exclamation;
 }

+// Main program loop, runs attract loop
 void loop() {
   byte newHiScorePos;


Updated game-over with smaller graphics

Updated game-over with smaller graphics

--- arduboy-game/arduboy-game.ino
+++ arduboy-game/arduboy-game.ino
@@ -27,7 +27,7 @@
 #include <EEPROM.h>

 #define DEBOUNCE_DELAY 100
-#define MAX_LIVES 4
+#define MAX_LIVES 0
 #define NUM_HIGH_SCORES 3
 #define NUM_STARS 15
 #define NOT_NEW_HI_SCORE 5
@@ -790,11 +790,12 @@
 void gameOverScreen() {
   arduboy.tunes.stopScore();
   arduboy.clear();
+
   drawBitmap(0, 23, gameOver, 0);
-  arduboy.drawFastHLine(0, 63, 36, 1);
-  printText("GAME", 40, 0, 2);
-  printText("OVER", 40, 40, 2);
-//  printText("dreams are lost!", 20, 50, 1);
+  arduboy.drawFastHLine(0, 63, 128, 1);
+
+  printText("GAME", 50, 5, 3);
+  printText("OVER", 50, 33, 3);
   arduboy.display();

   playMusic(4);


Make blinkelights a bit prettier

Make blinkelights a bit prettier

--- arduino-test/arduino-test.ino
+++ arduino-test/arduino-test.ino
@@ -47,6 +47,8 @@

 #define HALT_MASK (1<<6)

+uint_least32_t blinken_lights_a = 0, blinken_lights_b = 0;;
+
 void loop() {
     byte a0_7, a8_15, a16_24, ctrl;

@@ -59,14 +61,24 @@
     spi_communicate(MX7219_NOP, 0, 0x8);
     ctrl = spi_communicate(MX7219_NOP, 0);

-    spi_communicate(MX7219_DIGIT_0 + 0, ctrl);
-
     if(ctrl & HALT_MASK) {
+        spi_communicate(MX7219_DIGIT_0 + 0, ctrl);
         spi_communicate(MX7219_DIGIT_0 + 1, a0_7);
         spi_communicate(MX7219_DIGIT_0 + 2, a8_15);
         spi_communicate(MX7219_DIGIT_0 + 3, a16_24);
         spi_communicate(MX7219_DIGIT_0 + 4, chase & 0xff);
         spi_communicate(MX7219_DIGIT_0 + 5, (chase>>8) & 0xff);
+    } else {
+        for(int i=0; i<4; ++i) {
+            spi_communicate(
+                MX7219_DIGIT_0 + i,
+                (blinken_lights_a >> (i<<3)) & 0xff
+            );
+            spi_communicate(
+                MX7219_DIGIT_0 + 4 + i,
+                (blinken_lights_b >> (i<<3)) & 0xff
+            );
+        }
     }

     unsigned long now = millis();
@@ -83,11 +95,8 @@
             chase = 1;
         }

-        if(!(ctrl & HALT_MASK)) {
-            for(int i=1; i<=5; ++i) {
-                spi_communicate(MX7219_DIGIT_0 + i, random(0x100));
-            }
-        }
+        blinken_lights_a ^= 1UL << random(32);
+        blinken_lights_b ^= 1UL << random(32);
     }
 }


Fixing trigger conditions

Fixing trigger conditions

--- arduino/autofowl/autofowl.ino
+++ arduino/autofowl/autofowl.ino
@@ -368,13 +368,17 @@
   }

   // Determine if door should move up or down
-  if ( LightCurrent > LightThreshUp || between(ClockThreshDown, Now, ClockThreshUp) ) {
+  if ( DoorPosition != DOOR_POSITION_UP && (
+        ( between(ClockThreshDown, Now, ClockThreshUp) && LightCurrent > LightThreshDown ) ||
+        ( ! between(ClockThreshDown, Now, ClockThreshUp) && LightCurrent > LightThreshUp )
+       )
+    ) {

     // See if we could potentially change door position
     // If not, there's nothing else to do here
-    if ( DoorPosition == DOOR_POSITION_UP ) {
-      return;
-    }
+    // if ( DoorPosition == DOOR_POSITION_UP ) {
+    //   return;
+    // }

     LightThreshTicks++;
     updateLCD();
@@ -384,7 +388,11 @@
       // Done moving door so reset ticks
       LightThreshTicks = 0;
     }
-  } else if ( LightCurrent < LightThreshDown || ! between(ClockThreshDown, Now, ClockThreshUp) ) {
+  } else if ( DoorPosition != DOOR_POSITION_DOWN && (
+      ( ! between(ClockThreshDown, Now, ClockThreshUp) && LightCurrent < LightThreshUp ) ||
+      ( between(ClockThreshDown, Now, ClockThreshUp) && LightCurrent < LightThreshDown )
+    )
+  ) {

     // See if we could potentially change door position
     // If not, there's nothing else to do here
@@ -660,9 +668,6 @@
   Serial.print(" totalseconds(Now)=");
   Serial.print(totalseconds(Now), DEC);

-  Serial.print(" ShouldOpen=");
-  Serial.print(between(ClockThreshDown, Now, ClockThreshUp));
-
   Serial.print(" CurrentMode=");
   Serial.print(prettyMode());


Ajout références dans le code

Ajout références dans le code

--- arduino_code/arduino_code.ino
+++ arduino_code/arduino_code.ino
@@ -1,3 +1,8 @@
+//Merci aux documents d'aide fournis par AdaFruit avec le LiquidFlow Meter et le Thermistor
+//https://github.com/adafruit/Adafruit-Flow-Meter/blob/master/Adafruit_FlowMeter.pde
+//https://learn.adafruit.com/thermistor?view=all
+
+
 #include <Chrono.h>

 Chrono envoiMessage;
@@ -6,8 +11,6 @@
 #define input_wind A1
 #define input_fire A0
 #define resistor 10000
-
-

@@ -91,14 +94,12 @@
   }
   /////////////////////////////////////////////////////////////////////WIND

- // if ( envoiMessage.metro(10) ) {
     float read_wind;

     read_wind = analogRead(input_wind);

     Serial.print("wind ");
     Serial.println(read_wind);
-//  }
 }


Changed Version to 1.35. Changed DHT Pins to INPUT_PULLUP. But Pullup resistor of 5-10k ohm is required any way (depending on cable length). Added information about sensor min delay on startup. Added delay on startup to ensure DHTs are ready.

--- cellar-climate-controller.ino
+++ cellar-climate-controller.ino
@@ -203,7 +203,9 @@

 void setup() {
     pinMode(FAN_PIN_ON, OUTPUT);
-    pinMode(FAN_PIN_RPM,  INPUT);
+    pinMode(FAN_PIN_RPM, INPUT);
+    pinMode(DHT_PIN_OUTSIDE, INPUT_PULLUP);
+    pinMode(DHT_PIN_INSIDE, INPUT_PULLUP);

     attachInterrupt(digitalPinToInterrupt(FAN_PIN_RPM), rpm, RISING);

@@ -218,7 +220,7 @@
     lcd.setCursor(0, 0);
     lcd.print("***FanControl***");
     lcd.setCursor(0, 1);
-    lcd.print("***   1.34   ***");
+    lcd.print("***   1.35   ***");
     time = millis() - time;
     Serial.print("Took "); Serial.print(time); Serial.println(" ms");
     lcd.setBacklight(WHITE);
@@ -238,6 +240,7 @@
     Serial.print  ("Sensor:       "); Serial.println(sensor.name);
     Serial.print  ("Driver Ver:   "); Serial.println(sensor.version);
     Serial.print  ("Unique ID:    "); Serial.println(sensor.sensor_id);
+    Serial.print  ("Min Delay:    "); Serial.print(sensor.min_delay/1000); Serial.println(" ms");
     Serial.print  ("Max Value:    "); Serial.print(sensor.max_value); Serial.println(" *C");
     Serial.print  ("Min Value:    "); Serial.print(sensor.min_value); Serial.println(" *C");
     Serial.print  ("Resolution:   "); Serial.print(sensor.resolution); Serial.println(" *C");
@@ -249,6 +252,7 @@
     Serial.print  ("Sensor:       "); Serial.println(sensor.name);
     Serial.print  ("Driver Ver:   "); Serial.println(sensor.version);
     Serial.print  ("Unique ID:    "); Serial.println(sensor.sensor_id);
+    Serial.print  ("Min Delay:    "); Serial.print(sensor.min_delay/1000); Serial.println(" ms");
     Serial.print  ("Max Value:    "); Serial.print(sensor.max_value); Serial.println("%");
     Serial.print  ("Min Value:    "); Serial.print(sensor.min_value); Serial.println("%");
     Serial.print  ("Resolution:   "); Serial.print(sensor.resolution); Serial.println("%");
@@ -259,6 +263,7 @@
     Serial.print  ("Sensor:       "); Serial.println(sensor.name);
     Serial.print  ("Driver Ver:   "); Serial.println(sensor.version);
     Serial.print  ("Unique ID:    "); Serial.println(sensor.sensor_id);
+    Serial.print  ("Min Delay:    "); Serial.print(sensor.min_delay/1000); Serial.println(" ms");
     Serial.print  ("Max Value:    "); Serial.print(sensor.max_value); Serial.println(" *C");
     Serial.print  ("Min Value:    "); Serial.print(sensor.min_value); Serial.println(" *C");
     Serial.print  ("Resolution:   "); Serial.print(sensor.resolution); Serial.println(" *C");
@@ -270,6 +275,7 @@
     Serial.print  ("Sensor:       "); Serial.println(sensor.name);
     Serial.print  ("Driver Ver:   "); Serial.println(sensor.version);
     Serial.print  ("Unique ID:    "); Serial.println(sensor.sensor_id);
+    Serial.print  ("Min Delay:    "); Serial.print(sensor.min_delay/1000); Serial.println(" ms");
     Serial.print  ("Max Value:    "); Serial.print(sensor.max_value); Serial.println("%");
     Serial.print  ("Min Value:    "); Serial.print(sensor.min_value); Serial.println("%");
     Serial.print  ("Resolution:   "); Serial.print(sensor.resolution); Serial.println("%");
@@ -281,6 +287,7 @@
     pageCount = 1;
     showFirstPage = true;
     lastControl= millis();
+    delay(1000);
 }

 void loop() {


fix x360/joy switch

fix x360/joy switch

--- remap.ino
+++ remap.ino
@@ -222,15 +222,18 @@

 void inject(const Injector_t* injector, const GameCubeData_t* curDataP, const EllipticalData_t* ellipticalP) {
   didJoystick = false;
+  didX360 = false;

   if (currentUSBMode != injector->usbMode) {
     if (lastChangedModeTime + 1000 <= millis()) {
       if (currentUSBMode == &USBHID)
         USBHID.end();
-      else if (currentUSBMode == &XBox360)
+      else if (currentUSBMode == &XBox360)
         XBox360.end();
-      if (injector->usbMode == &USBHID)
-        beginUSBHID();
+
+      delay(100);
+      if (injector->usbMode == &USBHID)
+        beginUSBHID();
       else if (injector->usbMode == &XBox360)
         beginX360();
       currentUSBMode = injector->usbMode;
@@ -297,7 +300,7 @@
     Joystick.send();

   if (didX360)
-    XBox360.send();
+    XBox360.send();
 }

 #endif


COH-56

--- COHEAT2015/testBranch20150719/V0p2_Main/V0p2_Main.ino
+++ COHEAT2015/testBranch20150719/V0p2_Main/V0p2_Main.ino
@@ -219,17 +219,15 @@
     case OTRadioLink::FTp2_FullStatsIDL: case OTRadioLink::FTp2_FullStatsIDH:
       {
       // Maxmimum size is 8 including trailing CRC; fall through for possible further zeros trim.
-      buflen = min(initialBuflen, OTRadioLink::V0P2_MESSAGING_LEADING_FULL_STATS_MAX_BYTES_ON_WIRE);
+      buflen = min(initialBuflen, 8); // OTRadioLink::V0P2_MESSAGING_LEADING_FULL_STATS_MAX_BYTES_ON_WIRE);
       break;
       }
-
     case OTRadioLink::FTp2_JSONRaw:
       {
       // Maxmimum size is 56 including trailing CRC; fall through for possible further zeros trim.
       buflen = min(initialBuflen, MSG_JSON_ABS_MAX_LENGTH + 1);
       break;
       }
-
     case OTRadioLink::FTp2_FS20_native:
       {
       // Maxmimum size is 53 including trailing stats+CRC; fall through for possible further zeros trim.
@@ -237,7 +235,6 @@
       break;
       }
     }
-
   #if defined(CONFIG_TRAILING_ZEROS_FILTER_RX)
   // By default apply heuristic trim of trailing zeros to almost all message types.
   return(OTRadioLink::frameFilterTrailingZeros(buf, buflen)); // This will accept all messages.


Removed orphaned directory

Removed orphaned directory

--- TClab/TClab_Firmware/TClab_Firmware.ino
+++ TClab/TClab_Firmware/TClab_Firmware.ino
@@ -1,229 +0,0 @@
-/*
-  TCLab Temperature Control Lab Firmware
-  Jeffrey Kantor
-  October, 2017
-
-  This firmware is loaded into the Temperature Control Laboratory Arduino to
-  provide a high level interface to the Temperature Control Lab. The firmware
-  scans the serial port looking for case-insensitive commands:
-
-  Q1 int    set Heater 1, range 0 to 255 subject to limit
-  Q2 int    set Heater 2, range 0 to 255 subject to limit
-  T1        get Temperature T1, returns deg C as string
-  T2        get Temperature T2, returns dec C as string
-  VERSION   get firmware version string
-  X         enter sleep mode, reset required
-  A         software reset
-
-  Limits on the heater can be configured with the constants below.
-
-  Status is indicated by LED1 on the Temperature Control Lab. The status
-  conditions are:
-
-      LED1        LED1
-      Brightness  State
-      ----------  -----
-      dim         steady     Normal operation, heaters off
-      bright      steady     Normal operation, heaters on
-      dim         blinking   High temperature alarm on, heaters off
-      bright      blinking   High temperature alarm on, heaters on
-      dim         slow blink Sleep mode, needs hardware or software reset
-
-  The Temperature Control Lab enters sleep mode if it receives no host commands
-  during a timeout period (configure below), receives an "X" command, or receives
-  an unrecognized command from the host. Heaters are shutdown in sleep mode,
-  though temperature can continue to be monitored, and high temperature alarm is
-  still active on LED1.
-
-  Sleep mode is exited upon either a hardware reset with the button on the Arduino
-  board, or software reset with the "A" command.
-
-  The constants can be used to configure the firmware.
-*/
-
-// constants
-const String vers = "0.03";    // version of this firmware
-const int baud = 9600;         // serial baud rate
-const char sp = ' ';           // command separator
-const char nl = '\n';          // command terminator
-const int timeout = 300;       // device timeout in seconds
-
-// pin numbers corresponding to signals on the TC Lab Shield
-const int pinT1   = 0;         // T1
-const int pinT2   = 2;         // T2
-const int pinQ1   = 3;         // Q1
-const int pinQ2   = 5;         // Q2
-const int pinLED1 = 9;         // LED1
-
-// high limits expressed (units of pin values)
-const int limQ1   = 150;       // Q1 limit
-const int limQ2   = 150;       // Q2 limit
-const int limT1   = 310;       // T1 high alarm (50 deg C)
-const int limT2   = 310;       // T2 high alarm (50 deg C)
-
-// LED1 levels
-const int hiLED   =  50;       // hi LED
-const int loLED   = hiLED/16;  // lo LED
-
-// global variables
-char Buffer[64];               // buffer for parsing serial input
-String cmd;                    // command
-int pv;                        // command pin value
-int ledStatus;                 // 0: sleep mode
-                               // 1: loLED
-                               // 2: hiLED
-                               // 3: loLED blink
-                               // 4: hiLED blink
-int brdStatus = 1;             // board status 0:sleep, 1:normal
-int Q1 = 0;                    // last value written to Q1 pin
-int Q2 = 0;                    // last value written to Q2 poin
-int alarmStatus;               // hi temperature alarm status
-int tprev;                     // millis for last command
-
-// set Heater 1 to pv with hard limits imposed.
-void setHeater1(int pv) {
-  if (brdStatus > 0) {
-    Q1 = max(0, min(limQ1, pv));
-    analogWrite(pinQ1, Q1);
-  }
-}
-
-// set Heater 2 to pv with hard limits imposed.
-void setHeater2(int pv) {
-  if (brdStatus > 0) {
-    Q2 = max(0, min(limQ2, pv));
-    analogWrite(pinQ2, Q2);
-  }
-}
-
-void parseSerial(void) {
-  int ByteCount = Serial.readBytesUntil(nl,Buffer,sizeof(Buffer));
-  String read_ = String(Buffer);
-  memset(Buffer,0,sizeof(Buffer));
-
-  // separate command from associated data
-  int idx = read_.indexOf(sp);
-  cmd = read_.substring(0,idx);
-  cmd.trim();
-  cmd.toUpperCase();
-
-  // extract data. toInt() returns 0 on error
-  String data = read_.substring(idx+1);
-  data.trim();
-  pv = data.toInt();
-
-  // issue sleep command if we haven't heard from the host in timeout seconds
-  if (ByteCount > 0) {
-    tprev = millis();
-  } else {
-    if ((long) (millis() - tprev) > (long) 1000*timeout) {
-      cmd = "X";
-    }
-  }
-}
-
-void dispatchCommand(void) {
-  if (cmd == "A") {
-    brdStatus = 1;
-    setHeater1(0);
-    setHeater2(0);
-    Serial.println("OK");
-  }
-  else if (cmd == "Q1") {
-    setHeater1(pv);
-    Serial.println(Q1);
-  }
-  else if (cmd == "Q2") {
-    setHeater2(pv);
-    Serial.println(Q2);
-  }
-  else if (cmd == "T1") {
-    float mV = (float) analogRead(pinT1) * (3300.0/1024.0);
-    float degC = (mV - 500.0)/10.0;
-    Serial.println(degC);
-  }
-  else if (cmd == "T2") {
-    float mV = (float) analogRead(pinT2) * (3300.0/1024.0);
-    float degC = (mV - 500.0)/10.0;
-    Serial.println(degC);
-  }
-  else if (cmd == "VERSION") {
-    Serial.println("TClab Firmware Version " + vers);
-  }
-  else if ((cmd == "X") or (cmd.length() > 0)) {
-    setHeater1(0);
-    setHeater2(0);
-    brdStatus = 0;
-    Serial.println("Sleep");
-  }
-}
-
-void checkAlarm(void) {
-  if ((analogRead(pinT1) > limT1) or (analogRead(pinT2) > limT2)) {
-    alarmStatus = 1;
-  }
-  else {
-    alarmStatus = 0;
-  }
-}
-
-void updateStatus(void) {
-  // determine led status
-  ledStatus = brdStatus;
-  if ((Q1 > 0) or (Q2 > 0)) {
-    ledStatus = 2;
-  }
-  if (alarmStatus > 0) {
-    ledStatus = 3;
-    if ((Q1 > 0) or (Q2 > 0)) {
-      ledStatus = 4;
-    }
-  }
-  // update led depending on ledStatus
-  if (ledStatus == 0) {               // board is in sleep mode
-    if ((millis() % 5000) > 1000) {
-      analogWrite(pinLED1, 0);
-    } else {
-      analogWrite(pinLED1, loLED);
-    }
-  }
-  else if (ledStatus == 1) {          // normal operation, heaters off
-    analogWrite(pinLED1, loLED);
-  }
-  else if (ledStatus == 2) {          // normal operation, a heater on
-    analogWrite(pinLED1, hiLED);
-  }
-  else if (ledStatus == 3) {          // high temperature alarm, heater off
-    if ((millis() % 2000) > 1000) {
-      analogWrite(pinLED1, loLED);
-    } else {
-      analogWrite(pinLED1, 0);
-    }
-  }
-  else if (ledStatus == 4) {          // hight temperature alarm, a heater on
-    if ((millis() % 2000) > 1000) {
-      analogWrite(pinLED1, hiLED);
-    } else {
-      analogWrite(pinLED1, 0);
-    }
-  }
-}
-
-// arduino startup
-void setup() {
-  analogReference(EXTERNAL);
-  Serial.begin(baud);
-  while (!Serial) {
-    ; // wait for serial port to connect.
-  }
-  setHeater1(0);
-  setHeater2(0);
-}
-
-// arduino main event loop
-void loop() {
-  parseSerial();
-  dispatchCommand();
-  checkAlarm();
-  updateStatus();
-}


Refactor STATIC_INIT to reduce repetitive code

--- MapTheThings-Arduino/MapTheThings-Arduino.ino
+++ MapTheThings-Arduino/MapTheThings-Arduino.ino
@@ -270,54 +270,35 @@
   #else
     #define _memcpy memcpy
   #endif
+
+  #define SIZE_STRING(x) #x
+  #define STATIC_INIT(bytes, name, flag) \
+    static const PROGMEM u1_t name[] = bytes; \
+    static_assert(sizeof(settings.name) == sizeof(name), "DEVADDR needs to be " SIZE_STRING(sizeof(settings.name)) " bytes"); \
+    _memcpy(settings.name, name, sizeof(settings.name)); \
+    settings.flags |= flag; \
+    Log.Info(F("Overriding " #name " with static initializer: " #bytes CR)); \
+    debugLogData("Static " #name, settings.name, sizeof(settings.name)); \
+    write = true;
+
   #if defined(DEVADDR)
-    static const PROGMEM u1_t devaddr[] = DEVADDR;
-    static_assert(sizeof(settings.DevAddr) == sizeof(devaddr), "DEVADDR needs to be 4 bytes");
-    _memcpy(settings.DevAddr, devaddr, sizeof(settings.DevAddr));
-    settings.flags |= FLAG_DEV_ADDR_SET;
-    debugLogData("Setting DevAddr", settings.DevAddr, sizeof(settings.DevAddr));
-    write = true;
+    STATIC_INIT(DEVADDR, DevAddr, FLAG_DEV_ADDR_SET)
   #endif
   #if defined(NWKSKEY)
-    static const PROGMEM u1_t nwkskey[] = NWKSKEY;
-    static_assert(sizeof(settings.NwkSKey) == sizeof(nwkskey), "NWKSKEY needs to be 16 bytes");
-    _memcpy(settings.NwkSKey, nwkskey, sizeof(settings.NwkSKey));
-    settings.flags |= FLAG_NWK_SKEY_SET;
-    debugLogData("Setting NwkSKey", settings.NwkSKey, sizeof(settings.NwkSKey));
-    write = true;
+    STATIC_INIT(NWKSKEY, NwkSKey, FLAG_NWK_SKEY_SET)
   #endif
   #if defined(APPSKEY)
-    static const PROGMEM u1_t appskey[] = APPSKEY;
-    static_assert(sizeof(settings.AppSKey) == sizeof(appskey), "APPSKEY needs to be 16 bytes");
-    _memcpy(settings.AppSKey, appskey, sizeof(settings.AppSKey));
-    settings.flags |= FLAG_APP_SKEY_SET;
-    debugLogData("Setting AppSKey", settings.AppSKey, sizeof(settings.AppSKey));
-    write = true;
+    STATIC_INIT(APPSKEY, AppSKey, FLAG_APP_SKEY_SET)
   #endif

   #if defined(APPKEY)
-    static const PROGMEM u1_t appkey[] = APPKEY;
-    static_assert(sizeof(settings.AppKey) == sizeof(appkey), "APPKEY needs to be 16 bytes");
-    _memcpy(settings.AppKey, appkey, sizeof(settings.AppKey));
-    settings.flags |= FLAG_APP_KEY_SET;
-    debugLogData("Setting AppKey", settings.AppKey, sizeof(settings.AppKey));
-    write = true;
+    STATIC_INIT(APPKEY, AppKey, FLAG_APP_KEY_SET)
   #endif
   #if defined(APPEUI)
-    static const PROGMEM u1_t appeui[] = APPEUI;
-    static_assert(sizeof(settings.AppEUI) == sizeof(appeui), "APPEUI needs to be 8 bytes");
-    _memcpy(settings.AppEUI, appeui, sizeof(settings.AppEUI));
-    settings.flags |= FLAG_APP_EUI_SET;
-    debugLogData("Setting AppEUI", settings.AppEUI, sizeof(settings.AppEUI));
-    write = true;
+    STATIC_INIT(APPEUI, AppEUI, FLAG_APP_EUI_SET)
   #endif
   #if defined(DEVEUI)
-    static const PROGMEM u1_t deveui[] = DEVEUI;
-    static_assert(sizeof(settings.DevEUI) == sizeof(deveui), "DEVEUI needs to be 8 bytes");
-    _memcpy(settings.DevEUI, deveui, sizeof(settings.DevEUI));
-    settings.flags |= FLAG_DEV_EUI_SET;
-    debugLogData("Setting DevEUI", settings.DevEUI, sizeof(settings.DevEUI));
-    write = true;
+    STATIC_INIT(DEVEUI, DevEUI, FLAG_DEV_EUI_SET)
   #endif

   debugLog("Following static initialization, Flags: ", settings.flags);


typos fix

typos fix

--- examples/More/AppConnectedEvents/AppConnectedEvents.ino
+++ examples/More/AppConnectedEvents/AppConnectedEvents.ino
@@ -37,14 +37,14 @@
 // Go to the Project Settings (nut icon).
 char auth[] = "YourAuthToken";

-// This is called when Smartohone App is opened
+// This is called when Smartphone App is opened
 BLYNK_APP_CONNECTED() {
-  Serial.println("App Connect");
+  Serial.println("App Connected.");
 }

-// This is called when Smartohone App is closed
+// This is called when Smartphone App is closed
 BLYNK_APP_DISCONNECTED() {
-  Serial.println("App Disconnect");
+  Serial.println("App Disconnected.");
 }


Each team member should talk for 1.5 minutes instead

--- firmware/StandupPotato/StandupPotato.ino
+++ firmware/StandupPotato/StandupPotato.ino
@@ -26,7 +26,7 @@
 const unsigned int ACCELEROMETER_IN = PB3;
 const unsigned int ACCELEROMETER_POWER = PB4;

-const unsigned long TURN_DURATION = 120000; // The time in milliseconds that each person can talk
+const unsigned long TURN_DURATION = 90000; // The time in milliseconds that each person can talk
 unsigned long halfOfRemainingTime = TURN_DURATION / 2;
 volatile bool watchDogBarked = false;
 bool watchDogEnabled = false;


don't sync rtc if LCD not on

don't sync rtc if LCD not on

--- vibrate_alarm_clock_2.ino
+++ vibrate_alarm_clock_2.ino
@@ -137,7 +137,9 @@

 void loop (){

-  setSyncProvider(RTC.get);
+  if(showLCD){
+    setSyncProvider(RTC.get);
+  }

   int leftButtonState = digitalRead(LEFT_BUTTON_PIN);
   int middleButtonState = digitalRead(MIDDLE_BUTTON_PIN);