Set up all the motors in sampler.ino

Set up all the motors in sampler.ino

--- firmware/sampler.ino
+++ firmware/sampler.ino
@@ -5,10 +5,13 @@
   yMotor(Y_AXIS_PWM, Y_AXIS_FWD, Y_AXIS_REV),
   zMotor(Z_AXIS_PWM, Z_AXIS_FWD, Z_AXIS_REV);

+
 void setup() {
   Serial.begin(BAUDRATE);
   xMotor.begin();
-  xMotor.setPower(1);
+  yMotor.begin();
+  zMotor.begin();
 }

-void loop() {}
+void loop() {
+}


changed debouncing method for reed switch added door unlocking when opened during locking phase protected above against unlocking in case of reed switch failure

--- zamek.ino
+++ zamek.ino
@@ -71,6 +71,8 @@
 int soundDelayTimeout = 0;

 int lockTransitionTimeTimeout = 0;
+int doorServerRevertTimeout = 0;
+
 int udpResponseTimeout = 0;

 int lastCardChkTimeout = 0;
@@ -182,6 +184,9 @@
 				servo.detach();
 		}

+		if (doorServerRevertTimeout)
+			doorServerRevertTimeout--;
+
 		if (udpResponseTimeout)
 			udpResponseTimeout--;

@@ -238,32 +243,42 @@

 	// processing reed switch events
 	static unsigned long reedEvent = 0;
+	static bool reedToDebounce = false;
 	bool door = digitalRead(pinReedSwitch);
 	if (previousDoorState != door)
 	{
-		unsigned long time = millis() - reedEvent;
-
-		if (door == close)
-		{
-			lockDoor();
-		}
-		if (door == open)
-		{
-			isDoorLocked = false;
-		}
-
-		if (time > 20)
-		{
-			// sending notification about door state
-			udp.beginPacket(srvIp, 10000);
-			char buf[12];
-			int len = snprintf(buf, 12, "^%d|%08ld", door == close ? 0 : 1, time);
-			udp.write((uint8_t*)buf, len);
-			udp.endPacket();
-		}
-
 		reedEvent = millis();
 		previousDoorState = door;
+		reedToDebounce = true;
+	}
+
+	unsigned long time = millis() - reedEvent;
+	if (reedToDebounce && time > 200)
+	{
+		reedToDebounce = false;
+		// sending notification about door state
+		udp.beginPacket(srvIp, 10000);
+		char buf[12];
+		int len = snprintf(buf, 12, "^%d|%08ld", door == close ? 0 : 1, time);
+		udp.write((uint8_t*)buf, len);
+		udp.endPacket();
+
+		if (door == close)
+		{
+			lockDoor();
+		}
+		if (door == open)
+		{
+			// when door are opened during locking time, unlock door, but only
+			// within specific time since locking started
+			if (isDoorLocked && doorServerRevertTimeout)
+			{
+				int timeLeft = lockTransitionTime - lockTransitionTimeTimeout;
+				servoDo(servoUnlockAngle);
+				lockTransitionTimeTimeout = timeLeft;
+				isDoorLocked = false;
+			}
+		}
 	}

 inline int bufferIndex(int index){
@@ -330,24 +345,31 @@
 	servo.write(angle);
 	lockTransitionTimeTimeout = lockTransitionTime;
 }
+void servoDoTime(int angle, int time)
+{
+	servo.attach(pinServo);
+	servo.write(angle);
+	lockTransitionTimeTimeout = time;
+}
 void unlockDoor()
 {
 	if (!isDoorLocked)
 		return;
-	servoDo(clockwise);
+	servoDo(servoUnlockAngle);
 	isDoorLocked = false;
 }
 void unlockDoorForce()
 {
-	servoDo(clockwise);
+	servoDo(servoUnlockAngle);
 	isDoorLocked = false;
 }
 void lockDoor()
 {
 	if (isDoorLocked)
 		return;
-	servoDo(counterClockwise);
+	servoDo(servoLockAngle);
 	isDoorLocked = true;
+	doorServerRevertTimeout = 3000;
 }

 void cardAccepted()


Fixed bad adjustment on the servo. Added poor mans version check for the Arduino firmware since this change in OpenROV would send values that the old firmware may not be ready to accept

--- arduino/OpenROV/OpenROV.ino
+++ arduino/OpenROV/OpenROV.ino
@@ -5,6 +5,7 @@
 #include "Device.h"
 #include "Timer.h"
 #include "FreeMem.h"
+

 Motors motors(9, 10, 11);
 Command cmd;
@@ -97,7 +98,7 @@
     if (s>c_motors) c_motors += min(aggro,s-c_motors);
     if (tilt_val<c_tilt) c_tilt -= min(aggro,c_tilt-tilt_val);
     if (tilt_val>c_tilt) c_tilt += min(aggro,tilt_val-c_tilt);
-    tilt.writeMicroseconds(tilt_val);
+    tilt.writeMicroseconds(c_tilt);
     motors.go(c_motorp, c_motorv, c_motors);
   }

@@ -142,6 +143,17 @@
     Serial.print(",");
     Serial.print(s);
     Serial.print(";");
+    Serial.print("servo:");
+    Serial.print(c_tilt);
+    Serial.print(";");
+    Serial.print("starg:");
+    Serial.print(tilt_val);
+    Serial.print(";");
+    Serial.print("ver:");
+    //Version Number of last change from UTC date: .YYYYMMDDHHMMSS. If you make a change between this and the cockpit that requires the firmware to be in sync or it breaks the system your should update this version number
+    // and update the cockpit software lib/OpenROVControler.js to check and ensure the firmware is at this version.
+    Serial.print(".20130314034900");
+    Serial.print(";");
     Serial.print("time:");
     Serial.println(millis());
   }


v1.3 Add extra comments

v1.3 Add extra comments

--- GPSLCD.ino
+++ GPSLCD.ino
@@ -256,12 +256,12 @@
       lcd.print("         "); // Clear the extra chars
     }
 #else // #ifndef CONVERT_TO_LOCAL
-#ifdef DISPLAY_HDOP_ERROR
+#ifdef DISPLAY_HDOP
     // Display Horizontal Dilution of Precision (Hdop) with the format X.X
     // It comes in from the GPS module as XXX
     // If you care how Hdop is computed (I don't :-(), see the following:
     // http://www2.unb.ca/gge/Resources/gpsworld.may99.pdf
-    float Hdop = (float)GPSData.hdop / 100.0f; // In X.X format
+    float Hdop = (float)GPSData.hdop / 100.0f; // Hdop in X.X format
     lcd.print(" Hdop:");
     if (Hdop < 10.0f) {
       lcd.print(Hdop);
@@ -280,23 +280,23 @@
           lcd.print("   ");
         } // if (hdopToggle)
       } // if (now - prevHdopTime > TOGGLETIME_INTERVAL)
-    } // if (hdopInteger < 10)
-#else // #ifdef DISPLAY_HDOP_ERROR
+    } // if (Hdop < 10.0f)
+#else // #ifdef DISPLAY_HDOP
     // Display horizontal position error in feet
-    float hError = (float)GPSData.hdop / 100.0f; // In X.X format
+    float hError = (float)GPSData.hdop / 100.0f; // Error in X.X format
     hError *= GPS_RECEIVER_ERROR; // Error in meters
     hError *= _GPS_FEET_PER_METER; // Error in feet
     lcd.print(" Err: ");
     if (hError < 100.0f) {
       lcd.print((uint8_t)hError);
       if (hError < 10.0f) {
-        lcd.print("f ");
+        lcd.print("f "); // feet
       }
       else {
-        lcd.print("f");
-      }
-    }
-    else {
+        lcd.print("f"); // feet
+      }
+    }
+    else { // if (hError < 100.0f)
       // horizontal position error value too large for my LCD, so cross it out
       // Toggle Hdop indicator every TOGGLETIME_INTERVAL seconds
       if (now - prevHdopTime > TOGGLETIME_INTERVAL / 3) {
@@ -311,7 +311,7 @@
         } // if (hdopToggle)
       } // if (now - prevHdopTime > TOGGLETIME_INTERVAL)
     } // if (hError < 100.0f)
-#endif // #ifdef DISPLAY_HDOP_ERROR
+#endif // #ifdef DISPLAY_HDOP
 #endif // #ifndef CONVERT_TO_LOCAL
     lcd.setCursor (0, 2); // Go to 3rd line
     lcd.print("Spd: ");


randomly picks a pixel and changes the color to red.

--- Helios.ino
+++ Helios.ino
@@ -5,7 +5,8 @@
 #define PIN 6
 int day1 [3] = {209, 100, 39}; //jstart
 int day2 [3] = {220, 0, 0}; //end
-int currentColor[3] = {day1[0], day1[1], day1[2]};
+//int currentColor[3] = {day1[0], day1[1], day1[2]};
+int currentColors [45][3];

 /*
 int red = 200;
@@ -34,12 +35,16 @@
 #endif
   // End of trinket special code
   Serial.begin(9600);
+  initializePixels();
+  Serial.println(sizeof(currentColors[6]));
 //  Serial.println(strip.numPixels());
   setTime(4, 20, 00, 11, 59, 2015);
   strip.begin();
   strip.show(); // Initialize all pixels to 'off'
   powerOn(day1[0], day1[1], day1[2], 10);
-  delay(7000);
+  delay(1000);
+  srand(now());
+  delay(10);
   //strip.setPixelColor(15, strip.Color(196, 196, 48));
  // delay(1000);
  // powerOff();
@@ -49,36 +54,20 @@
  * use for random pixel "liveliness"
  */
 void loop() {
-  srand(now());
+  //srand(now());
   int randColor = rand() % 3 + 1;
   int randPix = rand() % strip.numPixels();
-  Serial.println("here");
-  switch(randColor) {
-    case 1:
-      Serial.println(randPix);
-      Serial.println("day1");
-      Serial.println();
-      if(!(currentColor[0] == day1[0] && currentColor[1] == day1[1] && currentColor[2] == day1[2])) {
-        fadeToColor(currentColor, day1, randPix);
-        currentColor[0] = day1[0];
-        currentColor[1] = day1[1];
-        currentColor[2] = day1[2];
-      }
-      break;
-
-    case 2:
-      if(!(currentColor == day2)){
-        fadeToColor(currentColor, day2, randPix);
-      }
-      break;
-
-    default:
-      Serial.println("default");
-      Serial.println();
-      break;
+  //Serial.println(randColor);
+  if(randColor == 1) {
+  //  if(!(currentColors[randPix][0] == day2[0] && currentColors[randPix][1] == day2[1] && currentColors[randPix][2] == day2[2])) {
+    //  Serial.print("Changing color on pixel ");
+   //  Serial.println(randPix);
+      fadeToColor(currentColors[randPix], day2, randPix);
+      for(int i = 0; i < sizeof(currentColors[randPix]); i++)
+        currentColors[randPix][i] = day1[i];
+    //}
   }
-  //fadeToColor(day2[0], day2[1], day2[2]);
-  delay(500);
+  delay(2000);
 }

 uint8_t splitColor ( uint32_t c, char value )
@@ -97,8 +86,8 @@
   int rnew = 0, gnew = 0, bnew = 0;
   for(int i = 0; i <= n; i++) {
     rnew = start[0] + (end_[0] - start[0]) * i / n;
-    rnew = start[1] + (end_[1] - start[1]) * i / n;
-    rnew = start[2] + (end_[2] - start[2]) * i / n;
+    gnew = start[1] + (end_[1] - start[1]) * i / n;
+    bnew = start[2] + (end_[2] - start[2]) * i / n;
     strip.setPixelColor(pix, strip.Color(rnew, gnew, bnew));
     strip.show();
     delay(100);
@@ -178,32 +167,20 @@
   }
 }

-// Fill the dots one after the other with a color
-void colorWipe(uint32_t c, uint8_t wait) {
-  for(uint16_t i=0; i<strip.numPixels(); i++) {
-      strip.setPixelColor(i, c);
-      strip.show();
-      delay(wait);
+void initializePixels() {
+  Serial.println(sizeof(currentColors));
+  Serial.println();
+  for(int a = 0; a < 45; a++) {
+    for(int k = 0; k < 3; k++) {
+      currentColors[a][k] = day1[k];
+     // delay(500);
+    }
   }
 }

-
-// Slightly different, this makes the rainbow equally distributed throughout
-void rainbowCycle(uint8_t wait) {
-  uint16_t i, j;
-
-  for(j=0; j<256*5; j++) { // 5 cycles of all colors on wheel
-    for(i=0; i< strip.numPixels(); i++) {
-      strip.setPixelColor(i, Wheel(((i * 256 / strip.numPixels()) + j) & 255));
-    }
-    strip.show();
-    delay(wait);
-  }
-}
-
-
 // Input a value 0 to 255 to get a color value.
 // The colours are a transition r - g - b - back to r.
+/*
 uint32_t Wheel(byte WheelPos) {
   WheelPos = 255 - WheelPos;
   if(WheelPos < 85) {
@@ -216,4 +193,4 @@
    return strip.Color(WheelPos * 3, 255 - WheelPos * 3, 0);
   }
 }
-
+*/


short delay before SR1

short delay before SR1

in order to sync the first frame correctly, a short delay before
sending SR1 seems to be necessary

--- d_BacpacCommands.ino
+++ d_BacpacCommands.ino
@@ -190,6 +190,8 @@
         Serial.println(tmp);
         digitalWrite(BUILTINLED, LOW);
       }
+      // in order to sync the first frame, a short delay seems to be necessary
+      delay(140); // 140ms
       buf[0] = 0x83; buf[1] = 'S'; buf[2] = 'R';
       if (!isMaster && recv[3] == 0 && td[TD_MODE] != MODE_TIMELAPSE) {
         // video capture end


Accumulator Code

Accumulator Code


Fixed that card could sometimes double scan.

--- firmware/sentry.ino
+++ firmware/sentry.ino
@@ -42,7 +42,17 @@
 // SD card that we use for storage.
 Store store = Store();

-Servo lockServo; // 20 - 85
+// This servo controls the door lock.
+Servo lockServo;
+
+// Minumum amount of milliseconds that it will lock out an already scanned card.
+#define CODE_RESCAN_DELAY 5000
+
+// The code of the last card read.
+int lastCode;
+
+// When that last card read is allowed ot be read again.
+unsigned long lastCodeCanRescanAt;

 bool connected = false;
 bool connecting = false;
@@ -119,7 +129,14 @@
   char line1[17];
   char line2[17];

+  // Prevent double scans by ignoring the same card within a short period.
+  if ((code == lastCode) && (millis() < lastCodeCanRescanAt)) {
+    return;
+  }
+
   if (store.allowCard(code, line1, line2)) {
+    lastCode = code;
+    lastCodeCanRescanAt = millis() + CODE_RESCAN_DELAY;
     allowCard(line1, line2);
   } else {
     denyCard(line1, line2);


v2.0 Flip date/time placement in code

v2.0 Flip date/time placement in code

--- GPSLCD.ino
+++ GPSLCD.ino
@@ -367,29 +367,7 @@
       // Toggle date/time every TOGGLETIME_INTERVAL seconds
       if (now - prevDateTime > TOGGLETIME_INTERVAL) {
         prevDateTime = now;
-        if (dateTimeToggle) {
-          // Display date
-          dateTimeToggle = false;
-          lcd.print("Date: ");
-          uint8_t hour = GPSData.hour;
-          uint8_t day  = GPSData.day;
-          uint8_t month = GPSData.month;
-          uint16_t year = GPSData.year;
-#ifdef CONVERT_TO_LOCAL
-          // Convert UTC date to local date
-          bool DST = convertToLocal (&hour, &year, &month,
-                                     &day, GPSData.lon, true); // true means date conversion
-#endif // #ifdef CONVERT_TO_LOCAL
-          if (month < 10) lcd.print("0");
-          lcd.print(month);
-          lcd.print("/");
-          if (day < 10) lcd.print("0");
-          lcd.print(day);
-          lcd.print("/");
-          lcd.print(year);
-          printDay (dayOfWeek (year, month, day));
-        } // if (dateTimeToggle)
-        else {
+        if (!dateTimeToggle) {
           // Display time
           dateTimeToggle = true;
           lcd.print("Time: ");
@@ -440,7 +418,29 @@
           lcd.print("   UTC");
 #endif // #ifdef DISPLAY_12_HOUR
 #endif // #ifndef CONVERT_TO_LOCAL
-        } // if (dateTimeToggle)
+        } // if (!dateTimeToggle)
+        else {
+          // Display date
+          dateTimeToggle = false;
+          lcd.print("Date: ");
+          uint8_t hour = GPSData.hour;
+          uint8_t day  = GPSData.day;
+          uint8_t month = GPSData.month;
+          uint16_t year = GPSData.year;
+#ifdef CONVERT_TO_LOCAL
+          // Convert UTC date to local date
+          bool DST = convertToLocal (&hour, &year, &month,
+                                     &day, GPSData.lon, true); // true means date conversion
+#endif // #ifdef CONVERT_TO_LOCAL
+          if (month < 10) lcd.print("0");
+          lcd.print(month);
+          lcd.print("/");
+          if (day < 10) lcd.print("0");
+          lcd.print(day);
+          lcd.print("/");
+          lcd.print(year);
+          printDay (dayOfWeek (year, month, day));
+        } // if (!dateTimeToggle)
       } // if (now - prevDateTime > TOGGLETIME_INTERVAL)
     } // if ((digitalRead(ALTITUDE_DATE_TIME_SW)))
 #endif //------------------------------------------------------------


Minor edits for ease of use

Minor edits for ease of use

--- Syma_servo_trinket.ino
+++ Syma_servo_trinket.ino
@@ -42,7 +42,7 @@

 #define servoPin 0
 int signal = 2; // The signal from the SYMA camera port
-int LEDsignal = 1; // LED
+int LEDsignal = 1; // onboard LED

 int current;         // Current state of the button
                      // (LOW is pressed b/c i'm using the pullup resistors)
@@ -53,13 +53,13 @@
 unsigned long firstTime; // how long since the signal was detected

-Adafruit_SoftServo myServo1;
+Adafruit_SoftServo myServo1;
 boolean toggle = true;

 void setup()
 {
-  digitalWrite(signal, HIGH);
-  pinMode(LEDsignal, OUTPUT);
+  digitalWrite(signal, HIGH);
+  pinMode(LEDsignal, OUTPUT); //Make the LED pin an output
   digitalWrite(LEDsignal, LOW);

@@ -107,7 +107,7 @@
         }
         //Move from 90 to 0 degrees (straight down to horizontal)
         else{
-          myServo1.write(180);
+          myServo1.write(180); //Using 180 here, but for some reason it moves the servo to -90
           toggle = !toggle;
           digitalWrite(LEDsignal, HIGH);   // turn the LED on (HIGH is the voltage level)
           delay(500);                       // wait
@@ -117,23 +117,23 @@

      // VIDEO BUTTON (low signal from Camera, ~0.75s)
       if (millis_held > 500) {
-        //whatever we want... for now let's just show it works
+        //whatever we want... for now let's just show it works with an LED blink
          digitalWrite(LEDsignal, HIGH);   // turn the LED on (HIGH is the voltage level)
          delay(1500);                       // wait
          digitalWrite(LEDsignal, LOW);    // turn the LED off by making the voltage LOW
       }//end_if video

       //----------------------------------------------------------
-      //----------------------------------------------------------
+      //---------------- End Controlling the servo ---------------

       }
   }
-
+// NEEDED for reading the camera signal
   previous = current;
   prev_secs_held = secs_held;
 } //end loop

-//----------------------------------------------------------
+//--------------------- Servo timing -----------------------
 //----------------------------------------------------------

 // We'll take advantage of the built in millis() timer that goes off


style

style

--- examples/adc_timer/adc_timer.ino
+++ examples/adc_timer/adc_timer.ino
@@ -142,8 +142,8 @@
   adc->resetError();

   // See if we have a timed read test that finished.
-  if (delta_time_adc_0)printTimedADCInfo(ADC_0, buffer_ADC_0, delta_time_adc_0);
-  if (delta_time_adc_1)printTimedADCInfo(ADC_1, buffer_ADC_1, delta_time_adc_1);
+  if (delta_time_adc_0) printTimedADCInfo(ADC_0, buffer_ADC_0, delta_time_adc_0);
+  if (delta_time_adc_1) printTimedADCInfo(ADC_1, buffer_ADC_1, delta_time_adc_1);

   //digitalWriteFast(LED_BUILTIN, !digitalReadFast(LED_BUILTIN));


Better FFat detection and formatting code. See #39 and #40.

Adafruit_ILI9341 to 1.5.7
Adafruit_GFX to 1.7.5

--- aquacontrol32.ino
+++ aquacontrol32.ino
@@ -7,8 +7,8 @@
 #include <ESPmDNS.h>               /* should be installed together with ESP32 Arduino install */
 #include <Preferences.h>           /* should be installed together with ESP32 Arduino install */
 #include <WiFi.h>                  /* should be installed together with ESP32 Arduino install */
-#include <Adafruit_ILI9341.h>      /* Install 1.5.1 via 'Manage Libraries' in Arduino IDE */
-#include <Adafruit_GFX.h>          /* Install 1.6.1 via 'Manage Libraries' in Arduino IDE */
+#include <Adafruit_ILI9341.h>      /* Install 1.5.4 via 'Manage Libraries' in Arduino IDE */
+#include <Adafruit_GFX.h>          /* Install 1.7.5 via 'Manage Libraries' in Arduino IDE */
 #include <SSD1306.h>               /* Install 4.0.0 via 'Manage Libraries' in Arduino IDE -> https://github.com/ThingPulse/esp8266-oled-ssd1306 */
 #include <XPT2046_Touchscreen.h>   /* Install 1.3 via 'Manage Libraries' in Arduino IDE */
 #include <AsyncTCP.h>              /* Reports as 1.0.3 https://github.com/me-no-dev/AsyncTCP */
@@ -333,8 +333,26 @@
       1);                             /* Core where the task should run */
   }

-  /* format fatfs on first boot */
-  if ( !preferences.getString("firstrun", "true" ).equals( "false" ) ) {
+  /* check if a ffat partition is defined and halt the system if it is not defined*/
+  if (!esp_partition_find_first(ESP_PARTITION_TYPE_DATA, ESP_PARTITION_SUBTYPE_DATA_FAT, "ffat")) {
+    ESP_LOGI( TAG, "No FFat partition defined. Halting.\nCheck 'Tools>Partition Scheme' in the Arduino IDE and select a FFat partition." );
+    const char * noffatStr = "No FFat found...";
+    if ( xTftTaskHandle ) {
+      tft.println( noffatStr );
+    }
+    if ( xOledTaskHandle ) {
+      OLED.drawString( 64, 20, noffatStr );
+      OLED.display();
+    }
+    while (true) delay(1000); /* system is halted */
+  }
+
+  /* partition is defined - try to mount it */
+  if ( FFat.begin() )
+    ESP_LOGI( TAG, "FFat mounted." );
+
+  /* partition is present, but does not mount so now we just format it */
+  else {
     const char * formatStr = "Formatting...";
     if ( xTftTaskHandle ) {
       tft.println( formatStr );
@@ -343,19 +361,13 @@
       OLED.drawString( 64, 20, formatStr );
       OLED.display();
     }
-
     ESP_LOGI( TAG, "%s", formatStr );
-
-    if ( FFat.format( true, (char*)"ffat" ) )
-      preferences.putString( "firstrun", "false" ); // and set token
-    else
-      ESP_LOGI( TAG, "Could not format FFat." );
-  }
-
-  if ( FFat.begin() )
-    ESP_LOGI( TAG, "FFat mounted." );
-  else
-    ESP_LOGI( TAG, "Could not mount FFat." );
+    FFat.format( true, (char*)"ffat" );
+    if (!FFat.begin()) {
+      ESP_LOGI( TAG, "FFat not mounted after formatting. Halting." );
+      while (true) delay(1000); /* system is halted */;
+    }
+  }

   if ( xOledTaskHandle ) {
     OLED.drawString( 64, 40, "Connecting..." );


HTML config pages size optimization

HTML config pages size optimization

--- A03_HTML_JSON.ino
+++ A03_HTML_JSON.ino
@@ -8,12 +8,12 @@

 #define ConfigPage "<!DOCTYPE html>" \
 "<meta charset='UTF-8'/><meta name='viewport' content='width=device-width/2, initial-scale=2.0'><title>36 Brick Setup</title>" \
-"" \
-" " \
-"
36Brick
%%TYPE%%
" \
-"<form method='GET' action='/saveCFG' style='clear:both;'>Brick Name
<input name='name' type='text' value='%%NAME%%' />

WIFI SSID
<select name='ssid' >%%SSID%%</select>
WIFI Password
<input name='pass' type='password' value='%%PASS%%' />

MQTT Server
<input name='mqttserv' type='text' value='%%MQTT_SERV%%'/>
MQTT Port
<input name='mqttport' type='text' value='%%MQTT_PORT%%' />

<input type='submit'/></form>"
+"" \
+"" \
+"
36Brick
%%TYPE%%
" \
+"<form method='GET' action='/saveCFG' style='clear:both'>Brick Name
<input name='name' type='text' value='%%NAME%%' />

WIFI SSID
<select name='ssid' >%%SSID%%</select>
WIFI Password
<input name='pass' type='password' value='%%PASS%%' />

MQTT Server
<input name='mqttserv' type='text' value='%%MQTT_SERV%%'/>
MQTT Port
<input name='mqttport' type='text' value='%%MQTT_PORT%%' />

<input type='submit'/></form>"

-#define ThxPage "<!DOCTYPE html>      <meta charset='UTF-8'/>   <meta name='viewport' content='width=device-width/2, initial-scale=2.0'>    <title>36 Brick Setup</title>
36Brick
%%TYPE%%

Config saved, you can reset the brick !"
+#define ThxPage "<!DOCTYPE html><meta charset='UTF-8'/><meta name='viewport' content='width=device-width/2, initial-scale=2.0'><title>36 Brick Setup</title>
36Brick
%%TYPE%%

Config saved, you can reset the brick !"

 #define serverUpdate "<form method='POST' action='/update' enctype='multipart/form-data'><input type='file' name='update'><input type='submit' value='Update'></form>"


update the SD card logger example

update the SD card logger example

--- examples/SdCardCsvLogger/SdCardCsvLogger.ino
+++ examples/SdCardCsvLogger/SdCardCsvLogger.ino
@@ -2,35 +2,36 @@
 #include <SD.h>
 #include <SPI.h>

-const int chipSelect = 4;
 RadiationWatch radiationWatch(2, 3, 0, 1);
+const int sdCardPin = 4;
 File dataFile;
 char* str;

 void onRadiationPulse() {
+  // For each radiation update the values sent to serial and SD card in CSV.
   str = radiationWatch.csvStatus();
   Serial.println(str);
   dataFile.println(str);
+  dataFile.flush();
 }

 void setup()
 {
-  // Serial init.
   Serial.begin(9600);
   // SD setup.
-  if(!SD.begin(chipSelect)) {
+  if(!SD.begin(sdCardPin)) {
     Serial.println("SD card init failed, or not present");
     return;
   }
-  dataFile = SD.open("log.txt", FILE_WRITE);
+  dataFile = SD.open("radiation.csv", FILE_WRITE);
   if(!dataFile) {
     Serial.println("Failed to open file");
     return;
   }
-  // Setup the lib and register the pulse callback.
+  // Setup the lib and register the callback.
   radiationWatch.setup();
-  radiationWatch.registerRPCallback(&onRadiationPulse);
-  // Print first status on serial and on SD card.
+  radiationWatch.registerRadiationCallback(&onRadiationPulse);
+  // Print the CSV keys and the initial values.
   str = radiationWatch.csvKeys();
   Serial.println(str);
   dataFile.println(str);
@@ -42,5 +43,4 @@
 void loop()
 {
   radiationWatch.loop();
-  dataFile.flush();
 }


SdCardCsvLogger.ino: use Print class for csv

Streaming of strings is the Arduino way and saves dynamic memory, here
60 bytes.

--- examples/SdCardCsvLogger/SdCardCsvLogger.ino
+++ examples/SdCardCsvLogger/SdCardCsvLogger.ino
@@ -10,10 +10,39 @@
 RadiationWatch radiationWatch;
 const byte sdCardPin = 4;
 File dataFile;
+unsigned long csvStartTime;
+
+void csvKeys(Print &print=Serial)
+{
+  // inizialise start time
+  csvStartTime = millis();
+  // Write CSV keys to a print class (default print class is Serial).
+  print.println("time(ms),count,cpm,uSv/h,uSv/hError");
+}
+
+void csvStatus(RadiationWatch radiationWatch, Print &print=Serial)
+{
+  // Write CSV to a print class (default print class is Serial).
+  // time(ms)
+  print.print(millis() - csvStartTime);
+  print.print(',');
+  // count
+  print.print(radiationWatch.radiationCount());
+  print.print(',');
+  // cpm
+  print.print(radiationWatch.cpm(), 3);
+  print.print(',');
+  // uSv/h
+  print.print(radiationWatch.uSvh(), 3);
+  print.print(',');
+  // uSv/hError
+  print.print(radiationWatch.uSvhError(), 3);
+  print.println("");
+}

 void onRadiationPulse() {
   // For each radiation write the current values to the SD card in CSV.
-  dataFile.println(radiationWatch.csvStatus());
+  csvStatus(radiationWatch, dataFile);
   dataFile.flush();
 }

@@ -32,8 +61,8 @@
   }
   radiationWatch.setup();
   // Print the CSV keys and the initial values.
-  dataFile.println(radiationWatch.csvKeys());
-  dataFile.println(radiationWatch.csvStatus());
+  csvKeys(dataFile);
+  csvStatus(radiationWatch, dataFile);
   dataFile.flush();
   // Register the callback.
   radiationWatch.registerRadiationCallback(&onRadiationPulse);


Create a debug block that will sound the alarm (currently just beeps).

--- timer/timer.ino
+++ timer/timer.ino
@@ -270,16 +270,23 @@

 void debug_state_loop(int button) {
-  // display.display_text("dbug");
-
-  // check that the buttons are working
-  int value = analogRead(PIN_BUTTON_LADDER);
-
-  // display value for 0.2 seconds
   long now = millis();
-  while (millis() < now + 200 ) {
-    display.display_number(value);
-  }
-
-}
-
+
+  display.display_text("dbug");
+
+  // // check that the buttons are working
+  // int value = analogRead(PIN_BUTTON_LADDER);
+  // while (millis() < now + 200 ) {
+  //   // display value for 0.2 seconds
+  //   display.display_number(value);
+  // }
+
+  // Sound the alarm until a button is pressed
+  speaker.beep();
+  // speaker.sound_alarm();
+  if (buttons.get_button_press() != NO_BUTTON ) {
+    change_to_state(STATE_WAITING);
+  }
+
+}
+


Delete arduino.ino

Delete arduino.ino

--- MarceloForesto/RobotArchitecture/arduino.ino
+++ MarceloForesto/RobotArchitecture/arduino.ino
@@ -1,52 +0,0 @@
-/*
-  Software serial multple serial test
- Receives from the hardware serial, sends to software serial.
- Receives from software serial, sends to hardware serial.
- The circuit:
- * RX is digital pin 10 (connect to TX of other device)
- * TX is digital pin 11 (connect to RX of other device)
- Note:
- Not all pins on the Mega and Mega 2560 support change interrupts,
- so only the following can be used for RX:
- 10, 11, 12, 13, 50, 51, 52, 53, 62, 63, 64, 65, 66, 67, 68, 69
- Not all pins on the Leonardo and Micro support change interrupts,
- so only the following can be used for RX:
- 8, 9, 10, 11, 14 (MISO), 15 (SCK), 16 (MOSI).
- created back in the mists of time
- modified 25 May 2012
- by Tom Igoe
- based on Mikal Hart's example
- This example code is in the public domain.
- ls --color=never
- */
-#include <SoftwareSerial.h>
-
-SoftwareSerial mySerial(10, 11); // RX, TX
-byte  serIn;
-void setup() {
-  pinMode(13,OUTPUT);
-  // Open serial communications and wait for port to open:
-  Serial.begin(115200);
-  while (!Serial) {
-    ; // wait for serial port to connect. Needed for native USB port only
-  }
-
-  // set the data rate for the SoftwareSerial port
-  mySerial.begin(115200);
-
-}
-
-void loop() { // run over and over
-  if(mySerial.available()>0){
-          serIn = mySerial.read();
-          Serial.println(char(serIn));
-          if (char(serIn) == '1'){
-            digitalWrite(13,HIGH);
-            mySerial.write("Ligou");
-          }
-          if (char(serIn) == '0'){
-            digitalWrite(13,LOW);
-            mySerial.write("Desligou");;
-          }
-  }
-}


RGBの値が大きいと点灯するLEDの数によっては色が安定しない問題が発生したので、制限をつける(MAX_VALUE=64) 例：30個なら問題なかったが、60個にすると200,100,100などの値で時間が経つと赤に変わってしまうなどの問題が発生していた

--- arduino-neopixel.ino
+++ arduino-neopixel.ino
@@ -22,47 +22,86 @@
   strip.show(); // Initialize all pixels to 'off'
   Serial.begin(9600);
   colorWipe(strip.Color(MAX_VAL, MAX_VAL, MAX_VAL), DELAY_TIME2); // White
-  colorWipe(strip.Color(0, 0, 0), DELAY_TIME2); // White
+  colorWipe(0, DELAY_TIME2);
+
+//  colorWipe(strip.Color(100, 250, 100), DELAY_TIME2);
+//  color(strip.Color(200,100,100));
+//  for (int i=0; i < strip.numPixels(); i++) {
+//    if(i < 30) {
+//      strip.setPixelColor(i, limitedColor(200,100,100));
+//    }
+//    else {
+//      strip.setPixelColor(i, limitedColor(200,100,100));
+//    }
+//  }
+//  strip.show();
 }
-
+
 void loop() {
-  // Some example procedures showing how to display to the pixels:
-//    colorWipe(strip.Color(0, 0, 0), DELAY_TIME); // Black
-//  colorWipe(strip.Color(MAX_VAL, 0, 0), DELAY_TIME); // Red
-//  colorWipe(strip.Color(0, MAX_VAL, 0), DELAY_TIME); // Green
-//  colorWipe(strip.Color(MAX_VAL, MAX_VAL, 0), DELAY_TIME); // Yellow
-//  colorWipe(strip.Color(0, 0, MAX_VAL), DELAY_TIME); // Blue
-//  colorWipe(strip.Color(MAX_VAL, 0, MAX_VAL), DELAY_TIME); // Purple
-//  colorWipe(strip.Color(0, MAX_VAL, MAX_VAL), DELAY_TIME); // Cyan
-//  colorWipe(strip.Color(MAX_VAL, MAX_VAL, MAX_VAL), DELAY_TIME); // White
-//  rainbow(DELAY_TIME2);
-//  rainbowCycle(DELAY_TIME2);
+
+//  for (int i=0; i < strip.numPixels(); i++) {
+//    strip.setPixelColor(i, 0);
+//  }
+//  Serial.println(strip.getPixelColor(1));
+
+  // OKだった
+//  for(int i=0; i<strip.numPixels(); i++) {
+////    if(i < 59) {
+//      strip.setPixelColor(i, strip.Color(250, 100, 100));
+////    }
+////    else {
+////      strip.setPixelColor(i, strip.Color(255, 0, 0));
+////    }
+//
+//  }
+//  strip.show();
+
+
+//  strip.show();
+//  delay(100);
+//  for(int i=0; i<strip.numPixels(); i++) {
+//    strip.setPixelColor(i, strip.Color(250,100,100));
+//  }
+//  strip.show();
+//  color(strip.Color(255,0,0));
+
+  // しばらくすると赤になる
+//  color(strip.Color(200,100,100));
+//  color(strip.Color(255,100,100));
+//  color(strip.Color(250,100,100));

   if (0<Serial.available()) {
     String str = Serial.readStringUntil('\n');
     int r = str.substring(0,3).toInt();
     int g = str.substring(4,7).toInt();
     int b = str.substring(8,11).toInt();
-    Serial.print("R:");
-    Serial.println(r);
-    Serial.print("G:");
-    Serial.println(g);
-    Serial.print("B:");
-    Serial.println(b);
-    color(strip.Color(r, g, b));
+
+    // あまり強く光らせると色が安定しないのでリミットを設ける
+    int _r = constrainValue(r);
+    int _g = constrainValue(g);
+    int _b = constrainValue(b);
+    Serial.println("::: setInstColor :::");
+    Serial.println("input:["+String(r)+","+String(g)+","+String(b)+"] constrains to ["+String(_r)+","+String(_g)+","+String(_b)+"]");
+
+    color(strip.Color(_r, _g, _b));
   }
 }

-String getValue(String data, char separator, int index)
-{
+// limitation of brightness
+// 0-255の値を0-MAX_VALの範囲に
+uint32_t constrainValue(int input) {
+  return float(input) / 255.0 * float(MAX_VAL);
+}
+
+String getValue(String data, char separator, int index) {
  int found = 0;
   int strIndex[] = { 0, -1 };
   int maxIndex = data.length()-1;
   for(int i=0; i<=maxIndex && found<=index; i++){
   if(data.charAt(i)==separator || i==maxIndex){
-  found++;
-  strIndex[0] = strIndex[1]+1;
-  strIndex[1] = (i == maxIndex) ? i+1 : i;
+    found++;
+    strIndex[0] = strIndex[1]+1;
+    strIndex[1] = (i == maxIndex) ? i+1 : i;
   }
  }
   return found>index ? data.substring(strIndex[0], strIndex[1]) : "";


Finalized Sound Sensor Code

Finalized Sound Sensor Code

Scales output based on input value. Piecewise-linear mapping.

--- Modules/Sensor/SoundSensor/ArduinoCodes/SoundSensorATtiny/SoundSensorATtiny.ino
+++ Modules/Sensor/SoundSensor/ArduinoCodes/SoundSensorATtiny/SoundSensorATtiny.ino
@@ -32,7 +32,7 @@
 SignalProcessing input(input_pin, filter_size);

 void setup() {
-  pinMode(output_pin, OUTPUT);
+  pinMode(output_pin, OUTPUT);
 }

 void loop() {
@@ -44,30 +44,27 @@
   unsigned int signal_max = 0;
   unsigned int signal_min = 1024;

-  if(input_val > 1){
-    while (millis() - start_millis < sample_window){
-        sensor_val = analogRead(sensor_pin);
-        if (sensor_val < 1024){  // toss out spurious readings
-           if (sensor_val > signal_max){
-              signal_max = sensor_val;  // save the max levels
-           }
-           else if (sensor_val < signal_min){
-              signal_min = sensor_val;  // save the min levels
-           }
-        }
-    }
-    if(signal_max - signal_min <= 10){            //when there is only background noise, output nothing
-        output_val = 0;
-    }
-    else if(signal_max - signal_min <=100){
-      output_val = cutAndMap(signal_max-signal_min, 10, 100, 28, 200);
-    }
-    else{
-        output_val = cutAndMap(signal_max-signal_min, 100, 350, 200, 255);
-    }
-    analogWrite(output_pin, output_val);
+
+  while (millis() - start_millis < sample_window){
+      sensor_val = analogRead(sensor_pin);
+      if (sensor_val < 1024){  // toss out spurious readings
+         if (sensor_val > signal_max){
+            signal_max = sensor_val;  // save the max levels
+         }
+         else if (sensor_val < signal_min){
+            signal_min = sensor_val;  // save the min levels
+         }
+      }
   }
-  else{
-    return;
+  if(signal_max - signal_min <= 10){            //when there is only background noise, output nothing
+      output_val = 0;
   }
+  else if(signal_max - signal_min <=100){
+    output_val = cutAndMap(signal_max-signal_min, 10, 100, input_val/36, input_val/5);
+  }
+  else{
+      output_val = cutAndMap(signal_max-signal_min, 100, 350, input_val/5, input_val/4);
+  }
+  analogWrite(output_pin, output_val);
+
 }


Changes from macbook pro

Changes from macbook pro

--- baton/baton.ino
+++ baton/baton.ino
@@ -12,9 +12,9 @@
 bool firstTimeRunningThroughPattern = true;

 #define BEAUTIFUL_SPARKLES 1
-#define NIGHT_SPARKLES 2
+#define NIGHT_SPARKLES 3
 // #define SINGLE_COLOR_SPARKLES 3
-#define DAVE 3
+#define DAVE 2
 #define WORMS 4
 #define DISCO_BARBER_1 5
 #define DISCO_TWIRL 6
@@ -112,13 +112,13 @@
 }

 void nightSparkles() {
-  if (firstTimeRunningThroughPattern) {
-    hue = 200;
+//  if (firstTimeRunningThroughPattern) {
+//    hue = 200;
 //    numberOfSparkles = 10;
-  }
+//  }
   fadeToBlackBy(leds, NUM_LEDS, 180);
   numberOfSparkles = upAndDownBy(numberOfSparkles, 1);
-  for (int i = 0; i < numberOfSparkles; i++) {
+  for (int i = 0; i < numberOfSparkles * 4; i++) {
     int pos = random16(NUM_LEDS);
     leds[pos] = CHSV(hue, 180, 255);
   }
@@ -130,7 +130,7 @@
 }

 void beautifulSparkles() {
-  fadeToBlackBy(leds, NUM_LEDS, 200);
+  fadeToBlackBy(leds, NUM_LEDS, 150);
   numberOfSparkles = upAndDownBy(numberOfSparkles, 1);
   for (int i = 0; i < numberOfSparkles * 3; i++) {
     int pos = random16(NUM_LEDS);
@@ -303,8 +303,8 @@
     thisrot = 0;                                          // You can change how quickly the hue rotates for this wave. Currently 0.
     allsat = 255;                                         // I like 'em fully saturated with colour.
     thisdir = 0;                                             // You can change direction.
-    thisspeed = 32;                                         // You can change the speed, and use negative values.
-    allfreq = 32;                                         // You can change the frequency, thus overall width of bars.
+    thisspeed = 6;                                         // You can change the speed, and use negative values.
+    allfreq = 64;                                         // You can change the frequency, thus overall width of bars.
     thisphase = 0;                                            // Phase change value gets calculated.
     thiscutoff = 200;                                     // You can change the cutoff value to display this wave. Lower value = longer wave.
   }


petite correction sur les stat de fin pour que la machine s'arette quand le compteur  reste stable à 20 impulsion pres.

--- calibrateur.ino
+++ calibrateur.ino
@@ -9,7 +9,7 @@

 //nettoyer code de la potence (2e servo)

-
+//afaire : faire un réinit propre car si on fait 2 étalonnage à la suite ca marche pas
 //a Faire : lire l'autre voie de la roue codeuse pour detectr les rebond du servo

 //a faire tester repetabilité avec tempo à 100 et à 200. Avec 100 on a des comportement louche lors des cycles de fin (le servo bouge apeine sur certains des cycle a la palce d'un grand débatement)
@@ -418,7 +418,7 @@
 							sleep(TEMPO_STAT);
               Serial.print("cmpt=");
               Serial.println(compteur);
-								while (compteur>compteurRef)
+								while (compteur>compteurRef+20)
 								{

 									compteurRef=compteur;
@@ -442,7 +442,7 @@
 							tempsMesureVitesse=millis();
 							leServo.setObjectif(leServo.getMin());
 							sleep(TEMPO_STAT);
-								while (compteur>compteurRef)
+								while (compteur>compteurRef+20)
 									{
 									compteurRef=compteur;


EEPROM 에 Config 를 저장하는 코드를 좀 더 직관적으로 바꿈.

--- Arduino/Arduino.ino
+++ Arduino/Arduino.ino
@@ -29,7 +29,7 @@
 #define RES_UNLINK_LEN 8
 #define RES_NONE 0

-#define VER 102
+#define VER 104
 #define MODE_BOOT 0
 #define MODE_SETUP 1
 #define MODE_RUN 2
@@ -37,6 +37,12 @@

 #define DELAY_PUSH_SETUP 5000
 #define DELAY_LED_SETUP 500
+#define DATA_STATE_WAIT 0
+#define DATA_STATE_HTTP_FIND_FPATH 1
+#define DATA_STATE_HTTP_FIND_EPATH 2
+#define DATA_STATE_HTTP_FIND_EOL 3
+#define DATA_STATE_HTTP_SEND_PAGE 4
+

 typedef struct Config {
   uint8_t version = VER;
@@ -44,8 +50,8 @@
   char ssid[32] = "unknown";
   char pass[32] = "unknown";
   char serverAddr[64] = "unknown";
-  int port = 80;
-  uint8_t tailVersion = VER;
+  uint16_t port = 80;
+  uint8_t tailVersion = VER;
 } CONFIG;

@@ -54,26 +60,24 @@
 uint8_t checkResString(char ch, uint8_t idx);
 bool equalResType(uint8_t refResLen, uint8_t targetResLen);
 bool isResCheckOk(uint8_t checkResresult);
-void intoSetupMode();
+bool checkConfig(CONFIG* config);
+void intoSetupMode(bool force = false);
 void setMode();
 void showStatusLed();
-void saveData(const void* data, int start, int length);
-void loadData(void* data, int offset, int length);
-bool checkConfig(CONFIG* config);
+void saveConfig();
+void loadConfig();
 void printConfig(CONFIG* config);

-bool _isLink = false;
+//bool _isLink = false;
+void resetBuffer();
 uint8_t _buffer[BUFF_SIZE];
 int _bufferIdx = 0;
 int _resIdx = 0;
+int _dataState = 0;
 long _lastClickMillis = 0;
 long _lastOnLedMillis = 0;
 CONFIG _config;
 SoftwareSerial wifi(WIFI_RX, WIFI_TX);
-
-
-
-

 void setup() {
@@ -84,7 +88,7 @@
     Serial.begin(9600);
     Serial.println("debug :: Ready..");
   #endif
-  loadData(&_config, 0, sizeof(_config));
+  loadConfig();
   if(!checkConfig(&_config)) {
     _config = Config();
     #ifdef DEBUG
@@ -97,7 +101,10 @@
     printConfig(&_config);
   }
   #endif
-
+  Serial.println(_config.mode );
+  if(_config.mode == MODE_SETUP) {
+    intoSetupMode(true);
+  }
 }

 void loop() {
@@ -119,30 +126,53 @@
       #endif
    }
    showStatusLed();
+

    if(_config.mode == MODE_SETUP && wifi.available()) {
       uint8_t data = wifi.read();
-      _buffer[_bufferIdx % BUFF_SIZE] = data;
       uint8_t result = checkResString(data,_resIdx);
+

       if(equalResType(RES_LINK_LEN,result)) {
-        _isLink = true;
+        _dataState = DATA_STATE_HTTP_FIND_FPATH;
         _resIdx = 0;
         #ifdef DEBUG
         Serial.println("debug : LINKED");
         #endif
-      } else if(equalResType(RES_UNLINK_LEN,result)) {
-        _isLink = false;
+      } else if(equalResType(RES_OK_LEN,result) && _dataState == DATA_STATE_HTTP_FIND_FPATH) {
+        _dataState = DATA_STATE_WAIT;
         _resIdx = 0;
         #ifdef DEBUG
-        Serial.println("debug : UNLINKED");
+        Serial.println("debug : WAIT");
         #endif
+      } else if(_dataState == DATA_STATE_HTTP_FIND_EOL && isResCheckOk(result)) {
+        if(strncmp((char*)_buffer, "/set/", 5) > 0) {
+          for(int i = 5; --i;) {
+            _buffer[5 - i - 1] = i;
+          }
+
+          char * token = NULL;
+
+
+        }
+
       } else if(result == RES_NONE || isResCheckOk(result)) {
         _resIdx = 0;
       } else {
         _resIdx++;
       }
-
+
+      if(_dataState == DATA_STATE_HTTP_FIND_FPATH && data == '/') {
+        _dataState = DATA_STATE_HTTP_FIND_EPATH;
+        resetBuffer();
+        _buffer[_bufferIdx % BUFF_SIZE] = data;
+      } else if(_dataState == DATA_STATE_HTTP_FIND_EPATH) {
+        if(data == ' ') {
+          _dataState = DATA_STATE_HTTP_FIND_EOL;
+        } else {
+          _buffer[_bufferIdx % BUFF_SIZE] = data;
+        }
+      }
       _bufferIdx++;
       #ifdef DEBUG
         Serial.write((char)data);
@@ -180,6 +210,16 @@

 }

+/**
+ * Buffer 에 있는 내용을 모두 0으로 채운다. memset 함수가 종종 이상하게 동작하여 느러도 이 것으로 대체.
+ */
+void resetBuffer() {
+  _bufferIdx = 0;
+  for(int i = BUFF_SIZE; --i;) {
+    _buffer[i] = 0;
+  }
+}
+

 void showStatusLed() {
   int delayMillis = 0;
@@ -201,10 +241,10 @@
   }
 }

-void intoSetupMode() {
-  if(_config.mode == MODE_SETUP) return;
+void intoSetupMode(bool force) {
+  if(_config.mode == MODE_SETUP && !force) return;
   _config.mode = MODE_SETUP;
-  saveData(&_config,0,sizeof(_config));
+  saveConfig();
   sendATCmd("AT+RST\r\n", 2000);
   sendATCmd("AT+CWMODE=2\r\n");
   sendATCmd("AT+CIPMUX=1\r\n");
@@ -269,6 +309,11 @@
   return (targetResLen & ~0x80) == refResLen;
 }

+/**
+ *
+ */
+
+
 uint8_t checkResString(char ch, uint8_t idx) {
   if(idx < RES_UNKNOWN_LEN && ch == RES_UNKNOWN[idx]) {
      return RES_UNKNOWN_LEN;
@@ -301,26 +346,55 @@
   return 0;
 }

-
-void loadData(void* data, int offset, int length) {
-    uint8_t* pos = (uint8_t*)data;
-    for(int i = 0; --length; ++i,++pos) {
-       *pos = EEPROM.read(i);
-    }
-}
-
-void saveData(const void* data, int start, int length) {
-  const uint8_t* pos = (const uint8_t*)data;
-  Serial.println(length);
-  int ln = length;
-  for(int i = start; --length; ++i,++pos) {
-      EEPROM.write(i, *pos);
-  }
-  #ifdef DEBUG
-      Serial.begin(9600);
-      Serial.println("debug :: config saved");
-   #endif
-}
+void loadConfig() {
+  int offset = 0;
+  _config.version = EEPROM.read(offset++);
+  _config.mode = EEPROM.read(offset++);
+  for(int i = 0, n = sizeof(_config.ssid);i < n; ++i)
+    _config.ssid[i] = EEPROM.read(offset++);
+
+  for(int i = 0, n = sizeof(_config.pass);i < n; ++i)
+    _config.pass[i] = EEPROM.read(offset++);
+
+  for(int i = 0, n = sizeof(_config.serverAddr);i < n; ++i)
+    _config.serverAddr[i] = EEPROM.read(offset++);
+
+  _config.port =  ((short)EEPROM.read(offset++)) << 8;
+  _config.port  |=  EEPROM.read(offset++);
+  _config.tailVersion = EEPROM.read(offset);
+}
+
+
+void saveConfig() {
+  Serial.print("SSID SIZE : ");
+  Serial.println(sizeof(_config.ssid));
+  int offset = 0;
+  EEPROM.write(offset++, _config.version);
+  EEPROM.write(offset++, _config.mode);
+  for(int i = 0, n = sizeof(_config.ssid);i < n; ++i)
+    EEPROM.write(offset++, _config.ssid[i]);
+
+  for(int i = 0, n = sizeof(_config.pass);i < n; ++i)
+    EEPROM.write(offset++, _config.serverAddr[i]);
+
+  for(int i = 0, n = sizeof(_config.serverAddr);i < n; ++i)
+    EEPROM.write(offset++, _config.serverAddr[i]);
+
+  EEPROM.write(offset++, (byte)(_config.port >> 8));
+  EEPROM.write(offset++, (byte)_config.port);
+  EEPROM.write(offset++, _config.tailVersion);
+}
+
+/*typedef struct Config {
+  uint8_t version = VER;
+  uint8_t mode = MODE_BOOT;
+  char ssid[32] = "unknown";
+  char pass[32] = "unknown";
+  char serverAddr[64] = "unknown";
+  int port = 80;
+  uint8_t tailVersion = VER;
+} CONFIG;*/
+

 bool checkConfig(CONFIG* config) {
   return config->tailVersion == VER && config->version == VER;


timelapse needs delay

timelapse needs delay

--- d_BacpacCommands.ino
+++ d_BacpacCommands.ino
@@ -1,4 +1,4 @@
-#define MEWPRO_VERSION_STRING "2016020700"
+#define MEWPRO_VERSION_STRING "2016021200"

 void printHex(uint8_t d, boolean upper)
 {
@@ -210,7 +210,7 @@
       Serial.println("");
     }
     buf[0] = 0x83; buf[1] = 'S'; buf[2] = 'R'; buf[3] = RECV(3);
-    if (buf[3] == 1 && td[TD_MODE] != MODE_TIMELAPSE) {
+    if (buf[3] == 1) {
       delay(1000); // start of a capture requres additional delay
     }
     delay(140);


Added interlock checking

Added interlock checking

--- module/module.ino
+++ module/module.ino
@@ -235,7 +235,8 @@
     	else {
       		i += 1;
     	}
-
+
+    	digitalWrite(interlock, HIGH);
 		delay(pollInterval);
 	}
 }


updates to new prototype walkie talkie code to include notification

--- WalkieTalkie/WalkieTalkie.ino
+++ WalkieTalkie/WalkieTalkie.ino
@@ -71,26 +71,27 @@
 RF24Audio rfAudio(radio,0); // Set up the audio using the radio, and set to radio number 0

 const uint8_t talkButton = 3;
-const uint8_t callButton = 2;

 int messageLength = 12;
 int msg[1];
-RF24 radio(7,8);
 const uint64_t pipe = 0xE8E8F0F0E1LL;
 int lastmsg = 1;
-String theMessage = "";
+//String theMessage = "";
 char theChar = 0;

-
+const uint8_t call = 5;

 void setup()
 {
   Serial.begin(115200);
+
+  pinMode(call, INPUT);
+  //digitalWrite(LED, LOW);

   printf_begin();
   radio.begin();
@@ -101,7 +102,6 @@

   //sets interrupt to check for button talk abutton press
   attachInterrupt(digitalPinToInterrupt(talkButton), talk, RISING);
-  attachInterrupt(digitalPinToInterrupt(callButton), call, RISING);

   //sets the default state for each module to recevie
   rfAudio.receive();
@@ -119,14 +119,66 @@
 }

-void call()
-{
-
-  if (digitalRead(talkButton)) rfAudio.transmit();
-  else rfAudio.receive();
-}
+//void call()
+//{
+//
+//  if (digitalRead(talkButton)) rfAudio.transmit();
+//  else rfAudio.receive();
+//}

 void loop()
 {
+  Serial.println(digitalRead(call));
+  if(digitalRead(call))
+  {
+
+    String theMessage = "*A";
+    int messageSize = theMessage.length();
+
+    for (int i = 0; i < messageSize; i++)
+    {
+      int charToSend[1];
+      charToSend[0] = theMessage.charAt(i);
+        radio.begin();
+  radio.openWritingPipe(pipe);
+
+      radio.write(charToSend, 1);
+      Serial.println("hello");
+      Serial.println(theMessage);
+    }
+
+    //send the 'terminate string' value
+    msg[0] = '&';
+    radio.write(msg,1);
+    Serial.println(theMessage);
+
+    delay(5);
+  }
+  delay(10);
+//
+//  if(radio.available())
+//  {
+//    //Serial.println("got the call");
+//
+//    radio.read(msg, 1);
+//    theChar = msg[0];
+//
+//    if(msg[0] == '*'){
+//      digitalWrite(LED, HIGH);
+//      radio.read(msg, 1);
+//      theChar = msg[0];
+//
+//      while(msg[0] != '&'){
+//
+//        if (theChar != NULL){
+//        theMessage.concat(theChar);
+//        }
+//
+//        radio.read(msg, 1);
+//        theChar = msg[0];
+//      }
+//    }
+//  }
+
 }


Changed the UI to be independent of the ranges of the motor. All calls now return -1 to 1 and the middleware maps that to the motor ranges in the ArduinoPhysics.js file.

--- OpenROV/OpenROV.ino
+++ OpenROV/OpenROV.ino
@@ -40,6 +40,8 @@
 int v = MIDPOINT;
 int s = MIDPOINT;
 int smoothingIncriment = 5; //How aggressive the throttle changes
+int deadZone_min = MIDPOINT;
+int deadZone_max = MIDPOINT;
 void setup(){

   Serial.begin(115200);
@@ -73,7 +75,14 @@
   // the way to the target this time.
   double x = target - current;
   int sign = (x>0) - (x<0);
-  return(current + sign * (min(abs(target - current), smoothingIncriment)));
+  int adjustedVal = current + sign * (min(abs(target - current), smoothingIncriment));
+  // skip the deadzone
+  if (sign<0) {
+    return (min(adjustedVal,deadZone_min));
+  } else if(sign>0){
+    return (max(adjustedVal,deadZone_max));
+  } else
+    return (adjustedVal);
 }

 void loop(){
@@ -110,6 +119,14 @@
       Serial.print("*settings:");
       Serial.print("smoothingIncriment|");
       Serial.print(String(smoothingIncriment) + ";");
+      Serial.print("deadZone_min|" + String(deadZone_min) + ";");
+      Serial.print("deadZone_max|" + String(deadZone_max) + ";");
+    }
+    else if (cmd.cmp("updateSetting")) {
+      cmd.parse(array);
+      smoothingIncriment = array[1];
+      deadZone_min = array[2];
+      deadZone_max = array[3];
     }
     else {
       motors.stop();


Changed timer5's divisor to make PWM frequency 3921Hz on PWM1,2 and 3

--- OpenROV/OpenROV.ino
+++ OpenROV/OpenROV.ino
@@ -17,6 +17,9 @@
 	NConfigManager::Initialize();
 	NModuleManager::Initialize();
 	NDataManager::Initialize();
+
+	// Set timer 5 divisor to 8 for PWM frequency of 3921.16Hz (D44, D45, D46)
+	TCCR5B = TCCR5B & B11111000 | B00000010;

 	// Boot complete
 	Serial.println( F( "boot:1;" ) );


Get DU-SEQ example to working state.

Get DU-SEQ example to working state.

--- examples/seq/seq.ino
+++ examples/seq/seq.ino
@@ -69,7 +69,7 @@
   uint8_t stage_count;
   bool diradd_mode;
   uint8_t slew_rate;
-  uint8_t gate_time;
+  uint16_t gate_ms;
   unsigned long clock_period;
   bool clock_ext;
 };
@@ -85,10 +85,11 @@

 class DU_SEQ_Function : public DUINO_Function {
  public:
-  DU_SEQ_Function() : DUINO_Function(0b0111110000) { }
+  DU_SEQ_Function() : DUINO_Function(0b0111111111) { }

   virtual void setup()
   {
+    // TODO: attach GT3 to hardware clock isr that sets clock to EXT
     gt_attach_interrupt(GT3, clock_isr, CHANGE);
     gt_attach_interrupt(GT4, reset_isr, RISING);

@@ -97,15 +98,17 @@

   virtual void loop()
   {
-    // cache stage and step
-    uint8_t cached_stage, cached_step;
+    // cache stage, step, and clock gate (so that each loop is "atomic")
     ATOMIC_BLOCK(ATOMIC_FORCEON)
     {
       cached_stage = stage;
       cached_step = step;
-    }
-
-    if(retrigger)
+      cached_clock_gate = clock_gate;
+      cached_retrigger = retrigger;
+      retrigger = false;
+    }
+
+    if(cached_retrigger)
     {
       if(!cached_step)
       {
@@ -157,32 +160,20 @@
     cv_out(CO1, seq_values.stage_cv[cached_stage]);

     // set gate and clock states
-    if(gate && (clock_gate || retrigger))
-    {
-      gt_out(GT_MULTI | (1 << GT5) | (1 << GT6), true);
-    }
-    else
-    {
-      gt_out(GT5, gate);
-      gt_out(GT6, clock_gate || retrigger);
-    }
-
-    // reset retrigger
-    if(retrigger)
-    {
-      retrigger = false;
-      clock_gate &= seq_values.clock_ext;
-    }
+    gt_out(GT5, gate);
+    gt_out(GT6, cached_clock_gate);
   }

  private:
   bool partial_gate()
   {
-    return (seq_values.clock_ext && clock_gate)
-           || (millis() - clock_time < (seq_values.gate_time * (seq_values.clock_period / 16000)))
-           || retrigger;
-  }
-
+    return (seq_values.clock_ext && cached_clock_gate)
+           || cached_retrigger
+           || ((millis() - clock_time) < seq_values.gate_ms);
+  }
+
+  uint8_t cached_stage, cached_step;
+  bool cached_clock_gate, cached_retrigger;
   unsigned long clock_time;
 };

@@ -262,7 +253,7 @@
     {
       params.vals.gate_time = 8;
     }
-    seq_values.gate_time = params.vals.gate_time;
+    seq_values.gate_ms = params.vals.gate_time * (uint16_t)(seq_values.clock_period / 8000);

     if(params.vals.clock_bpm < 0 || params.vals.clock_bpm > 30)
     {
@@ -270,8 +261,8 @@
     }
     seq_values.clock_period = bpm_to_us(params.vals.clock_bpm);
     seq_values.clock_ext = !(bool)params.vals.clock_bpm;
-    Timer1.initialize(seq_values.clock_period);
-    Timer1.attachInterrupt(clock_isr);
+    Timer1.initialize();
+    update_clock();

     // draw global elements
     display->draw_char(38, 2, '0' + params.vals.stage_count, DUINO_SSD1306::White);
@@ -405,7 +396,7 @@
               {
                 params.vals.gate_time = 16;
               }
-              seq_values.gate_time = params.vals.gate_time;
+              seq_values.gate_ms = params.vals.gate_time * (uint16_t)(seq_values.clock_period / 8000);
               display->fill_rect(79, 3, 16, 5, DUINO_SSD1306::White);
               display_gate_time(79, 3, params.vals.gate_time, DUINO_SSD1306::Black);
               break;
@@ -496,7 +487,7 @@
     }

     // display gate
-    if(!retrigger && (gate != last_gate || stage != last_stage))
+    /*if(!retrigger && (gate != last_gate || stage != last_stage))
     {
       if(gate)
       {
@@ -514,7 +505,7 @@
       last_gate = gate;
       last_stage = stage;
       display_changed = true;
-    }
+    }*/

     if(display_changed)
     {
@@ -526,14 +517,10 @@
  private:
   void update_clock()
   {
-    if(seq_values.clock_ext)
-    {
-      Timer1.detachInterrupt();
-    }
-    else
-    {
-      Timer1.setPeriod(seq_values.clock_period);
-      Timer1.attachInterrupt(clock_isr);
+    Timer1.detachInterrupt();
+    if(!seq_values.clock_ext)
+    {
+      Timer1.attachInterrupt(clock_isr, seq_values.clock_period);
     }
   }

@@ -544,7 +531,7 @@

   unsigned long bpm_to_us(uint8_t bpm)
   {
-    return 6000000 / (unsigned long)bpm;
+    return 750000 / (unsigned long)bpm;
   }

   void display_slew_rate(int16_t x, int16_t y, uint8_t rate, DUINO_SSD1306::SSD1306Color color)
@@ -719,7 +706,7 @@

 void clock_isr()
 {
-  clock_gate = !seq_values.clock_ext || function->gt_read(GT3);
+  clock_gate = seq_values.clock_ext ? function->gt_read_debounce(GT3) : !clock_gate;

   if(clock_gate)
   {
@@ -737,7 +724,6 @@
 void reset_isr()
 {
   stage = step = 0;
-  retrigger = true;
 }

 void setup()


Update PDM_SPM1423.ino

Update PDM_SPM1423.ino

--- examples/Unit/PDM_SPM1423/PDM_SPM1423.ino
+++ examples/Unit/PDM_SPM1423/PDM_SPM1423.ino
@@ -46,9 +46,12 @@
                                         // 固定为12位立体声MSB
         .channel_format =
             I2S_CHANNEL_FMT_ONLY_RIGHT,  // Set the channel format. 设置频道格式
+#if ESP_IDF_VERSION > ESP_IDF_VERSION_VAL(4, 1, 0)
         .communication_format =
             I2S_COMM_FORMAT_STAND_I2S,  // Set the format of the communication.
-                                  // 设置通讯格式
+#else                                   // 设置通讯格式
+        .communication_format = I2S_COMM_FORMAT_I2S,
+#endif
         .intr_alloc_flags =
             ESP_INTR_FLAG_LEVEL1,  // Set the interrupt flag.  设置中断的标志
         .dma_buf_count = 2,        // DMA buffer count.  DMA缓冲区计数


Reversion

Reversion

--- rocker/rocker.ino
+++ rocker/rocker.ino
@@ -45,7 +45,6 @@
 /* LOOP */
 /********/
 void loop() {
-  cli();
   Serial.println("Enter frequency, amplitude");
   while ( Serial.available() == 0 ) {}
    int n = Serial.readBytesUntil(',',buf,BUFLEN);
@@ -75,19 +74,17 @@
      float ampus = amp*(float)(maxt-mint)/180.0;
      float mid = (float)(maxt+mint)/2.0;
      long start = micros();
-     //cli();
+
      while ( Serial.available() == 0 ) {
        long time = micros();
-       digitalWrite(SERVO_PIN, HIGH);
        pos = round(ampus*sin(2*PI*freq*(time-start)/1000000.0) + mid);
-       while (micros() - time < pos) {}
-       digitalWrite(SERVO_PIN, LOW);
-       while (micros() - time < 20000) {}
+       servo.writeMicroseconds(pos);
      }
-     //sei();
+
      while( pos != round(mid))
      {
-       pos = round(ampus*sin(2*PI*freq*(micros()-start)/1000000.0) + mid);
+       long time = micros();
+       pos = round(ampus*sin(2*PI*freq*(time-start)/1000000.0) + mid);
        servo.writeMicroseconds(pos);
      }
    }


Better output.

Better output.

--- water_heater_monitor/water_heater_monitor.ino
+++ water_heater_monitor/water_heater_monitor.ino
@@ -103,7 +103,7 @@

 void updateWeb() {
-  Serial.print(F("Sending data... "));
+  Serial.println(F("Sending data... "));

   client.connect(PHANT_HOST, PHANT_HOST_PORT);
   if (client.connected()) {
@@ -155,9 +155,9 @@
     }

     client.close();
-    Serial.println(F(" done."));
+    Serial.println(F("Done."));
   } else {
-    Serial.println(F(" web server connection failed."));
+    Serial.println(F("Web server connection failed."));
   }

   data_port.flush();  // clear any data in the serial buffer we missed while sending.


Fouten

Fouten

--- Claw/Claw_controller/Claw_controller.ino
+++ Claw/Claw_controller/Claw_controller.ino
@@ -3,6 +3,7 @@
 int grabCount;
 int teller;
 int vorigeStatus;
+int graden;

 bool grabdingStaatStil = false;
 bool claw = false;
@@ -29,9 +30,9 @@
   // put your main code here, to run repeatedly:

   analogRead (buttonState);
-  servoposition = map(buttonState, 0, 1023, 0, 180); //" map(value, fromLow, fromHigh, toLow, toHigh)
+  servoPosition = map(buttonState, 0, 1023, 0, 180); //" map(value, fromLow, fromHigh, toLow, toHigh)

-  if (graden = < 30 && grabdingStaatStil)
+  if (graden <= 30 && grabdingStaatStil)
   {
     if (claw == false)
     {


update example

update example

--- Examples/SPIDaisyChain/SPIDaisyChain.ino
+++ Examples/SPIDaisyChain/SPIDaisyChain.ino
@@ -1,9 +1,12 @@
 #include "SPI.h"
 #include "SPIDaisyChain.h"

-SPIDaisyChain spi(10, 2);	// CS pin, chained number
+const uint8_t PIN_CS = 10;
+const uint8_t NUM_DEVICE = 3;
+SPIDaisyChain spi(PIN_CS, NUM_DEVICE);	// CS pin, chained number

-byte data[2] = {1, 2};
+byte send_data[NUM_DEVICE] = {1, 2, 3};
+byte recv_data[NUM_DEVICE] = {0, 0, 0};

 void setup()
 {
@@ -11,6 +14,12 @@

 void loop()
 {
-	// send data[0] to far device, data[1] to near device
-	spi.transferDaisyChain(data);
+    // send data[0] to far device, data[1] to near device
+    recv_data = spi.transferDaisyChain(data);
+
+    for (uint8_t i = 0; i < NUM_DEVICE; ++i)
+    {
+        Serial.print(recv_data[i], HEX); Serial.print(" ");
+    }
+    Serial.println();
 }


- slightly tweak LED example

- slightly tweak LED example

--- examples/led/led.ino
+++ examples/led/led.ino
@@ -5,28 +5,29 @@
 #define BLE_RDY 2
 #define BLE_RST 9

-BLEPeripheral blePeripheral = BLEPeripheral(BLE_REQ, BLE_RDY, BLE_RST);
+BLEPeripheral      blePeripheral       = BLEPeripheral(BLE_REQ, BLE_RDY, BLE_RST);

-BLEService ledService = BLEService("19b10001e8f2537e4f6cd104768a1214");
+BLEService        ledService           = BLEService("19b10000e8f2537e4f6cd104768a1214");
 BLECharacteristic switchCharacteristic = BLECharacteristic("19b10001e8f2537e4f6cd104768a1214", BLE_PROPERTY_READ | BLE_PROPERTY_WRITE, 1);
+
+char switchValue[1];

 void setup() {
   Serial.begin(115200);
-
+
   pinMode(3, OUTPUT);
-
+
   blePeripheral.setLocalName("LED");
-  blePeripheral.setAdvertisedServiceUuid("19b10001e8f2537e4f6cd104768a1214");
+  blePeripheral.setAdvertisedServiceUuid("19b10000e8f2537e4f6cd104768a1214");

   blePeripheral.addAttribute(ledService);
   blePeripheral.addAttribute(switchCharacteristic);

-  char initialSwitchValue[1] = {0x00};
-
-  switchCharacteristic.setValue(initialSwitchValue, 1);
+  switchValue[0] = 0;
+  switchCharacteristic.setValue(switchValue, 1);

   blePeripheral.begin();
-
+
   Serial.println(F("BLE LED Peripheral"));
 }


Fixed typo

Fixed typo

--- esp8266-weather-station.ino
+++ esp8266-weather-station.ino
@@ -301,7 +301,7 @@

         configTime(timezoneSec, 0, "pool.ntp.org", "time.nist.gov");
         DebugPrint(debug, "Waiting for time");
-        const unsigned int waitTill = millis() + 5000;
+        const unsigned long waitTill = millis() + 5000;
         while (millis() < waitTill)
         {
             DebugPrint(debug, ".");


Update receive_check.ino

Update receive_check.ino

Checking CAN.checkReceive() agains MC_STAT_RXIF_MASK doesn't seem to make sense, it was confusing to me because the code seemed to be using equality with a mask. Since checkReceive() actually returns CAN_MSGAVAIL or CAN_NOMSG, Comparison with CAN_MSGAVAIL seemed more informative than MC_STAT_RXIF_MASK.


Update Brief.ino

Update Brief.ino

--- examples/Brief/Brief.ino
+++ examples/Brief/Brief.ino
@@ -11,7 +11,7 @@

 void setup()
 {
-    brief::setup(19200);
+    brief::setup();

     // Bind extended function to a custom instruction (100)
     // In the interactive: 100 'delay instruction


Solved initial power reports instability

--- firmware/smc/src/smc.ino
+++ firmware/smc/src/smc.ino
@@ -7,14 +7,18 @@
 #define LIKE_BUT    7
 #define POT_IN      A0

+#include <TimerOne.h>
+
+// Third party libraries
+// ClickEncoder https://github.com/0xPIT/encoder
 #include <ClickEncoder.h>
-#include <TimerOne.h>
-#include <Bounce.h>
+// Bounce2 https://github.com/thomasfredericks/Bounce-Arduino-Wiring/
+#include <Bounce2.h>

 ClickEncoder *encoder;
 ClickEncoder::Button lastBtnState = encoder->getButton();

-Bounce bouncer = Bounce(POW_SWITCH, 20);
+Bounce bouncer = Bounce();

 void timerIsr()
@@ -71,6 +75,8 @@
     encoder->setAccelerationEnabled(true);

     pinMode(POW_SWITCH, INPUT_PULLUP);
+    bouncer.attach(POW_SWITCH);
+    bouncer.interval(10);
 }

 void loop()


PIDDDDDD!!!!!!

PIDDDDDD!!!!!!

--- firefighter/firefighter.ino
+++ firefighter/firefighter.ino
@@ -28,6 +28,9 @@
 #define LEFT_MOTOR_1B 3

 #define INTERRUPT_PIN 2
+
+#define setpoint 0
+#define kP 0.05

 Servo extingusher_servo;

@@ -53,7 +56,7 @@
 void hDrive(double move, double rotate, double strafe);
 void tankDrive(double leftSpeed, double rightSpeed, double strafeSpeed);
 void definedStartSearch();
-double getAngle(double targetAngle);
+double getAngle();
 double getAngle(char axis);
 double getPercentError(double actual, double target);
 void turnToAngle(double targetAngle, double speed);
@@ -406,6 +409,10 @@
   }

   hDrive(0.0, 0.0, 0.0);
+}
+
+double getPidOutput() {
+  return (setpoint - getAngle('x')) * kP;
 }

 void extinguish() {


Updated changes to ClockFOUR_30

Updated changes to ClockFOUR_30

--- arduino/ClockFOUR_30/LED_Display.ino
+++ arduino/ClockFOUR_30/LED_Display.ino
@@ -129,11 +129,9 @@
 	#define COLOUR_UPDATE	5		// Defines the rate at which the colour mode gets updated, in multiples of LETTER_FADE

 	static uint32_t lastRefresh = 0;
-
 	static uint8_t colourIteration = 0;
 	static int16_t fadeBrightness = 255;
 	static uint8_t colourUpdate = 0;
-	static uint8_t ledColours[MATRIX_WIDTH * MATRIX_HEIGHT * 3];

 	uint32_t currentMillis = millis();

@@ -170,24 +168,14 @@
 	// Loop through every LED
 	for(uint16_t pixIdx = 0; pixIdx < MATRIX_HEIGHT * MATRIX_WIDTH; pixIdx++) {

-		uint32_t pixColour = 0;
-
 		// Get the current pixel transition
 		PixelTransition pixTran = pixels.getPixel(pixIdx);
-
+
 		// Get the colour for the given pixel
+		uint32_t pixColour = 0;
+
 		if(pixTran != PIX_OFF) {
-			if(colourUpdate == 0) {
-				// Get new colour if we need to
-				pixColour = getPixColour(pixIdx, mode, colour, colourIteration);
-
-				ledColours[pixArrIdx] = (uint8_t)(pixColour >> 16);
-				ledColours[pixArrIdx + 1] = (uint8_t)(pixColour >>  8);
-				ledColours[pixArrIdx + 2] = (uint8_t)pixColour;
-			} else {
-				// Get the old colour
-				pixColour = strip.Color(ledColours[pixArrIdx], ledColours[pixArrIdx + 1], ledColours[pixArrIdx + 2]);
-			}
+			pixColour = getPixColour(pixIdx, mode, colour, colourIteration);
 		}

 		// Determine the pixel transitions
@@ -236,6 +224,25 @@

 // This function returns the colours of the different pixels given pixel index, colour mode, input colour and colour iteration
 inline uint32_t getPixColour(uint16_t pixIdx, uint8_t mode, uint32_t colour, uint8_t colourIteration)  {
+	static uint8_t prevIteration = 0;
+	static uint16_t randomSeed = 0;
+
+	uint16_t randomVal;
+
+	// Get a new random value whenever we enter a new iteration
+	if(prevIteration != colourIteration) {
+		randomSeed = random();
+		prevIteration = colourIteration;
+	}
+
+	// Perform a hashing operation based on the random seed and the pixIdx
+	randomVal = randomSeed + pixIdx;
+	randomVal += randomVal << 10;
+	randomVal ^= randomVal >> 6;
+	randomVal += randomVal << 3;
+	randomVal ^= randomVal >> 11;
+
+
 	switch(mode) {
 	case CM_ALL_WHITE:
 		return strip.Color(235,   255,   255);
@@ -254,7 +261,7 @@
 		break;

 	case CM_PARTY:
-		return wheel(random(0, 255));
+		return wheel(randomVal & 0xFF);
 		break;

 	default:


Initial response split for basic JSON

Initial response split for basic JSON

--- arduino-esp8266.ino
+++ arduino-esp8266.ino
@@ -1,4 +1,4 @@
-#include "config/config.h"
+#include "config.h"
 #include <AltSoftSerial.h>

 // Arduino pin 08 for RX
@@ -30,11 +30,26 @@
       // Make Request
       Serial.println("Making request");
       altSerial.print("GET " + BASE_REST + "list/game HTTP/1.0\r\n\r\n");
-      getReply( 5000 );
+      getGames( 5000 );
 }

 void loop() {

+}
+
+void getJSONFromResponse(char* responseData) {
+
+  char *p, *i, *x;
+
+   p = strtok_r(responseData, STARTDELIMITER,&i);
+   x = strtok_r(i,ENDDELIMITER,&i);
+   Serial.print(x);
+
+//
+//  Serial.println("--------------\r\n\r\n");
+//  Serial.println(responseData);
+//  Serial.println("--------------\r\n\r\n");
+//
 }

 void getReply(int wait)
@@ -58,3 +73,25 @@
     Serial.println("\r\n"); // New line for legibility
 }

+
+void getGames(int wait)
+{
+    int index = 0;
+    long int time = millis();
+
+    // Sorry
+    while( (time + wait) > millis())
+    {
+        while(altSerial.available())
+        {
+            char c = altSerial.read();
+              reply[index] = c;
+              index++;
+        }
+    }
+
+    getJSONFromResponse(reply);
+
+    Serial.println( reply ); // Output response
+    Serial.println("\r\n"); // New line for legibility
+}


updated parallel out test

updated parallel out test

--- proj/parallel_out_test/parallel_out_test.ino
+++ proj/parallel_out_test/parallel_out_test.ino
@@ -33,7 +33,9 @@
     if (ss == 0) {
       fill_solid(leds, NUM_LED, ColorFromPalette(test, ss * 16, 32, LINEARBLEND));
     }
-    fill_solid(leds + ss * NUM_LED, NUM_LED, ColorFromPalette(test, ss * 16, 32, LINEARBLEND));
+    else {
+      fill_solid(&(leds[ss * NUM_LED]), NUM_LED, ColorFromPalette(test, ss * 16, 32, LINEARBLEND));
+    }
   }


added logic

added logic

--- T3/src/AFE-Firmware-T3.ino
+++ T3/src/AFE-Firmware-T3.ino
@@ -21,11 +21,11 @@
 AFEMQTT Mqtt;
 AFEWebServer WebServer;
 AFELED Led;
-AFESwitch Switch;
+AFESwitch Switch[5];
 AFESwitch ExternalSwitch;
-AFERelay Relay;
+AFERelay Relay[4];
 MQTT MQTTConfiguration;
-AFEPIR Pir;
+AFEPIR Pir[4];

 void setup() {

@@ -54,9 +54,13 @@
   }

   /* Initializing relay and setting it's default state at power on*/
-  if (Device.getMode() == MODE_NORMAL && Device.configuration.isRelay[0]) {
-    Relay.begin(0);
-    Relay.setRelayAfterRestoringPower();
+  if (Device.getMode() == MODE_NORMAL) {
+    for (uint8_t i = 0; i < 4; i++) {
+      if (Device.configuration.isRelay[i]) {
+        Relay[i].begin(i);
+        Relay[i].setRelayAfterRestoringPower();
+      }
+    }
   }

   /* Initialzing network */
@@ -71,14 +75,18 @@
   }

   /* Initializing Switches */
-  if (Device.configuration.isSwitch[0]) {
-    Switch.begin(0);
-  }
-  if (Device.configuration.isSwitch[1]) {
-    ExternalSwitch.begin(1);
-  }
-
-  Pir.begin(0);
+  for (uint8_t i = 0; i < 5; i++) {
+    if (Device.configuration.isSwitch[i]) {
+      Switch[i].begin(i);
+    }
+  }
+
+  /* Initializing PIRs */
+  for (uint8_t i = 0; i < 4; i++) {
+    if (Device.configuration.isPIR[i]) {
+      Pir[i].begin(i);
+    }
+  }

   /* Initializing MQTT */
   if (Device.getMode() != MODE_ACCESS_POINT && Device.configuration.mqttAPI) {
@@ -115,24 +123,42 @@
           }
         }

-        /* Relay related code */
-        if (Device.configuration.isRelay[0]) {
-
-          /* One of the switches has been shortly pressed */
-          if (Switch.isPressed() || ExternalSwitch.isPressed()) {
-            Led.on();
-            Relay.toggle();
-            MQTTPublishRelayState(); // MQTT Listener library
-            Led.off();
-          }
-        }
-
-        if (Device.configuration.isPIR[0]) {
-          if (Pir.stateChanged()) {
-            if (Pir.getState()) {
-              Relay.on();
-            } else {
-              Relay.off();
+        /* Switch related code */
+        for (uint8_t i = 0; i < 5; i++) {
+          if (Device.configuration.isSwitch[i]) {
+            /* One of the switches has been shortly pressed */
+            if (Switch[i].isPressed() && Switch[i].getFunctionality() != 0) {
+              Led.on();
+              Relay[Switch[i].getFunctionality() - 11 + i].toggle();
+              MQTTPublishRelayState(Switch[i].getFunctionality() - 11 +
+                                    i); // MQTT Listener library
+              Led.off();
+            }
+          }
+        }
+
+        for (uint8_t i = 0; i < 4; i++) {
+          if (Device.configuration.isPIR[i]) {
+            if (Pir[i].stateChanged()) {
+              Led.on();
+              MQTTPublishPIRState(i);
+              if (Pir[i].Configuration.relayId != 9 &&
+                  Pir[i].get() == PIR_OPEN) { // 9 is none
+                Relay[i].setTimer(Pir[i].Configuration.howLongKeepRelayOn);
+                Relay[Pir[i].Configuration.relayId].on();
+              }
+              Led.off();
+            }
+          }
+        }
+
+        for (uint8_t i = 0; i < 4; i++) {
+          if (Device.configuration.isRelay[i]) {
+            if (Relay[i].autoTurnOff()) {
+              Led.on();
+              Mqtt.publish(Relay[i].getMQTTTopic(), "state", "off");
+              Relay[i].clearTimer();
+              Led.off();
             }
           }
         }
@@ -149,26 +175,32 @@
   }

   /* Listens for switch events */
-  Switch.listener();
-  ExternalSwitch.listener();
-
-  /* One of the Multifunction switches pressed for 10 seconds */
-  if ((Switch.getFunctionality() == SWITCH_MULTI && Switch.is10s()) ||
-      (ExternalSwitch.getFunctionality() == SWITCH_MULTI &&
-       ExternalSwitch.is10s())) {
-    Device.getMode() == MODE_NORMAL ? Device.reboot(MODE_ACCESS_POINT)
-                                    : Device.reboot(MODE_NORMAL);
-  }
-
-  /* One of the Multifunction switches pressed for 5 seconds */
-  if ((Switch.getFunctionality() == SWITCH_MULTI && Switch.is5s()) ||
-      (ExternalSwitch.getFunctionality() == SWITCH_MULTI &&
-       ExternalSwitch.is5s())) {
-    Device.getMode() == MODE_NORMAL ? Device.reboot(MODE_CONFIGURATION)
-                                    : Device.reboot(MODE_NORMAL);
-  }
-
-  Pir.listener();
+  for (uint8_t i = 0; i < 5; i++) {
+    if (Device.configuration.isSwitch[i]) {
+      Switch[i].listener();
+    }
+  }
+
+  for (uint8_t i = 0; i < 5; i++) {
+    if (Device.configuration.isSwitch[i]) {
+      /* One of the Multifunction switches pressed for 10 seconds */
+      if (Switch[i].getFunctionality() == SWITCH_MULTI) {
+        if (Switch[i].is10s()) {
+          Device.getMode() == MODE_NORMAL ? Device.reboot(MODE_ACCESS_POINT)
+                                          : Device.reboot(MODE_NORMAL);
+        } else if (Switch[i].is5s()) {
+          Device.getMode() == MODE_NORMAL ? Device.reboot(MODE_CONFIGURATION)
+                                          : Device.reboot(MODE_NORMAL);
+        }
+      }
+    }
+  }
+
+  for (uint8_t i = 0; i < 4; i++) {
+    if (Device.configuration.isPIR[i]) {
+      Pir[i].listener();
+    }
+  }

   Led.loop();
 }


Display time in seconds

Display time in seconds

--- arduino/mearm.ino
+++ arduino/mearm.ino
@@ -30,7 +30,7 @@
     };
   };
   void reportTime(void) {
-    Serial.print(millis());
+    Serial.print(millis() * 0.001);
     Serial.write("\r\n");
   }
   void reportPosition(int drive) {


major cleanup

major cleanup

--- hal100/hal100.ino
+++ hal100/hal100.ino
@@ -51,8 +51,6 @@

 // char array

-char enteredFreq[6];
-char tuningFreq[6];
 char key;
 char DisplayValueC1[6];
 char DisplayValueC1pF[6];
@@ -62,20 +60,7 @@
 char DisplayValueLUH[4];
 char DisplayValueSWR[6];
 char input; //buffer for input characters for calculations
-// char dataPrintout[10];
-
-// float tuningFreqCalc = 0;   // float for value C calculation
-// float KHz;                  // KHz constant
-// float PlanckTime;           // Planck constant
-// float pi;                   // π constant
-// float valueC1 = 0;           // calculated value C float
-// float valueCEffective = 0;  // calculated value C float
-// float valueL = 0;           // calculated value L float
-// float valueC1Corr = 0;      // calculated value C1 float
-// float valueC2Corr = 0;      // calculated value C1 float
-// float valueLcorr = 0;       // calculated value L float
-// float Cmult;                // constant multiplier to calculate C value
-// float Lmult;                // constant multiplier to calculate L value
+
 float valueRotateC1 = -1;
 float valueRotateC2 = -1;
 float valueRotateL = -1;
@@ -84,7 +69,6 @@

 boolean presentValue = false;

-String EnteredFreqString, TuningFreqString;
 String DisplayValueLstring;

 int i;
@@ -180,28 +164,6 @@
   keypad.addEventListener(keypadEvent);             //add an event listener for this keypad
 }

-//void SetFrequencyStage1() {
-// STAGE 1 tuning process
-//	calculateC();                                     // calculate C value at selected frequency
-//	calculateStepsC();                                // calculate steps needed to move C to value C
-//	CmoveStage1();                                    // send command to nano to move motor "C" to C step value
-//	calculateL();                                     // calculate L value at given frequency and C value
-//	calculateStepsL();                                // calculate steps needed to move C to value L
-//	LmoveStage1();                                    // send command to nano to move motor "L" to L step value
-//	EraseDisplayC1(), EraseDisplayL();                 // clear previous values L and C at display
-//	displayC1(), displayL();                           // display current values L and C at display
-//	mechSetPosition(round (valueRotateL), round (valueRotateC1), round (valueRotateC2));
-// End STAGE 1 tuning process
-//}
-
-// Pre-STAGE 1 (coarse tuning process) cleanups and displays - will be used later
-//void SetFrequency() {                               // when # pressed - sets frequency value at the bottom of the screen
-//  eraseFreqTopScreen();                             // clear previously entered drequesncy at display top
-//  eraseEnteredFrequency();                          // clear entered frequency at display bottom
-//  displayFreqTopScreen();                           // display desired frequesncy at display top
-//  SetFrequencyStage1();
-//}
-

 void incL(float diff) {                             // rotate motor L with number of steps
   mechSetPosition(round (diff), 0, 0);
@@ -214,55 +176,6 @@
 void incC2(float diff) {                            // rotate motor C2 Hot with number of steps
   mechSetPosition(0, 0, round(diff));
 }
-
-// void incLCorr(float diff) {
-//    if (tuningFreqCalc != 0.0) {
-//      valueLcorr = valueLcorr + diff;
-//      SetFrequencyStage1();
-//    }
-//}
-
-//void incC1Corr(float diff) {
-//    if (tuningFreqCalc != 0.0) {
-//      valueC1Corr = valueC1Corr + diff;
-//      SetFrequencyStage1();
-//    }
-//}
-
-//void incC2Corr(float diff) {
-//    if (tuningFreqCalc != 0.0) {
-//      valueC2Corr = valueC2Corr + diff;
-//      SetFrequencyStage1();
-//    }
-//}
-
-//void eraseFreqTopScreen() {                      // erases frequency value from top of display
-//  TFTscreen.stroke(0, 20, 30);
-//  TFTscreen.setTextSize(2);
-//  TFTscreen.text(tuningFreq, 50, 110);
-//  TuningFreqString = "";
-//}
-
-//void displayFreqTopScreen() {                   // shows frequency value at top of display font 4
-//  TuningFreqString = EnteredFreqString;
-//  TuningFreqString.toCharArray(tuningFreq, 6);
-//  EnteredFreqString = "";
-//  TFTscreen.stroke(255, 255, 0);
-//  TFTscreen.setTextSize(2);
-//  TFTscreen.text(tuningFreq, 50, 110);
-//}
-
-//void displayTunedFreqTopScreen() {             // Display tuningFreq at the top of the screen in "green tuned mode"
-//  TFTscreen.stroke(0, 255, 0);
-//  TFTscreen.setTextSize(2);
-//  TFTscreen.text(tuningFreq, 50, 110);
-//}
-
-//void eraseEnteredFrequency () {               // erase frequency value at the botton of the screen
-//  TFTscreen.setTextSize(2);
-//  TFTscreen.stroke(0, 20, 30);
-//  TFTscreen.text(enteredFreq, 50, 110);
-//}

 void displaySWRvalue() {                                    // process to display SWR values
   EraseDisplaySWR();
@@ -457,99 +370,6 @@
   ErasDisplayValueC2pF();
 }

-
-//void displayC2() {                                       // display C2 steps values
-//  dtostrf(valueRotateC2, 5, 0, DisplayValueC2);
-//  if (isBusy) {
-//    TFTscreen.stroke(255, 255, 0);
-//  } else {
-//    TFTscreen.stroke(0, 255, 0);
-//  }
-//  TFTscreen.setTextSize(2);
-//  TFTscreen.text(DisplayValueC2, 40, 85);
-//}
-
-//void EraseDisplayC2() {                                   // erase display C2 steps values
-//  TFTscreen.stroke(0, 20, 20);
-//  TFTscreen.setTextSize(2);
-//  TFTscreen.text(DisplayValueC2, 40, 85);
-//}
-
-//void eraseFrequency() {                         // when * pressed - erases entered frequency bottom of the screen
-//  EnteredFreqString = "";
-//  TuningFreqString = "";
-//  TFTscreen.stroke(0, 20, 30);
-//  TFTscreen.setTextSize(2);
-//  TFTscreen.text(enteredFreq, 50, 110);
-//}
-
-//void tuningDisplay() {
-//  for (i = 0; i < 4; i++) {
-//    TFTscreen.stroke(255, 255, 0);
-//    TFTscreen.setTextSize(1);
-//    TFTscreen.text("TUNING", 50, 45);
-//    delay(1000);
-//    TFTscreen.stroke(0, 20, 30);
-//    TFTscreen.text("TUNING", 50, 45);
-//    delay(500);
-//  }
-//}
-
-//void calculateC() {                             // Calculate value C from entered frequency: C = 299792458 / (tuningFreq * 1000)
-//  Serial.println(tuningFreq);
-//  tuningFreqCalc = atof(tuningFreq);  // convert Freq input character array to a float
-//  KHz = 1000;
-//  PlanckTime = 299792458;
-//  Cmult = 1.5;
-//  valueCEffective = PlanckTime / ( tuningFreqCalc * KHz ) * Cmult;
-//  valueC1 = valueCEffective + valueC1Corr;
-//  Serial.print("Value C1 pF=");
-//  Serial.println(valueC1);
-//}
-
-//void calculateL () {                            // Calculate "L" value from formula L=((1/(2*π*f*C))/(2*π*f))*1000000000000 (where f in KHz and C in pF)
-//  pi = 3.14159;
-//  Lmult = 1000000000000;
-//  valueL = ((1 / (2 * pi * tuningFreqCalc * (valueCEffective))) / (2 * pi * tuningFreqCalc)) * Lmult + valueLcorr;
-//  Serial.print("Value L uH=");
-//  Serial.println(valueL);
-//}
-
-//void calculateStepsC() {                        // calculate needed steps for C
-// Process for linear capacitor with 44-408 pF - need to ajust or change for different capacitor
-//  float totalStepsC = 2964;
-//  float pFmin = 20;
-//  float pFmax = 200;
-// float pFtotalValue = pFmax - pFmin;
-//  Serial.println(pFtotalValue);
-//  float pFperStep = pFtotalValue / ( totalStepsC / 2 );
-//  Serial.println(pFperStep);
-//  valueRotateC1 = ( valueC1 - pFmin ) / pFperStep;
-//  Serial.print("steps C to rotate=");
-//  Serial.println(valueRotateC1);
-//}
-
-//void CmoveStage1() {                            // Send commandn to move motor C
-//  send syntax '2,valueRotateC;' to Nano
-//}
-
-//void calculateStepsL() {                        // calculate needed steps for L
-// Process for non-linear variable inductor - need to ajust or change for different inductor
-// y = -0.0299x2 + 1.3867x + 0.5894
-// float totalStepsL = 2964;                                                              // total motor steps for 1 rotation
-// float LturnsRequred = ( -0.0299 * valueL * valueL ) + ( 1.3867 * valueL ) + 0.5894;    // poly math
-// valueRotateL = LturnsRequred * totalStepsL;
-// Serial.print("L turns requred=");
-// Serial.println(LturnsRequred);
-// Serial.print("steps L to rotate=");
-// Serial.println(valueRotateL);
-//}
-
-//void LmoveStage1() {                            // Send commandn to move motor L
-//  send syntax '1,valueRotateL;' to Nano
-//}
-
-
 void sendStatusRequest() {
   static const unsigned long REFRESH_INTERVAL = 100; // ms
   static unsigned long lastRefreshTime = 0;


Added multiple patterns, added brightness controls.  Works

--- m_led/m_led.ino
+++ m_led/m_led.ino
@@ -9,14 +9,6 @@

 static const int num_strips=sizeof(strips)/sizeof(strips[0]);

-void setup()
-{
-	for(int i=0;i<num_strips;i++)
-	{
-		strips[i]->setup();
-	}
-}
-
 void send_color_all(uint32_t color)
 {
 	for(int i=0;i<num_strips;i++)
@@ -25,36 +17,103 @@
 	}
 }

-typedef struct pattern_ts
+uint32_t brighten(uint32_t color,uint8_t brightness)
 {
-	const uint32_t colors[];
-	int length;
-	int slowness;
-} pattern_t;
+	uint32_t out=0;
+	uint32_t r;

-pattern_t patterns[]={
+	r=color & 0xFF;
+	r*=brightness;
+	r>>=8;
+	out |= r;
+
+	r=(color >> 8) & 0xFF;
+	r*=brightness;
+	r>>=8;
+	out |= r << 8;
+
+	r=(color >> 16) & 0xFF;
+	r*=brightness;
+	r>>=8;
+	out |= r << 16;
+	return out;
+}
+
+
+
+#define RAINBOW_SLOWNESS 25
+PROGMEM static const prog_uint32_t patterns[]=
+{
+	//4th of july
+	4,
+	500,0x0000FF,250,0xFFFFFF,500,0x00FF00,250,0xFFFFFF,
+	//rainbow (72)
+	72,
+	RAINBOW_SLOWNESS,0x0000ff,RAINBOW_SLOWNESS,0x0015ff,RAINBOW_SLOWNESS,0x002bff,RAINBOW_SLOWNESS,0x0040ff,RAINBOW_SLOWNESS,0x0055ff,
+	RAINBOW_SLOWNESS,0x006aff,RAINBOW_SLOWNESS,0x0080ff,RAINBOW_SLOWNESS,0x0095ff,RAINBOW_SLOWNESS,0x00aaff,RAINBOW_SLOWNESS,0x00bfff,
+	RAINBOW_SLOWNESS,0x00d5ff,RAINBOW_SLOWNESS,0x00eaff,RAINBOW_SLOWNESS,0x00ffff,RAINBOW_SLOWNESS,0x00ffea,RAINBOW_SLOWNESS,0x00ffd4,
+	RAINBOW_SLOWNESS,0x00ffbf,RAINBOW_SLOWNESS,0x00ffaa,RAINBOW_SLOWNESS,0x00ff95,RAINBOW_SLOWNESS,0x00ff80,RAINBOW_SLOWNESS,0x00ff6a,
+	RAINBOW_SLOWNESS,0x00ff55,RAINBOW_SLOWNESS,0x00ff40,RAINBOW_SLOWNESS,0x00ff2a,RAINBOW_SLOWNESS,0x00ff15,RAINBOW_SLOWNESS,0x00ff00,
+	RAINBOW_SLOWNESS,0x15ff00,RAINBOW_SLOWNESS,0x2bff00,RAINBOW_SLOWNESS,0x40ff00,RAINBOW_SLOWNESS,0x55ff00,RAINBOW_SLOWNESS,0x6aff00,
+	RAINBOW_SLOWNESS,0x80ff00,RAINBOW_SLOWNESS,0x95ff00,RAINBOW_SLOWNESS,0xaaff00,RAINBOW_SLOWNESS,0xbfff00,RAINBOW_SLOWNESS,0xd5ff00,
+	RAINBOW_SLOWNESS,0xeaff00,RAINBOW_SLOWNESS,0xffff00,RAINBOW_SLOWNESS,0xffea00,RAINBOW_SLOWNESS,0xffd400,RAINBOW_SLOWNESS,0xffbf00,
+	RAINBOW_SLOWNESS,0xffaa00,RAINBOW_SLOWNESS,0xff9500,RAINBOW_SLOWNESS,0xff8000,RAINBOW_SLOWNESS,0xff6a00,RAINBOW_SLOWNESS,0xff5500,
+	RAINBOW_SLOWNESS,0xff4000,RAINBOW_SLOWNESS,0xff2b00,RAINBOW_SLOWNESS,0xff1500,RAINBOW_SLOWNESS,0xff0000,RAINBOW_SLOWNESS,0xff0015,
+	RAINBOW_SLOWNESS,0xff002b,RAINBOW_SLOWNESS,0xff0040,RAINBOW_SLOWNESS,0xff0055,RAINBOW_SLOWNESS,0xff006a,RAINBOW_SLOWNESS,0xff0080,
+	RAINBOW_SLOWNESS,0xff0095,RAINBOW_SLOWNESS,0xff00aa,RAINBOW_SLOWNESS,0xff00bf,RAINBOW_SLOWNESS,0xff00d5,RAINBOW_SLOWNESS,0xff00ea,
+	RAINBOW_SLOWNESS,0xff00ff,RAINBOW_SLOWNESS,0xea00ff,RAINBOW_SLOWNESS,0xd400ff,RAINBOW_SLOWNESS,0xbf00ff,RAINBOW_SLOWNESS,0xaa00ff,
+	RAINBOW_SLOWNESS,0x9500ff,RAINBOW_SLOWNESS,0x8000ff,RAINBOW_SLOWNESS,0x6a00ff,RAINBOW_SLOWNESS,0x5500ff,RAINBOW_SLOWNESS,0x4000ff,
+	RAINBOW_SLOWNESS,0x2b00ff,RAINBOW_SLOWNESS,0x1500ff
+};
+
+static const int size_patterns=sizeof(patterns)/sizeof(patterns[0]);
+
+int iterate_pattern(int pptr,int pattern_frame_id,uint8_t brightness)
+{
+	uint32_t len=pgm_read_dword_near(patterns+pptr);
+
+	int pfidlu=pattern_frame_id << 1;
+	uint32_t slowness=pgm_read_dword_near(patterns+pptr+1+pfidlu);
+	uint32_t color=pgm_read_dword_near(patterns+pptr+2+pfidlu);
+	color=brighten(color,brightness);
+	send_color_all(color);
+	delay(slowness);
+	pattern_frame_id++;
+	if(pattern_frame_id >= len)
 	{
-		{0x00FF00,0xFF0000,0x0000FF},
-		3,
-		500
+		pattern_frame_id=0;
 	}
-};
-static const int num_patterns=sizeof(patterns)/sizeof(patterns[0]);
+	return pattern_frame_id;
+}

-int iterate_pattern(int pid,int pattern_frame_id)
+int increment_pattern(int pptr)
 {
-	pattern_t *selpattern=&patterns[pid % num_patterns];
-	const uint32_t *frames=selpattern->colors;
-	send_color_all(frames[pattern_frame_id % selpattern->length]);
-	delay(selpattern->slowness);
-	pattern_frame_id++;
-	return pattern_frame_id;
-}
+	pptr+=(pgm_read_dword_near(patterns+pptr) << 1);
+	pptr++;
+	if(pptr >= size_patterns)
+	{
+		pptr=0;
+	}
+	return pptr;
+}

 int pframeid=0;
-int curpattern=0;
+int initpattern=1;
+int curptr=0;
+uint8_t curbrightness=255;

+void setup()
+{
+	for(int i=0;i<num_strips;i++)
+	{
+		strips[i]->setup();
+	}
+	for(int i=0;i<initpattern;i++)
+	{
+		curptr=increment_pattern(curptr);
+	}
+}
 void loop()
-{
-	pframeid=iterate_pattern(curpattern,pframeid);
+{
+	pframeid=iterate_pattern(curptr,pframeid,curbrightness);
 }


Fixed #11 - LED 13 is turning off now. Also Arduino pins where changed.

--- meteo/meteo.ino
+++ meteo/meteo.ino
@@ -11,22 +11,22 @@
 const byte BRIGHTNESS = 255; // 0 - min, 255 - max
 const long DIGIT_DELAY_IN_MICROSECONDS = 500;

-const int DHT22_PIN = A0;
-const int MERCURY_SWITCH_PIN = A1;
-
-const int DIGIT_1_PIN = 3;
-const int DIGIT_2_PIN = 5;
-const int DIGIT_3_PIN = 6;
-const int DIGIT_4_PIN = 9;
-
-const int SEGMENT_A_PIN = 2;
-const int SEGMENT_B_PIN = 8;
-const int SEGMENT_C_PIN = 10;
-const int SEGMENT_D_PIN = 11;
-const int SEGMENT_E_PIN = 12;
-const int SEGMENT_F_PIN = 7;
-const int SEGMENT_G_PIN = 13;
-const int SEGMENT_DP_PIN = 4;
+const int DHT22_PIN = A4; // SET A7 ON ARDUINO PRO MINI
+const int MERCURY_SWITCH_PIN = A5; // SET A6 ON ARDUINO PRO MINI
+
+const int DIGIT_1_PIN = 11;    // LED pin 12
+const int DIGIT_2_PIN = A0;    // LED pin 9
+const int DIGIT_3_PIN = A1;   // LED pin 8
+const int DIGIT_4_PIN = 3;    // LED pin 6
+
+const int SEGMENT_A_PIN = 12;  // LED pin 11
+const int SEGMENT_B_PIN = A2; // LED pin 7
+const int SEGMENT_C_PIN = 5;  // LED pin 4
+const int SEGMENT_D_PIN = 7;  // LED pin 2
+const int SEGMENT_E_PIN = 8;  // LED pin 1
+const int SEGMENT_F_PIN = 13; // LED pin 10
+const int SEGMENT_G_PIN = 4;  // LED pin 5
+const int SEGMENT_DP_PIN = 6; // LED pin 3

 byte DIGIT_OFF;
 byte DIGIT_ON;
@@ -251,6 +251,21 @@
       digitalWrite(SEGMENT_G_PIN, SEGMENT_OFF);
   }
   digitalWrite(SEGMENT_DP_PIN, hasDecimalPoint ? SEGMENT_ON : SEGMENT_OFF);
+}
+
+void turnOffAllLedPins() {
+  analogWrite(DIGIT_1_PIN, LOW);
+  analogWrite(DIGIT_2_PIN, LOW);
+  analogWrite(DIGIT_3_PIN, LOW);
+  analogWrite(DIGIT_4_PIN, LOW);
+  digitalWrite(SEGMENT_A_PIN, LOW);
+  digitalWrite(SEGMENT_B_PIN, LOW);
+  digitalWrite(SEGMENT_C_PIN, LOW);
+  digitalWrite(SEGMENT_D_PIN, LOW);
+  digitalWrite(SEGMENT_E_PIN, LOW);
+  digitalWrite(SEGMENT_F_PIN, LOW);
+  digitalWrite(SEGMENT_G_PIN, LOW);
+  digitalWrite(SEGMENT_DP_PIN, LOW);
 }

 int readData() {
@@ -391,7 +406,7 @@
   pinMode(SEGMENT_F_PIN, OUTPUT);
   pinMode(SEGMENT_G_PIN, OUTPUT);
   pinMode(SEGMENT_DP_PIN, OUTPUT);
-
+
   if (COMMON_ANODE_LED) {
     // LED display with common anode:
     DIGIT_OFF = 0;
@@ -406,18 +421,7 @@
     SEGMENT_ON = HIGH;
   }

-  analogWrite(DIGIT_1_PIN, DIGIT_OFF);
-  analogWrite(DIGIT_2_PIN, DIGIT_OFF);
-  analogWrite(DIGIT_3_PIN, DIGIT_OFF);
-  analogWrite(DIGIT_4_PIN, DIGIT_OFF);
-  digitalWrite(SEGMENT_A_PIN, SEGMENT_ON);
-  digitalWrite(SEGMENT_B_PIN, SEGMENT_ON);
-  digitalWrite(SEGMENT_C_PIN, SEGMENT_ON);
-  digitalWrite(SEGMENT_D_PIN, SEGMENT_ON);
-  digitalWrite(SEGMENT_E_PIN, SEGMENT_ON);
-  digitalWrite(SEGMENT_F_PIN, SEGMENT_ON);
-  digitalWrite(SEGMENT_G_PIN, SEGMENT_ON);
-  digitalWrite(SEGMENT_DP_PIN, SEGMENT_ON);
+  turnOffAllLedPins();

   if (AUTO_START) {
     previousMercurySwitchIsOn = false;
@@ -436,10 +440,13 @@
       startModeMillis = millis();
       lastReadingMillis = startModeMillis;
       mode = TEMPERATURE;
+    } else {
+      // Just turned off:
+      turnOffAllLedPins();
     }
   }
   previousMercurySwitchIsOn = mercurySwitchIsOn;
-
+
   // Read data from sensor
   errorCode = readData();
   if (errorCode < 0) {
@@ -458,17 +465,19 @@
     if (mode == TEMPERATURE) setTemperature();
     else setHumidity();
   }
-
+
   // Draw one current digit on display
-  activateDigit(INACTIVE);
-  drawDigit(digits[currentDigitIndex], decimalPoints[currentDigitIndex]);
   if (mercurySwitchIsOn) {
-    activateDigit(currentDigitIndex);
-  }
-
-  // Change current digit
-  currentDigitIndex++;
-  if (currentDigitIndex >= 4) currentDigitIndex = 0;
+    activateDigit(INACTIVE);
+    drawDigit(digits[currentDigitIndex], decimalPoints[currentDigitIndex]);
+    if (mercurySwitchIsOn) {
+      activateDigit(currentDigitIndex);
+    }
+
+    // Change current digit
+    currentDigitIndex++;
+    if (currentDigitIndex >= 4) currentDigitIndex = 0;
+  }

   delayMicroseconds(DIGIT_DELAY_IN_MICROSECONDS);
 }


Partial refactoring of button into a class

--- moros/moros.ino
+++ moros/moros.ino
@@ -26,10 +26,19 @@

 int active_player = NONE;
-volatile int button_pressed = NONE;
+
+class Button {
+public:
+  static volatile int button_pressed;
+
+  Button(int interrupt_number, void (*interrupt_handler)()) {
+    attachInterrupt(interrupt_number, interrupt_handler, RISING);
+  }
+};
+volatile int Button::button_pressed = NONE;

 inline void handle_button_interrupt(int button) {
-  button_pressed = button;
+  Button::button_pressed = button;
 }

 void handle_button_interrupt_0() {
@@ -38,22 +47,6 @@
 void handle_button_interrupt_1() {
   handle_button_interrupt(1);
 }
-
-typedef struct {
-  unsigned int interrupt_number;
-  void (*interrupt_handler)();
-} Button;
-
-Button buttons[2] = {
-  {
-    .interrupt_number = 0,
-    .interrupt_handler = handle_button_interrupt_0
-  },
-  {
-    .interrupt_number = 1,
-    .interrupt_handler = handle_button_interrupt_1
-  }
-};

 class Screen {
 private:
@@ -140,22 +133,22 @@

 Player *players[2] = {
   new Player(
-    &buttons[0],
+    new Button(0, handle_button_interrupt_0),
     new Screen(4,5,6)
   ),
   new Player(
-    &buttons[1],
+    new Button(1, handle_button_interrupt_1),
     new Screen(7,8,9)
   )
 };

 void handle_button_press(int button) {
   serprintf("button %d pressed\r\n", button);
-  serprintf("before: active_player=%d, button_pressed=%d\r\n", active_player, button_pressed);
-  active_player = (button_pressed + 1) % 2;
+  serprintf("before: active_player=%d, button_pressed=%d\r\n", active_player, Button::button_pressed);
+  active_player = (Button::button_pressed + 1) % 2;
   players[active_player]->clock->last_update_ms = millis();
-  button_pressed = NONE;
-  serprintf("after:  active_player=%d, button_pressed=%d\r\n", active_player, button_pressed);
+  Button::button_pressed = NONE;
+  serprintf("after:  active_player=%d, button_pressed=%d\r\n", active_player, Button::button_pressed);
 }

 void setup(void) {
@@ -165,7 +158,6 @@
   for(unsigned int i = 0; i < sizeof(players) / sizeof(players[0]); i++) {
     players[i]->init();
     players[i]->update_display();
-    attachInterrupt(players[i]->button->interrupt_number, players[i]->button->interrupt_handler, RISING);
   }

   serprintf("done.\r\n");
@@ -177,7 +169,7 @@
     if (players[active_player]->out_of_time()) {
       serprintf("Flag fell for player %d\r\n", active_player);
       active_player = NONE;
-      button_pressed = NONE;
+      Button::button_pressed = NONE;
       return;
     }

@@ -185,8 +177,8 @@
     players[active_player]->update_display();
   }

-  if ((active_player == NONE || button_pressed == active_player) && button_pressed != NONE)   {
-    handle_button_press(button_pressed);
+  if ((active_player == NONE || Button::button_pressed == active_player) && Button::button_pressed != NONE)   {
+    handle_button_press(Button::button_pressed);
   }

 }


Fix example.

Fix example.

--- res/Examples/MIDI_RPN_NRPN/MIDI_RPN_NRPN.ino
+++ res/Examples/MIDI_RPN_NRPN/MIDI_RPN_NRPN.ino
@@ -65,7 +65,7 @@
                 }
                 break;

-            case midi::DataEntry:
+            case midi::DataEntryMSB:
                 if (mSelected)
                 {
                     Value& currentValue = getCurrentValue();
@@ -110,8 +110,8 @@

 typedef State<2> RpnState;  // We'll listen to 2 RPN
 typedef State<4> NrpnState; // and 4 NRPN
-typedef ParameterNumberParser<RpnState,  midi::RPNMSB,  midi::RPN>  RpnParser;
-typedef ParameterNumberParser<NrpnState, midi::NRPNMSB, midi::NRPN> NrpnParser;
+typedef ParameterNumberParser<RpnState,  midi::RPNMSB,  midi::RPNLSB>  RpnParser;
+typedef ParameterNumberParser<NrpnState, midi::NRPNMSB, midi::NRPNLSB> NrpnParser;

 struct ChannelSetup
 {


Add Tracer to the main loop with a 20% probabilty of running

Signed-off-by: Cody Massin <420bebd5a852fd1111446fa9e2d3f8a881db9ffd@gmail.com>

--- CocaCola/CocaCola.ino
+++ CocaCola/CocaCola.ino
@@ -246,6 +246,31 @@
     classicBackground();
 }

+void runTracer() {
+    for (int i = 0; i < sizeof(background); i++) {
+      digitalWrite(background[i], PATTERN_ON);
+    }
+    for (int i = 0; i < sizeof(letters); i++) {
+      digitalWrite(Lights[i], PATTERN_ON);
+      delay(250);
+      digitalWrite(Lights[i], PATTERN_OFF);
+      delay(250);
+    }
+    for(int j=0; j< 3; j++) {
+
+      for (int i = 0; i < sizeof(letters); i++) {
+        digitalWrite(Lights[i], PATTERN_ON);
+      }
+      delay(250);
+      for (int i = 0; i < sizeof(letters); i++) {
+        digitalWrite(Lights[i], PATTERN_OFF);
+      }
+      delay(250);
+
+    }
+    delay(250);
+}
+
 void runLetterPattern() {
 	// if new patterns are added, add a new case statement, and bump up the max random value by one
 	switch (random(0, 2)) {
@@ -271,10 +296,14 @@

 	int blinkMax = 0;
 	int possibility = random(0, 100);
-	if (possibility < 70) {
-		runClassic();
-
-		blinkMax = 3;
+    if (possibility < 20) {
+		runTracer();
+
+		blinkMax = 1;
+    } else if (possibility < 70) {
+        runClassic();
+
+        blinkMax = 3;
 	} else if (possibility < 95) {
 		if (random(0, 200) == 0) {
 			runBackgroundPattern();


Fixed auto-arm issue

Fixed auto-arm issue

--- interrupt_driven_rgb.ino
+++ interrupt_driven_rgb.ino
@@ -68,6 +68,7 @@
 // Internal States
 State Loading      = State(enterLoading, updateLoading, NULL);
 State Unarmed      = State(enterUnarmed, NULL, exitUnarmed);
+State LockBox      = State(updateLockBox);
 State GetFix       = State(enterGetFix, updateGetFix, exitGetFix);
 State ReadLocation = State(enterReadLocation, updateReadLocation, exitReadLocation);
 State SleepModules = State(enterSleepModules, updateSleepModules, exitSleepModules);
@@ -93,7 +94,7 @@

 void onHold(Button& button) {
   if(!isArmed() && !stateMachine.isInState(OpenBox)) {
-    stateMachine.transitionTo(GetFix);
+    stateMachine.transitionTo(LockBox);
     return;
   }

@@ -264,8 +265,12 @@
 }

 void exitUnarmed() {
+  TimedEvent.stop(READ_LOCATION_TIMER);
+}
+
+void updateLockBox() {
   lock();
-  TimedEvent.stop(READ_LOCATION_TIMER);
+  stateMachine.transitionTo(GetFix);
 }

 void enterGetFix() {


one last thing hopefully

one last thing hopefully

--- telemetryBox.ino
+++ telemetryBox.ino
@@ -95,6 +95,7 @@
 	Particle.subscribe(eventPrefix + "/waterTankPump/pumpOn", eventHandler, MY_DEVICES);
     Particle.publish(eventPrefix + "/waterTankSensor/online", "true"); // subscribe to this with the API like: curl https://api.particle.io/v1/devices/events/temp?access_token=1234
     bootupStartTime = millis();
+	measureUS();
     doTelemetry(); // always take the measurements at least once
 }


Updated example

Updated example

--- examples/FSKModem/FSKModem.ino
+++ examples/FSKModem/FSKModem.ino
@@ -43,6 +43,7 @@
   // current limit:               100 mA
   // data shaping:                Gaussian, BT = 0.3
   // sync word:                   0x2D  0x01
+  // OOK modulation:              false
   int state = fsk.beginFSK();
   if (state == ERR_NONE) {
     Serial.println(F("success!"));
@@ -71,6 +72,19 @@
   state = fsk.setSyncWord(syncWord, 8);
   if (state != ERR_NONE) {
     Serial.print(F("Unable to set configuration, code "));
+    Serial.println(state);
+    while (true);
+  }
+
+  // FSK modulation can be changed to OOK
+  // NOTE: When using OOK, the maximum bit rate is only 32.768 kbps!
+  //       Also, data shaping changes from Gaussian filter to
+  //       simple filter with cutoff frequency. Make sure to call
+  //       setDataShapingOOK() to set the correct shaping!
+  state = fsk.setOOK(true);
+  state = fsk.setDataShapingOOK(1);
+  if (state != ERR_NONE) {
+    Serial.print(F("Unable to change modulation, code "));
     Serial.println(state);
     while (true);
   }