Update nes_controller_sd.ino

Update nes_controller_sd.ino

Adding header comments

--- nes_controller_sd.ino
+++ nes_controller_sd.ino
@@ -1,155 +1,166 @@
-#include <SPI.h>
-#include <SD.h>
-
-#define BUFFER_SIZE 400
-
-const int chipSelect = 9;
-
-volatile int frame_cnt = 0;
-volatile int clk_cnt = 0;
-volatile uint8_t buttons_hold = 0;
-volatile uint8_t buttons = 0;
-uint8_t port_buffer = 0;
-volatile uint8_t button_state_a[BUFFER_SIZE];
-volatile uint8_t button_state_b[BUFFER_SIZE];
-volatile boolean send_data = false;
-volatile boolean use_a = true;
-volatile boolean change_buffer = false;
-boolean current_a = true;
-File dataFile;
-
-void setup() {
-  // put your setup code here, to run once:
-  //Serial.begin(115200);
-  pinMode(6, INPUT);
-  pinMode(4, OUTPUT);
-  digitalWrite(4, HIGH);
-
-  //Serial.println("Initializing SD");
-
-  if (!SD.begin(chipSelect)) {
-    //Serial.println("Failed to initialize SD");
-    return;
-  }
-
-  //Serial.println("Opening file");
-
-  dataFile = SD.open("smb_dh.bin");
-  //dataFile = SD.open("smb_wr.bin");
-  if (!dataFile) {
-    //Serial.println("Failed to open data file");
-    return;
-  }
-
-  //Serial.println("Loading buffer A");
-
-  for (int i = 0; i < BUFFER_SIZE; i++) {
-    button_state_a[i] = dataFile.read();
-  }
-
-  //Serial.println("Loading buffer B");
-
-  for (int i = 0; i < BUFFER_SIZE; i++) {
-    button_state_b[i] = dataFile.read();
-  }
-
-  //Serial.println("Attaching interrupts");
-
-  /*Serial.println("PRINTING A");
-  for (int i = 0; i < BUFFER_SIZE; i++) {
-    Serial.println(button_state_a[i], HEX);
-    delay(50);
-  }
-  Serial.println("PRINTING B");
-  for (int i = 0; i < BUFFER_SIZE; i++) {
-    Serial.println(button_state_b[i], HEX);
-    delay(50);
-  }*/
-
-  attachInterrupt(digitalPinToInterrupt(2), clock_handler, RISING);
-  attachInterrupt(digitalPinToInterrupt(3), latch_handler, RISING);
-
-  while (!digitalRead(6)) {}
-  frame_cnt = 0;
-}
-
-void loop() {
-  if (change_buffer) {
-    if (dataFile.available()) {
-      if (current_a) {
-        //Serial.println("LOADING A");
-        current_a = false;
-        for (int i = 0; i < BUFFER_SIZE; i++) {
-          button_state_a[i] = dataFile.read();
-        }
-      } else if (!current_a) {
-        //Serial.println("LOADING B");
-        current_a = true;
-        for (int i = 0; i < BUFFER_SIZE; i++) {
-          button_state_b[i] = dataFile.read();
-        }
-      }
-    } else {
-      if (current_a) {
-        current_a = false;
-        for (int i = 0; i < BUFFER_SIZE; i++) {
-          button_state_a[i] = 0x00;
-        }
-      } else if (!current_a) {
-        current_a = true;
-        for (int i = 0; i < BUFFER_SIZE; i++) {
-          button_state_b[i] = 0x00;
-        }
-      }
-      //dataFile.close();
-    }
-    change_buffer = false;
-  }
-}
-
-void initialize() {
-  for (int i = 0; i < BUFFER_SIZE; i++) {
-    button_state_a[i] = 0x00;
-    button_state_b[i] = 0x00;
-  }
-}
-
-void clock_handler() {
-  if (send_data) {
-    PORTD = port_buffer;
-    clk_cnt++;
-    port_buffer = B00010000 & (~(0x01 & (buttons_hold >> clk_cnt)) << 4);
-    if (clk_cnt > 8) {
-      frame_cnt++;
-      send_data = false;
-      PORTD = B00010000;
-      if (frame_cnt == BUFFER_SIZE) {
-        //Serial.println("CHANGING BUFFER");
-        //Serial.println(use_a);
-        use_a = (use_a) ? 0 : 1;
-        change_buffer = true;
-        //Serial.println(use_a);
-        frame_cnt = 0;
-      }
-    }
-  }
-}
-
-void latch_handler() {
-  if (!send_data) {
-    //clk_cnt = 0;
-    buttons_hold = (use_a) ? button_state_a[frame_cnt] : button_state_b[frame_cnt];
-    //buttons_hold = button_state_a[frame_cnt];
-    /*if (use_a) {
-      Serial.println("USING A");
-    } else {
-      Serial.println("USING B");
-    }*/
-    //frame_cnt++;
-    PORTD = B00010000 & (~(0x01 & (buttons_hold)) << 4);
-    send_data = true;
-    clk_cnt = 1;
-    port_buffer = B00010000 & (~(0x01 & (buttons_hold >> clk_cnt)) << 4);
-  }
-}
+/*
+ Copyright Bryan R. Craker 2017

+ Used to execute arbitrary controller input for an NES using an XLR8 board
+
+ Requires SD card on the SPI interface with CS on D09, NES clock on D02, NES latch on D03
+
+ Released without warranty, hoping people will find it useful
+
+*/
+
+#include <SPI.h>
+#include <SD.h>
+
+#define BUFFER_SIZE 400
+
+const int chipSelect = 9;
+
+volatile int frame_cnt = 0;
+volatile int clk_cnt = 0;
+volatile uint8_t buttons_hold = 0;
+volatile uint8_t buttons = 0;
+uint8_t port_buffer = 0;
+volatile uint8_t button_state_a[BUFFER_SIZE];
+volatile uint8_t button_state_b[BUFFER_SIZE];
+volatile boolean send_data = false;
+volatile boolean use_a = true;
+volatile boolean change_buffer = false;
+boolean current_a = true;
+File dataFile;
+
+void setup() {
+  // put your setup code here, to run once:
+  //Serial.begin(115200);
+  pinMode(6, INPUT);
+  pinMode(4, OUTPUT);
+  digitalWrite(4, HIGH);
+
+  //Serial.println("Initializing SD");
+
+  if (!SD.begin(chipSelect)) {
+    //Serial.println("Failed to initialize SD");
+    return;
+  }
+
+  //Serial.println("Opening file");
+
+  dataFile = SD.open("smb_dh.bin");
+  //dataFile = SD.open("smb_wr.bin");
+  if (!dataFile) {
+    //Serial.println("Failed to open data file");
+    return;
+  }
+
+  //Serial.println("Loading buffer A");
+
+  for (int i = 0; i < BUFFER_SIZE; i++) {
+    button_state_a[i] = dataFile.read();
+  }
+
+  //Serial.println("Loading buffer B");
+
+  for (int i = 0; i < BUFFER_SIZE; i++) {
+    button_state_b[i] = dataFile.read();
+  }
+
+  //Serial.println("Attaching interrupts");
+
+  /*Serial.println("PRINTING A");
+  for (int i = 0; i < BUFFER_SIZE; i++) {
+    Serial.println(button_state_a[i], HEX);
+    delay(50);
+  }
+  Serial.println("PRINTING B");
+  for (int i = 0; i < BUFFER_SIZE; i++) {
+    Serial.println(button_state_b[i], HEX);
+    delay(50);
+  }*/
+
+  attachInterrupt(digitalPinToInterrupt(2), clock_handler, RISING);
+  attachInterrupt(digitalPinToInterrupt(3), latch_handler, RISING);
+
+  while (!digitalRead(6)) {}
+  frame_cnt = 0;
+}
+
+void loop() {
+  if (change_buffer) {
+    if (dataFile.available()) {
+      if (current_a) {
+        //Serial.println("LOADING A");
+        current_a = false;
+        for (int i = 0; i < BUFFER_SIZE; i++) {
+          button_state_a[i] = dataFile.read();
+        }
+      } else if (!current_a) {
+        //Serial.println("LOADING B");
+        current_a = true;
+        for (int i = 0; i < BUFFER_SIZE; i++) {
+          button_state_b[i] = dataFile.read();
+        }
+      }
+    } else {
+      if (current_a) {
+        current_a = false;
+        for (int i = 0; i < BUFFER_SIZE; i++) {
+          button_state_a[i] = 0x00;
+        }
+      } else if (!current_a) {
+        current_a = true;
+        for (int i = 0; i < BUFFER_SIZE; i++) {
+          button_state_b[i] = 0x00;
+        }
+      }
+      //dataFile.close();
+    }
+    change_buffer = false;
+  }
+}
+
+void initialize() {
+  for (int i = 0; i < BUFFER_SIZE; i++) {
+    button_state_a[i] = 0x00;
+    button_state_b[i] = 0x00;
+  }
+}
+
+void clock_handler() {
+  if (send_data) {
+    PORTD = port_buffer;
+    clk_cnt++;
+    port_buffer = B00010000 & (~(0x01 & (buttons_hold >> clk_cnt)) << 4);
+    if (clk_cnt > 8) {
+      frame_cnt++;
+      send_data = false;
+      PORTD = B00010000;
+      if (frame_cnt == BUFFER_SIZE) {
+        //Serial.println("CHANGING BUFFER");
+        //Serial.println(use_a);
+        use_a = (use_a) ? 0 : 1;
+        change_buffer = true;
+        //Serial.println(use_a);
+        frame_cnt = 0;
+      }
+    }
+  }
+}
+
+void latch_handler() {
+  if (!send_data) {
+    //clk_cnt = 0;
+    buttons_hold = (use_a) ? button_state_a[frame_cnt] : button_state_b[frame_cnt];
+    //buttons_hold = button_state_a[frame_cnt];
+    /*if (use_a) {
+      Serial.println("USING A");
+    } else {
+      Serial.println("USING B");
+    }*/
+    //frame_cnt++;
+    PORTD = B00010000 & (~(0x01 & (buttons_hold)) << 4);
+    send_data = true;
+    clk_cnt = 1;
+    port_buffer = B00010000 & (~(0x01 & (buttons_hold >> clk_cnt)) << 4);
+  }
+}
+


example/FirebasePush: update example to loop

--- examples/FirebasePush_ESP8266/FirebasePush_ESP8266.ino
+++ examples/FirebasePush_ESP8266/FirebasePush_ESP8266.ino
@@ -14,11 +14,10 @@
 // limitations under the License.
 //

-// FirebasePush_ESP8266 is a sample that push a new timestamp to firebase
-// on each reset.
+// FirebasePush_ESP8266 is a sample that push a new value to Firebase
+// every seconds.

 #include <ESP8266WiFi.h>
-
 #include <FirebaseArduino.h>

 void setup() {
@@ -36,17 +35,19 @@
   Serial.println(WiFi.localIP());

   Firebase.begin("example.firebaseio.com", "auth_or_token");
+}

-  // add a new entry.
-  String name = Firebase.push("/logs", "{\".sv\": \"timestamp\"}");
+int n = 0;
+
+void loop() {
+  // push a new value.
+  String name = Firebase.push("/logs", n++);
   if (Firebase.failed()) {
-      Serial.println(" push failed");
+      Serial.print("push failed: ");
       Serial.println(Firebase.error());
       return;
   }
   Serial.print("pushed: ");
   Serial.println(name);
+  delay(1000);
 }
-
-void loop() {
-}


Minor changes

Minor changes

--- examples/JsonGeneratorExample/JsonGeneratorExample.ino
+++ examples/JsonGeneratorExample/JsonGeneratorExample.ino
@@ -11,17 +11,16 @@
 {
     Serial.begin(9600);

-    JsonHashTable<3> json;
-
-    json.add("sensor", "gps");
-    json.add("time", 1351824120);
-
-    JsonArray<3> array;
+    JsonArray<2> array;
     array.add(48.756080, 6);
     array.add(2.302038, 6);
-    json.add("data", array);

-    Serial.print(json); // {"sensor":"gps","time":1351824120,"data":[48.756080,2.302038]}
+    JsonHashTable<3> root;
+    root.add("sensor", "gps");
+    root.add("time", 1351824120);
+    root.add("data", array);
+
+    Serial.print(root); // {"sensor":"gps","time":1351824120,"data":[48.756080,2.302038]}
 }

 void loop()


Fixed JSON format

Fixed JSON format

--- Sensors/iot-demo-sensors/iot-demo-sensors.ino
+++ Sensors/iot-demo-sensors/iot-demo-sensors.ino
@@ -63,7 +63,7 @@
 }

 String getSensorValueJSON(int value){
-  return String("[\"messageName\" : {\"value\" : " + String(value, DEC) + "}]");
+  return String("[{\"messageName\" : {\"value\" : " + String(value, DEC) + "}}]");
 }

 void reportButtons(){


Some Tuning on PWR Calc

Some Tuning on PWR Calc

--- Software_Rectified_AC_Cur_to_PWR/AnalogInput/AnalogInput.ino
+++ Software_Rectified_AC_Cur_to_PWR/AnalogInput/AnalogInput.ino
@@ -27,14 +27,14 @@

  */

-long int RL = 234;
+long int RL = 550; //need to target as high as possible for accuracy
 long int Turns = 2000;
 float VoltsPer = 0.00488;
 float RmsFactor = 0.707;
 float VSenseRMS = 0;
 float Irms = 0;
 int VAC = 134;
-int sensorPin = A0;    // select the input pin for the potentiometer
+int sensorPin = A1;    // select the input pin for the potentiometer
 int ledPin = 13;      // select the pin for the LED
 int sensorValue = 0;  // variable to store the value coming from the sensor
 int newValue = 0;
@@ -46,13 +46,14 @@
 }

 void loop() {
-  for(int i=0; i < 1000; i++){
+  for(int i=0; i < 10000; i++){
   // read the value from the sensor:
   newValue = analogRead(sensorPin);
   if (newValue > sensorValue){
     sensorValue = newValue;
   }
   }
+  Serial.println(sensorValue);
   VSenseRMS = sensorValue*VoltsPer*RmsFactor;
   Irms = VSenseRMS / RL * Turns;
   Serial.println("***************");


Print interrupt profiler to dashboard

Print interrupt profiler to dashboard

--- examples/quadcopter/quadcopter.ino
+++ examples/quadcopter/quadcopter.ino
@@ -176,6 +176,7 @@
         comms.sendTelem(ALTITUDE+1 , altitude.getVelocity());
         comms.sendTelem(ALTITUDE+2 , altitudeSetpoint);
         comms.sendTelem(ALTITUDE+3 , baro.getAltitude());
+        comms.sendTelem(ALTITUDE+4 , profileTime(0));

         Serial.println();
         Serial.flush();


Changed nLEDs to actual value (#76)

Changed nLEDs to actual value (#76)

--- lighting/src/main/arduino/com/lynbrookrobotics/potassium/lighting/serialLightingControl/serialLightingControl.ino
+++ lighting/src/main/arduino/com/lynbrookrobotics/potassium/lighting/serialLightingControl/serialLightingControl.ino
@@ -1,7 +1,7 @@
 #include <Adafruit_NeoPixel.h>

 int pin  = 13;
-int nLEDs = 20;
+int nLEDs = 61;
 int incomingByte = 0;
 int iter = 0;
 int acc = 0;


Made Sindle Came example sync automatigacally

--- UCAM/examples/SingleCamera/SingleCamera.ino
+++ UCAM/examples/SingleCamera/SingleCamera.ino
@@ -20,29 +20,28 @@
   camSetUp = false;
 }

+void loop()
+{
+  if (!camSetUp)
+  {
+    camSetUp = setUpCam();
+  }
+
+  cam1.SNAPSHOT();
+  cam1.GET();
+  delay  (100000);
+  return;
+}
+
 boolean setUpCam()
 {
-    if (cam1.SYNC() ==0)
+  if (cam1.SYNC() == 0)
     {
-      digitalWrite(12,HIGH);
-    } else {;
+      digitalWrite(13,HIGH);
+    } else {
       cam1.RESET();
       return false;
     }
     cam1.INIT(&UCAM_8BIT_GREY,&UCAM_80X60);
     return true;
-}
-
-void loop()
-{
-  if (!camSetUp)
-  {
-    delay(1);
-    camSetUp = setUpCam();
-  } else {
-    cam1.SNAPSHOT();
-    cam1.GET();
-    delay  (100000);
-    return;
-  }
-}
+}


ble_broadcast done

ble_broadcast done

--- libraries/BLE/examples/ble_broadcast/ble_broadcast.ino
+++ libraries/BLE/examples/ble_broadcast/ble_broadcast.ino
@@ -40,7 +40,6 @@

  */
 #include <SPI.h>
-#include <avr/pgmspace.h>
 #include <ble_system.h>
 #include <lib_aci.h>
 #include <lib_traces.h>
@@ -133,16 +132,17 @@

   //We reset the nRF8001 here by toggling the RESET line connected to the nRF8001
   //and initialize the data structures required to setup the nRF8001
-  lib_aci_init(&aci_state);
+  lib_aci_init(&aci_state, true);
 }

 void loop()
 {
+  static bool setup_required = false;
+
   // We enter the if statement only when there is a ACI event available to be processed
   if (lib_aci_event_get(&aci_state, &aci_data))
   {
     aci_evt_t * aci_evt;
-
     aci_evt = &aci_data.evt;
     switch(aci_evt->evt_opcode)
     {
@@ -159,10 +159,7 @@
             When the device is in the setup mode
             */
             Serial.println(F("Evt Device Started: Setup"));
-            if (ACI_STATUS_TRANSACTION_COMPLETE != do_aci_setup(&aci_state))
-            {
-              Serial.println(F("Error in ACI Setup"));
-            }
+			setup_required = true;
             break;

             case ACI_DEVICE_STANDBY:
@@ -233,5 +230,17 @@
     // Arduino can go to sleep now
     // Wakeup from sleep from the RDYN line
   }
+
+  /* setup_required is set to true when the device starts up and enters setup mode.
+   * It indicates that do_aci_setup() should be called. The flag should be cleared if
+   * do_aci_setup() returns ACI_STATUS_TRANSACTION_COMPLETE.
+   */
+  if(setup_required)
+  {
+    if (SETUP_SUCCESS == do_aci_setup(&aci_state))
+    {
+      setup_required = false;
+    }
+  }
 }


whitespace cleanup in Serial sample

whitespace cleanup in Serial sample

--- L3G/examples/Serial/Serial.ino
+++ L3G/examples/Serial/Serial.ino
@@ -6,7 +6,7 @@
 void setup() {
   Serial.begin(9600);
   Wire.begin();
-
+
   if (!gyro.init())
   {
     Serial.println("Failed to autodetect gyro type!");
@@ -28,4 +28,4 @@
   Serial.println((int)gyro.g.z);

   delay(100);
-}+}


add map function

add map function

--- arduino/opencr_arduino/opencr/libraries/OpenManipulator/example/Arduino/Chain/d_open_manipulator_chain/d_open_manipulator_chain.ino
+++ arduino/opencr_arduino/opencr/libraries/OpenManipulator/example/Arduino/Chain/d_open_manipulator_chain/d_open_manipulator_chain.ino
@@ -23,6 +23,11 @@

 bool loop_flag = true;

+float fmap(float x, float in_min, float in_max, float out_min, float out_max)
+{
+  return (x - in_min) * (out_max - out_min) / (in_max - in_min) + out_min;
+}
+
 void setup()
 {
   Serial.begin(57600);
@@ -45,8 +50,9 @@
   if (loop_flag)
   {
     // chain.jointMove(CHAIN, goal_position, 2.0f);
-    // chain.toolMove(CHAIN, TOOL, true);
-    chain.toolMove(CHAIN, TOOL, 0.060f);
+    // chain.toolMove(CHAIN, TOOL, false);
+    // Serial.println(fmap(0.060, 0.040, 0.070, -0.785, 0.0));
+    chain.toolMove(CHAIN, TOOL, fmap(0.060, 0.040, 0.070, -2.09, 0.0));
     loop_flag = false;
   }


some fixes for firmware

some fixes for firmware

--- handlers/ESPHandler/ESPHandler.ino
+++ handlers/ESPHandler/ESPHandler.ino
@@ -1,5 +1,5 @@
-#define APA102
-//#define WS2812
+//#define APA102
+#define WS2812
 //#define WS2801

 #include <ESP8266WiFi.h>
@@ -9,6 +9,18 @@
 #include <ArduinoJson.h>
 #include <WiFiManager.h>

+#define D0   16
+#define D1   5
+#define D2   4
+#define D3   0
+#define D4   2
+#define D5   14
+#define D6   12
+#define D7   13
+#define D8   15
+#define D9   3
+#define D10  1
+
 #ifdef APA102
 #include <Adafruit_DotStar.h>
 #include <SPI.h>
@@ -31,8 +43,8 @@

 #define NUMPIXELS 1

-#define DATAPIN    13 // GPIO15 - MISO
-#define CLOCKPIN   9 // GPIO14 - CLK
+#define DATAPIN    D2
+#define CLOCKPIN   D5

 // ========== HANDLER INFO ==========
 const char* AUTOCONFIG_ACCESSPOINT_NAME = "LightHandlerConfigAP";
@@ -60,8 +72,6 @@
 WiFiClient client;

 ESP8266WebServer server(80);
-
-//TODO use fastled

 #ifdef APA102
 Adafruit_DotStar strip = Adafruit_DotStar(NUMPIXELS, DATAPIN, CLOCKPIN);
@@ -101,16 +111,18 @@
   Serial.println("Entered config mode");
   Serial.println(WiFi.softAPIP());

-  for (int i = 0; i < NUMPIXELS; i++) {
+  /*for (int i = 0; i < NUMPIXELS; i++) {
     strip.setPixelColor(i, strip.Color(0, 255, 0));
-  }
-  strip.show();
+    }
+    strip.show();*/
 }

 void setup()
 {
   Serial.begin(115200);

+  //strip.begin();
+
   WiFiManager wifiManager;

   String apName = String(AUTOCONFIG_ACCESSPOINT_NAME) + String("_") + String(ESP.getChipId());
@@ -126,10 +138,10 @@
     delay(1000);
   }

-  for (int i = 0; i < NUMPIXELS; i++) {
+  /*for (int i = 0; i < NUMPIXELS; i++) {
     strip.setPixelColor(i, strip.Color(0, 0, 255));
-  }
-  strip.show();
+    }
+    strip.show();*/

   Serial.println("Connected to WiFi");
 }
@@ -289,7 +301,7 @@
   return error;
 }

-void getCurrentColor() {
+/*void getCurrentColor() {
   Serial.println("> getCurrentColor()");

   if (connectToAPI()) {
@@ -357,7 +369,7 @@

     client.stop();
   }
-}
+  }*/

 void listenForServer()
 {
@@ -476,13 +488,14 @@

   server.begin();
   Serial.println("HTTP server started");
+
+  strip.begin();
 }

 void loop()
 {
   if (isInitialized) {
     server.handleClient();
-    //ESP.wdtDisable();
   } else if (serverAddress == "") { // has server data received
     if (!multicastServerIsStarted) {
       startMulticastServer();
@@ -495,7 +508,7 @@
       registerHandler();
       delay(500);
     } else {
-      getCurrentColor();
+      //getCurrentColor();
       startWebServer();
       isInitialized = true;
     }


staged for deployment

staged for deployment

--- code/Sender_/Sender_.ino
+++ code/Sender_/Sender_.ino
@@ -18,7 +18,7 @@
 #define V_BAT_PIN       A3
 #define V_EXCITE_PIN    A1
 #define SENS_EN         4
-#define debug           1
+#define debug           0

 int blinkCount = 1;


Fixed Typo

Fixed Typo

--- arduino/SHACv5.ino
+++ arduino/SHACv5.ino
@@ -9,10 +9,10 @@
  - Accomodate Arduino 1.0 String class reimplementation and in place replacement
  - Dependancies for SHAC :
    - https://github.com/Hardcore-fs/TinyWebServer/archive/master.zip
-     -> Extract above zip file to to sketchbook/libraries/TinyWebServer/
+     -> Extract above zip file to your sketchbook/libraries/TinyWebServer/
    - http://arduiniana.org/Flash/Flash4.zip
      -> See http://arduiniana.org/libraries/flash/
-     -> Extract above Flash4.zip file to to sketchbook/libraries/Flash/
+     -> Extract above Flash4.zip file to your sketchbook/libraries/Flash/

 The Webserver sub-implementation
 Copyright 2010 Ovidiu Predescu <ovidiu@gmail.com>


Bomb exploded animation

Bomb exploded animation

--- arduino/sketch.ino
+++ arduino/sketch.ino
@@ -10,6 +10,8 @@
 int counterColor[3] = {20, 36, 214};
 int deadColor[3] = {171, 3, 142};
 int bombColor[3] = {255, 0, 0};
+int explodedColor[3] = {255, 255, 255};
+int offColor[3] = {0, 0, 0};
 int currentColor[3] = {0, 0, 0};

 void setup() {
@@ -17,8 +19,8 @@
 	pinMode(REDPIN, OUTPUT);
 	pinMode(GREENPIN, OUTPUT);
 	pinMode(BLUEPIN, OUTPUT);
-
 	setColor(deadColor);
+	bombExploded();
 }

 void loop() {
@@ -37,8 +39,8 @@
 	}
 	Serial.println(bombStatus); */

-	fadeTo(bombColor);
-	fadeTo(terroColor);
+	/* fadeTo(bombColor);
+	fadeTo(terroColor); */
 }

 void initSerial() {
@@ -46,13 +48,6 @@
 	while (!Serial) {
 	  ;
 	}
-}
-
-void setColor(int color[]) {
-  analogWrite(REDPIN, color[0]);
-  analogWrite(GREENPIN, color[1]);
-  analogWrite(BLUEPIN, color[2]);
-  setCurrentColor(color);
 }

 void fadeTo(int color[]) {
@@ -80,6 +75,13 @@
 	}
 }

+void setColor(int color[]) {
+	analogWrite(REDPIN, color[0]);
+	analogWrite(GREENPIN, color[1]);
+	analogWrite(BLUEPIN, color[2]);
+	setCurrentColor(color);
+  }
+
 void setCurrentColor(int color[]) {
 	currentColor[0] = color[0];
 	currentColor[1] = color[1];
@@ -91,4 +93,20 @@
 		return true;
 	}
 	return false;
+}
+
+void bombBeep() {
+	setColor(offColor);
+	delay(900);
+	setColor(bombColor);
+	delay(100);
+}
+
+void bombExploded() {
+	while(millis() < 3000) {
+		setColor(offColor);
+		delay(50);
+		setColor(explodedColor);
+		delay(50);
+	}
 }


relay

relay

--- examples/Unit/4-RELAY/4-RELAY.ino
+++ examples/Unit/4-RELAY/4-RELAY.ino
@@ -7,7 +7,7 @@
 * 获取更多资料请访问：https://docs.m5stack.com/zh_CN/core/gray
 *
 * describe：4-Relay.  4个继电器
-* date：2021/8/9
+* date：2021/8/10
 *******************************************************************************
   Please connect to port A,Control 4 relays and demonstrate the asynchronous control relay LED
   请连接A端口，控制4继电器，并演示异步控制继电器LED


Update pattern and jack display outside of clock interrupt callback.

--- examples/rdt/rdt.ino
+++ examples/rdt/rdt.ino
@@ -88,6 +88,7 @@
     // initialize interface
     lfsr_loop_ = jack_1s_ = d_out_ = t_out_ = false;
     jack_d_ = jack_t_ = -1;
+    update_lfsr_jacks = update_pattern_dt_jacks = false;

     Clock.begin();
     Clock.attach_clock_callback(clock_callback);
@@ -276,6 +277,23 @@
       Display.fill_rect(34, 50, 3, 3, jack_t_ > 0 ? DUINO_SH1106::White : DUINO_SH1106::Black);
       Display.display(34, 36, 6, 6);
     }
+
+    if (update_lfsr_jacks)
+    {
+
+      Display.display(10, 12, 5, 5);
+      Display.display(115, 117, 5, 5);
+
+      update_lfsr_jacks = false;
+    }
+
+    if (update_pattern_dt_jacks)
+    {
+      Display.display(25, 102, 3, 3);
+      Display.display(91, 93, 5, 7);
+
+      update_pattern_dt_jacks = false;
+    }
   }

   void clock_clock_callback()
@@ -338,17 +356,15 @@

       // display pattern
       display_pattern(25, 24, widget_save_->params.vals.pattern, DUINO_SH1106::White);
-      Display.display(25, 102, 3, 3);
-
+
       // display jacks
       Display.fill_rect(10, 41, 3, 3, jacks & (1 << GT1) ? DUINO_SH1106::White : DUINO_SH1106::Black);
       Display.fill_rect(115, 41, 3, 3, jacks & (1 << GT2) ? DUINO_SH1106::White : DUINO_SH1106::Black);
       Display.fill_rect(91, 41, 3, 3, d_out_ ? DUINO_SH1106::White : DUINO_SH1106::Black);
       Display.fill_rect(91, 50, 3, 3, d_out_ ? DUINO_SH1106::Black : DUINO_SH1106::White);
-      Display.fill_rect(91, 59, 3, 3, t_out_ ? DUINO_SH1106::White : DUINO_SH1106::Black);
-      Display.display(10, 12, 5, 5);
-      Display.display(115, 117, 5, 5);
-      Display.display(91, 93, 5, 7);
+      Display.fill_rect(91, 59, 3, 3, t_out_ ? DUINO_SH1106::White : DUINO_SH1106::Black);
+
+      update_pattern_dt_jacks = true;
     }
     else
     {
@@ -356,9 +372,9 @@

       Display.fill_rect(10, 41, 3, 3, DUINO_SH1106::Black);
       Display.fill_rect(115, 41, 3, 3, DUINO_SH1106::Black);
-      Display.display(10, 12, 5, 5);
-      Display.display(115, 117, 5, 5);
-    }
+    }
+
+    update_lfsr_jacks = true;
   }

   void clock_external_callback()
@@ -500,6 +516,7 @@

   bool lfsr_loop_, jack_1s_, d_out_, t_out_;
   int8_t jack_d_, jack_t_;
+  volatile bool update_lfsr_jacks, update_pattern_dt_jacks;
 };

 DU_RDT_Function * function;


Rethought network architecture

Rethought network architecture

Each light now listens on two addresses: its individual endpoint
address and the broadcast address. All lights communicate to the base
station on one address.

--- receiver/receiver.ino
+++ receiver/receiver.ino
@@ -9,25 +9,31 @@
 #include <EEPROM.h>

-//RGB pins
-//Note: pins 5 and 6 use the fast, inaccurate PWM timer. If this becomes
-//an issue, look into software PWM implementations.
+// RGB pins
+// Note: pins 5 and 6 use the fast, inaccurate PWM timer. If this becomes
+// an issue, look into software PWM implementations.
 #define RED_PIN             3
 #define GREEN_PIN           5
 #define BLUE_PIN            6

-//Radio pins
-#define CE_PIN              9 //Radio chip enable pin
-#define CSN_PIN             10 //Radio chip select pin
-
-//Wireless protocol
-#define NODE_RF_ADDRESS         ((uint64_t)'SIGM!') //The 40-bit nRF address
-#define HEADER                  7446 //Must prefix every message
-#define BASE_STATION_ID         0x00 //The endpoint ID of the base station
+// Radio pins
+#define CE_PIN              9 // Radio chip enable pin
+#define CSN_PIN             10 // Radio chip select pin
+
+// Wireless protocol
+#define RF_ADDRESS(endpoint)         (0x5349474D00LL | (endpoint & 0xFF)) // Generates a 40-bit nRF address
+#define HEADER                  7446 // Must prefix every message
+#define BASE_STATION_ID         0x00 // The endpoint ID of the base station
+#define MULTICAST_ID            0xFF // The endpoint ID that all lights listen to
+
+#define ENDPOINT_PIPE           1 // The pipe for messages for this endpoint
+#define MULTICAST_PIPE          2 // The pipe for multicast messages
+
+#define CHANNEL                 80 // Channel center frequency = 2.4005 GHz + (Channel# * 1 MHz)
+#define NUM_RETRIES             5

 enum COMMANDS {
     CMD_SET_RGB       = 0x10,
-    CMD_BROADCAST_RGB = 0x11,
     CMD_PING          = 0x20,
     CMD_PING_RESPONSE = 0x21,
 };
@@ -35,16 +41,15 @@
 typedef struct packet_tag {
     uint16_t header;
     uint8_t command;
-    uint8_t endpoint;
-    uint8_t rgb[3];
+    uint8_t data[3];
 } packet_t;

-//Serial protocol
+// Serial protocol
 #define MAX_SERIAL_LINE_LEN 20

-//Firmware information
-#define VERSION                 0 //The firmware version number
-#define ENDPOINT_ID_LOCATION    0x000 //The address in EEPROM to store the ID
+// Firmware information
+#define VERSION                 0 // The firmware version number
+#define ENDPOINT_ID_LOCATION    0x000 // The address in EEPROM to store the ID

 void networkRead(void);
@@ -65,19 +70,22 @@
 unsigned long lastPingTime;

 /**
- * Initialize SPI, radio, and serial.
+ * Initialize radio and serial.
  */
 void setup() {
     // Initialize the radio
     radio.begin();
-    radio.setDataRate(RF24_250KBPS); // 250kbps is good enough
-    radio.setChannel(80); // Channel center frequency = 2.4005 GHz + (Channel# * 1 MHz)
-    radio.setPALevel(RF24_PA_MAX); // Range is important, not low power consumption
-    radio.setRetries(0, 0); // Real-time is critical - not retransmission
-    radio.setAutoAck(false); // It doesn't matter if packets don't get through
+    radio.setDataRate(RF24_250KBPS); // 250kbps should be plenty
+    radio.setChannel(CHANNEL);
+    radio.setPALevel(RF24_PA_MAX); // Range is important, not power consumption
+    radio.setRetries(0, NUM_RETRIES);
     radio.setCRCLength(RF24_CRC_8); // Minimal error detection is fine
     radio.setPayloadSize(sizeof(packet_t));
-    radio.openReadingPipe(0, NODE_RF_ADDRESS);
+
+    radio.openWritingPipe(RF_ADDRESS(BASE_STATION_ID));
+    radio.openReadingPipe(ENDPOINT_PIPE, RF_ADDRESS(endpointID));
+    radio.openReadingPipe(MULTICAST_PIPE, RF_ADDRESS(MULTICAST_ID));
+    radio.setAutoAck(MULTICAST_PIPE, false); // Prevent ACK collisions on the multicast pipe
     radio.startListening();

     // Initialize serial console
@@ -114,34 +122,25 @@
         return;
     }

-    if (packet.endpoint != endpointID &&
-        packet.command != CMD_BROADCAST_RGB) {
-        // Packet was not meant for this endpoint
-        return;
-    }
-
     switch (packet.command) {

-        case CMD_SET_RGB:
-        case CMD_BROADCAST_RGB: {
-            // The packet is intended for this endpoint, so update the color.
-            setRGB(packet.rgb[0], packet.rgb[1], packet.rgb[2]);
+        case CMD_SET_RGB: {
+            // Update the color
+            setRGB(packet.data[0], packet.data[1], packet.data[2]);
             break;
         }

         case CMD_PING: {
-            // Received a ping request. Respond with the endpoint ID and version.
+            // Respond to the ping with the endpoint ID and version
             packet_t response = {
                 HEADER,
                 CMD_PING_RESPONSE,
-                BASE_STATION_ID,
                 {endpointID, VERSION, 0}
             };

             radio.stopListening();
-            radio.openWritingPipe(NODE_RF_ADDRESS);
             radio.write(&response, sizeof(response));
-            radio.openReadingPipe(0, NODE_RF_ADDRESS);
+            radio.startListening();

             break;
         }


restructured transmission packet

restructured transmission packet

--- client/client.ino
+++ client/client.ino
@@ -19,12 +19,15 @@
 #include <nRF24L01.h>
 #include <MirfHardwareSpiDriver.h>

+#define NO_BUTTON 0
+#define SUCCESS 0
+#define TIMEOUT 1
+
 struct Message {
-  byte id;
-  //uint8_t destination;
-  //uint8_t source;
+  byte destination;
+  byte source;
   byte data;
-  byte checksum[2];
+  byte checksum;
 };

 Message tx_message;
@@ -61,84 +64,115 @@
   /* Configure and power up tranceiver */
   Mirf.config();

-  /* Initialize button */
+  /* Initialize button (set as input) */
   int i;
-  for ( i = 2; i <= 6; i++ ) {
+  for ( i = 2; i <= 6; i++ )
     pinMode( i, INPUT );
-    digitalWrite( i, LOW );
-  }
   Serial.println( "Beginning ... " );
 }

-uint8_t getButton() {
+/*
+ * function to check which button was pressed
+ * return - 0 when button was successfuly read
+ */
+uint8_t readButtons( uint8_t* button ) {
+  *button = NO_BUTTON;
   int i;
-  for ( i = 2; i <= 6; i++ ) {
-    if ( digitalRead( i ) ) {
-      Serial.print( "button " );
-      Serial.print( i );
-      Serial.println( " was pressed" );
-      return i;
-    }
-  }
-  return 0;
+  /* go trough all the button and check which one was pressed */
+  for ( i = 2; i <= 6; i++ )
+    if ( digitalRead( i ) ) *button = i; else continue;
+  Serial.print( "button was pressed, nr " );
+  Serial.println( *button );
+  return SUCCESS;
 }

-int receivePacket() {
+/*
+ * function to receive datapacket, must be called several times
+ * to receive all the bytes
+ * TIPS: use timeoutReceive(), if unsure
+ * returns - 0 when successfuly received
+ *           1 when data is not ready to be read
+ *           2 when receiving status was illegaly changed
+ */
+uint8_t receivePacket() {
   /* when nothing was received */
   if ( !Mirf.dataReady() ) return 1;
   byte b;
-  Mirf.getData( (byte *) b );
+  Mirf.getData( &b );
   /* according to our status we save the received byte and go to next state */
   switch ( rx_stat ) {
-    case 0: rx_message.id = b; rx_stat = 1; break;
-    case 1: rx_message.data = b; rx_stat = 2; break;
-    case 2: rx_message.checksum[0] = b; rx_stat = 3; break;
-    case 3: rx_message.checksum[1] = b; rx_finished = true; rx_stat = 0; break;
-    default: Serial.println( "Receiving status was changed illegaly!" ); break;
+    case 0: rx_message.destination = b; rx_stat = 1; break;
+    case 1: rx_message.source = b; rx_stat = 2; break;
+    case 2: rx_message.data = b; rx_stat = 3; break;
+    /* TODO: implement checksum verification */
+    case 3: rx_message.checksum = b; rx_finished = true; rx_stat = 0; break;
+    default: Serial.println( "Status illegaly changed!" ); rx_stat = 0; return 2;
   }
-  return 0;
+  return SUCCESS;
 }

-int transmitPacket() {
+/*
+ * function to transmits the datapacket to the server
+ * return - 0 when transmission successfuly finished
+ */
+uint8_t transmitPacket() {
+  tx_message.destination = 0xA1;
+  tx_message.source = 0xA2;
+  tx_message.data = 0x01;
+  /* calculate the checksum, use XOR */
+  tx_message.checksum = 0x00;
+  tx_message.checksum ^= tx_message.destination;
+  tx_message.checksum ^= tx_message.source;
+  tx_message.checksum ^= tx_message.data;
   /* Send the data packet */
-  Mirf.send( (byte *) tx_message.id );
-  Mirf.send( (byte *) tx_message.data );
-  Mirf.send( (byte *) tx_message.checksum[0] );
-  Mirf.send( (byte *) tx_message.checksum[1] );
+  Mirf.send( &tx_message.destination );
+  Mirf.send( &tx_message.source );
+  Mirf.send( &tx_message.data );
+  Mirf.send( &tx_message.checksum );

   /* Wait for data to be transmitted */
   while ( Mirf.isSending() );
   Serial.println( "Finished sending" );
   delay( 10 );
+
+  return SUCCESS;
 }

-void g() {
-  /* transmit the datapacket */
-  transmitPacket();
-
+/*
+ * function to receive the datapacket with timeout delay
+ * returns - 0 when successful, 1 when timeout
+ */
+uint8_t timeoutReceive() {
   /* timeout for receiving */
   long time = millis();
   while ( !rx_finished ) {
-    /* if we received successfuly, refresh timeout */
-    if( receivePacket() == 0 ) time = millis();
+    /* if we received byte successfuly, refresh timeout */
+    if( receivePacket() == SUCCESS ) time = millis();

     /* Timeout when data packet was not received within 1 second */
     if ( ( millis() - time ) > 1000 ) {
       Serial.println( "Timeout on response from server!" );
-      //return 1;
+      return TIMEOUT;
     }
   }
-
+  /* reset receiving status */
+  rx_finished = false;
   /* When transmission was successful */
+  return SUCCESS;
 }

 void loop() {
+  uint8_t button;
+  readButtons( &button );
   /* Wait for button to be pressed, TODO: implement interrupt */
-  if ( getButton() > 0 ) {
+  if ( button > NO_BUTTON ) {
     digitalWrite( 9, HIGH );
     Serial.println( "Finished sending!" );
   }

+  /* transmit and receive acknowledgement */
+  //transmitPacket();
+  //timeoutReceive();

   /* don't freeze the MCU */
   delay( 100 );


Support pause, rewind, fast forward, prev video

--- Arduino/LightPlayer/LightPlayer.ino
+++ Arduino/LightPlayer/LightPlayer.ino
@@ -46,7 +46,8 @@
 struct PendingOperations
 {
   uint8_t cycle_brightness;
-  uint8_t skip_video;
+  uint8_t next_video;
+  uint8_t prev_video;

   uint8_t cycle_ceiling_red;
   uint8_t cycle_ceiling_green;
@@ -55,6 +56,10 @@
   uint8_t cycle_floor_red;
   uint8_t cycle_floor_green;
   uint8_t cycle_floor_blue;
+
+  uint8_t reduce_speed;
+  uint8_t increase_speed;
+  uint8_t toggle_pause;

   uint8_t toggle_negative;
   uint8_t reset_settings;
@@ -104,8 +109,11 @@
 ColorIntensity r_intensity;
 ColorIntensity g_intensity;
 ColorIntensity b_intensity;
+int8_t speed;

 #define BRIGHTNESS_STEP 32
+const int8_t MIN_SPEED = -6;
+const int8_t MAX_SPEED = 4;

 //------------------------------------------------------------------------------
 // File system object.
@@ -176,13 +184,17 @@
 void printPendingOperations(PendingOperations & ops)
 {
   if (ops.cycle_brightness)    Serial.print(F("\ncycle_brightness"));
-  if (ops.skip_video)          Serial.print(F("\nskip_video"));
+  if (ops.next_video)          Serial.print(F("\nnext_video"));
+  if (ops.prev_video)          Serial.print(F("\nprev_video"));
   if (ops.cycle_ceiling_red)   Serial.print(F("\ncycle_ceiling_red"));
   if (ops.cycle_ceiling_green) Serial.print(F("\ncycle_ceiling_green"));
   if (ops.cycle_ceiling_blue)  Serial.print(F("\ncycle_ceiling_blue"));
   if (ops.cycle_floor_red)     Serial.print(F("\ncycle_floor_red"));
   if (ops.cycle_floor_green)   Serial.print(F("\ncycle_floor_green"));
   if (ops.cycle_floor_blue)    Serial.print(F("\ncycle_floor_blue"));
+  if (ops.reduce_speed)        Serial.print(F("\nreduce_speed"));
+  if (ops.increase_speed)      Serial.print(F("\nincrease_speed"));
+  if (ops.toggle_pause)        Serial.print(F("\ntoggle_pause"));
   if (ops.toggle_negative)     Serial.print(F("\ntoggle_negative"));
   if (ops.reset_settings)      Serial.print(F("\nreset_settings"));
 }
@@ -207,6 +219,8 @@
   Serial.print(b_intensity.ceil);
   Serial.print(F(" neg "));
   Serial.print(negative);
+  Serial.print(F(" speed "));
+  Serial.print(speed);
 }

 void resetDefaultSettings()
@@ -216,6 +230,7 @@
   b_intensity.reset();
   brightness = 255;
   negative = 0;
+  speed = 0;
 }

 void performPendingOperations(PendingOperations & ops)
@@ -225,25 +240,33 @@
 #endif

   if (ops.cycle_brightness)    brightness -= BRIGHTNESS_STEP;
-  if (ops.skip_video)          infile.close();
+  if (ops.next_video)          nextFile();
+  if (ops.prev_video)          previousFile();
   if (ops.cycle_ceiling_red)   r_intensity.lowerCeil();
   if (ops.cycle_ceiling_green) g_intensity.lowerCeil();
   if (ops.cycle_ceiling_blue)  b_intensity.lowerCeil();
   if (ops.cycle_floor_red)     r_intensity.raiseFloor();
   if (ops.cycle_floor_green)   g_intensity.raiseFloor();
   if (ops.cycle_floor_blue)    b_intensity.raiseFloor();
+  if (ops.reduce_speed)        speed = max(speed-1, MIN_SPEED);
+  if (ops.increase_speed)      speed = min(speed+1, MAX_SPEED);
+  if (ops.toggle_pause)        speed = (speed == -1 ? 0 : -1);
   if (ops.toggle_negative)     negative = !negative;
   if (ops.reset_settings)      resetDefaultSettings();

 #ifdef DEBUG
   if (    ops.cycle_brightness
-       || ops.skip_video
+       || ops.next_video
+       || ops.prev_video
        || ops.cycle_ceiling_red
        || ops.cycle_ceiling_green
        || ops.cycle_ceiling_blue
        || ops.cycle_floor_red
        || ops.cycle_floor_green
        || ops.cycle_floor_blue
+       || ops.reduce_speed
+       || ops.increase_speed
+       || ops.toggle_pause
        || ops.toggle_negative
        || ops.reset_settings)
   {
@@ -266,7 +289,7 @@
         } break;

         case Pressed::b: {
-          GlobalPendingOperations.skip_video = 1;
+          GlobalPendingOperations.next_video = 1;
         } break;

         case Pressed::ab: {
@@ -275,6 +298,10 @@

         case Pressed::cd: {
           CurrentMode = Mode::COLOR_FLOOR;
+        } break;
+
+        case Pressed::ad: {
+          CurrentMode = Mode::VIDEO_PLAYBACK;
         } break;

         case Pressed::bc: {
@@ -320,6 +347,34 @@

         case Pressed::c: {
           GlobalPendingOperations.cycle_floor_blue = 1;
+        } break;
+      }
+    } break;
+
+    case Mode::VIDEO_PLAYBACK: {
+      switch (button_states) {
+        case Pressed::d: {
+          CurrentMode = Mode::NORMAL;
+        } break;
+
+        case Pressed::a: {
+          GlobalPendingOperations.reduce_speed = 1;
+        } break;
+
+        case Pressed::b: {
+          GlobalPendingOperations.increase_speed = 1;
+        } break;
+
+        case Pressed::c: {
+          GlobalPendingOperations.toggle_pause = 1;
+        } break;
+
+        case Pressed::ac: {
+          GlobalPendingOperations.prev_video = 1;
+        } break;
+
+        case Pressed::bd: {
+          GlobalPendingOperations.next_video = 1;
         } break;
       }
     } break;
@@ -366,8 +421,54 @@
   }
 }

+bool previousFile() {
+  if (infile.isOpen()) {
+    infile.close();
+  }
+
+  // dir size is 32.
+  uint16_t index = sd.vwd()->curPosition()/32;
+  if (index < 2) return false;
+  // position to possible previous file location.
+  index -= 2;
+
+  do {
+    infile.open(sd.vwd(), index, O_READ);
+
+    if (infile.isOpen()) {
+      if (!infile.isHidden() && !infile.isSystem()) {
+#ifdef DEBUG
+        char buf[13];
+        infile.getName(buf, sizeof(buf));
+        cout << F("\nOpened prev file: ") << buf;
+#endif
+        return true;
+      }
+      infile.close();
+    } else {
+      return false;
+    }
+  } while (index-- > 0);
+
+  return false;
+}
+
 bool readFrame()
 {
+  int32_t seek_offset = (int32_t)speed * sizeof(frame);
+  if (speed < 0 && infile.curPosition() < -seek_offset) {
+    // Going backwards, and reached the start of this file.
+    if (!previousFile()) {
+      // No more files.  Restart from the first at normal speed.
+      speed = 0;
+      return false;
+    }
+    // Successfully opened previous file - start from the end.
+    infile.seekEnd();
+  }
+  if (!infile.seekCur(seek_offset)) {
+    return false;
+  }
   return infile.read(frame, sizeof(frame)) == sizeof(frame);
 }


Put button debug into #ifdef

Put button debug into #ifdef

--- midicontroller.ino
+++ midicontroller.ino
@@ -134,6 +134,7 @@
 }

 void debugButton(Button *button) {
+  #ifdef DEBUG_BUTTONS
   Serial.print("Button: ");
   Serial.print((*button).getPin());
   Serial.print(" Just pressed: ");
@@ -142,6 +143,7 @@
   Serial.print((*button).isPressed());
   Serial.print(" Just released : ");
   Serial.println((*button).isJustReleased());
+  #endif
 }

 void updateButtons() {


Add multiple comments Correct normalisations Get rid of 3.14 (pi) with a #define

--- Arduino/Complete/src/src.ino
+++ Arduino/Complete/src/src.ino
@@ -43,7 +43,8 @@
 TinyGPSPlus nmea;
 // O stands for Opensource, R for Robokite
 // The index is the place of the field in the NMEA message
-TinyGPSCustom feedback_request      (nmea, "ORFBR", 1);  // Feedback request
+TinyGPSCustom feedback_request      (nmea, "ORFBR", 1);  // Feedback request. The feedback are normalized between 0 and 1023
+// The orders are normalized between -127 and 127
 TinyGPSCustom pwm1     (nmea, "ORPW1", 1);  // Dimentionless voltage setpoint (Pulse Width Modulation) for Sabertooth output 1
 TinyGPSCustom pwm2     (nmea, "ORPW2", 1);  // Dimentionless voltage setpoint (Pulse Width Modulation) for Sabertooth output 2
 TinyGPSCustom setpos1  (nmea, "ORSP1", 1);  // Position setpoint for Sabertooth output 1
@@ -60,7 +61,7 @@
 PID myPID2(&Input2, &Output2, &Setpoint2, 1, 0, 0, DIRECT);

 // Define global variables to deal with encoder interrupt
-volatile unsigned long threshold = 1000;// 'threshold' is the De-bounce Adjustment factor for the Rotary Encoder. halfSteps
+volatile unsigned long threshold = 1000;// 'threshold' is the De-bounce Adjustment factor for the encoder. halfSteps
 volatile unsigned long int0time = 0;
 volatile unsigned long int1time = 0;
 volatile uint8_t int0signal = 0;
@@ -76,12 +77,12 @@
 // Hardware specific parameters
 // Potentiometer
 #define POT_RANGE_DEG      300 // 300 is the value for standard potentiometer
-#define POT_USED_RANGE_DEG  60 // To
-#define POT_OFFSET        0.05 // Distance from rotation axis to lever arm
-#define NEUTRAL_ANGLE_DEG  225
+#define POT_USED_RANGE_DEG  60 // To normalize and saturate rotation
+#define POT_OFFSET        0.05 // Distance from rotation axis to lever arm (in m)
+#define NEUTRAL_ANGLE_DEG  225 // Zero of the potentiometer
 // Linear encoder
-#define LINEAR_RESOLUTION 0.005
-#define LINEAR_USED_RANGE 0.05
+#define LINEAR_RESOLUTION 0.005// Resolution of the linear encoder
+#define LINEAR_USED_RANGE 0.05 // To normalize and saturate translation motion

 void setup()
 {
@@ -107,18 +108,18 @@
   // Turn the PID on
   myPID1.SetMode(MANUAL);
   myPID2.SetMode(MANUAL);
+  // Saturate the output to the maximum range (values are normalized between -1 and 1)
   myPID1.SetOutputLimits(-1, 1);
   myPID2.SetOutputLimits(-1, 1);

-    //*****************************************************
+  // Prepare interrupts for the linear encoder
   pinMode(A_PIN, INPUT);
   digitalWrite(A_PIN, HIGH);
   attachInterrupt(0, int0, CHANGE);
-  //PCintPort::attachInterrupt(pinA, &int0, CHANGE);
+
   pinMode(B_PIN, INPUT);
   digitalWrite(B_PIN, HIGH);
   attachInterrupt(1, int1, CHANGE);
-  //PCintPort::attachInterrupt(pinB, &int1, CHANGE);

   // Pin used to get absolute position
   pinMode(RESET_PIN, INPUT);
@@ -207,19 +208,20 @@
 // Linear encoder
 #define LINEAR_RESOLUTION 0.005
 #define LINEAR_USED_RANGE 0.05
+#define PI 3.1415
 void computeFeedback()
 {

   // Feedbacks are normalized between -1 and 1

-  // Potentiomete angle
-  float rawAngle_deg = analogRead(POT_PIN)/1024.0*POT_RANGE_DEG;
+  // Potentiometer angle
+  float rawAngle_deg = analogRead(POT_PIN)/1023.0*POT_RANGE_DEG;
   Input1 = (rawAngle_deg - NEUTRAL_ANGLE_DEG)/POT_USED_RANGE_DEG;

   // Linear encoder position
   Input2 = halfSteps*LINEAR_RESOLUTION/2/LINEAR_USED_RANGE;
-  // Correct for lever arm (potentiometer not on axis)
-  Input2+= (rawAngle_deg - NEUTRAL_ANGLE_DEG)* POT_OFFSET*3.14/180;
+  // Correction for lever arm (potentiometer not on axis)
+  Input2+= (rawAngle_deg - NEUTRAL_ANGLE_DEG)* POT_OFFSET*PI/180;

   // Line tension
   Input3 = analogRead(LINE_TENSION_PIN)/512 - 1;
@@ -227,17 +229,18 @@

 void sendFeedback()
 {
+  // All the feedback values are normalized in the range 0-1023 (10 bits resolution)
   if (isFeedbackRequested)
   {
-    Serial.print((power1+128)*4);
+    Serial.print((power1+127)*4);
     Serial.print(", ");
-    Serial.print((power2+128)*4);
+    Serial.print((power2+127)*4);
     Serial.print(", ");
-    Serial.print((Input1+1)*512);
+    Serial.print((Input1+1)/2*1023);
     Serial.print(", ");
-    Serial.print((Input2+1)*512);
+    Serial.print((Input2+1)/2*1023);
     Serial.print(", ");
-    Serial.print((Input3+1)*512);
+    Serial.print((Input3+1)/2*1023);
     Serial.println("");
     isFeedbackRequested = false;
   }
@@ -273,9 +276,10 @@
 {
   // Order in the range -127/127
    ST.motor(1, power1);
-   ST.motor(2, -power2);
-}
-
+   ST.motor(2, power2);
+}
+
+// Taken from http://playground.arduino.cc/Main/RotaryEncoders J.Carter(of Earth)
 void int0()
 {
   if ( micros() - int0time < threshold )
@@ -291,6 +295,7 @@
     halfSteps--;
 }

+// Taken from http://playground.arduino.cc/Main/RotaryEncoders J.Carter(of Earth)
 void int1()
 {
   if ( micros() - int1time < threshold )


basic KX3 serial frequency display

basic KX3 serial frequency display

--- src/sketch.ino
+++ src/sketch.ino
@@ -3,20 +3,16 @@
 #define LCD_PIN 5
 #define LED_PIN 13
 #define BLINK_DELAY 75
+#define BAUD_RATE 9600
+
+#define LOOP_DELAY 50

 serLCD lcd(LCD_PIN);

 void setup() {
-  delay(2000);
-
-  Serial.begin(9600);
-  Serial.println("hello world");
-
-  for (int i = 0; i < 4; i++) {
-    blink();
-  }
-
-  delay(1000);
+  delay(250);
+  Serial.begin(BAUD_RATE);
+  /*displayBanner();*/
 }

 String str = "";
@@ -24,7 +20,7 @@

 void loop() {
   ledOff();
-  Serial.print("fa;");
+  Serial.write("FA;");

   // wait for FA00000000000;
   while (Serial.available() > 0) {
@@ -40,14 +36,36 @@
     }
   }

-  delay(1000);
+  delay(LOOP_DELAY);
+}
+
+void displayBanner() {
+  lcd.clear();
+  lcd.setCursor(1,1);
+  lcd.print("KX3");
+
+  for (int i = 0; i < 4; i++) {
+    blink();
+  }
 }

 void displayFrequency(String msg) {
-  Serial.println();
-  Serial.println("------------");
-  Serial.println(msg);
-  Serial.println("------------");
+  lcd.setCursor(2, 7);
+  lcd.print(formatFrequency(msg));
+}
+
+String formatFrequency(String vfo) {
+  String freq = "";
+
+  // e.g. convert '07' to '7'
+  freq += String(vfo.substring(5, 7).toInt());
+
+  freq += ".";
+  freq += vfo.substring(7, 10);
+  freq += ".";
+  freq += vfo.substring(10, 13);
+
+  return freq;
 }

 void ledOn() {


Validate NMEA/GPS checksums so we stop trying to parse bad data. (The wifi board sometimes takes enough time to do stuff that we end up with mangled incoming nmea/gps sentences)

--- device.ino
+++ device.ino
@@ -85,10 +85,10 @@
 #define   WIFI_NOT_CELL
 #define WIFI_DEBUG_ON
 //#define GPRS_DEBUG_ON
-//#define GPS_DEBUG_ON
+#define GPS_DEBUG_ON
 //#define PUMP_DEBUG_ON
 //#define EXECUTION_PATH_DEBUG_ON
-//#define NMEA_DEBUG_ON
+#define NMEA_DEBUG_ON
 #define DEBUG_MEMORY_ON
 //#define STRESS_MEMORY_ON
 //#define BYPASS_AES_ON
@@ -447,7 +447,9 @@
   //

   //Serial3.println("$PMTK314,0,2,0,2,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0*28");	// Every 2 seconds
-  Serial3.println("$PMTK314,0,3,0,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0*2A");		// GGA every 1 second, RMC every 3
+  //Serial3.println("$PMTK314,0,3,0,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0*2A");		// GGA every 1 second, RMC every 3
+  Serial3.println("$PMTK314,0,3,0,2,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0*29");		// GGA every 2 second, RMC every 3
+  //Serial3.println("$PMTK314,0,5,0,3,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0*2E");		// GGA every 3 second, RMC every 5
 }

@@ -1212,7 +1214,8 @@
       sog_start < 0     ||    sog_start >= (int) gps_read_buffer.length()     ||
       tmg_start < 0     ||    tmg_start >= (int) gps_read_buffer.length()     ||
       date_start < 0    ||    date_start >= (int) gps_read_buffer.length()    ||
-      var_start < 0     ||    var_start >= (int) gps_read_buffer.length()     )
+      var_start < 0     ||    var_start >= (int) gps_read_buffer.length()     ||
+      gps_read_buffer.lastIndexOf('$') > 0)
   {
       #ifdef GPS_DEBUG_ON
       debug_info(F("Bad RMC string"));
@@ -1390,7 +1393,8 @@
       siv_start < 0  ||   siv_start >= (int) gps_read_buffer.length()    ||
       hdp_start < 0  ||   hdp_start >= (int) gps_read_buffer.length()    ||
       alt_start < 0  ||   alt_start >= (int) gps_read_buffer.length()    ||
-      altu_start < 0 ||   altu_start >= (int) gps_read_buffer.length())
+      altu_start < 0 ||   altu_start >= (int) gps_read_buffer.length()   ||
+      gps_read_buffer.lastIndexOf('$') > 0)
   {
       gps_valid = false;
       #ifdef GPS_DEBUG_ON
@@ -1447,6 +1451,39 @@
   }
 }

+bool validate_gps_buffer()
+{
+  byte_zero = 0;
+  for(i = gps_read_buffer.indexOf('$') + 1; i < gps_read_buffer.lastIndexOf('*'); i++)
+  {
+    byte_zero = byte_zero ^ gps_read_buffer.charAt(i);
+  }
+  if(gps_read_buffer.endsWith(String(byte_zero, HEX)))
+  {
+    return true;
+  }
+  #ifdef GPS_DEBUG_ON
+  debug_info("Bad GPS buffer: " + gps_read_buffer);
+  #endif
+  return false;
+}
+
+bool validate_nmea_buffer()
+{
+  byte_zero = 0;
+  for(i = nmea_read_buffer.indexOf('$') + 1; i < nmea_read_buffer.lastIndexOf('*'); i++)
+  {
+    byte_zero = byte_zero ^ nmea_read_buffer.charAt(i);
+  }
+  if(nmea_read_buffer.endsWith(String(byte_zero, HEX)))
+  {
+    return true;
+  }
+  #ifdef NMEA_DEBUG_ON
+  debug_info("Bad NMEA buffer: " + nmea_read_buffer);
+  #endif
+  return false;
+}

 void gps_read()
@@ -1456,23 +1493,26 @@
      int incoming_byte = Serial3.read();
      if(incoming_byte == '\n')
      {
-       if(gps_read_buffer.indexOf("$GPRMC,") == 0)
+       if(validate_gps_buffer())
        {
-         #ifdef GPS_DEBUG_ON
-         debug_info(F("--GPS BUF RMC--"));
-         debug_info(gps_read_buffer);
-         #endif
-         push_out_nmea_sentence(false);
-         parse_gps_buffer_as_rmc();
-       }
-       else if(gps_read_buffer.indexOf("$GPGGA,") == 0)
-       {
-         #ifdef GPS_DEBUG_ON
-         debug_info(F("--GPS BUF GGA--"));
-         debug_info(gps_read_buffer);
-         #endif
-         push_out_nmea_sentence(false);
-         parse_gps_buffer_as_gga();
+         if(gps_read_buffer.indexOf("$GPRMC,") == 0)
+         {
+           #ifdef GPS_DEBUG_ON
+           debug_info(F("--GPS BUF RMC--"));
+           debug_info(gps_read_buffer);
+           #endif
+           push_out_nmea_sentence(false);
+           parse_gps_buffer_as_rmc();
+         }
+         else if(gps_read_buffer.indexOf("$GPGGA,") == 0)
+         {
+           #ifdef GPS_DEBUG_ON
+           debug_info(F("--GPS BUF GGA--"));
+           debug_info(gps_read_buffer);
+           #endif
+           push_out_nmea_sentence(false);
+           parse_gps_buffer_as_gga();
+          }
        }
        gps_read_buffer = "";
      }
@@ -1487,6 +1527,9 @@
   }
   if((int) gps_read_buffer.length() >= MAX_GPS_BUFFER - 1 )
   {
+    #ifdef GPS_DEBUG_ON
+    debug_info(F("nuked gps buf"));
+    #endif
     gps_read_buffer = "";
   }
 }
@@ -3651,8 +3694,11 @@
      int incoming_byte = Serial2.read();
      if(incoming_byte == '\n')
      {
-       push_out_nmea_sentence(true);
-       parse_nmea_sentence();
+       if(validate_nmea_buffer())
+       {
+         push_out_nmea_sentence(true);
+         parse_nmea_sentence();
+       }
        nmea_read_buffer = "";
      }
      else if (incoming_byte == '\r')


Update InterleavedContinuous.ino

Update InterleavedContinuous.ino

--- firmware/examples/InterleavedContinuous.ino
+++ firmware/examples/InterleavedContinuous.ino
@@ -24,7 +24,7 @@

 The range readings are in units of mm. */

-#include <VL6180X_lib.h>
+#include <vl6180x_lib.h>

 VL6180X sensor;


some modifications to work with LED instead of relay

--- demo_photo_resistor/demo_photo_resistor.ino
+++ demo_photo_resistor/demo_photo_resistor.ino
@@ -15,10 +15,10 @@
   val = analogRead(0);// Asigns the sensor value in A0 to the variable.
   Serial.println(val);// Prints the value in the Serial Port

-if (val >300 and val <610)  digitalWrite(trans_base, HIGH),digitalWrite (warning, LOW); // If the sensor outcome is higher than 300 and less than 610, then activates the transistor and disable the warning pin.
+if (val >200 and val <400)  digitalWrite(trans_base, HIGH),digitalWrite (warning, LOW); // If the sensor outcome is higher than 300 and less than 610, then activates the transistor and disable the warning pin.
   else digitalWrite(trans_base, LOW);

-if (val > 610)  digitalWrite(trans_base, LOW), digitalWrite (warning, HIGH); // If the sensor outcome is higher than 610, then deactivates the transistor and activates the protection using the warning pin.
+if (val > 400)  digitalWrite(trans_base, HIGH), digitalWrite (warning, HIGH); // If the sensor outcome is higher than 610, then deactivates the transistor and activates the protection using the warning pin.

   }


correction from previous commit to the arduino file name

--- SerialEnabledRewards/SerialEnabledRewards.ino
+++ SerialEnabledRewards/SerialEnabledRewards.ino
@@ -61,6 +61,11 @@
 unsigned long Well_IR_Timer[nWells];    // timer for how long IR has been on.
 unsigned long PumpTimeRef[nWells];      // time ref for pump on
 unsigned long PumpTimer[nWells];        // timer for how long pump has been on
+
+char RR[] = "RR";
+char DD[] = "DD";
+char AW[] = "AW";
+char DW[] = "DW";

 // Setup
 void setup() {
@@ -128,10 +133,8 @@
           TurnOFFPump(well);
           Serial.print("<Reward Delivered to Well # ");
           Serial.println(well + 1);
-          Serial.print(">");
-          char eventCode[3];
-          sprintf(eventCode, "RR%d",well+1);
-          sendEventCode(eventCode);
+          Serial.print(">\n");
+          sendEventCode(RR,well+1);
           DeActivateWell(well);
         }
       }
@@ -162,11 +165,11 @@
 }

 // send event code
-void sendEventCode(char* code){
+void sendEventCode(char* code, int num){
    char str[10];
-   sprintf(str,"<EC_%s", code);
+   sprintf(str,"<EC_%s%d", code, num);
    Serial.println(str);
-   Serial.println(">");
+   Serial.println(">\n");
 }

 // Detection state
@@ -193,9 +196,7 @@
         Serial.print("<Detection on Well # ");
         Serial.println(well + 1);
         Serial.print(">\n");
-        char eventCode[3];
-        sprintf(eventCode, "DD%d",well+1);
-        sendEventCode(eventCode);
+        sendEventCode(DD,well+1);
       }
     }
   }
@@ -318,9 +319,7 @@
   Well_Active_TimeRef[well] = millis();
   Well_Active_Timer[well] = 0;
   Well_LED_ON(well);
-  char eventCode[3];
-  sprintf(eventCode, "AW%d",well+1);
-  sendEventCode(eventCode);
+  sendEventCode(AW,well+1);
 }

 void DeActivateWell(int well) {
@@ -328,9 +327,7 @@
   Well_Active_TimeRef[well] = 15000UL;
   Well_Active_Timer[well] = 0;
   Well_LED_OFF(well);
-  char eventCode[3];
-  sprintf(eventCode, "DW%d",well+1);
-  sendEventCode(eventCode);
+  sendEventCode(DW,well+1);
 }

 void  Well_LED_ON(int well) {


Moved "int ReadingNumber=0" out of Loop to avoid constantly resetting to zero

--- VernierAnalogVoltage/VernierAnalogVoltage.ino
+++ VernierAnalogVoltage/VernierAnalogVoltage.ino
@@ -1,5 +1,5 @@
 /*
-VernierAnalogVoltage (v 2014.09)
+VernierAnalogVoltage (v 2015.06)
 Reads a Vernier analog (BTA) sensor connected to pin A0 of the Arduino. This
 sketch displays the raw voltage reading on the Serial Monitor. As written, the
 reading will be displayed every half second. Change the variable TimeBetweenReadings
@@ -7,6 +7,7 @@

 See www.vernier.com/arduino for more information.
  */
+int ReadingNumber=0;
 int TimeBetweenReadings = 500;
 void setup() {
   // initialize serial communication at 9600 bits per second:
@@ -17,7 +18,7 @@
 float Count;
 float Voltage;
 float SensorReading;
-int ReadingNumber=0;
+
 float Time;//the print below does the division first to avoid overflows
   Serial.print(ReadingNumber/1000.0*TimeBetweenReadings);
   Count = analogRead(A0);


Update BB-UNIT.ino

Update BB-UNIT.ino

--- Firmware/BB-UNIT/BB-UNIT.ino
+++ Firmware/BB-UNIT/BB-UNIT.ino
@@ -443,7 +443,7 @@
   	}
   	digitalWrite(pinDirX, directX); // dirX

-  	if(x > (setpointX + hysteresis) || (x < setpointX - hysteresis ))
+  	if(x > (setpointX + hysteresis) || (x < setpointX - hysteresis || !xok ))
   	{
   	    digitalWrite(pinStepX, 1);
             delayMicroseconds( 500 );
@@ -471,7 +471,7 @@
   	}
   	digitalWrite(pinDirY, directY); // dirX

-  	if(y > (setpointY + hysteresis) || (y < setpointY - hysteresis ))
+  	if(y > (setpointY + hysteresis) || (y < setpointY - hysteresis || !yok))
   	{
   	    digitalWrite(pinStepY, 1);
             delayMicroseconds( 500 );
@@ -489,7 +489,7 @@
   	}

   	// SET Z IN POSITION
-  	if(!Z_POSITION)
+  	if(!digitalRead(Z_POSITION))
   	{
   	    digitalWrite(pinStepZ, 1);
             delayMicroseconds( 500 );


add in moving average functions.

add in moving average functions.


fix: print zero on MacAddress

fix: print zero on MacAddress

--- ArduinoFirmwareEsp/WBServer.ino
+++ ArduinoFirmwareEsp/WBServer.ino
@@ -1,4 +1,5 @@
-
+// uint8_t MAC_array[6];   //mac_address
+// char macAddress[12];    //mac_address
 String newSSID_param;
 String newPASSWORD_param;
 IPAddress default_IP(192,168,240,1);
@@ -251,11 +252,9 @@

   tot = WiFi.scanNetworks();
   //set default AP
-  byte mac[6];
-  WiFi.macAddress(mac);
-  String apSSID = String(SSIDNAME) + "-" +  String(mac[3], HEX) + String(mac[4], HEX) + String(mac[5], HEX);
+  String mac = WiFi.macAddress();
+  String apSSID = String(SSIDNAME) + "-" + String(mac[9])+String(mac[10])+String(mac[12])+String(mac[13])+String(mac[15])+String(mac[16]);
   char softApssid[18];
-  //memset(softApssid,0,sizeof(softApssid));
   apSSID.toCharArray(softApssid, apSSID.length()+1);
   delay(1000);
   WiFi.softAP(softApssid);
@@ -266,7 +265,7 @@
   if( tmpHostname!="" )
     HOSTNAME = tmpHostname;
   // else
-  //   HOSTNAME = apSSID;
+  //   HOSTNAME = SSIDNAME;

     //Enable to start in AP+STA mode
    WiFi.mode(WIFI_AP_STA);


Topside Updates

Topside Updates

--- Topside/Topside.ino
+++ Topside/Topside.ino
@@ -26,6 +26,8 @@
   boolean statusAux             = false;        // 0 = Off / 1 = On
   boolean statusError           = false;
   char currentCycle         = 'Z';       // Current Cycle
+  String currentTime        = "";        // Current Time
+  int currentError          = 0;         // Current Error
   int currentTemp           = -1;        // Currently Displaying Temperature
   int cycleRemain           = -1;        // Time Remaining in Cycle
   int tempSet               = -1;        // Temperature Currently Set To
@@ -263,6 +265,8 @@
 //|=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-||

   void time(String timeNow) {
+    if (currentTime == timeNow) return;
+    currentTime = timeNow;
     String tempS = String(timeNow);
     char charBuf[6];
     tempS.toCharArray(charBuf, 6);
@@ -318,6 +322,8 @@
 //|=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-||

   void error(int errorCode) {
+    if (currentError == errorCode) return;
+    currentError = errorCode;
     String errorMessage = "";
     switch(errorCode) {
       case 101 : errorMessage = "ERROR : LOW PRESSURE"; break;


Update LogoBotWifiScribbler.ino

Update LogoBotWifiScribbler.ino

Corrected bug in driveTo()

--- software/firmware/LogoBotWifiScribbler/LogoBotWifiScribbler.ino
+++ software/firmware/LogoBotWifiScribbler/LogoBotWifiScribbler.ino
@@ -283,22 +283,15 @@
 }

 void driveTo(long x, long y) {
-  Serial.print(x);
-  Serial.print(",");
-  Serial.println(y);
-
   // calc angle
   long ang = atan2(y-position.y, x-position.x) * 180 / PI;
   // now angle delta
   ang = ang - position.ang;
-  if (ang > 0)
-    pushCmd("LT " + String(ang));
-  else
-    pushCmd("RT " + String(-ang));
+  turn(ang);

   // and distance
   long dist = sqrt(sqr(y-position.y) + sqr(x-position.x));
-  pushCmd("FD "+String(dist));
+  drive(dist);
 }

 void drive(long distance)
@@ -307,11 +300,7 @@
   position.x += distance * cos(position.ang * PI / 180);
   position.y += distance * sin(position.ang * PI / 180);

-  Serial.print("Pos: ");
-  Serial.print(position.x);
-  Serial.print(",");
-  Serial.println(position.y);
-
+  // prime the move
   distance *= STEPS_PER_MM;
   stepperL.move(distance);
   stepperR.move(distance);
@@ -322,17 +311,14 @@
   // update state
   position.ang += ang;

+  // correct wrap around
+  if (position.ang > 360) position.ang -= 360;
+  if (position.ang < -360) position.ang += 360;
+
+  // prime the move
   ang *= STEPS_PER_DEG;
   stepperR.move(ang);
   stepperL.move(-ang);
-
-
-  // correct wrap around
-  if (position.ang > 360) position.ang -= 360;
-  if (position.ang < -360) position.ang += 360;
-
-  Serial.print("Angle: ");
-  Serial.println(position.ang);
 }

 void buzz(int len)


Its fairly important to call bot.run()

Its fairly important to call bot.run()

--- software/firmware/LogoBotWifiScribbler/LogoBotWifiScribbler.ino
+++ software/firmware/LogoBotWifiScribbler/LogoBotWifiScribbler.ino
@@ -46,6 +46,8 @@
       cmd += c;
     }
   }
+
+  bot.run();

   if (!bot.isMoving()) {
     if (cmdQ.isEmpty()) {


Invert the rainbow

Invert the rainbow

--- blinky-tape/src/TestStatus.ino
+++ blinky-tape/src/TestStatus.ino
@@ -24,7 +24,7 @@
   int interval = 254 / LED_COUNT;
   for(int i=0; i < LED_COUNT; i += 1) {
     if(i < mActualLevel){
-      leds[i] = CRGB(254 - (i * interval), 0, (i * interval));
+      leds[i] = CRGB((i * interval), 0, 254 - (i * interval));
     } else {
       leds[i] = CRGB(0, 0, 0);
     }


Replaced info header.

Replaced info header.

--- Project/demo_just_get_it_working/demo_just_get_it_working.ino
+++ Project/demo_just_get_it_working/demo_just_get_it_working.ino
@@ -1,28 +1,16 @@
-/*
-SparkFun Inventor's Kit
-Example sketch 08-2
-
-SINGLE SERVO
-
-  Sweep a servo back and forth through its full range of motion.
-
-  A "servo", short for servomotor, is a motor that includes
-  feedback circuitry that allows it to be commanded to move to
-  specific positions. This one is very small, but larger servos
-  are used extensively in robotics to control mechanical arms,
-  hands, etc. You could use it to make a (tiny) robot arm,
-  aircraft control surface, or anywhere something needs to be
-  moved to specific positions.
-
-
-This sketch was written by SparkFun Electronics,
-with lots of help from the Arduino community.
-This code is completely free for any use.
-Visit http://learn.sparkfun.com/products/2 for SIK information.
-Visit http://www.arduino.cc to learn about the Arduino.
-
-Version 2.0 6/2012 MDG
-*/
+/**
+ *             demo_just_get_it_working
+ *             demo_just_get_it_working.ino
+ * Purpose:    Quick and dirty scripts to test parts of my project robot.
+ *
+ * @author:    Tyler Lucas
+ * Student ID: 3305203
+ * Date:       May 5, 2017
+ * Version     1.01
+ *
+ * References: SparkFun Inventor's Kit Example sketch 08-2: SINGLE SERVO Version 2.0 6/2012 MDG
+ *
+ */

 #include <Servo.h>  // servo library


Fix the dummy bytes issue before the JPEG maker FF D8

--- ArduCAM/examples/Shield_V2/ArduCAM_Video2SD/ArduCAM_Video2SD.ino
+++ ArduCAM/examples/Shield_V2/ArduCAM_Video2SD/ArduCAM_Video2SD.ino
@@ -59,6 +59,7 @@
 #endif

 #define AVIOFFSET 240
+  bool is_header = false;
 unsigned long movi_size = 0;
 unsigned long jpeg_size = 0;
 const char zero_buf[4] = {0x00, 0x00, 0x00, 0x00};
@@ -96,6 +97,7 @@
   unsigned long position = 0;
   uint16_t frame_cnt = 0;
   uint8_t remnant = 0;
+  bool is_header = false;
   //Create a avi file
   k = k + 1;
   itoa(k, str, 10);
@@ -147,7 +149,14 @@
       #endif
       temp_last = temp;
       temp = SPI.transfer(0x00);
-      //Write image data to buffer if not full
+     if ((temp == 0xD8) & (temp_last == 0xFF))//find header
+    {
+      is_header = true;
+      buf[i++] = temp_last;
+      buf[i++] = temp;
+    }
+    if (is_header == true){
+           //Write image data to buffer if not full
       if (i < 256)
         buf[i++] = temp;
       else
@@ -160,8 +169,10 @@
         myCAM.CS_LOW();
         myCAM.set_fifo_burst();
         jpeg_size += 256;
-      }
-    }
+      }
+    }
+  }
+  buf[i++] = temp;  //save the last  0XD9
     //Write the remain bytes in the buffer
     if (i > 0)
     {
@@ -170,6 +181,7 @@
       jpeg_size += i;
     }
     temp=0;temp_last=0;
+    is_header == false;
     remnant = (4 - (jpeg_size & 0x00000003)) & 0x00000003;
     jpeg_size = jpeg_size + remnant;
     movi_size = movi_size + jpeg_size;
@@ -283,7 +295,7 @@
     Serial.println("SD Card detected!");
 }
 void loop(){
-
+  Video2SD();
   delay(5000);

 }


downlink cleanup/fix channel create

downlink cleanup/fix channel create

--- examples/Downlink/Downlink.ino
+++ examples/Downlink/Downlink.ino
@@ -31,25 +31,6 @@
 }

 void
-channel_create(const char * channel_name)
-{
-    int8_t result;
-    int    status;
-    do
-    {
-        // Ensure we're connected
-        connect();
-        Serial.print("Creating Channel - ");
-        status = channel.begin(channel_name, &result);
-        // Print status and result
-        if (report_status(status, result) != helium_status_OK)
-        {
-            delay(1000);
-        }
-    } while (helium_status_OK != status || result != 0);
-}
-
-void
 channel_poll(void * data, size_t len, size_t * used)
 {
     int status;
@@ -76,7 +57,7 @@
     // Connect the Atom to the Helium Network
     connect();
     // and ensure the channel is created
-    channel_create(CHANNEL_NAME);
+    channel_create(&channel, CHANNEL_NAME);
 }


Added typecast

Added typecast

--- Python_To_Arduino_Communication/Python_To_Arduino_Communication.ino
+++ Python_To_Arduino_Communication/Python_To_Arduino_Communication.ino
@@ -12,7 +12,7 @@

     while (Serial.available())
     {
-      char inChar = Serial.read();
+      char inChar = (char)Serial.read();
       if (inChar != '~'){
           inputString += inChar;
       }


add information about internal pulldown/up resistors

--- examples/adc_test/adc_test.ino
+++ examples/adc_test/adc_test.ino
@@ -77,6 +77,12 @@
 #endif

 // test the analog pins that also have a digital function
+// Teensy LC has 20-50 kOhm pullup, no idea about pulldown (do they exist?)
+// Teensy 3.0 has 22-50 kOhm pullup and pulldown
+// Teensy 3.1/3.2 has 20-50 kOhm pullup and pulldown
+// Teensy 3.5 has 20-50 kOhm pullup and pulldown
+// Teensy 3.6 has 20-50 kOhm pullup and pulldown
+// Teensy 4 has 100 kOhm pulldow, and 22 kOhm pullup, so pulldown will fail faster
 bool test_pullup_down(bool pullup, bool debug=false) {
     uint8_t mode = pullup ? INPUT_PULLUP : INPUT_PULLDOWN;

@@ -277,7 +283,7 @@
               adc->adc1->wait_for_cal();
               #endif

-              bool test = test_pullup_down(false, false);
+              bool test = test_pullup_down(pullup=true, false);
               if (!test & debug) {
                 Serial.print("Average: "); Serial.print(average);
                 Serial.print(", Resolution: "); Serial.print(resolution);


Aggiunte funzioni per il test Black Box funzionale tramite Espresso su Android Studio.

--- Smart_Green_House_codiceArduino/Smart_Green_House_codiceArduino.ino
+++ Smart_Green_House_codiceArduino/Smart_Green_House_codiceArduino.ino
@@ -287,3 +287,122 @@

 }
 }
+
+void testOk(){  //invio una determinata stringa di dati che inizia per * e termina con # al fine di condificare correttamente tramite l'app l'inizio e la fine trasmissione dati
+  //stringa per testare la "Lettura Dati" entro i range di corretto lavoro della serricoltura
+  bluetooth.print("*");
+  bluetooth.print(20);
+  bluetooth.print(" ");
+  bluetooth.print(50);
+  bluetooth.print(" ");
+  bluetooth.print(50);
+  bluetooth.print(" ");
+  bluetooth.print(15);
+  bluetooth.print(" ");
+  bluetooth.print(50);
+  bluetooth.print(" ");
+  bluetooth.println("#");
+  delay(1000);
+}
+
+void testTemp15(){  //invio una determinata stringa di dati che inizia per * e termina con # al fine di condificare correttamente tramite l'app l'inizio e la fine trasmissione dati
+  //stringa per testare la "Lettura Dati"; Temperatura sotto il range di normale funzionamento
+  bluetooth.print("*");
+  bluetooth.print(15);      //temperatura out of bound
+  bluetooth.print(" ");
+  bluetooth.print(50);
+  bluetooth.print(" ");
+  bluetooth.print(50);
+  bluetooth.print(" ");
+  bluetooth.print(15);
+  bluetooth.print(" ");
+  bluetooth.print(50);
+  bluetooth.print(" ");
+  bluetooth.println("#");
+  delay(1000);
+}
+
+void testUmidita80(){  //invio una determinata stringa di dati che inizia per * e termina con # al fine di condificare correttamente tramite l'app l'inizio e la fine trasmissione dati
+  //stringa per testare la "Lettura Dati"; Umidità Aria sopra il range di normale funzionamento
+  bluetooth.print("*");
+  bluetooth.print(20);
+  bluetooth.print(" ");
+  bluetooth.print(80);        //umidità out of bound
+  bluetooth.print(" ");
+  bluetooth.print(50);
+  bluetooth.print(" ");
+  bluetooth.print(15);
+  bluetooth.print(" ");
+  bluetooth.print(50);
+  bluetooth.print(" ");
+  bluetooth.println("#");
+  delay(1000);
+}
+
+void testUmidita40(){  //invio una determinata stringa di dati che inizia per * e termina con # al fine di condificare correttamente tramite l'app l'inizio e la fine trasmissione dati
+  //stringa per testare la "Lettura Dati"; Umidità Aria sotto il range di normale funzionamento
+  bluetooth.print("*");
+  bluetooth.print(20);
+  bluetooth.print(" ");
+  bluetooth.print(40);       //umidità out of bound
+  bluetooth.print(" ");
+  bluetooth.print(50);
+  bluetooth.print(" ");
+  bluetooth.print(15);
+  bluetooth.print(" ");
+  bluetooth.print(50);
+  bluetooth.print(" ");
+  bluetooth.println("#");
+  delay(1000);
+}
+
+void testLuce35(){  //invio una determinata stringa di dati che inizia per * e termina con # al fine di condificare correttamente tramite l'app l'inizio e la fine trasmissione dati
+  //stringa per testare la "Lettura Dati"; Luminosità ambientale sotto il range di normale funzionamento
+  bluetooth.print("*");
+  bluetooth.print(20);
+  bluetooth.print(" ");
+  bluetooth.print(50);
+  bluetooth.print(" ");
+  bluetooth.print(35);   //Luce out of bound
+  bluetooth.print(" ");
+  bluetooth.print(15);
+  bluetooth.print(" ");
+  bluetooth.print(50);
+  bluetooth.print(" ");
+  bluetooth.println("#");
+  delay(1000);
+}
+
+void testAltezza22(){  //invio una determinata stringa di dati che inizia per * e termina con # al fine di condificare correttamente tramite l'app l'inizio e la fine trasmissione dati
+  //stringa per testare la "Lettura Dati"; Altezza pianta sopra il range di raccolta/cimatura
+  bluetooth.print("*");
+  bluetooth.print(20);
+  bluetooth.print(" ");
+  bluetooth.print(50);
+  bluetooth.print(" ");
+  bluetooth.print(50);
+  bluetooth.print(" ");
+  bluetooth.print(22);    //altezza out of bound
+  bluetooth.print(" ");
+  bluetooth.print(50);
+  bluetooth.print(" ");
+  bluetooth.println("#");
+  delay(1000);
+}
+
+void testAllAlert(){  //invio una determinata stringa di dati che inizia per * e termina con # al fine di condificare correttamente tramite l'app l'inizio e la fine trasmissione dati
+  //stringa per testare la "Lettura Dati"; Tutti i parametri sotto il range di normale funzionamento
+  bluetooth.print("*");
+  bluetooth.print(15);
+  bluetooth.print(" ");
+  bluetooth.print(30);
+  bluetooth.print(" ");
+  bluetooth.print(30);
+  bluetooth.print(" ");
+  bluetooth.print(25);
+  bluetooth.print(" ");
+  bluetooth.print(20);
+  bluetooth.print(" ");
+  bluetooth.println("#");
+  delay(1000);
+}


Correction in invaders example

Correction in invaders example

--- examples/invaders/invaders.ino
+++ examples/invaders/invaders.ino
@@ -115,7 +115,7 @@

 // Allow the overall speed of the game to be adjusted.
 // Higher number (like 1.5) slow the game down.  Lower numbers (like 0.6) speed it up.
-float speedAdjust = 0.05;
+float speedAdjust = 1;

 /* Prototypes */
 void initVars();


Small tweak of the code for sending sensor values.

--- arduinoSensor/arduinoSensor.ino
+++ arduinoSensor/arduinoSensor.ino
@@ -100,17 +100,11 @@
   pd.id = ID;
   pd.soilHumidity = moistureValue;
   pd.airTemperature = tempValue;
-//  if (DHTLIB_OK == humidityValues) {
   pd.airHumidity = humidityValue;
-  //}
   pd.light = lightValue;

   radio.write(&pd, sizeof(pd));

-  //const char text[] = "Hello World";
-  radio.write(&pd, sizeof(pd));
-  //radio.write(&time, sizeof(time));
-  //printf("Sent: %s, with time; %ul\n", text, time);
   printf("Sent: %i bytes of data\n", sizeof(pd));

   delay(1000);


Working RF emitter

Working RF emitter

--- arduino/switch_n_RF/switch_n_RF.ino
+++ arduino/switch_n_RF/switch_n_RF.ino
@@ -2,43 +2,23 @@
 #include <LowPower.h>

 /*
- * This example shows how to read the status of a input switch
- * and flash a LED when that switch change its state.
- * To reduce power consumption, the MCU is put to sleep and we
- * use the switch pin as a interrupt source.
+ * This example demonstrate how to use the generic 433 Mhz
+ * Radio Frequency emitter using the RFSwitch library
+ * LowPower is used to decrease power consumption.
  */

-//RCSwitch rfDevice = RCSwitch();
+RCSwitch rfDevice = RCSwitch();

 int SERIAL_COMMUNICATION_SPEED = 9600;
-// How long do we sleep. The longer, the better for the battery but the
-// resolution of our switch will suffer.
-period_t SLEEP_PERIOD = SLEEP_15MS;
-// Pin on which the magnetic swith is plugged.
-int MAGNETIC_SWITCH_PIN = 3;
 // Pin on which the RF device is plugged;
 int RF_DEVICE_PIN = 12;
 // internal LED
 int INTERNAL_LED = 13;
-// Status of the magnetic switch. We consider the door closed
-boolean contact = true;
-
-// Function called on interrupt
-void wakeUp() {
-  // It is a critical section so don't do anything
-}
-
-void flashLED() {
-  digitalWrite(RF_DEVICE_PIN, HIGH);
-  delay(50);
-  digitalWrite(RF_DEVICE_PIN, LOW);
-}

 void setup() {
+  Serial.begin(SERIAL_COMMUNICATION_SPEED);
   /***********************  RF Device initialisation **************************/
-  Serial.begin(SERIAL_COMMUNICATION_SPEED);
-  // Transmitter is connected to Arduino Pin #10
-  //rfDevice.enableTransmit(RF_DEVICE_PIN);
+  rfDevice.enableTransmit(RF_DEVICE_PIN);
   // Optional set pulse length.
   // rfDevice.setPulseLength(320);
   // Optional set protocol (default is 1, will work for most outlets)
@@ -46,13 +26,6 @@
   // Optional set number of transmission repetitions.
   // rfDevice.setRepeatTransmit(15);
   /*************************  Pins initialisation ****************************/
-  // Allow wake up pin to trigger interrupt on state change.
-  attachInterrupt(digitalPinToInterrupt(MAGNETIC_SWITCH_PIN), wakeUp, CHANGE);
-  // Set the pin to PULLUP so we don't need an additional resistor
-  // WARNING, the order of the instruction matters. attachInterrup will
-  // erase the PULLUP switch, so configure the PULLUP after the
-  // attacheInterrupt
-  pinMode(MAGNETIC_SWITCH_PIN, INPUT_PULLUP);
   pinMode(RF_DEVICE_PIN, OUTPUT);
   // Just turn useless LED to off
   pinMode(INTERNAL_LED, OUTPUT);
@@ -60,19 +33,12 @@
 }

 void loop() {
-  // Go to sleep mode
-  LowPower.powerDown(SLEEP_FOREVER, ADC_OFF, BOD_OFF);
-
-  // Check contact state. We assume a normally closed switch.
-  boolean newContact = digitalRead(MAGNETIC_SWITCH_PIN);
-  // Does the contact status changed since we last check
-  if (newContact != contact) {
-    // Send the status of the contact on one bit
-    //rfDevice.send(contact, 1);
-    flashLED();
-    // Update the status of the contact
-    contact = newContact;
-    //Serial.print("pushing to RF device: ");
-    //Serial.println(contact);
-  }
+  Serial.print("sending...");
+  rfDevice.send(5393, 24);
+  Serial.println("done");
+  delay(1000);
+  Serial.print("sending...");
+  rfDevice.send(5396, 24);
+  Serial.println("done");
+  delay(1000);
 }


Sound instead of the servo

Sound instead of the servo

--- magbot_test/magbot_test.ino
+++ magbot_test/magbot_test.ino
@@ -1,10 +1,11 @@
 /**
- HC-SR04 Ultrasonic Range Finder attached to the servo.
+ HC-SR04 Ultrasonic Range Finder.
  Two motors attached to the motor shield.
+ speaker/piezo for sound
  */

 #include <NewPing.h> // From https://code.google.com/p/arduino-new-ping/
-#include <Servo.h>
+#include <NewTone.h> // From https://code.google.com/p/arduino-new-tone/

 // Motor attached to channel A:
 const byte motorA_direction = 12;
@@ -25,21 +26,21 @@
 unsigned long sonar_last = 0; // When the last ping happened.
 NewPing sonar(sonar_trigger, sonar_echo, sonar_distance); // NewPing setup of pins and maximum distance.

-// Servo configuration
-const byte servo_pin = 6;
-byte servo_sweep_direction = 0; // The current direction the servo is sweeping; 0 or 1
-const byte servo_delay = 25; // Number of milliseconds to wait before next move
-unsigned long servo_last = 0; // When the last move happened.
-Servo servo;  // create servo object to control a servo
+// Tone configuration
+const byte tone_pin = 2;
+unsigned long melody_delay = 10000; // Number of milliseconds to wait before next melody
+unsigned long melody_last = 0; // When the last melody played.
+// Melody (liberated from the toneMelody Arduino example sketch by Tom Igoe).
+int melody[] = { 262, 196, 196, 220, 196, 0, 247, 262 };
+int noteDurations[] = { 4, 8, 8, 4, 4, 4, 4, 4 };

 unsigned long millis_now;

 void setup() {
   Serial.begin(9600); // Open serial monitor at 9600 baud to see ping results.

-  servo.attach(servo_pin);  // attaches the sonar servo to the servo object

-    // Setup Channel A
+  // Setup Channel A
   pinMode(motorA_direction, OUTPUT); // Initiates motor pin for channel A
   pinMode(motorA_brake, OUTPUT); // Initiates break pin for channel A

@@ -52,12 +53,13 @@
   digitalWrite(motorB_brake, LOW);   // Disengage the Brake for Channel B

-  // Turn in place
+  // Turn in place constantly.
   digitalWrite(motorA_direction, HIGH); // Channel A forward
   digitalWrite(motorB_direction, LOW); // Channel B backward
-
   analogWrite(motorA_pwm, 255); // Channel A at max speed
   analogWrite(motorB_pwm, 255); // Channel B at max speed
+
+  playMelody();
 }

 void loop() {
@@ -74,28 +76,31 @@
     Serial.println("cm");
   }

-  // Check to see if it's time for another soanr servo move.
-  if (millis_now - servo_last > servo_delay) {
-    // Remember when this move was done, so we know when to do the next one.
-    servo_last = millis_now;
-
-    // Sweep
-    // Get the last angle the servo was set to.
-    int servo_pos = servo.read();
-    if (servo_sweep_direction == 0) {
-      servo_pos++; // Add 1 degree to the servo's position.
-    } else {
-      servo_pos--; // Remove 1 degree to the servo's position.
-    }
-
-    // At the end of the sweep, change directions for the next move.
-    if (servo_pos == 170) {
-      servo_sweep_direction = 1;
-    } else if (servo_pos == 10) {
-      servo_sweep_direction = 0;
-    }
-    servo.write(servo_pos);
+  // Check to see if it's time for another melody.
+  if (millis_now - melody_last > melody_delay) {
+    // Remeber when this ping was done, so we know when to do the next one.
+    melody_last = millis_now;
+    playMelody();
   }

 }

+void playMelody() {
+  // iterate over the notes of the melody:
+  for (int thisNote = 0; thisNote < 8; thisNote++) {
+
+    // to calculate the note duration, take one second
+    // divided by the note type.
+    //e.g. quarter note = 1000 / 4, eighth note = 1000/8, etc.
+    int noteDuration = 1000/noteDurations[thisNote];
+    NewTone(tone_pin, melody[thisNote],noteDuration);
+
+    // to distinguish the notes, set a minimum time between them.
+    // the note's duration + 30% seems to work well:
+    int pauseBetweenNotes = noteDuration * 1.30;
+    delay(pauseBetweenNotes);
+    // stop the tone playing:
+    noNewTone(tone_pin);
+  }
+}
+


Switched to pololu lsm303 lib

Switched to pololu lsm303 lib

--- gps_arduino/gps_arduino.ino
+++ gps_arduino/gps_arduino.ino
@@ -11,10 +11,7 @@
 #include <SoftwareSerial.h>
 #include <TinyGPS.h>
 #include <Wire.h>
-#include <Adafruit_Sensor.h>
-#include <Adafruit_LSM303_U.h>
-#include <Adafruit_L3GD20_U.h>
-#include <Adafruit_9DOF.h>
+#include <LSM303.h>
 #include <SabertoothSimplified.h>
 #include <EasyTransfer.h>
 #include <Kalman.h>
@@ -66,15 +63,7 @@
 SoftwareSerial mySerial(2, 255);    //used for gps rx and tx pins in use

 //Compass Stuff
-/* Assign a unique ID to the sensors */
-Adafruit_9DOF                dof   = Adafruit_9DOF();
-Adafruit_LSM303_Accel_Unified accel = Adafruit_LSM303_Accel_Unified(30301);
-Adafruit_LSM303_Mag_Unified   mag   = Adafruit_LSM303_Mag_Unified(30302);
-
-/* Update this with the correct SLP for accurate altitude measurements */
-float seaLevelPressure = SENSORS_PRESSURE_SEALEVELHPA;
-
-//Compass stuff
+LSM303 compass;
 float compassHeading;
 int mHeadingOffset = 0;
 #define HEADING_ADJUST_PIN A2
@@ -160,16 +149,17 @@
     mySerial.begin(9600);

     /* Initialise the compass */
-    if(!accel.begin()){
-    /* There was a problem detecting the LSM303 ... check your connections */
-    lcd.println(F("Ooops, no LSM303 detected ... Check your wiring!"));
-    while(1);
-   }
-    if(!mag.begin()){
-      /* There was a problem detecting the HMC5883 ... check your connections */
-      lcd.println("Ooops, no HMC5883 detected ... Check your wiring!");
-      while(1);
-    }
+    Wire.begin();
+    compass.init();
+    compass.enableDefault();
+    /*
+    Calibration values; the default values of +/-32767 for each axis
+    lead to an assumed magnetometer bias of 0. Use the Calibrate example
+    program to determine appropriate values for your particular unit.
+    */
+    compass.m_min = (LSM303::vector<int16_t>){-767, -642, -379};
+    compass.m_max = (LSM303::vector<int16_t>){+322, +647, +616};
+
     //Setup test waypoint. Start 38.631514, -90.271908
     mLat[0] = 38.631158;
     mLon[0] = -90.272172;
@@ -224,37 +214,10 @@
   * Reades the heading from HMC5883 and update compassHeagin in degrees
   */
   void updateHeading(){
-    /* Get a new sensor event */
-    sensors_event_t event;
-    sensors_event_t accel_event;
-    accel.getEvent(&accel_event);
-    mag.getEvent(&event);
-
-    if(!dof.magTiltCompensation(SENSOR_AXIS_Z, &event, &accel_event)){
-      return;
-    }
-
-    // Hold the module so that Z is pointing 'up' and you can measure the heading with x&y
-    // Calculate heading when the magnetometer is level, then correct for signs of axis.
-    float heading = atan2(event.magnetic.y, event.magnetic.x);
-
-    // Once you have your heading, you must then add your 'Declination Angle', which is the 'Error' of the magnetic field in your location.
-    // Find yours here: http://www.magnetic-declination.com/
-    // Mine is: -13* 2' W, which is ~13 Degrees, or (which we need) 0.22 radians
-    // If you cannot find your Declination, comment out these two lines, your compass will be slightly off.
-    float declinationAngle = 0.01;
-    heading += declinationAngle;
-
-    // Correct for when signs are reversed.
-    if(heading < 0)
-      heading += 2*PI;
-
-    // Check for wrap due to addition of declination.
-    if(heading > 2*PI)
-      heading -= 2*PI;
-
-    // Convert radians to degrees for readability.
-    compassHeading = heading * 180/M_PI;
+
+    compass.read();
+    compassHeading = compass.heading();
+
     //Adjust heading
     compassHeading += mHeadingOffset;
     if(compassHeading >= 360){
@@ -262,9 +225,8 @@
     } else if (compassHeading < 0){
       compassHeading += 360;
     }
-
     //Filter compass value to smooth out values
-    compassHeading = compassFilter.getFilteredValue(compassHeading);
+    //compassHeading = compassFilter.getFilteredValue(compassHeading);
   }

   void updateDisplay(bool newData){


Added commented out code to disable dithering

--- examples/FastLED_Controller/FastLED_Controller.ino
+++ examples/FastLED_Controller/FastLED_Controller.ino
@@ -89,6 +89,11 @@

   // FastLED disables SmartMatrix's gamma correction by default, turn it on if you like
   //pSmartMatrix->setColorCorrection(cc48);
+
+  // With gamma correction on, the 24 bit color gets stretched out over 36-bits, now
+  // try enabling/disabling FastLED's dithering and see the effect
+  //FastLED.setDither( 0 );
+
 }

 // Fill the x/y array of 8-bit noise values using the inoise8 function.


fix Serial1 issue, now we can build clean release

--- neurite.ino
+++ neurite.ino
@@ -133,7 +133,8 @@
 		log_err("invalid url\n\r");
 		return -1;
 	}
-	log_info("ota firmware: %s\n\r", url);
+	CMD_SERIAL.print("ota: ");
+	CMD_SERIAL.println(url);

 	t_httpUpdate_return ret;
 	ret = ESPhttpUpdate.update(url);
@@ -310,7 +311,7 @@
 static void wifi_connect(struct neurite_data_s *nd)
 {
 	log_dbg("Connecting to ");
-	Serial.println(nd->cfg.ssid);
+	LOG_SERIAL.println(nd->cfg.ssid);
 	WiFi.mode(WIFI_STA);
 #ifdef NEURITE_ENABLE_WIFIMULTI
 	WiFiMulti.addAP(nd->cfg.ssid, nd->cfg.psk);
@@ -889,7 +890,6 @@
 	}
 }

-
 inline void neurite_worker(void)
 {
 	struct neurite_data_s *nd = &g_nd;
@@ -991,10 +991,14 @@

 void setup()
 {
-	LOG_SERIAL.begin(115200);
-	LOG_SERIAL.setDebugOutput(false);
-	LOG_SERIAL.printf("\n\r");
-	LOG_SERIAL.flush();
+	Serial.begin(115200);
+	Serial.setDebugOutput(false);
+	Serial.printf("\n\r");
+	Serial.flush();
+	Serial1.begin(115200);
+	Serial1.setDebugOutput(false);
+	Serial1.printf("\n\r");
+	Serial1.flush();
 	pinMode(NEURITE_LED, OUTPUT);
 	digitalWrite(NEURITE_LED, HIGH);
 	pinMode(NEURITE_BUTTON, INPUT);


Performance improvement

Performance improvement

--- arduinofences.ino
+++ arduinofences.ino
@@ -230,7 +230,6 @@
   int buttonState = digitalRead(BUTTON_PIN);

   if (buttonState == HIGH) {
-    Serial.println("Feed me");
     if (irrecv.decode(&results)) {
       storeCode(&results);
       irrecv.resume(); // resume receiver


tested and working!

tested and working!

--- html/examples/02.Digital/BlinkWithoutDelay/BlinkWithoutDelay.ino
+++ html/examples/02.Digital/BlinkWithoutDelay/BlinkWithoutDelay.ino
@@ -1,3 +1,4 @@
+//  This example is Chibitronics Love to Code tested!
 /* Blink without Delay

  Turns on and off a light emitting diode(LED) connected to a digital
@@ -5,16 +6,16 @@
  can run at the same time without being interrupted by the LED code.

  The circuit:
- * LED attached from pin 13 to ground.
- * Note: on most Arduinos, there is already an LED on the board
- that's attached to pin 13, so no hardware is needed for this example.
-
+ * LED attached from pin A2 to ground.
+ * Note: on the chibitronics board, this LED is already attached

  created 2005
  by David A. Mellis
  modified 8 Feb 2010
  by Paul Stoffregen
-
+ modified 25 May 2016
+ by chibitronics
+
  This example code is in the public domain.

@@ -23,7 +24,7 @@

 // constants won't change. Used here to
 // set pin numbers:
-const int ledPin =  13;      // the number of the LED pin
+const int ledPin =  A2;      // the number of the LED pin

 // Variables will change:
 int ledState = LOW;             // ledState used to set the LED


Correction to 'Averaging of N-X ADC samples'

--- battery-monitor.ino
+++ battery-monitor.ino
@@ -119,11 +119,11 @@

     qsort(readings, ADC_SAMPLES, sizeof(uint16_t), uint16Compare);

-    for (int i = ADC_DISPERSED; i < ADC_SAMPLES - ADC_DISPERSED; i++) {
+    for (int i = ADC_DISPERSED; i < (ADC_SAMPLES - ADC_DISPERSED); i++) {
         mV += readings[i];
     }

-    return round(mV * DIV_RATIO / (float) ADC_SAMPLES - (2 * ADC_DISPERSED));
+    return round(mV * DIV_RATIO / (float) (ADC_SAMPLES - (2 * ADC_DISPERSED)));
 }

 // Averaging of N ADC samples as per ST Application Note AN4073


little change for the dailler

little change for the dailler

--- hook___dail/hook___dail.ino
+++ hook___dail/hook___dail.ino
@@ -53,7 +53,7 @@
 int debounceDelay = 10;
 int needToPrint = 0;
 int count;
-int in = 5;
+int in = A1;
 int lastState = LOW;
 int trueState = LOW;
 long lastStateChangeTime = 0;
@@ -96,7 +96,7 @@

 void loop()
 {
-  while (digitalRead(10)==HIGH)
+  while (digitalRead(A0)==HIGH)
 {
   int reading = digitalRead(in);


Minor check in prior to Mega rework for N2K

--- mega/mega.ino
+++ mega/mega.ino
@@ -1,9 +1,14 @@
 /*

  FloatHub Arduino Code
- (c) 2011-2019 Modiot Labs
+ (c) 2011-2021 Modiot Labs
  (begun June 6, 2011)

+
+  December 2020
+
+  Major rework to do all the encryption at the ESP level so we have enough
+  resources on the mega to handle the new N2K processing.

   March 2018

@@ -130,9 +135,9 @@
 #define BARO_HWARE_BMP180 4

 //define BARO_HWARE BARO_HWARE_BMP280
-//#define BARO_HWARE BARO_HWARE_BME280
+#define BARO_HWARE BARO_HWARE_BME280
 //#define BARO_HWARE BARO_HWARE_BME680
-#define BARO_HWARE BARO_HWARE_BMP180
+//#define BARO_HWARE BARO_HWARE_BMP180

 #include <Wire.h>

@@ -310,7 +315,7 @@
 */

 #define SOFT_SERIAL_RX_PIN 10
-#define SOFT_SERIAL_TX_PIN 11  // We don't actually currently use this for anything
+#define SOFT_SERIAL_TX_PIN 12  // We don't actually currently use this for anything
 SoftwareSerial soft_serial (SOFT_SERIAL_RX_PIN, SOFT_SERIAL_TX_PIN);


New nuncha test

New nuncha test

Three oscillators, the roll and pitch of the Nunchuck are used to
decide which oscillator has priority.
Would be nice to combine together the three oscillators.

--- nuncha/nuncha.ino
+++ nuncha/nuncha.ino
@@ -1,37 +1,48 @@
-#include "Arduino.h"                                 // common Arduion constants and definitions
-#include "Nunchuck.h"                                // Wii nunchuck library
+#include "Arduino.h"
+#include "Nunchuck.h"
 #include <Wire.h>
 #include <MozziGuts.h>

 #define CONTROL_RATE 64 // powers of 2 please

-#define  StickThresh  0.2f                           // joystick threshold for change (0-1)
+#define LEFT 0
+#define RIGHT 1
+#define UP 2
+
+int bumpy_input = 0;
+
+int rollpitch = 0;

 #include <Oscil.h> // oscillator template
 #include <tables/sin2048_int8.h> // sine table for oscillator
+#include <tables/triangle2048_int8.h> // triangle table for oscillator
+#include <tables/saw2048_int8.h> // saw table for oscillator
 #include <RollingAverage.h>

 // use: Oscil <table_size, update_rate> oscilName (wavetable), look in .h file of table #included above
-Oscil <SIN2048_NUM_CELLS, AUDIO_RATE> aSin0(SIN2048_DATA);
-Oscil <SIN2048_NUM_CELLS, AUDIO_RATE> aSin1(SIN2048_DATA);
+Oscil <SIN2048_NUM_CELLS, AUDIO_RATE> aSin(SIN2048_DATA);
+Oscil <TRIANGLE2048_NUM_CELLS, AUDIO_RATE> aTri(TRIANGLE2048_DATA);
+Oscil <SAW2048_NUM_CELLS, AUDIO_RATE> aSaw(SAW2048_DATA);

 // use: RollingAverage <number_type, how_many_to_average> myThing
-RollingAverage <float, 32> kAverage; // how_many_to_average has to be power of 2
-int averaged;
+// how_many_to_average has to be power of 2
+RollingAverage <float, 8> rollLAverage;
+RollingAverage <float, 8> rollRAverage;
+RollingAverage <float, 8> pitchAverage;
+RollingAverage <float, 4> xAverage;
+RollingAverage <float, 4> yAverage;
+int rollLeft;
+int rollRight;
+int pitch;
+int xStick;
+int yStick;

-unsigned char gain = 255;
-float val = 0;
+int play = 0;

 void setup(){
   uint8_t error;

-  // initialize the Nunchuck
-
-  Serial.begin ( 19200 );
-
   error = Nunchuck.begin ();
-
-  startMozzi(CONTROL_RATE); // set a control rate of 64 (powers of 2 please)

   /*if ( error )
   {
@@ -40,96 +51,76 @@
     while ( 1 );
   }*/

-  aSin0.setFreq(440); // set the frequency
-  aSin1.setFreq(440); // set the frequency
+  startMozzi(CONTROL_RATE); // set a control rate of 64 (powers of 2 please)
+
+  // set the frequency
+  aSin.setFreq(440);
+  aTri.setFreq(440);
+  aSaw.setFreq(440);
 }

 void updateControl(){
-  uint8_t error;
+   // read the input device

-  static bool  lastStickUp = false;
-  static bool  lastStickDn = false;
-  static bool  lastStickLf = false;
-  static bool  lastStickRt = false;
-
-
-  // read the input device
+   Nunchuck.update();
+
+   if ( !Nunchuck.getZButton() )
+   {
+     bumpy_input = constrain(Nunchuck . getRoll(), -180, -1);
+     bumpy_input = map(-bumpy_input, 0, 180, 0, 800);
+     rollLeft = rollLAverage.next(bumpy_input);
+     bumpy_input = constrain(Nunchuck . getRoll(), 0, 180);
+     bumpy_input = map(bumpy_input, 0, 180, 0, 800);
+     rollRight = rollRAverage.next(bumpy_input);
+     bumpy_input = constrain(Nunchuck . getPitch(), 100, 174);
+     bumpy_input = map(bumpy_input, 100, 174, 0, 800);
+     pitch = pitchAverage.next(bumpy_input);

-  Nunchuck.update();
-
-  // compute stick postion as a 4 way switch
-
-   float xStick = Nunchuck.getXStick();
-   float yStick = Nunchuck.getYStick();
-
-   bool stickDn = ( yStick < - StickThresh ? true : false );
-   bool stickUp = ( yStick >   StickThresh ? true : false );
-
-   bool stickLf = ( xStick < - StickThresh ? true : false );
-   bool stickRt = ( xStick >   StickThresh ? true : false );
-
-   // in harmonizer mode ( no CButton ) use roll for note and use stick to control key changes
-
-   if ( Nunchuck.getCButton() )
-   {
-     //float bumpy_input = map(Nunchuck . getRoll(), -180, 180, 0, 800);
-     float bumpy_input = map(Nunchuck . getPitch(), 0, 180, 0, 800);
-     averaged = kAverage.next(bumpy_input);
-
-     aSin0.setFreq(bumpy_input);
-     aSin1.setFreq(averaged);
-     //val = map(Nunchuck . getRoll(), -180, 180, -3, +3);
-     //gain = gain + val;
-     // use the 4 way switch to change key ( L/R = major / minor , U/D = major 3rd )
-     //if ( stickUp && lastStickUp ) { gain = gain +3; }
-     //if ( stickDn && lastStickDn ) { gain = gain -3; }
-     //if ( stickUp && !lastStickUp ) { Synth.setKey ( Synth.getPendingKey()  + 5 );  Synth.setKeyMode ( 0 ); }
-     //if ( stickDn && !lastStickDn ) { Synth.setKey ( Synth.getPendingKey()  - 5 );  Synth.setKeyMode ( 1 ); }
-     //if ( stickLf && !lastStickLf ) { Synth.setKeyMode ( 1 ); }
-     //if ( stickRt && !lastStickRt ) { Synth.setKeyMode ( 0 ); }
+     aSin.setFreq(rollLeft);
+     aTri.setFreq(rollRight);
+     aSaw.setFreq(pitch);

+     play = 1;
    }

-
-   // in arpeggiator mode use roll for the stick to control the arpeggiator
-
-   else
-   {
-     gain = gain - 3;
-     // set the arpeggiator input with roll axis
-
-     //Synth.setArpOctave ( -1.0f + 4.0f * Nunchuck . getRoll()  / 90.0f   );
-
-
-      // L/R changes tempo,  U/D changes legato
-
-     //if ( stickUp && !lastStickUp ) Synth.setArpLegato ( Synth.getArpLegato() + 0.1f );
-     //if ( stickDn && !lastStickDn ) Synth.setArpLegato ( Synth.getArpLegato() - 0.1f );
-     //if ( stickLf && !lastStickLf ) Synth.setArpTempo  ( Synth.getArpTempo()   - 10 );
-     //if ( stickRt && !lastStickRt ) Synth.setArpTempo  ( Synth.getArpTempo()   + 10 );
-
-   }
-
-
-  // update shadow state
-
-  lastStickUp = stickUp;
-  lastStickDn = stickDn;
-  lastStickLf = stickLf;
-  lastStickRt = stickRt;
-
-  //Nunchuck.printReal();
-  //Serial.println();
+   else{play = 0;}
 }

-/*
+
 int updateAudio(){
-  return (aSin.next()* gain)>>8; // return an int signal centred around 0
-}
-*/
-int updateAudio(){
-  //return 3*(aSin0.next()+aSin1.next())>>2;
-  return (aSin1.next());
+  if (play)
+  {
+    if ( pitch >= rollLeft)
+    {
+      if ( pitch >= rollRight)
+      { return aSaw.next(); }
+      else
+      { return aTri.next(); }
+    }
+    else if ( pitch >= rollRight)
+    {
+      if ( pitch >= rollLeft)
+      { return aSaw.next(); }
+      else
+      { return aSin.next(); }
+    }
+    else if ( rollRight >= rollLeft)
+    {
+      if ( pitch >= rollRight)
+      { return aSaw.next(); }
+      else
+      { return aTri.next(); }
+    }
+    else if ( rollLeft >= rollRight)
+    {
+      if ( pitch >= rollLeft)
+      { return aSaw.next(); }
+      else
+      { return aSin.next(); }
+    }
+  }
+
+  return 0;
 }

 void loop(){


Workaround for when no Content-Length is supplied

--- http_test.ino
+++ http_test.ino
@@ -16,6 +16,8 @@
 const int kNetworkTimeout = 5*1000;
 // Number of milliseconds to wait if no data is available before trying again
 const int kNetworkDelay = 200;
+// If Content-Length isn't given this is used for the max body length
+const int fallbackContentLength = 1024;

 void setup() {
   Serial.begin(9600);
@@ -62,7 +64,11 @@

         // Now we've got to the body, so we can print it out
         unsigned long timeoutStart = millis();
+        if (bodyLen <= 0)
+          bodyLen = fallbackContentLength;
+
         char body[bodyLen+1];
+
         char c;
         int i = 0;
         // Whilst we haven't timed out & haven't reached the end of the body
@@ -74,17 +80,16 @@
             c = http.read();
             body[i] = c;
             i++;
-
-            if (http.endOfBodyReached()) {
-              //Workaround for TCPClient.Connected() bug
-              http.stop();
-            }
-
             // We read something, reset the timeout counter
             timeoutStart = millis();
           }
           else
           {
+            //Workaround for TCPClient.Connected() bug
+            if (http.endOfBodyReached()) {
+              Serial.println("End of body reached according to http.endOfBodyReached()");
+              http.stop();
+            }
             // We haven't got any data, so let's pause to allow some to
             // arrive
             delay(kNetworkDelay);