fully functional arduino code

fully functional arduino code

--- arduino/alarm/alarm.ino
+++ arduino/alarm/alarm.ino
@@ -1,13 +1,53 @@
-const int gatePin = 5;
+const int gate_pin = 5;
+String light_state;
+
+boolean serialEvent();
+void alarm();
+
+void alarm() {
+  boolean stop_alarm = false;
+  for (int i = 1; i < 256; i++) {
+    if (stop_alarm) {
+      break;
+    }
+    analogWrite(gate_pin, i);
+    for (int j = 0; j < 7059; j++) {
+      if (Serial.available() > 0) {
+        stop_alarm = serialEvent();
+      }
+      delay(1);
+    }
+  }
+  light_state = "on";
+}
+
+boolean serialEvent() {
+  String serial_data = Serial.readString();
+  Serial.flush();
+  if (light_state != "on" && serial_data == "o") {
+    analogWrite(gate_pin, 255);
+    light_state = "on";
+  } else if (serial_data == "o") {
+    analogWrite(gate_pin, 0);
+    light_state = "off";
+  } else if (serial_data == "a" && light_state == "off") {
+    light_state = "alarm";
+    alarm();
+  } else {
+    return false;
+  }
+  return true;
+}

 void setup() {
-  pinMode(gatePin, OUTPUT);
+  pinMode(gate_pin, OUTPUT);
+  analogWrite(gate_pin, 0);
+  light_state = "off";
   Serial.begin(9600);
 }

 void loop() {
-  for (int i = 1; i <= 255; i++) {
-    analogWrite(gatePin, i);
-    delay(20);
+  if (Serial.available() > 0) {
+    serialEvent();
   }
 }


Remove tmp_volt from the json. Cause invalid json message

--- WindSensor/WindSensor.ino
+++ WindSensor/WindSensor.ino
@@ -119,7 +119,7 @@

   JsonObject& root = jsonBuffer.createObject();
   root["sensor"] = "wind";
-  root["tmp_volts"] = TMP_Therm_ADunits * 0.0048828125;
+//  root["tmp_volts"] = TMP_Therm_ADunits * 0.0048828125;
   //  root["rv_volts"] = RV_Wind_Volts;
   //  root["tempc_100"] = TempCtimes100;
   //  root["zerowind_volts"] = zeroWind_volts;


Update reference voltage to optimized value

Also reports the PID parameters in the serial plot.

--- firmware/firmware.ino
+++ firmware/firmware.ino
@@ -40,8 +40,12 @@
 // only for plotting:
 char oven_is_on = 0;

-//Specify PID pointers and initial tuning parameters
-PID control_PID(&PID_in, &PID_out, &PID_setpoint,2,5,1, DIRECT);
+#define PID_Kp 2
+#define PID_Ki 5
+#define PID_Kd 1
+
+//Specify PID pointers and tuning parameters
+PID control_PID(&PID_in, &PID_out, &PID_setpoint, PID_Kp, PID_Ki, PID_Kd, DIRECT);

 // Digital outputs
 //     relay -> fan
@@ -68,13 +72,14 @@
  * timestamps, the temperature is interpolated linearly.
  */
 const unsigned int tprofile_n = 5;
-const unsigned long tprofile_times[] = {10000, 20000, 30000, 50000, 60000};
+const unsigned long tprofile_times[] = {10000000, 20000, 30000, 50000, 60000};
 const float tprofile_temps[] =         {80, 200, 235, 235,   0};
 reflow_profile tprofile(tprofile_n, tprofile_times, tprofile_temps);

 void plot_callback(void) {
   // plotting thread
   plotter.Plot();
+  //Serial.println(PID_in);
 }

 void control_callback(void) {
@@ -149,8 +154,12 @@
   digitalWrite(THERMISTOR_MOSFET, HIGH);
   double avg = (double) sum / count;

-  double inp_voltage = avg * 1.1 / 1023; // Reference voltage = 1.1V,
-                                         // maximum value = 1023 (10 bits)
+  //return(filt_2nd_stage.processReading(avg));
+
+  // Reference voltage is supposed to be 1.1V. Measuring the actual
+  // temperature inicates it is a little too low.
+  // Maximum value @10 bits resolution: 1023
+  double inp_voltage = avg * 1.0598865 / 1023;
   // voltage divider 1k over PT100 thermistor connected to 5V
   double R_PT100 = 1000./(5./inp_voltage-1);

@@ -192,11 +201,21 @@

   // Set up serial plotter
   plotter.Begin(); // start plotter
-  plotter.AddTimeGraph( "Reflow oven variables", 6000,//18000, // about 3 minutes
+  String headline = "Reflow oven (PID constants: P=";
+  headline += String(PID_Kp);
+  headline += " I=";
+  headline += String(PID_Ki);
+  headline += " D=";
+  headline += String(PID_Kd);
+  headline += ")";
+  plotter.AddTimeGraph(headline,
+                          18000, // about 3 minutes
                           "PID Setpoint (°C)", PID_setpoint,
                           "PID Input (°C)", PID_in,
                           "PID Output (%)", PID_out_percent,
                           "Oven state (on/off)", oven_is_on);
+
+ // Serial.begin(115200);

   // Configure PID controller
   control_PID.SetOutputLimits(0, pwm_window);


firmware: refactor object maxim -> max1464

--- firmware/firmware.ino
+++ firmware/firmware.ino
@@ -24,7 +24,7 @@
 boolean writingToFlash = false;  // whether we are currently writing to MAX1464
                                  // flash memory
 unsigned long hexLinesWritten = 0; // count hex lines written during flash loop
-MAX1464 maxim(10);
+MAX1464 max1464(10);

 void printIden() {
     Serial.println("Arduino MAX1464 Serial Terminal");
@@ -35,8 +35,8 @@
     printIden();
     inputString.reserve(200);

-//    maxim.setPins(11,12,13); // only for software SPI
-    maxim.begin();
+//    max1464.setPins(11,12,13); // only for software SPI
+    max1464.begin();
 }

 void serialEvent() {
@@ -60,7 +60,7 @@
                 writingToFlash = false;
                 Serial.println("\nAbort writing to flash memory...");
             }
-            else if(!maxim.writeHexLineToFlashMemory(inputString)) {
+            else if(!max1464.writeHexLineToFlashMemory(inputString)) {
                 Serial.print("\nIllegal line ");
                 Serial.println(inputString);
             }
@@ -71,7 +71,7 @@
                     hexLinesWritten = 0;
                     Serial.println();
                 }
-                if(maxim.hasEOFBeenReached()) {
+                if(max1464.hasEOFBeenReached()) {
                     writingToFlash = false;
                     Serial.println();
                 }
@@ -86,15 +86,15 @@
             if(partition_cp != NULL) {
                 partition = atoi(partition_cp);
             }
-            maxim.readFirmware(partition);
+            max1464.readFirmware(partition);
         }
         else if(String("HALTCPU").startsWith(inputString)) {
             Serial.println("Halting CPU");
-            maxim.haltCpu();
+            max1464.haltCpu();
         }
         else if(String("RESETCPU").startsWith(inputString)) {
             Serial.println("Resetting CPU");
-            maxim.resetCpu();
+            max1464.resetCpu();
         }
         else if(String("RP").startsWith(inputString)) {
             char *port_cp = strtok(NULL, " ");
@@ -103,22 +103,22 @@
                 Serial.print("CPU port ");
                 Serial.print(port_cp);
                 Serial.print(" == ");
-                uint16_t value = maxim.readCpuPort(port);
+                uint16_t value = max1464.readCpuPort(port);
                 printHex16(value);
                 Serial.println();
             }
         }
         else if(String("STEP").startsWith(inputString)) {
             Serial.println("stepping");
-            maxim.singleStepCpu();
+            max1464.singleStepCpu();
         }
         else if(String("RELEASECPU").startsWith(inputString)) {
             Serial.println("Releasing CPU");
-            maxim.releaseCpu();
+            max1464.releaseCpu();
         }
         else if(String("!ERASEFLASHMEMORY!").equals(inputString)) {
             Serial.println("Erasing FLASH memory");
-            maxim.eraseFlashMemory();
+            max1464.eraseFlashMemory();
         }
         else if(String("!WRITEFLASHMEMORY!").equals(inputString)) {
             char *partition_cp = strtok(NULL, " ");
@@ -128,7 +128,7 @@
             }
             writingToFlash = true;
             hexLinesWritten = 0;
-            maxim.startWritingToFlashMemory(partition);
+            max1464.startWritingToFlashMemory(partition);
             Serial.println("Writing to flash memory...");
         }
         else {


add gear switch set speed to 9600

add gear switch
set speed to 9600

--- ksp-gegi/ksp-gegi.ino
+++ ksp-gegi/ksp-gegi.ino
@@ -1,32 +1,33 @@

 #include <Arduino.h>

-// P0:
-// potencjometr od nawilżacza
-// nieprzylutowane -> GND, środek (czerwony pasek) -> A0, przylutowane -> 5V
-// kalibracja: po włączeniu przekręcić w obie skrajne pozycje
-// D0:
-// zielona strona, pomiędzy GND a D4
+// diody LED: niebieskie (bez rezystora) do GND, białe (z rezystorem) do pinu
+// potencjometr: niebieski z czarną kreską do GND, biały do +5V, niebieski do pinu A0
+// przełączniki: niebieski do GND, biały do pinu, wszystkie zamontowane tak, aby niebieski był w środku, biały na dole, a niepodłączone u góry (wtedy gałka w górę==załączenie)

-// circuit
-const int throttlePin = A0;  // P0: Analog input pin that the potentiometer is attached to
+// przepisać tablice+npins jako klasę?
+// to: oraz array.size() zamiast nPins http://hackaday.com/2015/11/13/code-craft-embedding-c-timing-virtual-functions/
+//   ok jeśli będzie niedużo gorsze od 5104 bajtów

-const uint8_t nPins = 2;
-const uint8_t switchPins[] = {4, 5, 8};	// Dx: stage, RCS, SAS switch
-const uint8_t onPins[] = {0, 13, 9};	// Gx: stage, RCS, SAS ON (green)
-const uint8_t offPins[] = {0, 7, 10};	// Rx: stage, RCS, SAS OFF (red)
-uint8_t lastPinState[] = {HIGH, HIGH, HIGH};
+const int throttlePin = A0;  // P0
+
+const uint8_t nPins = 4; // długość tabel poniżej
+const uint8_t switchPins[] = {4, 5, 8, 12};	// Dx: stage, RCS, SAS, gear switch
+const uint8_t onPins[] = {0, 13, 9, 0};	// Gx: stage, RCS, SAS ON (green)
+const uint8_t offPins[] = {0, 0, 0, 0};	// Rx: stage, RCS, SAS OFF (red)
+uint8_t lastPinState[] = {HIGH, HIGH, HIGH, HIGH};

 // throttle control
 int lastThrottleValue = 0;
 int throttleValue = 0;
 int throttleMin = 1023;
 int throttleMax = 0;
-#define THROTTLE_THRESHOLD 4
+#define THROTTLE_THRESHOLD 2
+#define SERIAL_SPEED 9600

 void setup() {
   // initialize serial communications at 9600 bps:
-  Serial.begin(38400);
+  Serial.begin(SERIAL_SPEED);
   // make button pins inputs
   for (uint8_t i=0; i<nPins; i++) {
 	// switch pin input
@@ -97,7 +98,7 @@
     c = Serial.read();
     id = Serial.parseInt();  // skip '='
     val = Serial.parseInt(); // skip newline
-    Serial.print(c); Serial.print(id); Serial.println(val);  // echo for ack
+//    Serial.print(c); Serial.print(id); Serial.println(val);  // echo for ack
 	if (id<nPins) {
 		if (c=='G') { ledPin = onPins[id]; }
 		if (c=='R') { ledPin = offPins[id]; }


made code more configurable

made code more configurable

--- Arduino/HvacMonitor/HvacMonitor.ino
+++ Arduino/HvacMonitor/HvacMonitor.ino
@@ -26,7 +26,7 @@
 void setup() {
   byte addr[8];

-  //Serial.begin(9600);
+  Serial.begin(9600);
   Serial.println("Starting search now");
   while (ds.search(addr)) {
     Serial.println("Found Sensor.. Addindg it");


More work on i2c Sensor board :)

More work on i2c Sensor board :)

--- Arduino/IRI2CBoard/IRI2CBoard.ino
+++ Arduino/IRI2CBoard/IRI2CBoard.ino
@@ -7,12 +7,21 @@
 // Command defintions
 byte ENABLE_INTERRUPT=1;
 byte SET_INTERRUPT_DISTANCE=2;
-byte READ_INTERRUPT_DISTANCE=4;
-byte READ_MAX_MIN=8;
+byte READ_INTERRUPT_DISTANCE=3;
+byte SENSOR_DATA=4;
+
+#define REG_MAP_SIZE 4
+#define SLAVE_ADDRESS  0x01
+//data
+byte data[8];
+

 void setup(){
-  Wire.begin();        // join i2c bus (address optional for master)
+  Wire.begin(SLAVE_ADDRESS);        // join i2c bus
+
   Wire.onReceive(receiveEvent); // register event
+  Wire.onRequest(requestEvent);
+
   Serial.begin(9600);           // start serial for output
 }

@@ -33,3 +42,7 @@
   int x = Wire.read();    // receive byte as an integer
   Serial.println(x);         // print the integer
 }
+
+void requestEvent(){
+  Wire.write(data, REG_MAP_SIZE);  //Set the buffer up to send all 14 bytes of dat
+}


add buzzer

add buzzer

--- src/basic/basic.ino
+++ src/basic/basic.ino
@@ -16,10 +16,14 @@

 int lastExecutionMillis = 0;
 int lastSendMillis = 0;
+int buzzerPin = 5;
 // Setup routine runs once when you press reset
 void setup() {
   pinMode(13, OUTPUT);
   led_on();
+  pinMode(buzzerPin, OUTPUT); //Set buzzerPin as output
+  //beep(500); //Beep
+  //beep(50);

   // Open serial communications and wait for port to open:
   Serial.begin(57600);
@@ -52,6 +56,14 @@

   led_off();
   delay(2000);
+}
+
+void beep(unsigned char delayms) { //creating function
+  analogWrite(buzzerPin, 20); //Setting pin to high
+  delay(delayms); //Delaying
+  analogWrite(buzzerPin ,0); //Setting pin to LOW
+  delay(delayms); //Delaying
+
 }

 // the loop routine runs over and over again forever:


Implement reading from saved memory, flip defaults for pro micro

--- CoreIR.ino
+++ CoreIR.ino
@@ -12,14 +12,15 @@
 */
 //CONFIGURABLE SECTION - SET TRANSPONDER ID
 //change transponder ID # by setting a different transponder number for tx_id
+//WARNING: IDs set by CoreIR-Uplink tool will override these numbers
 long tx_id = 4444444;
 long tx_alt_id = 8901234;

 //if using an attiny, comment out the atmega line below otherwise leave as is.
-//#define atmega
+#define atmega

 //if using a arduino pro micro, uncomment the below line
-//#define micro
+#define micro

 //CONFIGURATION END

@@ -272,13 +273,11 @@
   #ifdef atmega
     // save the new transponder numbers in eeprom if they are not already there
     if (EEPROMReadlong(0) != tx_id) {
-      EEPROMWritelong(0, tx_id);
+      long tx_id = EEPROMReadlong(0);
     }
     if (EEPROMReadlong(4) != tx_alt_id) {
-      EEPROMWritelong(4, tx_alt_id);
-    }
-    long tx_id = EEPROMReadlong(0);
-    long tx_alt_id = EEPROMReadlong(4);
+      long tx_alt_id = EEPROMReadlong(4);
+    }
   #endif
   // set up jumper bridge for alternate ID
   pinMode(bridgePinIn, INPUT);


Moved clock divider into board specific sections

--- src/faros/faros.ino
+++ src/faros/faros.ino
@@ -84,6 +84,11 @@
 // RDYN low, when it has some data to send to the MCU.
 // pin 3 = RDYN is linked to INT0 on Arduino Pro Micro.
 #define RDYN_INTR_NO 0
+
+// nRF8001 supports max. 3 MHz SPI clock frequency.
+// Arduino Pro Micro runs at 8 MHz. By dividing by 4, we
+// set the SPI clock frequency to 2 MHz.
+#define SPI_CLOCK_DIV SPI_CLOCK_DIV4
 #endif

 #ifdef HARDWARE_ATMEGA328P_1MHz
@@ -103,12 +108,12 @@
 // RDYN low, when it has some data to send to the MCU.
 // pin 2 = RDYN is linked to INT0 on the Faros board.
 #define RDYN_INTR_NO 0
+
+// nRF8001 supports max. 3 MHz SPI clock frequency.
+// The Faros board runs at 1 MHz. Two is the smallest clock
+// divider that we can set:
+#define SPI_CLOCK_DIV SPI_CLOCK_DIV2
 #endif
-
-// nRF8001 supports max. 3 MHz SPI clock frequency.
-// Arduino Pro Micro runs at 8 MHz. By dividing by 4, we
-// set the SPI clock frequency to 2 MHz.
-#define SPI_CLOCK_DIV SPI_CLOCK_DIV4

 // Advertisement interval in 0.625 ms, min 0x0020 (20 ms), max 0x4000 (10.240 s).
 // 1600 -> 1 s


Update time only when needed. Add optional clock icon.


adjustable number of ADC readouts

adjustable number of ADC readouts

--- examples/Ports/bandgap/bandgap.ino
+++ examples/Ports/bandgap/bandgap.ino
@@ -10,11 +10,11 @@

 ISR(ADC_vect) { adcDone = true; }

-static byte vccRead () {
+static byte vccRead (byte count =4) {
   set_sleep_mode(SLEEP_MODE_ADC);
   ADMUX = bit(REFS0) | 14; // use VCC and internal bandgap
   bitSet(ADCSRA, ADIE);
-  for (byte i = 0; i < 4; ++i) {
+  while (count-- > 0) {
     adcDone = false;
     while (!adcDone)
       sleep_mode();


Added swipe logic to sketch list

Added swipe logic to sketch list

Signed-off-by: Irmo van den Berge <0370dce6b07866a7132582d46388cf81833cb900@home.nl>

--- examples/SketchList/SketchList.ino
+++ examples/SketchList/SketchList.ino
@@ -9,6 +9,10 @@
 /* General defines */
 #define LCD_RIGHT_BORDER    32
 #define HOLD_ACTIVATE_DELAY 1000
+
+/* Swipe settings and calibration */
+#define SWIPE_FADE          0.05
+#define SWIPE_THRESHOLD     2.0

 /* Sketches list settings */
 #define SKETCHES_CNT_X      4
@@ -87,8 +91,11 @@
 #define COLOR_NAME_KEY_SEL  BLUE_8BIT  /* Key foreground color when pressed */

 /* LCD touch input variables */
-uint16_t touch_x, touch_y;
-boolean touch_waitup;
+uint16_t touch_x, touch_y; /* Touch x/y coordinates, is 0xFFFF when not pressed */
+boolean touch_waitup;      /* Whether we are waiting a cycle */
+uint32_t swipe_last_time;  /* Last known time while swiping */
+uint16_t swipe_last_pos;   /* Last known position while swiping */
+float swipe_speed;         /* Speed of swiping in pixels/ms */

 /* Sketch information buffer */
 typedef struct {
@@ -327,8 +334,37 @@
     }
   } while ((icon_idx < MENU_IDX_NONE) && (sketch_index < sketches_buff_cnt));

+  /* Update the swipe measurements, on release perform action */
+  if (!LCD_isTouchedAny()) {
+    /* Handle releases, evaluate previously measured swipe speed */
+    if (swipe_speed > SWIPE_THRESHOLD) {
+      sketch_icon_dirty[touchedIndex] = 1;
+      touchedIndex = MENU_IDX_DOWN;
+    }
+    if (swipe_speed < -SWIPE_THRESHOLD) {
+      sketch_icon_dirty[touchedIndex] = 1;
+      touchedIndex = MENU_IDX_UP;
+    }
+    swipe_speed = 0.0F;
+  } else if (swipe_last_pos != 0xFFFF) {
+    /* Handle swipe speed measurement */
+    float diff = (float) ((int) touch_y - (int) swipe_last_pos);
+    float time = (float) (millis() - swipe_last_time);
+    float curr_speed = diff / time;
+    if (abs(curr_speed) > abs(swipe_speed)) {
+      swipe_speed = curr_speed;
+    } else {
+      swipe_speed += SWIPE_FADE * (curr_speed - swipe_speed);
+    }
+  }
+
+  /* Update last known swipe position and time */
+  swipe_last_pos = touch_y;
+  swipe_last_time = millis();
+
   /* Handle button presses here */
   if (touchedIndex != MENU_IDX_NONE) {
+
     /* Open edit menu when holding down on a sketch icon for some time */
     if (touchedIndex >= MENU_IDX_SKET && ((millis() - pressed_time_start) > HOLD_ACTIVATE_DELAY)) {
       editSketch(sketch_icon_text[touchedIndex], false);
@@ -340,7 +376,7 @@
         case MENU_IDX_UP:
           /* Move sketch list one page up, ignore if impossible */
           if (sketch_offset) {
-            sketch_offset -=  SKETCHES_PGINCR;
+            sketch_offset -= SKETCHES_PGINCR;
             redrawIcons = true;
           }
           break;


spped adjust

spped adjust


Wire in tuning

Wire in tuning

--- dds_playground/src/sketch.ino
+++ dds_playground/src/sketch.ino
@@ -21,6 +21,7 @@
 #define ACCUMULATOR_STEPS 2048UL

 #include "wavetables.h"
+#include "tuning.h"

 #define N_WAVETABLES 6
 Wavetable wavetables[N_WAVETABLES];
@@ -79,7 +80,7 @@
     digitalWrite(13, HIGH);
     for (int i=0; i<N_WAVETABLES; i++) {
         if (wavetables[i].currentnote == NONOTE) {
-            wavetables[i].increment = 512 * pitch;
+            wavetables[i].increment = note_to_increment(pitch, wavetables[0].basefreq);
             wavetables[i].currentnote = pitch;
             used_wavetables++;
             break;


modifica delle temperature simulate

modifica delle temperature simulate

--- nodeMCU/plant/plant.ino
+++ nodeMCU/plant/plant.ino
@@ -16,7 +16,7 @@
 void loop() {
   int rnd;

-  rnd = random(1,100);
+  rnd = random(0,40);

 //  Serial.print(String(sent)+" Temperature: ");
   Serial.println(rnd);


Adds comment for mains power and battery usage

--- examples/wifiLinkit/wifiLinkit.ino
+++ examples/wifiLinkit/wifiLinkit.ino
@@ -54,7 +54,8 @@
 void setup()
 {
   Serial.begin(115200);
-  while(!Serial);                                                       //for the linkit, we need to wait until the serial monitor is initialized correclty, if we don't do this, we don't get to see the logging.
+  while(!Serial);                                     //for the linkit, we need to wait until the serial monitor is initialized correctly, if we don't do this, we don't get to see the logging.
+                                                      //Warning for battery and mains power usage, comment out the above line, other wise the setup() will continue to wait for the Serial to become available
   pinMode(a1, OUTPUT);

   Serial.println("starting");


Fix to the default lfcr eoln format

Fix to the default lfcr eoln format

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

--- zimodem/zcommand.ino
+++ zimodem/zcommand.ino
@@ -19,7 +19,7 @@
 ZCommand::ZCommand()
 {
   strcpy(CRLF,"\r\n");
-  strcpy(LFCR,"\r\n");
+  strcpy(LFCR,"\n\r");
   strcpy(LF,"\n");
   strcpy(CR,"\r");
   strcpy(ECS,"+++");


Fix indent

Fix indent

--- examples/Widgets/Bridge/Bridge.ino
+++ examples/Widgets/Bridge/Bridge.ino
@@ -54,16 +54,16 @@
     bridge1.digitalWrite(9, HIGH);  // Digital Pin 9 on the second board will be set HIGH
     bridge1.virtualWrite(V5, 1); // Sends 1 value to BLYNK_WRITE(V5) handler on receiving side.

-  /////////////////////////////////////////////////////////////////////////////////////////
-  // Keep in mind that when performing virtualWrite with Bridge,
-  // second board will need to process the incoming command.
-  // It can be done by using this handler on the second board:
-  //
-  //    BLYNK_WRITE(V5){
-  //    int pinData = param.asInt(); // pinData variable will store value that came via Bridge
-  //    }
-  //
-  /////////////////////////////////////////////////////////////////////////////////////////
+    /////////////////////////////////////////////////////////////////////////////////////////
+    // Keep in mind that when performing virtualWrite with Bridge,
+    // second board will need to process the incoming command.
+    // It can be done by using this handler on the second board:
+    //
+    //    BLYNK_WRITE(V5){
+    //    int pinData = param.asInt(); // pinData variable will store value that came via Bridge
+    //    }
+    //
+    /////////////////////////////////////////////////////////////////////////////////////////
   } else {
     bridge1.digitalWrite(9, LOW); // Digital Pin 9 on the second board will be set LOW
     bridge1.virtualWrite(V5, 0); // Sends 0 value to BLYNK_WRITE(V5) handler on receiving side.


Delete vb04_servo.ino

Delete vb04_servo.ino

--- examples/vb04_servo/vb04_servo.ino
+++ examples/vb04_servo/vb04_servo.ino
@@ -1,24 +0,0 @@
-/**
- * servo
- * Lees de potmeter uit en laat de servo de potmeter volgen
- */
-
-#include <Servo.h>
-#include <InkyBoard.h>
-#include <Display.h>
-
-InkyBoard B; // definieer B als InkyBoard
-void setup() {
-  B.init(); // initieer het bord (de vier led's knipperen 1x bij opstaren)
-}
-
-void loop() {
-  B.setServo( B.getPot(true) ); // de functie getPot heeft een optionele parameter, als deze waar (true) is dan wordt de standaard waarde (0-1023) omgezet naar graden (0-180)
-
-  //B.setServo( B.getLight(true) ); // de functie getLight heeft dezelfde optionele parameter als getPot
-}
-
-
-
-
-


Changing to Bytes from JSON

Changing to Bytes from JSON

Changing to Bytes from JSON wayyy faster.

--- LightController/LightController.ino
+++ LightController/LightController.ino
@@ -1,10 +1,8 @@
 #include <SPI.h>         // needed for Arduino versions later than 0018
 #include <Ethernet.h>
 #include <EthernetUdp.h>
-#define UDP_TX_PACKET_MAX_SIZE 1280 // Current JSON is 70 -> 1210
+#define UDP_TX_PACKET_MAX_SIZE 1024 // Current light command is 8
 #include <G35String.h>
-#include <JsonParser.h>
-using namespace ArduinoJson::Parser;

 // Total # of lights on string (usually 50, or 25). Maximum is 63, because
@@ -44,14 +42,10 @@
 G35String lights_12(G35_PIN_12, LIGHT_COUNT);
 G35String lights_13(G35_PIN_13, LIGHT_COUNT_LARGE);

-// Define JSON parser can handle 16 parts
-JsonParser<380> parser;
-
-
 // Enter a MAC address and IP address for your controller below.
 byte mac[] = {
-  0x90, 0xA2, 0xDA, 0x0E, 0xAF, 0x5D // Live system
-  //0x90, 0xA2, 0xDA, 0x0E, 0xAF, 0x5E // Test System
+  //0x90, 0xA2, 0xDA, 0x0E, 0xAF, 0x5D // Live system
+  0x90, 0xA2, 0xDA, 0x0E, 0xAF, 0x5E // Test System
 };

 unsigned int localPort = 8888;      // local port to listen on
@@ -100,7 +94,11 @@

   //Create Serial Object
   Serial.begin(9600);
-
+
+  // print your local IP address:
+  Serial.print("My IP address: ");
+  Serial.println(Ethernet.localIP());
+
   resetPacketBuffer();
   Serial.println(F("We are good to go!"));
 }
@@ -109,15 +107,17 @@
   memset(packetBuffer, 0, UDP_TX_PACKET_MAX_SIZE);
 }

-void processCommand(ArduinoJson::Parser::JsonObject root) {
-  //Serial.println(F("Sending Command"));
-  long lightStringIndex  = root["s"];
-  long bulbIndex         = root["l"];
-  long colorSelect       = root["c"];
-  long r                 = root["r"];
-  long g                 = root["g"];
-  long b                 = root["b"];
-  long brightness        = root["i"];
+// 0 = commnad, 1 = size, 2 = string, 3 = bulb...
+void processSingleLightCommand(int offset) {
+  //Serial.print(F("Offset: "));
+  //Serial.println(offset);
+  long lightStringIndex  = (int)packetBuffer[2+offset] & 0xFF;
+  long bulbIndex         = (int)packetBuffer[3+offset] & 0xFF;
+  long colorSelect       = (int)packetBuffer[4+offset] & 0xFF;
+  long r                 = (int)packetBuffer[5+offset] & 0xFF;
+  long g                 = (int)packetBuffer[6+offset] & 0xFF;
+  long b                 = (int)packetBuffer[7+offset] & 0xFF;
+  long brightness        = (int)packetBuffer[8+offset] & 0xFF;

   // Get the String
   setString(lightStringIndex);
@@ -141,21 +141,31 @@

 }

-void processArrayOfCommands(ArduinoJson::Parser::JsonObject root) {
-  JsonArray commands = root["lightData"];
-  if (!commands.success())
+void processMultiLightCommand() {
+  long numberOfCommands  = (int)packetBuffer[1] & 0xFF;
+
+  for (int i = 0; i < numberOfCommands; ++i)
   {
-    error2();
-    resetPacketBuffer();
-    return;
-  }
-  for (int i = 0; i < commands.size(); ++i)
-  {
-    processCommand(commands[i]);
-  }
-}
-
-
+    processSingleLightCommand(i*7);
+  }
+}
+
+void error() {
+  Serial.println(F("Unknown COMMAND failed"));
+  lights = &lights_13;
+  lights->fill_color(0, lights->get_light_count(), G35::MAX_INTENSITY, COLOR_WARMWHITE);
+  delay(100);
+  lights->fill_color(0, lights->get_light_count(), G35::MAX_INTENSITY, COLOR_RED);
+  delay(100);
+  lights->fill_color(0, lights->get_light_count(), G35::MAX_INTENSITY, COLOR_WARMWHITE);
+  delay(100);
+  lights->fill_color(0, lights->get_light_count(), G35::MAX_INTENSITY, COLOR_RED);
+  delay(100);
+
+  Udp.beginPacket(Udp.remoteIP(), Udp.remotePort());
+  Udp.write(ReplyError);
+  Udp.endPacket();
+}

 color_t getColor(long colorSelect, long r, long g, long b) {
   color_t color = COLOR(r, g, b);
@@ -219,40 +229,6 @@
   } else if (lightStringIndex == 13) {
     lights = &lights_13;
   }
-}
-
-void error() {
-  Serial.println(F("JsonParser.parse() failed"));
-  lights = &lights_13;
-  lights->fill_color(0, lights->get_light_count(), G35::MAX_INTENSITY, COLOR_WARMWHITE);
-  delay(100);
-  lights->fill_color(0, lights->get_light_count(), G35::MAX_INTENSITY, COLOR_RED);
-  delay(100);
-  lights->fill_color(0, lights->get_light_count(), G35::MAX_INTENSITY, COLOR_WARMWHITE);
-  delay(100);
-  lights->fill_color(0, lights->get_light_count(), G35::MAX_INTENSITY, COLOR_RED);
-  delay(100);
-
-  Udp.beginPacket(Udp.remoteIP(), Udp.remotePort());
-  Udp.write(ReplyError);
-  Udp.endPacket();
-}
-
-void error2() {
-  Serial.println(F("JsonParser2.parse() failed"));
-  lights = &lights_13;
-  lights->fill_color(0, lights->get_light_count(), G35::MAX_INTENSITY, COLOR_WARMWHITE);
-  delay(100);
-  lights->fill_color(0, lights->get_light_count(), G35::MAX_INTENSITY, COLOR_BLUE);
-  delay(100);
-  lights->fill_color(0, lights->get_light_count(), G35::MAX_INTENSITY, COLOR_WARMWHITE);
-  delay(100);
-  lights->fill_color(0, lights->get_light_count(), G35::MAX_INTENSITY, COLOR_BLUE);
-  delay(100);
-
-  Udp.beginPacket(Udp.remoteIP(), Udp.remotePort());
-  Udp.write(ReplyError);
-  Udp.endPacket();
 }

 void allOffFade(long fadeDelay) {
@@ -302,30 +278,29 @@
   int packetSize = Udp.parsePacket();
   if (packetSize)
   {
-    //Serial.print(F("Received packet of size: "));
-    //Serial.println(packetSize);
+    Serial.print(F("Received packet of size: "));
+    Serial.println(packetSize);

     // read the packet into packetBufffer
     Udp.read(packetBuffer, UDP_TX_PACKET_MAX_SIZE);
-    //Serial.print(F("Data: "));
-    //Serial.println(packetBuffer);
-
-    JsonObject root = parser.parse(packetBuffer);
-    if (!root.success())
-    {
-      error();
-      resetPacketBuffer();
-      return;
-    }
-    char* command  = root["command"];
+//    Serial.println(F("Data: "));
+//    Serial.println((int)packetBuffer[0] & 0xFF);
+//    Serial.println((int)packetBuffer[1] & 0xFF);
+//    Serial.println((int)packetBuffer[2] & 0xFF);
+//    Serial.println((int)packetBuffer[3] & 0xFF);
+//    Serial.println((int)packetBuffer[4] & 0xFF);
+//    Serial.println((int)packetBuffer[5] & 0xFF);
+//    Serial.println((int)packetBuffer[6] & 0xFF);
+
+    int command  = (int)packetBuffer[0] & 0xFF;
     Serial.print(F("Got command: "));
     Serial.println(command);
-    if (String("0").equalsIgnoreCase(command)) {
-      processCommand(root["lightData"]);
-    } else if (String("1").equalsIgnoreCase(command)) {
-      processArrayOfCommands(root);
-    } else if (String("2").equalsIgnoreCase(command)) {
-      allOffFade(root["delay"]);
+    if (command==0) {
+      processSingleLightCommand(0);
+    } else if (command==1) {
+      processMultiLightCommand();
+    } else if (command==2) {
+      allOffFade(packetBuffer[1] & 0xFF);
     } else {
       Serial.print(F("Unknown Command: "));
       Serial.println(command);


cleaning up code

cleaning up code

--- game.ino
+++ game.ino
@@ -86,12 +86,7 @@

 		checkCollision(ball,lPad,rPad,court_width,court_height);

-
 		drawFrame(LD, ball, lPad, rPad, court_width, court_height);
-
-
-
-

 	}
 }
@@ -104,7 +99,6 @@
 *	@param rPad	The right paddle object.
 *	@param cWidth The width of the court.
 *	@param cHeigh The height of the court.
-
 **/
 void drawFrame(
 	LaserDriver &LD,
@@ -278,27 +272,3 @@
 		ball.setVel( -ball.getDx(), (ball.getY() - (rPad.getY()/2)) /15 );
 	}
 }
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-	 //SAVING DARREN'S VALUES   float  SX_ball = 1.5,
-	 //SAVING DARREN'S VALUES          SY_ball = 2.5,
-	 //SAVING DARREN'S VALUES          X_ball = 128.0,
-	 //SAVING DARREN'S VALUES          Y_ball = 128.0;


Tweak Init Params

Tweak Init Params

--- WeatherStation/WeatherStation.ino
+++ WeatherStation/WeatherStation.ino
@@ -43,9 +43,9 @@

   configureLightSensor();

-  //Delay for 30 sec at startup after a manual RST to allow for the wireless programmer to transition
+  //Delay for 15 sec at startup after a manual RST to allow for the wireless programmer to transition
   // the board into the bootloader, or change other XBEE settings remotely, c.f. disable pin sleep mode to keep the XBEE up
-  blink(30, 500);
+  blink(15, 500);
 }

 void blink(int times){


Update _firmware.ino

Update _firmware.ino

--- Arduino/_firmware/_firmware.ino
+++ Arduino/_firmware/_firmware.ino
@@ -110,6 +110,8 @@
     drop_occured = false;
     }

+  //////////////////////////////////////////////////////Printing
+
   if (millis() - last_print_time >= PRINT_DELAY){
     Serial.print ("rpm = ");
     Serial.println (rpm);


Added 'big' functions to example

Added 'big' functions to example

--- examples/unicode_text/unicode_text.ino
+++ examples/unicode_text/unicode_text.ino
@@ -18,7 +18,7 @@
 #include "GT20L16_drive.h"

-#define SCREEN_SIZE 200                 // choose screen size: 144, 200, 270
+#define SCREEN_SIZE 270                 // choose screen size: 144, 200, 270

 #if (SCREEN_SIZE == 144)
 #define EPD_SIZE    EPD_1_44
@@ -46,9 +46,11 @@
     GT20L16.begin();

     EPAPER.drawString("SeeedStudio", 10, 10);
-    EPAPER.drawUnicodeString(uniCode, 5, 30, 40);
+    EPAPER.drawStringBig("SeeedStudio", 10, 30);

-    EPAPER.display();                                   // use only once
+    EPAPER.drawUnicodeString(uniCode, 5, 30, 80);
+    EPAPER.drawUnicodeStringBig(uniCode, 5, 30, 100);
+    EPAPER.display();

 }


Hey look, new APIs for getting at leds..

--- examples/NoisePlayground/NoisePlayground.ino
+++ examples/NoisePlayground/NoisePlayground.ino
@@ -37,7 +37,7 @@

 void loop() {
   // fill the led array 2/16-bit noise values
-  fill_2dnoise16(leds, kMatrixWidth, kMatrixHeight, kMatrixSerpentineLayout,
+  fill_2dnoise16(LEDS.leds(), kMatrixWidth, kMatrixHeight, kMatrixSerpentineLayout,
                 octaves,x,xscale,y,yscale,time,
                 hue_octaves,x,hue_scale,y,hue_scale,hue_time, false);
   LEDS.show();


Remove LCD code, use shift register based display (p1 only right now)

--- pingpong/pingpong.ino
+++ pingpong/pingpong.ino
@@ -1,13 +1,13 @@
-#include <LiquidCrystal.h>
-
-LiquidCrystal lcd(12,11,5,4,3,2);
-
-// End display setup
-
 #define P1PIN           8
 #define P2PIN           9
 #define SPEAKERPIN      6
 #define LONGPRESS_TIME 25
+#define LATCH 4
+#define CLK   3
+#define DATA  2
+
+// Seven Segment Display Handling
+byte DigitBytes[10]= {0x3F, 0x06, 0x5B, 0x4F, 0x66, 0x6D, 0x7D, 0x07, 0x7F, 0x67};

 // Button handling
 enum { BUTTON_NONE=0, BUTTON_SHORT, BUTTON_LONG};
@@ -124,6 +124,8 @@
 int p2Score = 0;
 int currentServe = 0; // p1 = 0, p2 = 1
 int numServes = 0;
+boolean p1Win = false;
+boolean p2Win = false;

 int gameOver = 0;

@@ -133,11 +135,10 @@

 void setup()
 {
-  lcd.begin(16, 2);
-  lcd.clear();
-  lcd.print("Ping Ponger");
-
-  Serial.begin(9600);
+  pinMode(LATCH, OUTPUT);
+  pinMode(CLK, OUTPUT);
+  pinMode(DATA, OUTPUT);
+
   showScore();

   p1Button.init();
@@ -148,6 +149,7 @@
 void loop()
 {
   int p1Event, p2Event;
+

   p1Event = p1Button.handle();
   if (!gameOver && p1Event == BUTTON_SHORT) {
@@ -178,59 +180,52 @@
     numServes = 0;
     showScore();
   }
-
+
   delay(20);
 }

+void showP1Score(int score, boolean serve) {
+  int onesIndex = score % 10;
+  int tensIndex = score / 10;
+
+  int ones = DigitBytes[onesIndex];
+  int tens = DigitBytes[tensIndex];
+
+  if (serve) {
+    tens |= 0x80;
+  }
+
+  digitalWrite(LATCH, LOW);
+  shiftOut(DATA, CLK, MSBFIRST, ones);
+  shiftOut(DATA, CLK, MSBFIRST, tens);
+  digitalWrite(LATCH, HIGH);
+}
+
+
 void showScore()
 {
-  lcd.clear();
-  lcd.setCursor(0, 0);
-  lcd.print("Player 1");
-  lcd.setCursor(13, 0);
-  lcd.print(p1Score);
-
-
-  lcd.setCursor(0, 1);
-  lcd.print("Player 2");
-  lcd.setCursor(13, 1);
-  lcd.print(p2Score);
-
   if (numServes == 2) {
     numServes = 0;
     currentServe = currentServe == 0 ? 1 : 0;
   }
-
+
   if (currentServe == 0) {
-    lcd.setCursor(15, 0);
+    showP1Score(p1Score, true);
   } else {
-    lcd.setCursor(15, 1);
-  }
-  lcd.print("*");
-
-  Serial.print("P1: ");
-  Serial.print(p1Score);
-  Serial.print("  P2: ");
-  Serial.println(p2Score);
+    showP1Score(p1Score, false);
+  }
 }

 void checkForWinner()
 {
   if ((p1Score >= 11 || p2Score >= 11) && abs(p1Score - p2Score) >= 2) {

-    Serial.print("*** WINNER ***   ");
     if (p1Score > p2Score) {
-      Serial.print("P1");
-      lcd.setCursor(10, 0);
-      lcd.print("WINNER");
+      p1Win = true;
     } else {
-      Serial.print("P2");
-      lcd.setCursor(10, 1);
-      lcd.print("WINNER");
+      p2Win = true;
     }
-    Serial.println("   *** WINNER ***");
     victorySong.play();
-
     gameOver = 1;
   }
 }
@@ -239,6 +234,8 @@
 {
   p1Score = 0;
   p2Score = 0;
+  p1Win = false;
+  p2Win = false;
   gameOver = 0;
 }


'menus' T and R implemented

'menus' T and R implemented

--- Memory/FlashReader/FlashReader.ino
+++ Memory/FlashReader/FlashReader.ino
@@ -184,19 +184,90 @@
       token = strtok(0, " ");
     }

+#if 0
     // final control output after tokenisation
     if ( command && !err ) {
       Serial << F("command= '") << command << "'" << endl;
       for ( int i=0; i<nopts; ++i )
         Serial << F("option[") << i << F("]= '") << option[i] << "'" << endl;
     }
+#endif

     if ( !err ) {
+
+      size_t total_length, len, nBytes;
+
       switch ( command[0] ) {
-        case 't': break;
-        case 'r': break;
-        case 'w': break;
-        case '?': break;
+
+        case 't':
+        case 'T':
+          // requires exactly one parameter
+          if ( nopts != 1 ) {
+            err = 1;
+            Serial << F("ERR: number of parameters mismatch") << endl;
+          }
+          else if ( *option[0] == '?' ) {
+            Serial << F("T ") << (int)eepromType << endl;
+          }
+          else if (    atoi(option[0]) > (int)EEprom::eEEPROM_2716
+                    || atoi(option[0]) <= (int)EEprom::eEEPROM_27040 ) {
+            eepromType = (EEprom::eEEPROMtype)atoi(option[0]);
+            eeprom.setType( eepromType );
+          }
+          else {
+            err = 1;
+            Serial << F("ERR: parameter range mismatch") << endl;
+          }
+        break;
+
+        case 'r':
+        case 'R':
+          // requires exactly two parameters
+          if ( nopts != 2 ) {
+            err = 1;
+            Serial << F("ERR: number of parameters mismatch") << endl;
+          }
+          else {
+            eepromAddr = atoi(option[0]);
+            total_length = atoi(option[1]);
+
+            if ( eepromAddr >= eeprom.getSize() ) {
+              err = 1;
+              Serial << F("ERR: start address outside E(E)PROM address range") << endl;
+            }
+            if ( total_length <= 0 ) {
+              err = 1;
+              Serial << F("ERR: illegal length parameter") << endl;
+            }
+            if ( !err ) {
+              len = total_length;
+              while ( len > 0 ) {
+                nBytes = min(len, kMAX_BLOCK_SIZE);
+                len -= nBytes;
+
+                eeprom.read(eepromAddr, eepromData, nBytes);
+                writeIhexData(Serial, eepromData, nBytes, eepromAddr);
+
+                eepromAddr += nBytes;
+              }
+              writeIhexEOF(Serial);
+            }
+          }
+        break;
+
+        case 'w':
+        case 'W':
+          // requires exactly two parameters
+          if ( nopts != 2 ) {
+            err = 1;
+            Serial << F("ERR: number of parameters mismatch") << endl;
+          }
+        break;
+
+        case '?':
+          Serial << F("R W T") << endl;
+        break;
+
         default:
           Serial << F("ERR: unknown command entered!") << endl;
           err = true;
@@ -285,8 +356,6 @@
       case 'L':
         Serial.print(F("\nEnter block length? ")); Serial.flush();
         total_length = readInt();
-        //total_length = Serial.parseInt();
-        //Serial.println(total_length);
         Serial.println();
         break;

@@ -342,7 +411,6 @@
           eepromType = (EEprom::eEEPROMtype)readInt((uint16_t)EEprom::eEEPROM_NONE,
                                                     (uint16_t)EEprom::eEEPROM_27040); // Serial.parseInt();
           if (eepromType) {
-            //Serial.println(eepromType);
             eeprom.setType(eepromType);
             eepromAddr = 0;  // start again with first addr
           }
@@ -462,4 +530,4 @@

   delay(2500);
 }
-
+


I think the PID system is configured like it should be, now. The coefficients are wrong, but it's actually a PID system, now.

--- temp_ctrl/temp_ctrl.ino
+++ temp_ctrl/temp_ctrl.ino
@@ -20,17 +20,18 @@
 #define TEMP_ADC_PIN A3
 #define HEATER_PIN 8

-#define SAMPLE_DELAY_MS 400L
-#define HEATER_PERIOD_MS 10000L
-#define PID_UPDATE_PERIOD_MS SAMPLE_DELAY_MS + 33L
+#define SAMPLE_DELAY_MS 50L
+#define PRINT_DELAY_MS 1000L
+#define HEATER_PERIOD_MS 5000L
+#define PID_UPDATE_PERIOD_MS 5000L

 //#define OPEN_LOOP_MODE
 #define PID_MODE

 #	define DUTY_INIT 0.0

-#define PGAIN 1.1
-#define IGAIN 0.0005
+#define PGAIN 2
+#define IGAIN 0
 #define DGAIN 0
 #define IMIN -10000 // arbitrarily large min and max so they don't have effect, for now
 #define IMAX 10000
@@ -40,8 +41,8 @@
 #define TEMP_TO_DUTY_SLOPE 0.1
 #define TEMP_TO_DUTY_OFFSET 0.0

-#define DRIVE_MAX 100
-#define DRIVE_MIN 10
+//#define DRIVE_MAX 100
+//#define DRIVE_MIN 10

 struct SPid
 {
@@ -63,7 +64,7 @@
 	}
 };

-#define ROLLING_AVG_DATA_POINTS 200
+#define ROLLING_AVG_DATA_POINTS 100
 #define TEMP_AVERAGING_INITIAL_VALUE (float)21
 class RollingAverage
 {
@@ -110,8 +111,8 @@
 float tempRiseTarget, tempZero;
 RollingAverage tempAvg(TEMP_AVERAGING_INITIAL_VALUE);
 float heaterDutyCycle;
-uint32_t timeZero, sampleTime, heaterOnTime, heaterPeriodTime, pidUpdateTime;
-long sampleTimeLeft, heaterOnTimeLeft, heaterPeriodTimeLeft, pidUpdateTimeLeft;
+uint32_t timeZero, sampleTime, heaterOnTime, heaterPeriodTime, pidUpdateTime, printTime;
+long sampleTimeLeft, heaterOnTimeLeft, heaterPeriodTimeLeft, pidUpdateTimeLeft, printTimeLeft;
 SPid pid;
 float pidDrive;
 bool heaterIsOn;
@@ -150,6 +151,16 @@
   return min(1.0, max(0.0, tempChange * TEMP_TO_DUTY_SLOPE + TEMP_TO_DUTY_OFFSET));
 }

+float getErr()
+{
+  return -(tempAvg.getAverage() - tempZero - tempRiseTarget) / tempRiseTarget;
+}
+
+float getPos()
+{
+  return (tempAvg.getAverage() - tempZero) / tempRiseTarget;
+}
+
 void heaterOn()
 {
 	digitalWrite(HEATER_PIN, HIGH);
@@ -161,16 +172,6 @@
 {
 	digitalWrite(HEATER_PIN, LOW);
   heaterIsOn = false;
-}
-
-float getErr()
-{
-  return ( tempZero + tempRiseTarget - tempAvg.getAverage() ) / tempRiseTarget;
-}
-
-float getPos()
-{
-  return ( tempAvg.getAverage() - tempZero ) / tempRiseTarget;
 }

 const char comma PROGMEM = ',';
@@ -215,11 +216,12 @@
   tempRiseTarget = TARGET;

 	pid.init();
-	pidDrive = updatePID(&pid, getErr(), getPos());
+	pidDrive = updatePID(&pid,getErr(),getPos());
 	heaterDutyCycle = DUTY_INIT;

 	timeZero = millis();
 	sampleTime = millis();			// sample (etc) immediately
+  printTime = millis();
 	heaterPeriodTime = millis();	// start new period immediately
 }

@@ -227,15 +229,21 @@
 void loop()
 {
 	sampleTimeLeft = sampleTime - millis();
+  printTimeLeft = printTime - millis();
 	heaterOnTimeLeft = heaterOnTime - millis();
 	heaterPeriodTimeLeft = heaterPeriodTime - millis();

 	if (sampleTimeLeft < 0)
 	{
 		tempAvg.push(getTemperature());
-		printData(&pid);
 		sampleTime = millis() + SAMPLE_DELAY_MS;
 	}
+
+  if (printTimeLeft < 0)
+  {
+    printData(&pid);
+    printTime = millis() + PRINT_DELAY_MS;
+  }

 	if (heaterOnTimeLeft < 0 && heaterIsOn)
 		heaterOff();
@@ -260,6 +268,7 @@
 void loop()
 {
   sampleTimeLeft = sampleTime - millis();
+  printTimeLeft = printTime - millis();
   pidUpdateTimeLeft = pidUpdateTime - millis();
   heaterOnTimeLeft = heaterOnTime - millis();
   heaterPeriodTimeLeft = heaterPeriodTime - millis();
@@ -267,8 +276,13 @@
   if (sampleTimeLeft < 0)
   {
     tempAvg.push(getTemperature());
+    sampleTime = millis() + SAMPLE_DELAY_MS;
+  }
+
+  if (printTimeLeft < 0)
+  {
     printData(&pid);
-    sampleTime = millis() + SAMPLE_DELAY_MS;
+    printTime = millis() + PRINT_DELAY_MS;
   }

   if (heaterOnTimeLeft < 0 && heaterIsOn)
@@ -284,7 +298,8 @@
   if (pidUpdateTimeLeft < 0)
   {
     pidDrive = updatePID(&pid, getErr(), getPos());
-    heaterDutyCycle = tempChangeToDuty(pidDrive * tempRiseTarget);
+//    heaterDutyCycle = tempChangeToDuty(pidDrive * tempRiseTarget);
+    heaterDutyCycle = constrain(pidDrive, 0, 1);
     pidUpdateTime = millis() + PID_UPDATE_PERIOD_MS;

     DEBUG2(F("pidDrive        = "), pidDrive);


Fix throttle position parsing

Fix throttle position parsing

--- Event_Printer/Event_Printer.ino
+++ Event_Printer/Event_Printer.ino
@@ -141,8 +141,8 @@
 void handle_MSG_ID_BMSK_Control_Module(unsigned char *data, unsigned char length)
 {
     // THROTTLE POSITION
-    unsigned char byte2 = data[1];
-    uint8_t throttlePosition = (byte2 / 255)*100;
+    float byte2 = data[1];
+    float throttlePosition = (byte2 / 255) * 100;
     Serial.print("Throttle Position: ");
     Serial.print(throttlePosition, DEC);
     Serial.println();


add comments and program description

add comments and program description

--- arduinoTest/_7segment/_7segment.ino
+++ arduinoTest/_7segment/_7segment.ino
@@ -1,3 +1,10 @@
+//Zachary Nelson
+//znelson1@ford.com
+//This program uses a 74hc595 shift register and a
+//7-sement display to display the numbers 0 - 9. It
+//is used to test future implementations of the
+//display control.
+
 //Pin connected to ST_CP of 74HC595
 int latchPin = 8;
 //Pin connected to SH_CP of 74HC595
@@ -5,16 +12,16 @@
 ////Pin connected to DS of 74HC595
 int dataPin = 11;

-int digit0 = 0b0;
-int digit1 = 0b00010001;
-int digit2 = 0b01101011;
-int digit3 = 0b00111011;
-int digit4 = 0b00011101;
-int digit5 = 0b00111110;
-int digit6 = 0b01111100;
-int digit7 = 0b00010011;
-int digit8 = 0b01111111;
-int digit9 = 0b00011111;
+int digit0 = 0b10001000;
+int digit1 = 0b11101110;
+int digit2 = 0b10010100;
+int digit3 = 0b11000100;
+int digit4 = 0b11100010;
+int digit5 = 0b11000001;
+int digit6 = 0b10000011;
+int digit7 = 0b11101100;
+int digit8 = 0b10000000;
+int digit9 = 0b11100000;
 // if you want to add in the decimal point simply add 1 to each number

 void setup() {
@@ -35,7 +42,6 @@
     sendDigit(digit7);
     sendDigit(digit8);
     sendDigit(digit9);
-  }
 }

 void sendDigit(int x){
@@ -43,7 +49,7 @@
   // the LEDs don't change while you're sending in bits:
   digitalWrite(latchPin, LOW);
   // shift out the bits:
-  shiftOut(dataPin, clockPin, MSBFIRST, x);
+  shiftOut(dataPin, clockPin, LSBFIRST, x);

   //take the latch pin high so the LEDs will light up:
   digitalWrite(latchPin, HIGH);


Add Az and El calculations

Add Az and El calculations

--- PortableAntennaRotorControl.ino
+++ PortableAntennaRotorControl.ino
@@ -548,16 +548,65 @@
     targetAlt += ( targetValt * deltaT );
   }

-  //FOR DEBUG PURPOSES
-  Serial.println(targetPosX);
-  Serial.println(targetPosY);
-  Serial.println(targetPosZ);
-  Serial.println(targetVelX);
-  Serial.println(targetVelY);
-  Serial.println(targetVelZ);
-  Serial.println(lastAprsTime);
-  Serial.println(targetTime);
-
-}
-
-
+  // Update AZ and EL angles
+  targetAz = azimuthAngle( gpsLon, gpsLat, targetLon, targetLat );
+  targetEl = elevationAngle( gpsLon, gpsLat, gpsAlt,
+                             targetLon, targetLat, targetAlt );
+
+  if ( DEBUG ) {
+    digitalClockDisplay( (long)targetTime );
+    Serial.print(" Local: Lon Lat Alt: ");
+    Serial.print( gpsLon, 8 );Serial.print(' ');
+    Serial.print( gpsLat, 8 );Serial.print(' ');
+    Serial.println( gpsAlt );
+    Serial.print("Target: Lon Lat Alt: ");
+    Serial.print( targetLon, 8 );Serial.print(' ');
+    Serial.print( targetLat, 8 );Serial.print(' ');
+    Serial.println( targetAlt );
+    Serial.print( "Target: Az El: " );
+    Serial.print( targetAz / deg2rad );Serial.print(' ');
+    Serial.println( targetEl / deg2rad );
+  }
+}
+
+/*
+ * Azimuth and Elevation functions take Latitude, Longitude and
+ * Altitude of reference (1) and target (2) as arguments
+ *
+ * lonX = Longitude (radians) of reference (X=1) or target (X=2) position
+ * latX = Latitude (radians) of reference (X=1) or target (X=2) position
+ * zX = Altitude (meters) of reference (X=1) or target (X=2) position
+ *
+ * Returns angle in radians.
+ *
+ * Note that elevantionAngle casts arguments as doubles as this (exact)
+ * calcuation requires the highest precision.
+ */
+
+float elevationAngle( double lon1, double lat1, double z1,
+                      double lon2, double lat2, double z2 ) {
+
+  // ECEF radii to 1st and 2nd points
+  double a = z1 + rEarth;
+  double b = z2 + rEarth;
+
+  // Central angle
+  double gamma = acos( sin(lat1) * sin(lat2) +
+                 cos(lat1) * cos(lat2) * cos(lon2-lon1) );
+
+  // Linear distance between points (triangle side opposite gamma)
+  double c = sqrt( a*a + b*b - 2 * a * b * cos( gamma ) );
+
+  // Elevation angle is angle at location (beta) minus 90 degrees
+  return acos( 0.5 * ( -b*b + c*c + a*a ) / a / c ) - PI / 2.0;
+}
+
+float azimuthAngle( float lon1, float lat1, float lon2, float lat2 ) {
+
+  return atan2( cos( lat1 ) * sin( lat2 )
+              - sin( lat1 ) * cos( lat2 ) * cos( lon2 - lon1 ),
+                sin( lon2 - lon1 ) * cos( lat2 ) );
+
+
+}
+


Commit now!

Commit now!

--- bupigo.ino
+++ bupigo.ino
@@ -18,6 +18,11 @@
 // Baseline distance between the wheels in mm
 double BASELINE_MM = 103.0;
 double HALF_BASELINE_MM = BASELINE_MM / 2.0;
+
+// Maximum speed achievable per-wheel when the robot is being driven
+// forward at 1000 mm/s and simultaneously rotating at 1 rad/s.
+//double MAX_SPEED = (1000 + HALF_BASELINE_MM) / WHEEL_RADIUS_MM;
+double MAX_SPEED = 1000 / WHEEL_RADIUS_MM;

 // Pin ID's for setting motors
 int MOTOR_LEFT_FORWARD = 44;  // Right motor Forward (M1)
@@ -143,11 +148,18 @@
   double v = forwardSpeed; // Forward speed in mm / sec
   double w = angularSpeed / 1000.0; // Angular speed in radians / sec

-  // Apply differential-drive kinematic model.
-  long leftVelocity = (long)( (v - HALF_BASELINE_MM * w) / WHEEL_RADIUS_MM);
-  long rightVelocity = (long)( (v + HALF_BASELINE_MM * w) / WHEEL_RADIUS_MM);
-
-  bupigoSetSpeeds(leftVelocity, rightVelocity);
+  // Apply differential-drive kinematic model to obtain wheel speeds
+  // in mm / sec.
+  double leftSpeed = (v - HALF_BASELINE_MM * w) / WHEEL_RADIUS_MM;
+  double rightSpeed = (v + HALF_BASELINE_MM * w) / WHEEL_RADIUS_MM;
+
+  // Convert to integer values in the range +/- 255
+  int leftSpeedPWM = (int)( 255 * leftSpeed / MAX_SPEED );
+  int rightSpeedPWM = (int)( 255 * rightSpeed / MAX_SPEED );
+  leftSpeedPWM = constrain(leftSpeedPWM, -255, 255);
+  rightSpeedPWM = constrain(rightSpeedPWM, -255, 255);
+
+  bupigoSetSpeeds(leftSpeedPWM, rightSpeedPWM);
 }

 void bupigoSetServoAngle(long angle) {


Fixed compatibility with USB OSD hardware mAh icon fix

--- KISS_OSD/KISS_OSD.ino
+++ KISS_OSD/KISS_OSD.ino
@@ -312,16 +312,16 @@
 #ifdef NEW_FC_SETTINGS
 enum _SETTING_MODES
 {
+  FC_SETTINGS,
   FC_RATES,
   FC_PIDS,
   FC_VTX,
   FC_FILTERS,
-  FC_TPA,
-  FC_SETTINGS
+  FC_TPA
 };
 static const uint8_t MAX_SETTING_MODES = 6;
-static const uint8_t getSettingModes[MAX_SETTING_MODES] = { 0x4D, 0x43, 0x45, 0x47, 0x4B, 0x30 };
-static const uint8_t setSettingModes[MAX_SETTING_MODES] = { 0x4E, 0x44, 0x46, 0x48, 0x4C, 0x10 };
+static const uint8_t getSettingModes[MAX_SETTING_MODES] = { 0x30, 0x4D, 0x43, 0x45, 0x47, 0x4B };
+static const uint8_t setSettingModes[MAX_SETTING_MODES] = { 0x10, 0x4E, 0x44, 0x46, 0x48, 0x4C };
 static bool fcSettingModeChanged[MAX_SETTING_MODES] = { false, false, false, false, false, false };
 static uint8_t settingMode = 0;
 #endif
@@ -465,7 +465,7 @@
         if(fcSettingChanged && !menuActive)
         {
           bool savedBefore = false;
-          for(i=0; i<(MAX_SETTING_MODES-1); i++)
+          for(i=1; i<MAX_SETTING_MODES; i++)
           {
             if(savedBefore && fcSettingModeChanged[i])
             {
@@ -873,14 +873,14 @@
           {
             uint8_t batCount = (LipoMAH+previousMAH) / settings.m_batSlice;
             uint8_t batStatus = 0x88;
-            while(batCount > 4)
+            while(batCount > 4 && batStatus > 0x84)
             {
               batStatus--;
               batCount--;
             }
             batterySymbol[2] = (char)batStatus;
             batStatus = 0x88;
-            while(batCount > 0)
+            while(batCount > 0 && batStatus > 0x84)
             {
               batStatus--;
               batCount--;


Now using big-endian

Now using big-endian

--- receiver/receiver.ino
+++ receiver/receiver.ino
@@ -20,10 +20,14 @@
 #define CE_PIN                  9 // Radio chip enable pin
 #define CSN_PIN                 10 // Radio chip select pin

+// Network-host endianness conversions
+#define htons(n) (((((uint16_t)(n) & 0xFF)) << 8) | (((uint16_t)(n) & 0xFF00) >> 8))
+#define ntohs(n) (((((uint16_t)(n) & 0xFF)) << 8) | (((uint16_t)(n) & 0xFF00) >> 8))
+
 // Wireless protocol
 #define HASH(a)                 ((a) ^ 73) // Simple 1:1 single byte hash to minimize repeating bit patterns in address
 #define RF_ADDRESS(endpoint)    (0x5349474D00LL | HASH(endpoint & 0xFF)) // Generates a 40-bit nRF address
-#define HEADER                  7446 // Must prefix every message
+#define HEADER                  htons(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


Reformat RIODuino.ino

Reformat RIODuino.ino

--- RIODuino/RIODuino.ino
+++ RIODuino/RIODuino.ino
@@ -18,9 +18,9 @@

 Adafruit_NeoPixel controller = Adafruit_NeoPixel
 (
-  LED_COUNT,
-  LED_PIN,
-  NEO_GRB + NEO_KHZ800
+LED_COUNT,
+LED_PIN,
+NEO_GRB + NEO_KHZ800
 );

 long color = 0x000000;
@@ -39,9 +39,9 @@
   if (Serial.available())
   {
     byte data = Serial.read();
-
+
     byte colorData = (byte) (data & 0xF);
-
+
     color = 0x000000;
     if (colorData & 0b100)
     {
@@ -55,11 +55,11 @@
     {
       color += 0x0000FF;
     }
-
+
     byte height = (byte) (data >> 4);
-
+
     lightCount = (float) height / MAX_STACK_HEIGHT * LED_COUNT;
-
+
     setAll(color);
     update();
   }
@@ -92,3 +92,4 @@
 {
   controller.show();
 }
+


Changed LED_STRIP pin to PWM

Changed LED_STRIP pin to PWM

--- software/my_shiny_metal_tooth/my_shiny_metal_tooth.ino
+++ software/my_shiny_metal_tooth/my_shiny_metal_tooth.ino
@@ -38,7 +38,7 @@

 #define DEBUG

-#define LED_STRIP  4
+#define LED_STRIP  9
 #define GREEN_WIRE 5
 #define BLUE_WIRE  6

@@ -128,7 +128,7 @@
             if (mNow > mSunset && mNow < TURN_OFF_TIME)
                 state = S_ON;

-            digitalWrite (LED_STRIP, LOW);
+            analogWrite (LED_STRIP, 0);
             digitalWrite (GREEN_WIRE, LOW);
             digitalWrite (BLUE_WIRE, LOW);
             break;
@@ -139,7 +139,7 @@
                 break;
             }

-            digitalWrite (LED_STRIP, HIGH);
+            analogWrite (LED_STRIP, 120);

             rNum = rand () % 12;
             if (rNum < 6)      state = L_ON;     // 50%


stairs: remove traces of old operation requiring pots

--- stairs/src/main.ino
+++ stairs/src/main.ino
@@ -10,7 +10,6 @@
 #include <PubSubClient.h>

 // Serial DEBUG mode on/off
-#define DEBUG_SERIAL
 #undef DEBUG_ANIMATION

 #define LIGHT_ON "ON"
@@ -21,6 +20,8 @@

 // Number of LEDs in the strip.
 #define NUM_LEDS 60
+
+#define ANIMATION_SPEED 50

 // This variable holds the LED color state.
 CRGB leds[NUM_LEDS];
@@ -38,85 +39,21 @@
 void modeSolid();
 void modeTemperature();

-// Set the order of modes in the Modeselektor.
-void (*modes[MAX_MODES])() = {
-    &modeOff,
-    &modeTemperature,
-    &modeSolid,
-    &modeGradient,
-    &modeEase,
-    &modeRainbowTrain,
-    &modeRainbow,
-    &modeBreathe,
-    &modeBreatheGradient,
-    &modeJuggle
-};
-
+// Current state
 struct {
     bool on;
     uint8_t brightness;
     uint8_t temperature;
+    void (*effectFunc)();
     char* effect;
     uint8_t r;
     uint8_t g;
     uint8_t b;
 } state;

-struct {
-    uint8_t mode;
-    uint8_t var;
-    uint8_t hue;
-    uint8_t sat;
-    uint8_t val;
-} settings;
-
 // MQTT client handles
 WiFiClient wifi_client;
 PubSubClient mqtt_client(wifi_client);
-
-// function called when a MQTT message arrived
-void mqtt_callback(char* p_topic, byte* p_payload, unsigned int p_length) {
-    char msg[512];
-    char payload[256];
-
-    memcpy(payload, p_payload, 256);
-    payload[p_length] = '\0';
-
-    sprintf(msg, "Topic '%s' received payload: '%s'", p_topic, payload);
-    Serial.println(msg);
-
-    if (!strcmp(payload, LIGHT_ON)) {
-        state.on = true;
-    } else {
-        state.on = false;
-    }
-}
-
-
-// Initial setup, called once on boot.
-void setup() {
-    Serial.begin(115200);
-
-    FastLED.addLeds<NEOPIXEL, PIN_LED>(leds, NUM_LEDS).setCorrection(TypicalSMD5050);
-
-    memset(&state, sizeof state, 0);
-
-    fill_solid(&leds[0], NUM_LEDS, HeatColor(170));
-    FastLED.setBrightness(100);
-    FastLED.show();
-
-    settings.mode = 3;
-    settings.var  = 127;
-    settings.hue  = 0;
-    settings.sat  = 255;
-    settings.val  = 127;
-
-    WiFi.begin(WIFI_SSID, WIFI_PASSWORD);
-
-    // init the MQTT connection
-    mqtt_client.setServer(MQTT_SERVER_IP, MQTT_SERVER_PORT);
-    mqtt_client.setCallback(mqtt_callback);
-}

 // animate returns true if the animation should be stepped.
 uint8_t animate(uint8_t speed) {
@@ -125,11 +62,6 @@
     uint32_t clock;
     uint32_t expectedDelay;

-    // Animations are disabled when speed is zero.
-    if (settings.var == 0) {
-        return 0;
-    }
-
     clock = millis();
     diff = clock - lastClock;

@@ -140,6 +72,10 @@
     }

     return 0;
+}
+
+CRGB currentRGB() {
+    return CRGB(state.r, state.g, state.b);
 }

 // animation animates from 0-255.
@@ -160,128 +96,21 @@

 // Fill all LEDs with the same color. This mode does not have an additional parameter.
 void modeSolid() {
-    fill_solid(&leds[0], NUM_LEDS, CHSV(settings.hue, settings.sat, settings.val));
-}
-
-// Fill all LEDs with a solid color on the temperature scale. The color
-// breathes in and out to another temperature, defined by the extra parameter.
+    fill_solid(&leds[0], NUM_LEDS, currentRGB());
+}
+
+// Fill all LEDs with a solid color on the temperature scale.
 void modeTemperature() {
-    uint8_t wave;
-    uint8_t hue;
-
-    wave = sin8(animation(230));
-    hue = map8(wave, settings.hue, max(settings.var, settings.hue));
-
-    fill_solid(&leds[0], NUM_LEDS, HeatColor(hue));
-    FastLED.setBrightness(settings.val);
-}
-
-// Draw a linear gradient between two colors. The additional parameter defines
-// the destination hue. The same saturation and value applies to both colors.
-void modeGradient() {
-    fill_gradient(
-        &leds[0],
-        0,          CHSV(settings.hue, settings.sat, settings.val),
-        NUM_LEDS-1, CHSV(settings.var, settings.sat, settings.val)
-    );
-}
-
-// Animate the rainbow. The hue parameter moves the rainbow back and forth,
-// while the additional parameter regulates the animation speed.
+    fill_solid(&leds[0], NUM_LEDS, HeatColor(state.temperature));
+    FastLED.setBrightness(state.brightness);
+}
+
+// Animate the rainbow.
 void modeRainbow() {
     uint8_t hue;
     for (uint8_t led = 0; led < NUM_LEDS; led++) {
-        hue = ledAngle(led) + animation(settings.var) + settings.hue;
-        leds[led] = CHSV(hue, settings.sat, settings.val);
-    }
-}
-
-// Fill all LEDs with a single color. Animate the intensity as a sine wave.
-void modeBreathe() {
-    uint8_t start;
-    uint8_t sine;
-    uint8_t value;
-
-    sine = cubicwave8(animation(settings.var));
-    start = settings.val - 100;
-    if (start > settings.val) {
-        start = 0;
-    }
-    value = map8(sine, start, settings.val);
-
-#ifdef DEBUG_ANIMATION
-    char buf[128];
-    sprintf(buf, "sine:%4d  start:%4d  pot:%4d  value:%4d", sine, start, settings.val, value);
-    Serial.println(buf);
-    delay(20);
-#endif
-
-    fill_solid(&leds[0], NUM_LEDS, CHSV(settings.hue, settings.sat, value));
-}
-
-// Fill all LEDs with a single color, animating between two hues in a cubic
-// ease in-out wave resembling a sine wave. The speed is calculated
-// automatically based on distance on the color wheel.
-void modeBreatheGradient() {
-    uint8_t angle;
-    uint8_t hue;
-    uint8_t distance;
-    uint8_t speed;
-
-    distance = settings.var - settings.hue;
-    speed = 255 - map8(distance, 15, 130);
-
-    angle = cubicwave8(animation(speed));
-    hue = map8(angle, settings.hue, settings.var);
-
-    fill_solid(&leds[0], NUM_LEDS, CHSV(hue, settings.sat, settings.val));
-}
-
-// 1-N colored dots, weaving in and out of sync with each other. The variable
-// adjusts the number of dots between 1 and half the LED strip.
-//
-// This function is adapted from https://github.com/atuline/FastLED-Demos.
-void modeJuggle() {
-    uint8_t led;
-    uint8_t hue = settings.hue;
-    uint8_t dots = map8(settings.var, 1, NUM_LEDS / 2);
-    uint8_t step = 256 / dots;
-
-    fadeToBlackBy(leds, NUM_LEDS, 20);
-
-    for(uint8_t dot = 0; dot < dots; dot++) {
-        led = beatsin16(dot+6, 0, NUM_LEDS-1);
-        leds[led] |= CHSV(hue, settings.sat, settings.val);
-        hue += step;
-    }
-}
-
-// Animate each LED's intensity according to a cubic ease in-out function.
-void modeEase() {
-    uint8_t angle;
-    uint8_t value;
-    uint8_t an = animation(settings.var);
-    for (uint8_t led = 0; led < NUM_LEDS; led++) {
-        angle = map(led, 0, NUM_LEDS-1, 0, 255);
-        value = ease8InOutCubic(sin8(angle + an));
-        value = map(value, 0, 255, 0, settings.val);
-        leds[led] = CHSV(settings.hue, settings.sat, value);
-    }
-}
-
-// Animate a rainbow easing in and out. The hue parameter decides how far the
-// rainbow will stretch on the color wheel, while the variable determines the speed.
-void modeRainbowTrain() {
-    uint8_t hue = 0;
-    uint8_t angle;
-    uint8_t value;
-    uint8_t an = animation(settings.var);
-    for (uint8_t led = 0; led < NUM_LEDS; led++) {
-        angle = map(led, 0, NUM_LEDS-1, 0, 255);
-        value = ease8InOutCubic(sin8(angle + an));
-        hue = map8(value, 0, settings.hue);
-        value = map8(value, 0, settings.val);
-        leds[led] = CHSV(hue, settings.sat, value);
+        hue = ledAngle(led) + animation(ANIMATION_SPEED);
+        leds[led] = CHSV(hue, 200, state.brightness);
     }
 }

@@ -293,7 +122,48 @@
     }
 }

-void mqtt_reconnect() {
+void mqtt_handle_effect(const char *payload) {
+    if (!strcmp(payload, "solid")) {
+        state.effectFunc = modeSolid;
+    } else if (!strcmp(payload, "temperature")) {
+        state.effectFunc = modeTemperature;
+    } else if (!strcmp(payload, "rainbow")) {
+        state.effectFunc = modeRainbow;
+    } else {
+        return;
+    }
+    strcpy(state.effect, payload);
+}
+
+void mqtt_handle_command(const char *payload) {
+    if (!strcmp(payload, LIGHT_ON)) {
+        state.on = true;
+        mqtt_handle_effect(state.effect);
+    } else {
+        state.on = false;
+        state.effectFunc = modeOff;
+    }
+}
+
+// function called when a MQTT message arrived
+void mqtt_callback(char* p_topic, byte* p_payload, unsigned int p_length) {
+    char msg[512];
+    char payload[256];
+
+    memcpy(payload, p_payload, 256);
+    payload[p_length] = '\0';
+
+    sprintf(msg, "Topic '%s' received payload: '%s'", p_topic, payload);
+    Serial.println(msg);
+
+    if (!strcmp(p_topic, MQTT_LIGHT_COMMAND_TOPIC)) {
+        mqtt_handle_command(payload);
+    }
+
+    mqtt_publish_state();
+}
+
+void mqtt_connect() {
     Serial.println("INFO: Attempting MQTT connection...");
     if (mqtt_client.connect(MQTT_CLIENT_ID, MQTT_USER, MQTT_PASSWORD)) {
         Serial.println("INFO: connected");
@@ -307,21 +177,31 @@
     }
 }

-// Read all potentiometers, and run one iteration of the active mode.
+// Initial setup, called once on boot.
+void setup() {
+    Serial.begin(115200);
+
+    FastLED.addLeds<NEOPIXEL, PIN_LED>(leds, NUM_LEDS).setCorrection(TypicalSMD5050);
+
+    memset(&state, sizeof state, 0);
+    mqtt_handle_effect("solid");
+
+    WiFi.begin(WIFI_SSID, WIFI_PASSWORD);
+
+    mqtt_client.setServer(MQTT_SERVER_IP, MQTT_SERVER_PORT);
+    mqtt_client.setCallback(mqtt_callback);
+}
+
+// Main loop. Make sure MQTT is connected, and render the LEDs.
 void loop() {
     if (WiFi.status() == WL_CONNECTED) {
         if (!mqtt_client.connected()) {
-            mqtt_reconnect();
+            mqtt_connect();
             return;
         }
         mqtt_client.loop();
     }

-    modes[settings.mode]();
-    if (state.on) {
-        settings.val = 200;
-    } else {
-        settings.val = 0;
-    }
+    state.effectFunc();
     FastLED.show();
 }


Use prescaler ADC magic to make analog reads faster.

--- firmware/firmware.ino
+++ firmware/firmware.ino
@@ -8,6 +8,15 @@
 #include "Timer.h"

+#ifndef cbi
+    #define cbi(sfr, bit) (_SFR_BYTE(sfr) &= ~_BV(bit))
+#endif
+
+#ifndef sbi
+    #define sbi(sfr, bit) (_SFR_BYTE(sfr) |= _BV(bit))
+#endif
+
+
 Receiver receivers[RECEIVER_COUNT];

 #ifdef TEMP_MONITORING_ENABLED
@@ -28,6 +37,8 @@

 void setup() {
+    enableFastAdcRead();
+
     // Set pin defaults.
     pinMode(LED_PIN, OUTPUT);
     pinMode(RECEIVER_PIN_SPI_CLK, OUTPUT);
@@ -223,3 +234,9 @@
         Serial.println("ok");
     }
 }
+
+void enableFastAdcRead() {
+    sbi(ADCSRA, ADPS2);
+    cbi(ADCSRA, ADPS1);
+    cbi(ADCSRA, ADPS0);
+}


sketch: progress calculating distance and time

--- src/src.ino
+++ src/src.ino
@@ -1,40 +1,61 @@
 #include <math.h>

 typedef struct Location {
-  char name[16];
   double lat;
   double lng;
 } Location;

-unsigned long updateAt = 0;
+typedef struct Destination {
+  char name[16];
+  Location loc;
+} Destination;

+// Updated by onNewGps
+// Location
 Location currentLoc = {0};
-Location lastLoc = {0};
-double currentMph = 0;
-double currentHeading = 0;
+// Time in seconds
+unsigned long currentTime = 0;
+unsigned long lastTime = 0;
+double deltaTime = 0;
+// Distance in degrees
+double currentDist = 0;
+double lastDist = 0;
+double deltaDist = 0;
+// ETA in seconds. If negative, we're traveling away from currentDest
+double etaTime = 0;

-Location locations[] = {
-  {"Home", 45.022884, -93.244983},
-  {"Work", 44.989136, -93.250454},
+Destination dests[] = {
+  {"Test", {0.0, 10.0}},
+  {"Home", {45.022884, -93.244983}},
+  {"Work", {44.989136, -93.250454}},
 };
+
+Location currentDest = dests[0].loc;

 double distance(Location from, Location to) {
   return sqrt(pow(from.lat - to.lat, 2) + pow(from.lng - to.lng, 2));
 }

-void onNewGps(double lat, double lng, double mph, double heading) {
+void onNewGps(double lat, double lng) {
   currentLoc.lat = lat;
   currentLoc.lng = lng;
-  currentMph = mph;
-  Serial.println(currentLoc.lat, 6);
-  Serial.println(currentLoc.lng, 6);
-  Serial.println(distance(lastLoc, currentLoc));
-  lastLoc = currentLoc;
+
+  lastTime = currentTime;
+  currentTime = millis();
+  deltaTime = currentTime - lastTime;
+
+  lastDist = currentDist;
+  currentDist = distance(currentLoc, currentDest);
+  deltaDist = currentDist - lastDist;
+
+  etaTime = -deltaTime * currentDist / deltaDist;
 }

 void setup() {
   Serial.begin(9600);
 }
+
+unsigned long updateAt = 0;

 void loop() {
   if (millis() >= updateAt) {
@@ -42,9 +63,14 @@
     int ticks = (millis() / 1000) % 24;
     onNewGps(
       (double) cos(ticks * (2 * 3.14159 / 24)),
-      (double) sin(ticks * (2 * 3.14159 / 24)),
-      (double) random(0, 8000) / 100,
-      (double) random(0, 360)
+      (double) sin(ticks * (2 * 3.14159 / 24))
     );
+    Serial.print(currentLoc.lat, 6);
+    Serial.print(", ");
+    Serial.println(currentLoc.lng, 6);
+    Serial.println(currentDist);
+    Serial.println(deltaDist);
+    Serial.println(etaTime);
+    Serial.println();
   }
 }


arduino code

arduino code

--- station/station.ino
+++ station/station.ino
@@ -7,7 +7,7 @@
  compiled with Arduino 2:1.0.5+dfsg2-4 running on
  ubuntu 16.04 LTS (64Bit)

- created 10 Jul 2016
+ created 11 Jul 2016
  by Andreas Rix (DL9LJ)

  */


fixed CRC calculation

fixed CRC calculation

--- reciever/reciever.ino
+++ reciever/reciever.ino
@@ -48,11 +48,13 @@
 // G0-H3 - humidity written backwards as 100 - HUMIDITY in two's compliment code, for example:
 //          1110|1011 = 59% because 101001 (inverted all bits and add 1) = 41, and 100 - 41 = 59
 //
-// I0-I3 - 4 less significant bits of check sum of the tetrads T1-T8 written backwards.
+// I0-I3 - 4 check sum which is calculated as a sum of less significant bits
+//            of check sum of the tetrads T1-T8 written backwards.
 //            for example let's look at the example message:
-//            1011|1100|0000|0101|0011|0000|0001|1011|1101
-//            sum of the tetrad T1-T8 = 101011, lets take last 4 bits and wrote them backward:
-//            1101 which is equal T9 tetrad
+//            1011|1100|0100|0000|1111|0000|0010|1111|0010
+//            sum of the tetrad T1-T8 where each bit written backwards = 110100,
+//            lets take last 4 bits and wrote them backward:
+//            0010 which is equal to T9 tetrad

 volatile byte data[DATA_ARRAY_SIZE] = {0, 0, 0, 0, 0, 0, 0, 0, 0};

@@ -176,7 +178,7 @@
     //Sum first 8 tetrads
     int sum = 0;
     for (byte i = 0; i < DATA_ARRAY_SIZE - 1; i++) {
-        sum += (int)data[i];
+        sum += getLastFourBitsReversed(data[i]);
     }

     //returns true if calculated check sum matches received
@@ -193,10 +195,10 @@

     if ((data[5] & 1) == 1) {
         //negative number, use two's compliment conversion
-        temperature = (~temperature + 1);
+        temperature = ~temperature + 1;

         //clear higher bits
-        temperature = temperature & 4096;
+        temperature = temperature & 4095;
     }

     return temperature;
@@ -259,8 +261,8 @@
 }

 //Whether pulse length value matches specified constant with specified threshold
-boolean match(int value, int mathConst, int treshold) {
-    return value > mathConst - treshold && value < mathConst + treshold;
+boolean match(int value, int mathConst, int threshold) {
+    return value > mathConst - threshold && value < mathConst + threshold;
 }

 //set state to new value but only when condition is true
@@ -270,3 +272,4 @@

+


current init config

current init config

--- init.ino
+++ init.ino
@@ -94,23 +94,24 @@

 void led_man_queue() {
 	// manually queue animations for startup
-  thread_handler.queue(new Animation_Simple_DeskWhitePurpleFade());
-	//thread_handler.queue(new Animation_Static_DeskThirdDimAmbient());
-	//thread_handler.queue(new Animation_Simple_Indiv_Rainbow(&desk1));
-	//thread_handler.queue(new Animation_Simple_Indiv_Rainbow(&desk2));

-	//thread_handler.queue(new Animation_Holiday_Halloween_WinAllHalloweenSparkle());
+	// thread_handler.queue(new Animation_Simple_DeskWhitePurpleFade());
+	thread_handler.queue(new Animation_Static_Indiv_ThirdDimAmbient(&desk2));
+	thread_handler.queue(new Animation_Simple_Indiv_RainbowCycle(&desk1));
+	// thread_handler.queue(new Animation_Simple_Indiv_RainbowCycle(&desk2));

-	//thread_handler.queue(new Animation_Seasonal_Winter_WindowSnow(&window1));
-	//thread_handler.queue(new Animation_Seasonal_Winter_WindowSnow(&window3));
+	// thread_handler.queue(new Animation_Holiday_Halloween_WinAllHalloweenSparkle());

-	thread_handler.queue(new Animation_Simple_Indiv_CalmPurpleFade(&window1));
-	//thread_handler.queue(new Animation_Simple_Indiv_CalmPurpleFade(&window2));
-	thread_handler.queue(new Animation_Simple_Indiv_CalmPurpleFade(&window3));
+	// thread_handler.queue(new Animation_Seasonal_Winter_WindowSnow(&window1));
+	// thread_handler.queue(new Animation_Seasonal_Winter_WindowSnow(&window3));

-	//thread_handler.queue(new Animation_Simple_Indiv_RainbowCycle(&window1));
-	thread_handler.queue(new Animation_Simple_Indiv_RainbowCycle(&window2));
-	//thread_handler.queue(new Animation_Simple_Indiv_RainbowCycle(&window3));
+	// thread_handler.queue(new Animation_Simple_Indiv_CalmPurpleFade(&window1));
+	// thread_handler.queue(new Animation_Simple_Indiv_CalmPurpleFade(&window2));
+	// thread_handler.queue(new Animation_Simple_Indiv_CalmPurpleFade(&window3));

-	thread_handler.queue(new Animation_Advanced_Audio_BeatWindowPulse());
+	// thread_handler.queue(new Animation_Simple_Indiv_RainbowCycle(&window1));
+	// thread_handler.queue(new Animation_Simple_Indiv_RainbowCycle(&window2));
+	// thread_handler.queue(new Animation_Simple_Indiv_RainbowCycle(&window3));
+
+	thread_handler.queue(new Animation_Advanced_Audio_MaxEqualizerWindow());
 }