TX9/RX8 + use bytes

TX9/RX8 + use bytes

--- dummycomm.ino
+++ dummycomm.ino
@@ -5,14 +5,14 @@
 */

 #define LED 13
-#define BTX 8
-#define BRX 9
+#define BTX 9
+#define BRX 8
 #define CARRIER 2
 #define ERROR -1

 int sleepms = 20;
-int bytebits[8];
-int bytesbuf[256];
+byte bytebits[8];
+byte bytesbuf[256];

 void setup() {
 	pinMode(LED, OUTPUT);


Disabled sensor jack disconnection detection since it doesn't quite work how we want it to.

--- Sensorizer.ino
+++ Sensorizer.ino
@@ -245,7 +245,11 @@
         byte pinIdx = analogPin - ANALOG_PIN_START;
         int val;

-        if (isSensorPluggedIn(analogPin)) {
+
+        // so the problem is that isSensorPluggedIn() only detects whether the foot pedal is plugged in, not the rest of the DrumPads.
+        // and the problem with that is if they press all the way down on the foot pedal, it will register as disconnected.
+        // therefore we should not use this method as of yet.
+        if (true) { //isSensorPluggedIn(analogPin)) {
           val = analogRead(analogPin);
         }
         else {


moved data conversion to sync

moved data conversion to sync

sill som packet loss

--- VertigoLED.ino
+++ VertigoLED.ino
@@ -6,6 +6,11 @@
 #include <ArtNode.h>
 #include "ArtNetFrameExtension.h"
 #include "OctoWS2811.h"
+
+
+#if F_BUS < 60000000
+#error "Teensy needs to run at 120MHz to read all packets in time"
+#endif

 #include "TeensyMAC.h"
 #include <EEPROM.h>
@@ -35,7 +40,7 @@
 #define NUM_PIXELS_PR_STRIP 384  //3 DMX universes * 512 = 1536
                             //1536/4 = 384
                             //384/144 = 2.6 meter
-
+uint32_t dmxMemory[NUM_PIXELS_PR_STRIP*8];
 DMAMEM uint32_t displayMemory[NUM_PIXELS_PR_STRIP*8];
 uint32_t drawingMemory[NUM_PIXELS_PR_STRIP*8];

@@ -55,7 +60,7 @@
   0, 0,                                 // Net (0-127) and subnet (0-15)
   "VertigoLED",                           // Short name
   "VertigoLED",                           // Long name
-  15,                                    // Number of ports
+  18,                                    // Number of ports
   {PortTypeDmx | PortTypeOutput,
   PortTypeDmx | PortTypeOutput,
   PortTypeDmx | PortTypeOutput,
@@ -166,7 +171,7 @@
   // Open ArtNet
   node = ArtNodeExtended(config, sizeof(udp_buffer), udp_buffer);

-  Serial.begin(250000);
+  Serial.begin(230400);
   LEDS.begin();
   LEDS.show();

@@ -198,14 +203,18 @@
                 bitSet(portSyncFlag, port);
                 uint16_t portOffset = port*128;
                 //write the dmx data to the Octo frame buffer
-                uint32_t* data = (uint32_t*) dmx->Data;
+                //uint32_t* dmxData = (uint32_t*) dmx->Data;
                 for (int i = 0; i < 128; i++) {
-                  LEDS.dmxPixel(i+portOffset, data[i]);
+                  memcpy(dmxMemory+portOffset+i, dmx->Data+i*4, 32);
+                  //LEDS.dmxPixel(i+portOffset, data[i]);
                 }
               }
               break;}
             // OpSync
             case 0x5200: {
+              for (int i = 0; i < 128*config.numPorts; i++) {
+                LEDS.dmxPixel(i, dmxMemory[i]);
+              }
               LEDS.show();
               syncFps++;
               //Serial.println(portSyncFlag,BIN);


better error checking during json parsing (#150)

--- examples/ws2812fx_patterns_web/ws2812fx_patterns_web.ino
+++ examples/ws2812fx_patterns_web/ws2812fx_patterns_web.ino
@@ -43,7 +43,7 @@
 #include <EEPROM.h>
 #include <ArduinoOTA.h>

-#define VERSION "2.0.7"
+#define VERSION "2.0.8"

 uint8_t  dataPin = D1; // default digital pin used to drive the LED strip
 uint16_t numLeds = 30; // default number of LEDs on the strip
@@ -215,8 +215,9 @@
     String data = server.arg("plain");
     Serial.println(data);

-    json2patterns(data.c_str());
-    if (numPatterns > 0) {
+    bool isParseOk = json2patterns(data.c_str());
+
+    if (isParseOk && numPatterns > 0) {
       ws2812fx.stop();
       ws2812fx.clear();
       ws2812fx.resetSegments();
@@ -275,7 +276,7 @@

 #if ARDUINOJSON_VERSION_MAJOR == 5
 //#pragma message("Compiling for ArduinoJson v5")
-void json2patterns(const char* json) {
+bool json2patterns(const char* json) {
   DynamicJsonBuffer jsonBuffer(2000);
   JsonObject& deviceJson = jsonBuffer.parseObject(json);
   if (deviceJson.success()) {
@@ -341,18 +342,21 @@
         if (numPatterns >= MAX_NUM_PATTERNS) break;
       }
     } else {
-      Serial.println("JSON contains no pattern data");
+      Serial.println(F("JSON contains no pattern data"));
+      return false;
     }
   } else {
-    Serial.println("Could not parse JSON payload");
-  }
+    Serial.println(F("Could not parse JSON payload"));
+    return false;
+  }
+  return true;
 }
 #endif

 #if ARDUINOJSON_VERSION_MAJOR == 6
 //#pragma message("Compiling for ArduinoJson v6")
-void json2patterns(const char* json) {
-  DynamicJsonDocument doc;
+bool json2patterns(const char* json) {
+  DynamicJsonDocument doc(2000);
   DeserializationError error = deserializeJson(doc, json);
   if (!error) {
     JsonObject deviceJson = doc.as<JsonObject>();
@@ -419,10 +423,14 @@
         if (numPatterns >= MAX_NUM_PATTERNS)  break;
       }
     } else {
-      Serial.println("JSON contains no pattern data");
+      Serial.println(F("JSON contains no pattern data"));
+      return false;
     }
   } else {
-    Serial.println("Could not parse JSON payload");
-  }
+    Serial.print(F("Could not parse JSON payload: "));
+    Serial.println(error.c_str());
+    return false;
+  }
+  return true;
 }
 #endif


Complete mcp2515 canbus reveive sleep example

--- examples/receive_sleep/receive_sleep.ino
+++ examples/receive_sleep/receive_sleep.ino
@@ -15,7 +15,7 @@
 //   will retransmit the same message a few times. See below for a simple solution to filter duplicate messages out.

 #include <SPI.h>
-#include "mcp_can.h"
+#include "mcp2515_can.h"
 #include <avr/sleep.h>

 /*SAMD core*/
@@ -35,7 +35,7 @@
 #define RS_TO_MCP2515 true                                   // Set this to false if Rs is connected to your Arduino
 #define RS_OUTPUT MCP_RX0BF                                  // RX0BF is a pin of the MCP2515. You can also define an Arduino pin here

-MCP_CAN CAN(SPI_CS_PIN);                                    // Set CS pin
+mcp2515_can CAN(SPI_CS_PIN); // Set CS pin

 #define KEEP_AWAKE_TIME 200                                  // time the controller will stay awake after the last activity on the bus (in ms)
 unsigned long lastBusActivity = millis();


Examples: Sound Level Meter: another tweak to cal factor

--- examples/02-Utility/SoundLevelMeter/SoundLevelMeter.ino
+++ examples/02-Utility/SoundLevelMeter/SoundLevelMeter.ino
@@ -37,7 +37,7 @@

 //calibraiton information for the microphone being used
 //float32_t mic_cal_dBFS_at94dBSPL_at_0dB_gain = -47.4f ;  //PCB Mic, http://openaudio.blogspot.com/search/label/Microphone
-float32_t mic_cal_dBFS_at94dBSPL_at_0dB_gain = -47.4f + 8.4575;  //PCB Mic baseline with manually tested adjustment.   Baseline:  http://openaudio.blogspot.com/search/label/Microphone
+float32_t mic_cal_dBFS_at94dBSPL_at_0dB_gain = -47.4f + 9.2175;  //PCB Mic baseline with manually tested adjustment.   Baseline:  http://openaudio.blogspot.com/search/label/Microphone

 //other variables
 #define BOTH_SERIAL audioHardware


firmware: print newline when writing firmware finished

--- firmware/firmware.ino
+++ firmware/firmware.ino
@@ -80,12 +80,14 @@
                 Serial.println(inputString);
             }
             else {
-                if(maxim.hasEOFBeenReached())
-                    writingToFlash = false;
                 Serial.print(".");
                 flashLinesWritten++;
                 if(flashLinesWritten>80) {
                     flashLinesWritten = 0;
+                    Serial.println();
+                }
+                if(maxim.hasEOFBeenReached()) {
+                    writingToFlash = false;
                     Serial.println();
                 }
             }


disconnect the wifi module from the AP to conserve energy and delay 2 min

--- firmware/firmware.ino
+++ firmware/firmware.ino
@@ -103,8 +103,11 @@
     }
   }

+  // disconnect from the AP to conserve energy
+  network.send_command("AT+CWQAP", "OK", 2, 1500);

 	Serial.println(F("Waiting 20 seconds ..."));
-	delay(20000);
+	delay(60000); // maxes out at 1 min apartenly..
+  delay(60000);

 }


Kleine aanpassing

Kleine aanpassing

--- src/Arduino/voorbeeld_registers/voorbeeld_registers.ino
+++ src/Arduino/voorbeeld_registers/voorbeeld_registers.ino
@@ -1,4 +1,3 @@
-
 #define USEDPINS_PORTB 0xE0 //b1110 0000
 #define USEDPINS_PORTD 0x0C //b0000 1100
 #define USEDPINS_PORTE 0x38 //b0011 1000
@@ -188,27 +187,27 @@
  //Dit is gewoon om de status van de poorten te printen in de seriële console.
  //DEBUG, Niet nodig in finale code
 void printStatusPorts() {
-  Serial.print("PORTB: ");
+  Serial.print("PORTB: 0x");
   Serial.print(PORTB, HEX);
   Serial.print("=>");
   Serial.println(PORTB, BIN);

-  Serial.print("PORTD: ");
+  Serial.print("PORTD: 0x");
   Serial.print(PORTD, HEX);
   Serial.print("=>");
   Serial.println(PORTD, BIN);

-  Serial.print("PORTE: ");
+  Serial.print("PORTE: 0x");
   Serial.print(PORTE, HEX);
   Serial.print("=>");
   Serial.println(PORTE, BIN);

-  Serial.print("PORTH: ");
+  Serial.print("PORTH: 0x");
   Serial.print(PORTH, HEX);
   Serial.print("=>");
   Serial.println(PORTH, BIN);

-  Serial.print("PORTJ: ");
+  Serial.print("PORTJ: 0x");
   Serial.print(PORTJ, HEX);
   Serial.print("=>");
   Serial.println(PORTJ, BIN);


working pid, however pan/tilt will fail mysteriously, probably m probably memory issues

--- controller/controller.ino
+++ controller/controller.ino
@@ -14,8 +14,14 @@
 // Library : https://github.com/DerekK19/Arduino/tree/master/libraries/ServoTimer2
 #include <ServoTimer2.h>

+// PID controllers for wheels
+// #include <PID_v1.h> // Couldn't use, ran out of memory, using function-based PID
+
+#define ROS_SERIAL_BAUD_RATE 115200 // Rosserial baud rate 115200 bps for example
+
 // Distance between both wheels
 #define WHEEL_OFFSET_M 0.0889 // 3.5" ~ 8.89cm
+#define HALF_WHEEL_OFFSET_M 0.04445 // distance from center to wheel along turning axis

 #define MAX_REAL_SPEED 0.65 // m/s
 #define MAX_MOTOR_SPEED 400.0 // RPM
@@ -28,16 +34,22 @@
 #define BATTERY_VOLTAGE_PUBLISH_RATE 1000 // ms (publish voltage every second)

 // Encoders
-#define ENCODER_LEFT_PIN_A 2
-#define ENCODER_LEFT_PIN_B 11
-
-#define ENCODER_RIGHT_PIN_A 3
-#define ENCODER_RIGHT_PIN_B 4
-
-// #define TICKS_PER_REV 380 // ticks for one wheel revolution
+#define ENCODER_LEFT_PIN_A 3
+#define ENCODER_LEFT_PIN_B 4
+
+#define ENCODER_RIGHT_PIN_A 2
+#define ENCODER_RIGHT_PIN_B 11
+
+
+#define TICKS_PER_REV 379 // ticks for one wheel revolution
 #define TICKS_PER_METER 3110 // 790 ticks for 10 inches, 790 ticks per .254m ~ 3110.23622 ticks/meter
-
-#define WHEEL_VEL_PUBLISH_RATE 50 // ms (20Hz)
+#define METERS_PER_REV 0.12186495176848874 // meters per full revolution
+#define REV_PER_METER 8.20580474934037 // revolutions per meter
+
+
+#define WHEEL_VEL_PUBLISH_RATE 100 // ms (10Hz)
+#define MOTOR_PID_RATE 20 // ms (50Hz) PID Motor update rate (Should be < WHEEL_VEL_PUBLISH_RATE)
+#define MOTOR_SPEED_CUTOFF 20 // lowest motor speed at which to zero it

 // Pan Tilt Servo pins
 #define SERVO_PAN_PIN 5 // Pan
@@ -106,18 +118,29 @@
 unsigned long encoder_last_velocity_time = 0; // microseconds
 long last_wheel_ticks_published = 0;

+// Motor PIDs
+double pid_left_input = 0, pid_left_output = 0, pid_left_setpoint = 0;
+double pid_right_input = 0, pid_right_output = 0, pid_right_setpoint = 0;
+
+// PID pid_left(&pid_left_input, &pid_left_output, &pid_left_setpoint, 20, 500, 0, DIRECT);
+// PID pid_right(&pid_right_input, &pid_right_output, &pid_right_setpoint, 20, 500, 0, DIRECT);
+unsigned long last_motor_pid_updated = 0;
+
+
 // Encoder tick publishers
 std_msgs::Float32 wheel_vel;
 ros::Publisher lwheel_pub("wheel_velocity/left", &wheel_vel);
 ros::Publisher rwheel_pub("wheel_velocity/right", &wheel_vel);

 // Publish left and right wheel encoder ticks
-void publichWheelVelocity() {
-  updateWheelPositionVelocity();
-  wheel_vel.data = encoder_left_velocity;
+void publishWheelVelocity() {
+  // updateWheelPositionVelocity();
+
+  // encoder velocities are in rev/sec, convert to m/s
+  wheel_vel.data = encoder_left_velocity * METERS_PER_REV;
   lwheel_pub.publish(&wheel_vel);

-  wheel_vel.data = encoder_right_velocity;
+  wheel_vel.data = encoder_right_velocity * METERS_PER_REV;
   rwheel_pub.publish(&wheel_vel);
 }

@@ -133,6 +156,7 @@

 // Command Velocity Callback
 void cmd_vel_callback( const geometry_msgs::Twist& twist_msg) {
+  // messages in meters per second
   diff_drive(twist_msg.linear.x, twist_msg.angular.z);
 }

@@ -161,19 +185,22 @@
   }

   // Attach Encoder Interrupts
-  attachInterrupt(0, measureLeftEncoder, CHANGE); // 0 = pin 2 interrupt
-  attachInterrupt(1, measureRightEncoder, CHANGE); // 1 = pin 3 interrupt
+  attachInterrupt(1, measureLeftEncoder, CHANGE); // 1 = pin 3 interrupt
+  attachInterrupt(0, measureRightEncoder, CHANGE); // 0 = pin 2 interrupt

   // Left motor power wiring is reversed.
   motors.flipLeftMotor(true);

   // Initial speed is zero
-  drive_stop();
-
+  drive(0, 0);
+
+  // Initialize PIDs
+  initPIDs();

   // Init pan/tilt to center
-  setZero();
-
+  setPanTiltZero();
+
+  nh.getHardware()->setBaud(ROS_SERIAL_BAUD_RATE);
   nh.initNode();
   nh.advertise(battery_pub); // Battery Voltage Publisher

@@ -186,7 +213,6 @@
     nh.subscribe(pan_tilt_sub); // Pan/Tilt Subscriber
   }

-
   last_battery_published = millis();
 }

@@ -202,36 +228,39 @@
   // Publish encoder at 100 Hz
   if (millis() - last_wheel_ticks_published > WHEEL_VEL_PUBLISH_RATE)
   {
-    publichWheelVelocity();
+    publishWheelVelocity();
     last_wheel_ticks_published = millis();
   }

+  if (millis() - last_motor_pid_updated > MOTOR_PID_RATE)
+  {
+    updateMotorPIDs();
+    last_motor_pid_updated = millis();
+  }
+
   nh.spinOnce();
 }

 ////////////////////////////////////////////////////////////////////////////////
-// Motor drive speeds
-int vl = 0, vr = 0;
-
-// cmd_x  : linear x velocity (forward velocity)
-// cmd_th : angular z velocity (rotation of heading)
+// Motor drive
+
+// cmd_x  : linear x velocity (forward velocity) m/s
+// cmd_th : angular z velocity (rotation of heading) rad/s
 void diff_drive(double cmd_x, double cmd_th) {
-  vl = (cmd_x - cmd_th * WHEEL_OFFSET_M / 2.0) * MAX_MOTOR_SPEED / MAX_REAL_SPEED;
-  vr = (cmd_x + cmd_th * WHEEL_OFFSET_M / 2.0) * MAX_MOTOR_SPEED / MAX_REAL_SPEED;
-  drive();
-}
-
-// Drive left and right wheel motors vased on vl and vr
-void drive() {
-  motors.setLeftSpeed(vl);
-  motors.setRightSpeed(vr);
-}
-
-// Stops motors
-void drive_stop() {
-  vl = 0;
-  vr = 0;
-  drive();
+  // cmd_x in m/s
+  double vl = cmd_x - cmd_th * HALF_WHEEL_OFFSET_M;
+  double vr = cmd_x + cmd_th * HALF_WHEEL_OFFSET_M;
+
+  // velocities in m/s, convert to rev/s
+  pid_left_setpoint = vl * REV_PER_METER;
+  pid_right_setpoint = vr * REV_PER_METER;
+  // values used by PID loop
+}
+
+void drive(int lspeed, int rspeed)
+{
+  motors.setLeftSpeed(lspeed);
+  motors.setRightSpeed(rspeed);
 }

 // Battery Voltage
@@ -249,7 +278,6 @@
         else {encoder_left_ticks++;}
     }
     encoder_left_pin_A_last = encoder_left_val;
-    // updateWheelPositionVelocity();
 }

 void measureRightEncoder()
@@ -261,8 +289,8 @@
         else {encoder_right_ticks++;}
     }
     encoder_right_pin_A_last = encoder_right_val;
-    // updateWheelPositionVelocity();
-}
+}
+

 void updateWheelPositionVelocity()
 {
@@ -272,10 +300,14 @@
   long dleft = encoder_left_ticks - encoder_left_ticks_old;
   long dright = encoder_right_ticks - encoder_right_ticks_old;

-  // Velocity in meters/second
+  // Velocity in rev/second
   // 1e6 because dt is in microseconds
-  encoder_left_velocity = (float)(1000000*dleft) / (TICKS_PER_METER * dt);
-  encoder_right_velocity = (float)(1000000*dright) / (TICKS_PER_METER * dt);
+  encoder_left_velocity = (float)(1000000*dleft) / (TICKS_PER_REV * dt);
+  encoder_right_velocity = (float)(1000000*dright) / (TICKS_PER_REV * dt);
+
+  // Update PID inputs
+  pid_left_input = (double)encoder_left_velocity;
+  pid_right_input = (double)encoder_right_velocity;

   // Update previous values
   encoder_left_ticks_old = encoder_left_ticks;
@@ -283,14 +315,44 @@
   encoder_last_velocity_time = micros();
 }

+void updateMotorPIDs()
+{
+  // Update wheel velocities (pid inputs)
+  updateWheelPositionVelocity();
+
+  // run pid controller, setting pid outputs
+  // pid_left.Compute();
+  // pid_right.Compute();
+  doLeftPID();
+  doRightPID();
+
+  // If desired motor speed is less than threshold, zero it out
+  if (abs(pid_left_output) < MOTOR_SPEED_CUTOFF) { pid_left_output = 0; }
+  if (abs(pid_right_output) < MOTOR_SPEED_CUTOFF) { pid_right_output = 0; }
+
+  // Set motor speeds
+  motors.setLeftSpeed(pid_left_output);
+  motors.setRightSpeed(pid_right_output);
+}
+
+// Init PIDs for zumo motors
+void initPIDs()
+{
+  // Init setpoints in case they aren't yet set
+  pid_left_setpoint = 0;
+  pid_right_setpoint = 0;
+
+  // pid_left.SetMode(AUTOMATIC);
+  // pid_left.SetOutputLimits(-400,400);
+  // pid_left.SetSampleTime(20);
+  // pid_right.SetMode(AUTOMATIC);
+  // pid_right.SetOutputLimits(-400,400);
+  // pid_right.SetSampleTime(20);
+}

 // Smoothly move to pan tilt pos 0-100 range for both (50 centered)
 void moveTo(int pan, int tilt)
 {
-  if (vl != 0 || vr != 0) {
-    // WARNING
-    // Left Encoder will miss steps due to the delay in this while loop!
-  }
   while (abs(pan_pos - pan) + abs(tilt_pos - tilt) > 0) {
     pan_pos += pan_pos > pan ? -1 : pan_pos < pan ? 1 : 0;
     tilt_pos += tilt_pos > tilt ? -1 : tilt_pos < tilt ? 1 : 0;
@@ -309,7 +371,7 @@
 }

 // Center Pan/Tilt servos
-void setZero()
+void setPanTiltZero()
 {
   moveTo(50,50);
 }
@@ -325,4 +387,55 @@
 {
   tilt_deg = constrain(tilt_deg, SERVO_TILT_MIN, SERVO_TILT_MAX);
   servo_tilt.write(map(tilt_deg, 0, 180, ST2_MIN, ST2_MAX));
+}
+
+
+#define PID_OUTMIN -400
+#define PID_OUTMAX 400
+
+#define KP 20
+#define KI 10 // 500 * 20ms = 10
+#define KD 0
+
+// Had to do PIDs unclassed manually since we're running out of memory.
+double left_ITerm = 0;
+double left_lastInput = 0;
+void doLeftPID()
+{
+    /* Compute all the working error variables */
+    double error = pid_left_setpoint - pid_left_input;
+    left_ITerm += (KI * error);
+    if(left_ITerm > PID_OUTMAX) left_ITerm= PID_OUTMAX;
+    else if(left_ITerm < PID_OUTMIN) left_ITerm= PID_OUTMIN;
+    double dInput = (pid_left_input - left_lastInput);
+
+    /* Compute PID Output */
+    pid_left_output = KP * error + left_ITerm- KD * dInput;
+
+    if(pid_left_output > PID_OUTMAX) pid_left_output = PID_OUTMAX;
+    else if(pid_left_output < PID_OUTMIN) pid_left_output = PID_OUTMIN;
+
+    /* Remember some variables for next time */
+    left_lastInput = pid_left_input;
+}
+
+double right_ITerm = 0;
+double right_lastInput = 0;
+void doRightPID()
+{
+    /* Compute all the working error variables */
+    double error = pid_right_setpoint - pid_right_input;
+    right_ITerm += (KI * error);
+    if(right_ITerm > PID_OUTMAX) right_ITerm= PID_OUTMAX;
+    else if(right_ITerm < PID_OUTMIN) right_ITerm= PID_OUTMIN;
+    double dInput = (pid_right_input - right_lastInput);
+
+    /* Compute PID Output */
+    pid_right_output = KP * error + right_ITerm- KD * dInput;
+
+    if(pid_right_output > PID_OUTMAX) pid_right_output = PID_OUTMAX;
+    else if(pid_right_output < PID_OUTMIN) pid_right_output = PID_OUTMIN;
+
+    /* Remember some variables for next time */
+    right_lastInput = pid_right_input;
 }


use official irq api

use official irq api

--- gamecubecontroller.ino
+++ gamecubecontroller.ino
@@ -134,20 +134,6 @@
   } while(bits);
 }

-void disableIRQ() {
-  __asm volatile
-  (
-      " CPSID   I        \n"
-  );
-}
-
-void enableIRQ() {
-  __asm volatile
-  (
-      " CPSIE   I        \n"
-  );
-}
-
 // bits must be greater than 0
 uint8_t gameCubeReceiveBits(void* data0, uint32_t bits) {
   uint8_t* data = (uint8_t*)data0;
@@ -187,16 +173,16 @@

 uint8_t gameCubeReceiveReport(GameCubeData_t* data, uint8_t rumble) {
   if (fails >= maxFails) {
-    disableIRQ();
+    nvic_globalirq_disable();
     gameCubeSendBits(0b000000001l, 9);
-    enableIRQ();
+    nvic_globalirq_enable();
     delayMicroseconds(400);
     fails = 0;
   }
-  disableIRQ();
+  nvic_globalirq_disable();
   gameCubeSendBits(rumble ? 0b0100000000000011000000011l : 0b0100000000000011000000001l, 25);
   uint8_t success = gameCubeReceiveBits(data, 64);
-  enableIRQ();
+  nvic_globalirq_enable();
   if (success && 0 == (data->buttons & 0x80) && (data->buttons & 0x8000) ) {
     gpio_write_bit(ledPort, ledPin, 0);
     return 1;
@@ -235,13 +221,11 @@
     }
   }

-  iwdg_feed();
   if (savedInjectionMode != injectionMode && (millis()-lastChangedModeTime) >= saveInjectionModeAfterMillis) {
     saveInjectionMode(injectionMode);
     savedInjectionMode = injectionMode;
   }

-  iwdg_feed();
   if (gameCubeReceiveReport(&data, 0)) {
 #ifdef SERIAL_DEBUG
     Serial.println("buttons1 = "+String(data.buttons));
@@ -249,7 +233,6 @@
     Serial.println("c-stick = "+String(data.cX)+","+String(data.cY));
     Serial.println("shoulders = "+String(data.shoulderLeft)+","+String(data.shoulderRight));
 #else
-    iwdg_feed();
     inject(injectors + injectionMode, &data);
 #endif
   }


update test program with new functions

update test program with new functions

--- test/test_led/test_led.ino
+++ test/test_led/test_led.ino
@@ -1,11 +1,10 @@
-#include "StreamController.h"
-#include "Dynamixel.h"
+#include <StreamController.h>
+#include <Dynamixel.h>

 SerialController Controller;
 DynamixelInterface Dynamixel(Serial, Controller);
 DynamixelDevice device(Dynamixel, BROADCAST_ID);
-bool on=true;
-uint8_t buffer[256];
+uint8_t on=true;

 void setup() {
   Serial.begin(1000000);
@@ -13,8 +12,7 @@
 }

 void loop() {
-   buffer[1]=on;
-   device.write(0x19, 1, buffer+1);
+   device.write(0x19, on);
    on=!on;
    delay(1000);
 }


Only return values on API call '/api/timezone'.

--- webserver.ino
+++ webserver.ino
@@ -204,7 +204,7 @@
       updateChannels();
       writeConfigFile();
     }
-    webServer.send( 200, FPSTR( textplainHEADER ), "Timezone is " + String( timeZone ) );
+    webServer.send( 200, FPSTR( textplainHEADER ), String( timeZone ) );
   });

   webServer.on( "/api/upload", HTTP_POST, []() {


Reverted changes in arduino code

Reverted changes in arduino code

--- arduino/arduino.ino
+++ arduino/arduino.ino
@@ -44,8 +44,8 @@
   send_message.concat(message);

   // Add and calculate checksum
-  byte byteBuf[send_length+3];
-  send_message.getBytes(byteBuf, send_length+3);
+  byte byteBuf[send_length+4];
+  send_message.getBytes(byteBuf, send_length+4);
   byte checksum = CRC8(byteBuf, send_length+3);
   send_message.concat(char(checksum));


Fixed lunar cycle.

Fixed lunar cycle.

--- dimmertask.ino
+++ dimmertask.ino
@@ -87,17 +87,12 @@
         }

         /* check if channel has a minimum set */
-        if ( newPercentage < channel[channelNumber].minimumLevel )
-        {
-          if ( MOON_SIMULATOR )
-          {
-            newPercentage = channel[channelNumber].minimumLevel * moonData.percentLit;
-          }
-          else
-          {
-            newPercentage = channel[channelNumber].minimumLevel;
-          }
-        }
+        if ( !MOON_SIMULATOR && newPercentage < channel[channelNumber].minimumLevel )
+          newPercentage = channel[channelNumber].minimumLevel;
+
+        /* calculate moon light */
+        if ( MOON_SIMULATOR && newPercentage < ( channel[channelNumber].minimumLevel * moonData.percentLit ) )
+          newPercentage = channel[channelNumber].minimumLevel * moonData.percentLit;

         /* done, set the channel */
         channel[channelNumber].currentPercentage = newPercentage;


some ints to bytes. Free RAM 140 to 143.

--- jemmaclock/jemmaclock.ino
+++ jemmaclock/jemmaclock.ino
@@ -170,19 +170,19 @@

 // the first byte (address 0) of the EEPROM
 // EEPROM addresses, 0 to 255
-static int eepromAddress0 = 0; // first run?
+static byte eepromAddress0 = 0; // first run?
 byte eepromDefaultsExist;
-static int eepromAddress1 = 1; // timezone
+static byte eepromAddress1 = 1; // timezone
 byte eepromTimeZone;
-static int eepromAddress2 = 2; // daylight time
+static byte eepromAddress2 = 2; // daylight time
 byte eepromDaylightTime;
-static int eepromAddress3 = 3; // brightness
+static byte eepromAddress3 = 3; // brightness
 byte eepromBrightness;
-static int eepromAddress4 = 4; // 24 hour (0) or 12 hour (1)
+static byte eepromAddress4 = 4; // 24 hour (0) or 12 hour (1)
 byte eepromTimeFormat;
-static int eepromAddress5 = 5; // 2014-12-25 (0), 12/25/2014 (1), 25/12/2014 (2)
+static byte eepromAddress5 = 5; // 2014-12-25 (0), 12/25/2014 (1), 25/12/2014 (2)
 byte eepromDateFormat;
-static int eepromAddress6 = 6; // slide left to right (0), bounce left or right (1)
+static byte eepromAddress6 = 6; // slide left to right (0), bounce left or right (1)
 byte eepromClockFormat;

 byte statConfMenu = 0; // status: are we displaying configuration menu?
@@ -191,8 +191,8 @@
 int switchDaylightTime = A1;                   // flip to enable Daylight Time
 //A2 unused
 // A4 and A5 for i2c
-int potentiometerTimezone = 6;     //  input pin for the TimeZone potentiometer
-int potentiometerBrightness = 7;   // input pin for the Brightness potentiometer
+byte potentiometerTimezone = 6;     //  input pin for the TimeZone potentiometer
+byte potentiometerBrightness = 7;   // input pin for the Brightness potentiometer
 #define ANTENNALED 4;
 //int nmeaRx = 2;

@@ -213,7 +213,7 @@
 // likely to occur is in sections of code associated with interrupts, called
 // an interrupt service routine."

-volatile int pps_loop =0;
+volatile byte pps_loop = 0;
 void pps_interrupt(){
   // if we're not in the configuration menu and we have a good fix,
   if ( (!statConfMenu) && (gps.time.isValid()) )   {


Time DS1302 LCD 5110 v2 - added space value for print strings with variable length

--- time_ds1302_lcd_5110_v2/time_ds1302_lcd_5110_v2.ino
+++ time_ds1302_lcd_5110_v2/time_ds1302_lcd_5110_v2.ino
@@ -34,27 +34,31 @@
 #include "Cyruit_PCD8544.h"
 #include "Cyruit.h"

-// D3 - LCD 1 - reset (RST)
-// D4 - LCD 2 - chip select (CS)
+// Vcc = 3.3V
+// GND and Light on GND pin
+
+// Software SPI (slower updates, more flexible pin options):
+// D7 - LCD 1 - reset (RST)
+// D6 - LCD 2 - chip select (CS)
 // D5 - LCD 3 - Data/Command select (D/C)
-// D6 - LCD 4 - Serial data out (DIN)
-// D7 - LCD 5 - Serial clock out (SCLK)
+// D4 - LCD 4 - Serial data out (DIN)
+// D3 - LCD 5 - Serial clock out (SCLK)
 Cyruit_PCD8544 lcd = Cyruit_PCD8544(3, 4, 5, 6, 7);
 Cyruit display = Cyruit(&lcd, 84, 48, 6, 8);

 #include "Time.h"
 #include "DS1302RTC.h"
+#define DS1302_VCC_PIN 8
+#define DS1302_GND_PIN 9
 // Set pins:  CE, IO,CLK
 DS1302RTC RTC(12, 11, 10);
-#define DS1302_GND_PIN 9
-#define DS1302_VCC_PIN 8

 const char hello_str[] PROGMEM = "доброї ночі\rдоброго ранку\rдоброго дня\rдоброго вечора";

 void setup() {
   lcd.begin();
-  lcd.setContrast(51);
+  lcd.setContrast(60);

   digitalWrite(DS1302_GND_PIN, LOW);
   pinMode(DS1302_GND_PIN, OUTPUT);
@@ -77,10 +81,10 @@

   display.print(tm.Day, 0, 0);
   display.init(F("січня\rлютого\rберезня\rквітня\rтравня\rчервня\rлипня\rсерпня\rвересня\rжовтня\rлистопада\rгрудня"));
-  display.printn(tm.Month - 1, 3, 0);
+  display.printn(tm.Month - 1, 3, 0, 9);

   display.init(F("неділя\rпонеділок\rвівторок\rсереда\rчетвер\rп'ятниця\rсубота"));
-  display.printn(tm.Wday - 1, -1, 1);
+  display.printn(tm.Wday - 1, -1, 1, 9);

   char buffer[9];
   buffer[8] = 0;


fix rain temperature failure with PID

fix rain temperature failure with PID

--- arduino/sadr_meteo_no_firmata/sadr_meteo_no_firmata.ino
+++ arduino/sadr_meteo_no_firmata/sadr_meteo_no_firmata.ino
@@ -275,14 +275,15 @@
   float average;

   // take N samples in a row, with a slight delay
-  for (i = 0; i < NUMSAMPLES; i++) {
-    samples[i] = analogRead(THERMISTORPIN);
-  }
+  //for (i = 0; i < NUMSAMPLES; i++) {
+  //  samples[i] = analogRead(THERMISTORPIN);
+  //}

   // average all the samples out
   average = 0;
   for (i = 0; i < NUMSAMPLES; i++) {
-    average += samples[i];
+    //average += samples[i];
+    average += analogRead(THERMISTORPIN);
   }
   average /= NUMSAMPLES;

@@ -300,6 +301,7 @@

   return steinhart;
 }
+
 void regulHeat(double Temperature, double Target) {

   double gap = abs(Target - Temperature); //distance away from setpoint
@@ -578,11 +580,15 @@
      }
   }

-  //if ((Temp < HOT_TEMPERATURE_SECURITY) | (Temp > COLD_TEMPERATURE_SECURITY)) {
-  if (Temp < HOT_TEMPERATURE_SECURITY) {
+  if ((Temp <= HOT_TEMPERATURE_SECURITY) | (Temp >= COLD_TEMPERATURE_SECURITY)) {
     regulHeat(Temp, Consigne);
   } else {
-    regulHeat(Temp, -50);
+    if (rainy == 1) {
+        Mosfet = 100;
+    } else {
+        Mosfet = 60;
+    }
+    analogWrite(OUTP, Mosfet);
   }
   #endif //USE_RAIN_SENSOR*/


use binary representations for registry vars

--- super_freq/super_freq.ino
+++ super_freq/super_freq.ino
@@ -20,6 +20,7 @@
 int max_value;
 int sum_fft;
 float frequency;  // only used for debugging
+byte low_byte;

 void setup() {
     if (DEBUG) {
@@ -36,10 +37,14 @@
         set_LED_count_mode = true;
     }

-    //TIMSK0 = 0;           // turn off timer0 for lower jitter
-    ADCSRA = 0xe5;        // set the adc to free running mode
-    ADMUX = 0x40;         // use adc0
-    DIDR0 = 0x01;         // turn off the digital input for adc0
+    // set ADC to free running mode w/ prescaler set to a
+    // division factor of 32 (B101)
+    ADCSRA = B11100101;
+
+    ADMUX = B01000000;  // use adc0
+
+    // turn off the digital input for all analog pins
+    DIDR0 = B00111111;

     // initial color palette
     for (int i = 0; i < 24; i++) {
@@ -76,13 +81,12 @@
          * SAMPLE_RATE / (SKIP_MULT / 2)
          */
         for (int j = 0; j < SKIP_MULT; j++) {
-            while(!(ADCSRA & 0x10)); // wait for adc to be ready
-            ADCSRA = 0xf5;           // restart adc
-        }
-
-        byte m = ADCL;             // fetch ADC data (low byte)
-        byte j = ADCH;             // fetch ADC data (high byte)
-        int k = (j << 8) | m;      // combine low/high bytes to form into an int
+            while(!(ADCSRA & B00010000)); // wait for adc to be ready
+            ADCSRA = B11110101;           // restart adc
+        }
+
+        low_byte = ADCL;           // fetch ADC data (low byte)
+        int k = (ADCH << 8) | low_byte;  // combine low/high bytes to form into an int
         k -= 0x0200;               // form into a signed int
         k <<= 6;                   // form into a 16b signed int
         fft_input[i] = k;          // put real data into even bins


typos in comments

typos in comments

--- 11-OLEDApps/Code/01-DigitalWatch/DigitalWatch.ino
+++ 11-OLEDApps/Code/01-DigitalWatch/DigitalWatch.ino
@@ -267,7 +267,7 @@
     if ((seconds % 2) == 0) // If seconds is even
         oled.print(":");    // Print a colon
     else                    // Otherwise
-        oled.print(" ");    // Print a spaces
+        oled.print(" ");    // Print a space

     // Another printWithLeadZero, this time for minutes.
     printWithLeadZero(minutes, 2);
@@ -352,8 +352,8 @@
     interrupts(); // re-enable interrupts
 }

-// If hour is 0, then it'll draw HH:MM.
-// If hour is greater than 0, it'll draw MM:SS
+// If hour is greater than 0, then it'll draw HH:MM.
+// If hour is 0, it'll draw MM:SS
 void displayTimer(unsigned int hour, unsigned int min, unsigned int sec)
 {
     unsigned int first, second; // variables to track first and second digit
@@ -428,4 +428,4 @@
     }
     // Otherwise return false.
     return false;
-}+}


Updated datalogger.ino

Updated datalogger.ino

Removed excess code. Added comments for explanation.

--- Datalogger.ino
+++ Datalogger.ino
@@ -1,22 +1,18 @@
 #include <Statistic.h>
 Statistic myStats;
-//long double initialReading = 0;
 int sourceSensePin = A0;    // select the input pin for the potentiometer
 int drainSensePin = A1;
 double sourceSense = 0;
 double drainSense = 0;
 double sensor = 0;
-int numberOfReadings = 400;
+int numberOfReadings = 400; // change this as required
 unsigned int ADCValue;
 double Vcc;
-double result;
+long result;
 double averagedOutput;
-
-double array[99];

 long readVcc() {
-  long result;
   // Read 1.1V reference against AVcc
   ADMUX = _BV(REFS0) | _BV(MUX3) | _BV(MUX2) | _BV(MUX1);
   delay(2); // Wait for Vref to settle
@@ -38,20 +34,8 @@
   drainSense = (drainSense / 1024.0) * Vcc;

   sensor = sourceSense - drainSense;
-  if (sensor == 0) {
-    sensor = reading();
-  }
-//  Serial.println(sensor);

   return sensor;
-}
-
-double average (double * array, int len)
-{
-  long sum = 0L ;  // sum will be larger than an item, long for safety.
-  for (int i = 0 ; i < len ; i++)
-    sum += array[i];
-  return  ((double) sum) / len ;  // average will be fractional, so float may be appropriate.
 }

 void setup() {
@@ -61,13 +45,11 @@

 void loop() {
 //  int start_time = millis();
-  memset(array,0,sizeof(array));
-
   for (int i = 0; i < numberOfReadings; i++) {
     double sample_reading = reading();
       myStats.add(sample_reading);
-      // Code takes ~245 ms to run (100 readings per output reading).
-      //Adding a delay of 1 ms increases run time to 345 ms.
+//    Code takes ~245 ms to run (100 readings per output reading).
+//    When delay = 0
       delay(0);
   }

@@ -77,4 +59,4 @@
 //  int difference = finish_time - start_time;
 //  Serial.println(difference);

-}
+}


Forced all strings into PROGMEM

Forced all strings into PROGMEM

--- DigitalVFO.ino
+++ DigitalVFO.ino
@@ -342,23 +342,23 @@
 void decode_debug_levels(int debug)
 {
   if (debug & DEBUG_DDS)
-    Serial.println("    DEBUG_DDS\tbit is set");
+    Serial.println(F("    DEBUG_DDS\tbit is set"));
   if (debug & DEBUG_FREQ)
-    Serial.println("    DEBUG_FREQ\tbit is set");
+    Serial.println(F("    DEBUG_FREQ\tbit is set"));
   if (debug & DEBUG_MENU)
-    Serial.println("    DEBUG_MENU\tbit is set");
+    Serial.println(F("    DEBUG_MENU\tbit is set"));
   if (debug & DEBUG_EVENT)
-    Serial.println("    DEBUG_EVENT\tbit is set");
+    Serial.println(F("    DEBUG_EVENT\tbit is set"));
   if (debug & DEBUG_ACT)
-    Serial.println("    DEBUG_ACT\tbit is set");
+    Serial.println(F("    DEBUG_ACT\tbit is set"));
   if (debug & DEBUG_RE)
-    Serial.println("    DEBUG_RE\tbit is set");
+    Serial.println(F("    DEBUG_RE\tbit is set"));
   if (debug & DEBUG_INT)
-    Serial.println("    DEBUG_INT\tbit is set");
+    Serial.println(F("    DEBUG_INT\tbit is set"));
   if (debug & DEBUG_DISP)
-    Serial.println("    DEBUG_DISP\tbit is set");
+    Serial.println(F("    DEBUG_DISP\tbit is set"));
   if (debug & DEBUG_BATT)
-    Serial.println("    DEBUG_BATT\tbit is set");
+    Serial.println(F("    DEBUG_BATT\tbit is set"));
 }

 //----------------------------------------
@@ -1896,7 +1896,7 @@
   Serial.printf(F("DEBUG is defined as %06X:\n"), DEBUG);
   decode_debug_levels(DEBUG);
 #else
-  Serial.println("DEBUG is not turned on.");
+  Serial.println(F("DEBUG is not turned on."));
 #endif

   // dump EEPROM values


Updating sketch to latest version

Updating sketch to latest version

--- sketches/WeatherPod/WeatherPod.ino
+++ sketches/WeatherPod/WeatherPod.ino
@@ -6,54 +6,13 @@
  * 		Time
  * 		DHT
  * 		Adafruit_BMP085_Unified
- * 		Adafruit_Sensor
- * 		DS1307RTC
- * 		LiquidCrystal_I2C2004V1
+ * 		Adafruit_Sensor          for pressure, temp, humidity
+ * 		DS1307RTC                for clocl
+ * 		LiquidCrystal_I2C2004V1  for display
  * 		SimpleTimer
  *
- *
- *
- *
- * 		By carefully watching the pressure on a barometer, you can forecast local weather
- * 		using these simple guidelines:
- *
- * 			Decreasing barometric pressure indicates storms, rain and windy weather.
- *
- * 			Rising barometric pressure indicates fair, dry, and colder weather.
- *
- * 			Slow, regular and moderate falls in pressure suggest a low pressure
- *			area is passing some distance away. Marked changes in the weather are unlikely.
- *
- * 			Small rapid decreases in pressure indicate a nearby change in weather.
- *			They are usually followed by short lasting wind and showers.
- *
- * 			A quick drop in pressure over a short time indicates a storm is likely in 5
- * 			to 6 hours.
- *
- * 			Large, slow and sustained decreasing pressure forecasts a long period of
- *			poor weather. The weather will be more pronounced if the pressure started
- *			rising before it began to drop.
- *
- * 			A rapid rise in pressure, during fair weather and average, or above average
- *			pressure, indicates a low pressure cell is approaching. The pressure will
- *			soon decrease forecasting poorer weather.
- *
- * 			Quickly rising pressure, when the pressure is low, indicates a short period
- *			of fair weather is likely.
- *
- * 			A large, slow and sustained rise in pressure forecasts a long period of good
- *			weather is on its way.
- *
-			Definition of Pressure Tendency Terms
-
-			Term							Pressure Tendency Over 3 Hours
-			Steady							Less than 0.1 mb
-			Rising or falling slowly		0.1 to 1.5 mb
-			Rising or falling				1.6 to 3.5 mb
-			Rising or falling quickly		3.6 to 6.0 mb
-			Rising or falling very rapidly	More than 6.0 mb
- *
- */
+ */
+

 #include <Arduino.h>
 #include <SimpleTimer.h>
@@ -61,6 +20,7 @@
 #include <LiquidCrystal_I2C.h>

 #define DHTTYPE DHT22   // DHT 22  (AM2302)
+
 #include <DHT.h>
 #include <Wire.h>
 #include <Adafruit_Sensor.h>
@@ -72,7 +32,7 @@
 #define LOW_PRESSURE 1002
 #define HIGH_PRESSURE 1020

-const uint8_t pinDHT = 2, pin7Segment = 7;
+const uint8_t pinDHT = 2;
 DHT dht(pinDHT, DHTTYPE);
 LiquidCrystal_I2C lcd(0x3F, 20, 4);
 Adafruit_BMP085_Unified bmp = Adafruit_BMP085_Unified(10085);
@@ -232,6 +192,8 @@

 	dht.begin();
 	bmp.begin();
+	pinMode(7, OUTPUT);
+	digitalWrite(7, HIGH);

 	lcd.init();
 	lcd.backlight();


bugfix: prevent sending noise data more than once

--- noise_monitor/noise_monitor.ino
+++ noise_monitor/noise_monitor.ino
@@ -18,7 +18,7 @@
 #define CNT_MAX 2000

 // number of samples used to calibrate min and max
-#define CALIBRATION_SAMPLES 50
+#define CALIBRATION_SAMPLES 30

 // size of diff histo for calibration
 #define CALIBRATION_HISTO_SIZE 10
@@ -47,7 +47,7 @@
 int cnt, val_min, val_max, diff;

 // global vars for accumulated noise measures
-int acc_max, acc_sum, acc_cnt, samples_cnt;
+int acc_max, acc_sum, acc_cnt, samples_cnt, calibration_cnt;
 long acc_start;

 // global vars for calibration
@@ -208,7 +208,14 @@
   diff_min = 0;

   // reset number of samples sent
-  samples_cnt = 0;
+  samples_cnt = 0;
+
+  // reset calibration sample count
+  calibration_cnt = 0;
+
+  for (int i = 0; i < CALIBRATION_HISTO_SIZE; i++) {
+    calibration_histo[i] = 0;
+  }
 }

 // reset variables for raw noise measurments
@@ -224,6 +231,7 @@
   acc_cnt = 0;
   acc_sum = 0;
   acc_max = 0;
+  acc_start = millis();
 }

 // update variables for raw noise measurments
@@ -239,54 +247,38 @@
 }

 // update calibration of noise level differences
+// assumtion is that most frequently observed difference
+// between max and min value represents silence.
 void updateNoiseLevelCalibration() {

-  // init calibration histo
-  if (acc_cnt == 0) {
-    for (int i = 0; i < CALIBRATION_HISTO_SIZE; i++) {
-      calibration_histo[i] = 0;
-    }
-  }
-
-  // collecting samples for calibration
-  if (acc_cnt < CALIBRATION_SAMPLES) {
-    calibration_diff[acc_cnt] = val_max - val_min;
-  }
-  // computing current calibration
-  else if (acc_cnt == CALIBRATION_SAMPLES) {
-    // update histogram for calibration
-    for (int i = 0; i < CALIBRATION_SAMPLES; i++) {
-      if (calibration_diff[i] < CALIBRATION_HISTO_SIZE) {
-        calibration_histo[calibration_diff[i]]++;
-      }
-    }
-
-    // reset diff_min
-    diff_min = 0;
-
-    // find best diff_min.
-    // assumpion: most frequent noise diff value represents silence
-    for (int i = 1; i < CALIBRATION_HISTO_SIZE; i++) {
-      if (calibration_histo[i] > calibration_histo[diff_min]) {
-        diff_min = i;
-      }
-    }
-
-    if (PRINT_DEBUG) {
-      Serial.println(LINE);
-      Serial.print("new calibration difference: ");
-      Serial.println(diff_min);
-      Serial.println(LINE);
+  // continuous sampling
+  calibration_diff[calibration_cnt++ % CALIBRATION_SAMPLES] = val_max - val_min;
+
+  if(calibration_cnt == CALIBRATION_SAMPLES) {
+    calibration_cnt = 0;
+  }
+
+  // update histogram for calibration
+  for (int i = 0; i < CALIBRATION_SAMPLES; i++) {
+    if (calibration_diff[i] < CALIBRATION_HISTO_SIZE) {
+      calibration_histo[calibration_diff[i]]++;
+    }
+  }
+
+  // reset diff_min
+  diff_min = 0;
+
+  // find best diff_min.
+  // assumpion: most frequent noise diff value represents silence
+  for (int i = 1; i < CALIBRATION_HISTO_SIZE; i++) {
+    if (calibration_histo[i] > calibration_histo[diff_min]) {
+      diff_min = i;
     }
   }
 }

 // update variables for accumulated noise measurments
 void updateNoiseLevelValues(int d) {
-  if (acc_cnt == 0) {
-    acc_start = millis();
-  }
-
   if (diff > acc_max) {
     acc_max = d;
   }
@@ -317,6 +309,8 @@
     Serial.print(val_min);
     Serial.print(" max ");
     Serial.print(val_max);
+    Serial.print(" diff_min ");
+    Serial.print(diff_min);
     Serial.print(") cnt=");
     Serial.print(cnt);
     Serial.print(" time=");


[Arduino] Implemented to always read last packet from FIFO.

Signed-off-by: Juri Berlanda <5bfdca9e82c53adb0603ce7083f4ba4f2da5cacf@hotmail.com>

--- Arduino/vj-flight-controller/vj-flight-controller.ino
+++ Arduino/vj-flight-controller/vj-flight-controller.ino
@@ -122,10 +122,12 @@

   if (mpuIntStatus & 0x02) {
     checkFifo();
-    // read a packet from FIFO
-    mpu.getFIFOBytes(fifoBuffer, packetSize);
-
-    // TODO: Read the lastmost packet from FIFO
+
+    // Read all packets from FIFO and kepp last
+    while (fifoCount > packetSize) {
+      mpu.getFIFOBytes(fifoBuffer, packetSize);
+      fifoCount -= packetSize;
+    }

     // Get Euler angles in degrees and Acceleration in world-frame
     mpu.dmpGetQuaternion(&q, fifoBuffer);


Run for a set period of time (1 hour), then go to "sleep", just lighting up one LED in the middle of the grid.

--- xy.ino
+++ xy.ino
@@ -14,6 +14,22 @@
 //  types
 // ---------------------------------------------------------------------------------------------------------------------

+enum gridColorspace
+{
+   RGB = 1,
+   HSL
+};
+
+enum axisColorspace
+{
+   RED = 1,
+   GREEN,
+   BLUE,
+   HUE,
+   SAT,                      // Saturation
+   LIGHT                     // Lightness
+};
+
 struct point
 {
    int x,y;
@@ -24,6 +40,25 @@
    int r,g,b;
 };

+typedef struct runParamTuple
+{
+   gridColorspace colorspace;
+   axisColorspace xAxisSpace, yAxisSpace;
+
+   // Axis values may be non-linear (e.g., intensity)
+   union
+   {
+      int axisIntValues[GRID_SIZE_X];
+      float axisFloatValues[GRID_SIZE_X];
+   } x;
+
+   union
+   {
+      int axisIntValues[GRID_SIZE_Y];
+      float axisFloatValues[GRID_SIZE_Y];
+   } y;
+};
+
 // ---------------------------------------------------------------------------------------------------------------------
 //  globals
 // ---------------------------------------------------------------------------------------------------------------------
@@ -38,14 +73,45 @@
 struct point org = { 0, 0   }   ;
 struct point gridSize = (point) {GRID_SIZE_X, GRID_SIZE_Y };

+// Gonna cheat, since we know we have a square grid:  same values on each axis.
+
+float lightness[GRID_SIZE_X]; // HSL
+float saturation[GRID_SIZE_X]; // HSL
+
+int ledBrightness[GRID_SIZE_X]; // RGB intensity
+float dLedBrightness = 1.0 / (GRID_SIZE_X - 1);
+float dLightness = 1.0 / (GRID_SIZE_X + 1); // Will drop lightness = 0 (black) and 1 (white), since that results in an
+                                            // entire row/column being all the same (fully off or fully on).
+
+int exponent = 4;               // Non-linear brightness increase as {x^exponent : x in [0.0..1.0]}
+
+float v;
+float dHue = 60.0; // 360.0 / GRID_SIZE_X;
+
+struct runParamTuple runParams[6] = { { RGB , RED   , GREEN } ,  // 0
+                                      { RGB , BLUE  , RED }   ,  // 1
+                                      { RGB , GREEN , BLUE }  ,  // 2
+                                      { HSL , HUE   , SAT }   ,  // 3
+                                      { HSL , HUE   , LIGHT } ,  // 4
+                                      { HSL , SAT   , LIGHT } }; // 5
+
 // ---------------------------------------------------------------------------------------------------------------------
 //  setup
 // ---------------------------------------------------------------------------------------------------------------------

 void setup() {
+   int t;
+   unsigned long desiredDuration = 3600 * 1000; // total desired run time, milliseconds
+
   strip.begin();
   // clearStrip();
   strip.show();
+  setupRotatingColorAxes();
+
+  while (millis() < desiredDuration)
+     rotatingColorAxes();
+
+   clearStrip();
 }

 // ---------------------------------------------------------------------------------------------------------------------
@@ -59,8 +125,26 @@

    // cartesianTest();

-   rotatingColorAxes();
-}
+   // rotatingColorAxes();
+
+   showSleepState();
+}
+
+// ---------------------------------------------------------------------------------------------------------------------
+//  showSleepState
+// ---------------------------------------------------------------------------------------------------------------------
+
+void showSleepState()
+{
+   struct point pt;
+   struct rgbTriple rgb;
+
+   rgb = hsl2rgb( 5, 1.0, 0.1);
+   pt = {2,2 } ;
+   strip.setPixelColor( point2seq( pt, org, gridSize), Color( rgb.r, rgb.g, rgb.b));
+   strip.show();
+}
+

 // ---------------------------------------------------------------------------------------------------------------------
 //  flashTwoDifferentColors
@@ -187,12 +271,83 @@
 //  rotatingColorAxes
 // ---------------------------------------------------------------------------------------------------------------------

+// Setup for rotationColorAxes()
+void setupRotatingColorAxes()
+{
+   int i;
+
+   ledBrightness[0]               = 0;
+   ledBrightness[GRID_SIZE_X - 1] = 255;
+
+   saturation[0]                  = 0;
+   saturation[GRID_SIZE_X - 1]    = 1;
+
+   clearStrip();
+
+   for (i = 1; i < GRID_SIZE_X - 1; i++)
+   {
+      v = i * dLedBrightness;   // Linear
+      saturation[i] = v;
+      v = pow( v, exponent);    // Non-linear
+      ledBrightness[i] = v * 256; // Don't need to constrain; won't get close to 255.
+   }
+
+   for (i = 0; i < GRID_SIZE_X; i++)
+   {
+      v = (i + 1) * dLightness; // See dLightness.
+      v = pow( v, 3.45);
+      lightness[i] = v;
+   }
+
+
+   // // Debug:
+   // for (i = 0; i < GRID_SIZE_X; i++)
+   // {
+   //    pt = {i, 4 } ;
+   //    rgb = hsl2rgb( 0, saturation[i], 0.5); // red/pink
+   //    c = Color( rgb.r, rgb.g, rgb.b);
+   //    strip.setPixelColor( point2seq( pt, org, gridSize), c);
+
+   //    pt = {i, 3 } ;
+   //    rgb = hsl2rgb( 120, 0.5, lightness[i]); // greenish
+   //    c = Color( rgb.r, rgb.g, rgb.b);
+   //    strip.setPixelColor( point2seq( pt, org, gridSize), c);
+
+   //    pt = {i, 2 } ;
+   //    c = Color( 0, 0, ledBrightness[i]); // blue
+   //    strip.setPixelColor( point2seq( pt, org, gridSize), c);
+   // }
+   // strip.show();
+   // delay( 15000);
+
+   // RGB
+   for (i = 0; i < 3; i++)
+   {
+      copyIntArray( runParams[i].x.axisIntValues, ledBrightness, GRID_SIZE_X);
+      copyIntArray( runParams[i].y.axisIntValues, ledBrightness, GRID_SIZE_X);
+   }
+
+   // HSL
+   for (i = 0; i < GRID_SIZE_X; i++)
+   {
+      runParams[3].x.axisIntValues[i] = (int) (i * dHue + 0.5);
+      runParams[4].x.axisIntValues[i] = (int) (i * dHue + 0.5);
+   }
+   copyFloatArray( runParams[3].y.axisFloatValues, saturation, GRID_SIZE_X);
+   copyFloatArray( runParams[4].y.axisFloatValues, lightness, GRID_SIZE_X);
+   copyFloatArray( runParams[5].y.axisFloatValues, lightness, GRID_SIZE_X);
+
+   copyFloatArray( runParams[5].x.axisFloatValues, saturation, GRID_SIZE_X);
+}
+
+// Show two of three axes of RGB and HSL colorspaces, with the third axis held to some reasonable constant, blending
+// those values into a single unique colorspace point.  Rotate among the choice of which two axes to use (e.g.,
+// red/green, hue/saturation, etc.).
 void rotatingColorAxes()
 {
    int x,y;
    int dColor = 64;
    float d1 = 1.0 / (5-1);      // 0..4 ==> 0..1.0 in 5 steps
-   int exponent = 4;            // Non-linear brightness increase as {x^exponent : x in [0.0..1.0]}
    struct rgbTriple rgb;
    int r,g,b;
    float rf, gf, bf;
@@ -202,135 +357,12 @@
    int i;
    struct point pt;

-   enum gridColorspace
-   {
-      RGB = 1,
-      HSL
-   };
-
-   enum axisColorspace
-   {
-      RED = 1,
-      GREEN,
-      BLUE,
-      HUE,
-      SAT,                      // Saturation
-      LIGHT                     // Lightness
-   };
-
-   typedef struct
-   {
-      gridColorspace colorspace;
-      axisColorspace xAxisSpace, yAxisSpace;
-
-      // Axis values may be non-linear (e.g., intensity)
-      union
-      {
-         int axisIntValues[GRID_SIZE_X];
-         float axisFloatValues[GRID_SIZE_X];
-      } x;
-
-      union
-      {
-         int axisIntValues[GRID_SIZE_Y];
-         float axisFloatValues[GRID_SIZE_Y];
-      } y;
-   } runParamTuple;
-
-   // TODO: put the following setup in setup() ----------------------------------------------------------------
-
-   // Gonna cheat, since we know we have a square grid:  same values on each axis.
-
-   int ledBrightness[GRID_SIZE_X]; // RGB intensity
-   float dLedBrightness = 1.0 / (GRID_SIZE_X - 1);
-   float dLightness = 1.0 / (GRID_SIZE_X + 1); // Will drop lightness = 0 (black) and 1 (white), since that results in
-                                               // an entire row/column being all the same (fully off or fully on).
-   float lightness[GRID_SIZE_X]; // HSL
-   float saturation[GRID_SIZE_X]; // HSL
-
-   ledBrightness[0]               = 0;
-   ledBrightness[GRID_SIZE_X - 1] = 255;
-
-   saturation[0]                  = 0;
-   saturation[GRID_SIZE_X - 1]    = 1;
-
-   float v;
-
-   clearStrip();
-
-   for (i = 1; i < GRID_SIZE_X - 1; i++)
-   {
-      v = i * dLedBrightness;   // Linear
-      saturation[i] = v;
-      v = pow( v, exponent);    // Non-linear
-      ledBrightness[i] = v * 256; // Don't need to constrain; won't get close to 255.
-   }
-
-   for (i = 0; i < GRID_SIZE_X; i++)
-   {
-      v = (i + 1) * dLightness; // See dLightness.
-      v = pow( v, 3.45);
-      lightness[i] = v;
-   }
-
-
-   // // Debug:
-   // for (i = 0; i < GRID_SIZE_X; i++)
-   // {
-   //    pt = {i, 4 } ;
-   //    rgb = hsl2rgb( 0, saturation[i], 0.5); // red/pink
-   //    c = Color( rgb.r, rgb.g, rgb.b);
-   //    strip.setPixelColor( point2seq( pt, org, gridSize), c);
-
-   //    pt = {i, 3 } ;
-   //    rgb = hsl2rgb( 120, 0.5, lightness[i]); // greenish
-   //    c = Color( rgb.r, rgb.g, rgb.b);
-   //    strip.setPixelColor( point2seq( pt, org, gridSize), c);
-
-   //    pt = {i, 2 } ;
-   //    c = Color( 0, 0, ledBrightness[i]); // blue
-   //    strip.setPixelColor( point2seq( pt, org, gridSize), c);
-   // }
-   // strip.show();
-   // delay( 15000);
-
-   runParamTuple runParams[6] = { { RGB , RED   , GREEN } ,  // 0
-                                  { RGB , BLUE  , RED }   ,  // 1
-                                  { RGB , GREEN , BLUE }  ,  // 2
-                                  { HSL , HUE   , SAT }   ,  // 3
-                                  { HSL , HUE   , LIGHT } ,  // 4
-                                  { HSL , SAT   , LIGHT } }; // 5
-
-   // RGB
-   for (i = 0; i < 3; i++)
-   {
-      copyIntArray( runParams[i].x.axisIntValues, ledBrightness, GRID_SIZE_X);
-      copyIntArray( runParams[i].y.axisIntValues, ledBrightness, GRID_SIZE_X);
-   }
-
-   // HSL
-   float dHue = 60.0; // 360.0 / GRID_SIZE_X;
-   for (i = 0; i < GRID_SIZE_X; i++)
-   {
-      runParams[3].x.axisIntValues[i] = (int) (i * dHue + 0.5);
-      runParams[4].x.axisIntValues[i] = (int) (i * dHue + 0.5);
-   }
-   copyFloatArray( runParams[3].y.axisFloatValues, saturation, GRID_SIZE_X);
-   copyFloatArray( runParams[4].y.axisFloatValues, lightness, GRID_SIZE_X);
-   copyFloatArray( runParams[5].y.axisFloatValues, lightness, GRID_SIZE_X);
-
-   copyFloatArray( runParams[5].x.axisFloatValues, saturation, GRID_SIZE_X);
-
-   // (setup ends) ----------------------------------------------------------------
-
-   int run;
-
-   // Label the runs for x and y axes: rg, br, gb
-   // 0, 1, 2
+   int run;                     // We're going to do a series of "runs", in which we pick the axes, set the third
+                                // component to a constant and then generate values for each grid point.

    for (run = 0; run < 6; run++)
    {
-      runParamTuple rp = runParams[run];
+      struct runParamTuple rp = runParams[run];
       for (y = 0; y < GRID_SIZE_Y; y++)
          for (x = 0; x < GRID_SIZE_X; x++)
          {
@@ -387,7 +419,7 @@
       // c = Color( rgb.r, rgb.g, rgb.b);
       // strip.setPixelColor( run, c);
       strip.show();
-      delay( run < 3 ? 5000 : 20000); // Delay longer for HSL part of run
+      delay( run < 3 ? 5000 : 20000); // Delay longer for HSL part of run (3 * 5 + 3 * 20 = 75 seconds)
    }

    // Since we skipped "black" and "white", show a checkerboard of those.
@@ -399,6 +431,7 @@
    strip.show();
    delay( 5000);

+   // Old code, to be deleted at some point:
    // for (run = 0; run < 3; run++)
    // {
    //    for (y = 0; y < 5; y++)


Update tripMeterArduino.ino

Update tripMeterArduino.ino

--- tripMeterArduino/tripMeterArduino.ino
+++ tripMeterArduino/tripMeterArduino.ino
@@ -6,10 +6,11 @@
 int right_value = 0;
 int left_value = 0;

+// sensor max value ~4.3, min value ~2.0
 int right_high_limit = 750; // 3.67 / 5.0 * 1023;
 int right_low_limit = 610; // 2.98 / 5.0 * 1023;
-int left_high_limit = 635; // 3.67 / 5.0 * 1023;
-int left_low_limit = 495; // 2.98 / 5.0 * 1023;
+int left_high_limit = 635; // 3.10 / 5.0 * 1023;
+int left_low_limit = 495; // 2.42 / 5.0 * 1023;

 bool right_prev_high = false;
 bool left_prev_high = false;


bugfix

bugfix

--- RGB_matrix.ino
+++ RGB_matrix.ino
@@ -70,12 +70,12 @@
     while(1){
         lighting(pattern1,1500);  //pattern1を1500[ms]出力し続ける

-        byte pattern2;
+        byte pattern2[9];
         setAll(pattern2,RED);    //すべて同じ色ならsetAll()で設定可能
         lighting(pattern2,800);     //pattern2を800[ms]出力し続ける

         setAll(pattern2,OFF);     //pattern2に上書き
-        lightning(pattern2,2000);     //pattern2を2000[ms]出力し続ける
+        lighting(pattern2,2000);     //pattern2を2000[ms]出力し続ける
     }
 }

@@ -83,7 +83,7 @@
     for(int i=0;i<9;i++) data[i]=color;
 }

-void lighting(byte data[],int wait){
+void lighting(byte data[],unsigned long wait){
     unsigned long begin = millis();
     while( (millis()-begin)>wait ) lighting(data);
 }


Update Example with mods

Update Example with mods

--- examples/amazonDashButton/amazonDashButton.ino
+++ examples/amazonDashButton/amazonDashButton.ino
@@ -1,32 +1,33 @@
 /*******************************************************************
- Check out the included Arduino sketches and the getting started
- guide here!
+ Check out the included Arduino sketches and the getting started
+ guide here!
  https://github.com/andium/AmazonDRS
-
+
  This is an Arduino implementation of an Amazon Dash Replenishment
  device. It currently supports the critical API endpoints necessary
- for registering a device and submitting replenishment requests. This
- library is tightly coupled to the WiFi101 library, which means it will
- work great with the Arduino MKR1000, Adafruit Feather MO w/ the ATWINC1500,
- Arduino WiFi101 shiled or anywhere the WiFi101 library is supported. Json
+ for registering a device and submitting replenishment requests. This
+ library is tightly coupled to the WiFi101 library, which means it will
+ work great with the Arduino MKR1000, Adafruit Feather MO w/ the ATWINC1500,
+ Arduino WiFi101 shiled or anywhere the WiFi101 library is supported. Json
  parsing is provided via ArduinoJson, thanks bblanchon!
  https://github.com/bblanchon/ArduinoJson
-
+
  Written by Brian Carbonette Copyright © 2016 Andium
-
  Licensed under the Apache License, Version 2.0 (the "License");
  you may not use this file except in compliance with the License.
  You may obtain a copy of the License at
-
+
  http://www.apache.org/licenses/LICENSE-2.0
-
+
  Unless required by applicable law or agreed to in writing, software
  distributed under the License is distributed on an "AS IS" BASIS,
  WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
  See the License for the specific language governing permissions and
  limitations under the License.
  *******************************************************************/
-
+ #include <ESP8266WiFi.h>
+ #include <WiFiClientSecure.h>
+ //#include <WiFi101.h>
 #include "AmazonDRS.h"

 AmazonDRS DRS = AmazonDRS();
@@ -39,23 +40,34 @@
 #define slotNumber 1 //This will vary for multi slot devices - dash buttons typically only serve one product/slot

 const int dashButton = 14;     //DIO number of the pushbutton pin
-static long buttonHigh = 0;    //millis of last button push for switch debouncing
-static String slotStatus = ""; //boolean which depicts if slot is available for replenishment
-static String slotId = "";     //unique slot id ex: 0a5038b7-7609-4b81-b87e-3e291f386324
-
+static long buttonHigh = 12;    //millis of last button push for switch debouncing
+static String slotStatus = "true"; //boolean which depicts if slot is available for replenishment
+static String slotId = "11111111-2222-3333-4444-555555555555";     //unique slot id ex: 0a5038b7-7609-4b81-b87e-3e291f386324
+int status = WL_IDLE_STATUS;

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

   pinMode(dashButton, INPUT);
-
-  while (!Serial) {
-      ; // wait for serial port to connect. Needed for native USB port only
-   }

-  //Start up DRS
-  DRS.begin(ssid,pass);
-
+
+   WiFiClientSecure client;
+
+   DRS.begin(&client);
+
+  //connect to WiFi
+  Serial.println("Initializing DRS... connecting to WiFi");
+  while (status != WL_CONNECTED) {
+    // Connect to WPA/WPA2 network. Change this line if using open or WEP network:
+    status = WiFi.begin(ssid, pass);
+    Serial.println(".");
+    delay(3000);
+    status = WiFi.status();
+  }
+
+  Serial.print("Connected to ");
+  Serial.println(WiFi.SSID());
+
   //initialize slots
   DRS.retrieveSubscriptionInfo();  //check slot statuses

@@ -70,12 +82,12 @@

   if (buttonPushed())
     {
-
+
        //Check if slot is available, if so replenish
-
-        if(slotStatus == "true")   //if the product in slot are available
+
+        if(slotStatus == "true")   //if the product in slot are available
         {
-            //we have a match! replenish the products associated with that slot!
+            //we have a match! replenish the products associated with that slot!
             DRS.requestReplenishmentForSlot(slotId);
         }
         else
@@ -84,24 +96,23 @@
           Serial.print(slotId);
           Serial.println(" is not available at this time");
         }
-
+
     }

 }

 bool buttonPushed(void)
 {
-  int buttonState = digitalRead(dashButton);
-
+  int buttonState = digitalRead(dashButton);
+
   if(buttonState && ((millis() - buttonHigh) > 5000))
   {
     buttonHigh = millis();
     Serial.println("Button pressed!!");
     return true;
   }
-  else
+  else
   {
     return false;
   }
 }
-


Refactorizando parseador lectura comando serie

--- Ardufocuser/Ardufocuser.ino
+++ Ardufocuser/Ardufocuser.ino
@@ -1,5 +1,5 @@

-#define DEBUG 0
+#define DEBUG 1

 #include <TimerOne.h>
 #include <LiquidCrystal.h>
@@ -448,17 +448,16 @@
         // Volcamos contenido del buffer en el contenedor del comando, buscando el delimitador.
         for (i; ((i<byteCount) and (c!= delimiter)) ; i++){
               c=buffer[i];
-              command[i]=c;
+              if (c!= delimiter) command[i]=c;

         }
-
-        //Avanzamos hasta despues  del delimitador.
-        i++;
+
         int a=0;
          // Volcamos contenido del buffer en el contenedor del dato.
         for (i; (i<byteCount) ; i++){
           c=buffer[i];
-          data[a]=c;
+
+          if ( c>47 && c < 123) data[a]=c;
           a++;
       }
     }
@@ -603,7 +602,7 @@
   readTemperature();
   updateLCD();
   manualPerformance();
-  sendCurrentposition();
+  //sendCurrentposition();
   remoteManager();

 }


space

space

--- vibrate_alarm_clock_2.ino
+++ vibrate_alarm_clock_2.ino
@@ -23,7 +23,7 @@

 #define ADC_PRECISION 1024

- //You may need to calibrate these values. My values are based on this data sheet http://www.adafruit.com/datasheets/18650%204400mAh.pdf
+//You may need to calibrate these values. My values are based on this data sheet http://www.adafruit.com/datasheets/18650%204400mAh.pdf
 #define MIN_BATTERY_MILLIVOLT 2750
 #define MAX_BATTERY_MILLIVOLT 4200


Delete GPRS_SMSread.ino

Delete GPRS_SMSread.ino

--- examples/GPRS_SMSread.ino
+++ examples/GPRS_SMSread.ino
@@ -1,59 +0,0 @@
-/*
-GPRS SMS Read
-
-This sketch is used to test seeeduino GPRS_Shield's reading SMS
-function.To make it work, you should insert SIM card
-to Seeeduino GPRS Shield,enjoy it!
-
-There are two methods to read SMS:
-  1. GPRS_LoopHandle.ino  -> in order to recieve "+CMTI: "SM""
-      may be you need to send this command to your shield: "AT+CNMI=2,2,0,0,0"
-  2. GPRS_SMSread.ino -> you have to check if there are any
-      UNREAD sms, and you don't need to check serial data continuosly
-
-create on 2014/10/16, version: 0.1
-by op2op2op2(op2op2op2@hotmail.com)
-*/
-
-#include <GPRS_Shield_Arduino.h>
-#include <SoftwareSerial.h>
-#include <Wire.h>
-#include <Suli.h>
-
-#define PIN_TX    7
-#define PIN_RX    8
-#define BAUDRATE  9600
-
-#define MESSAGE_LENGTH 160
-char message[MESSAGE_LENGTH];
-int messageIndex = 0;
-
-char phone[16];
-char datetime[24];
-
-GPRS gprsTest(PIN_TX,PIN_RX,BAUDRATE);//RX,TX,PWR,BaudRate
-
-void setup() {
-  Serial.begin(9600);
-  while(0 != gprsTest.init()) {
-      delay(1000);
-      Serial.print("init error\r\n");
-  }
-  delay(3000);
-  Serial.println("Init Success, please send SMS message to me!");
-}
-
-void loop() {
-   messageIndex = gprsTest.isSMSunread();
-   if (messageIndex > 0) { //At least, there is one UNREAD SMS
-      gprsTest.readSMS(messageIndex, message, MESSAGE_LENGTH, phone, datetime);
-      //In order not to full SIM Memory, is better to delete it
-      gprsTest.deleteSMS(messageIndex);
-      Serial.print("From number: ");
-      Serial.println(phone);
-      Serial.print("Datetime: ");
-      Serial.println(datetime);
-      Serial.print("Recv Message: ");
-      Serial.println(message);
-   }
-}


AudioPassThru: change input to INPUT_JACK_AS_MIC

--- examples/01-Basic/AudioPassThru/AudioPassThru.ino
+++ examples/01-Basic/AudioPassThru/AudioPassThru.ino
@@ -38,8 +38,8 @@
   audioHardware.enable(); // activate AIC

   //Choose the desired input
-  audioHardware.inputSelect(TYMPAN_INPUT_ON_BOARD_MIC); // use the on board microphones
-  //  audioHardware.inputSelect(TYMPAN_INPUT_JACK_AS_MIC); // use the microphone jack - defaults to mic bias 2.5V
+  //audioHardware.inputSelect(TYMPAN_INPUT_ON_BOARD_MIC); // use the on board microphones
+  audioHardware.inputSelect(TYMPAN_INPUT_JACK_AS_MIC); // use the microphone jack - defaults to mic bias 2.5V
   //  audioHardware.inputSelect(TYMPAN_INPUT_JACK_AS_LINEIN); // use the microphone jack - defaults to mic bias OFF

   //Set the desired volume levels


Clean up include and reduce print out.

Clean up include and reduce print out.

--- examples/Ethernet/CosaWebServer/CosaWebServer.ino
+++ examples/Ethernet/CosaWebServer/CosaWebServer.ino
@@ -29,8 +29,8 @@
 #include "Cosa/Pins.hh"
 #include "Cosa/Watchdog.hh"
 #include "Cosa/Trace.hh"
+#include "Cosa/INET.hh"
 #include "Cosa/IOStream.hh"
-#include "Cosa/IOBuffer.hh"
 #include "Cosa/IOStream/Driver/UART.hh"
 #include "Cosa/Socket/Driver/W5100.hh"

@@ -98,7 +98,6 @@

   // Read request and print contents
   sock->gets(buf, sizeof(buf));
-  trace << uptime << ':' << nr << ':' << buf << endl;

   // Reply page; header and footer are static, contents dynamic
   static const char header[] PROGMEM =
@@ -126,7 +125,7 @@
   page << PSTR("Memory (byte): ") << free_memory();
   page << PSTR("(") << setup_free_memory << PSTR(")") << BR;
   page << PSTR("Uptime (h:m:s): ") << h << ':' << m << ':' << s << BR;
-  page << PSTR("Requests: ") << nr++ << BR;
+  page << PSTR("Request(") << nr++ << PSTR("): ") << buf << BR;
   page << PSTR("MAC: "); INET::print_mac(page, addr.mac); page << BR;
   page << PSTR("IP: "); INET::print_addr(page, addr.ip, addr.port); page << BR;
   page << footer;


Minor scaling rate fix.

Minor scaling rate fix.

--- Temperature/Temperature.ino
+++ Temperature/Temperature.ino
@@ -22,7 +22,7 @@
 #define TMP102_ADDR_3 0xF4633

 #define MAX_SAMPLE_RATE 10
-#define MAX_SAMPLE_COUNT 10
+#define MAX_SAMPLE_COUNT 4
 #define MAX_DELTA 0.5

 #define HEATER_PIN 22
@@ -102,7 +102,7 @@

 static void scale_rate(TemperatureSensor* sensor)
 {
-    if(sensor->prev_temp == sensor->curr_temp) {
+    if(abs(sensor->prev_temp - sensor->curr_temp) <= MAX_DELTA) {
        sensor->sample_count--;
     } else {
        sensor->sample_count++;
@@ -199,8 +199,9 @@
   create_sensor(sensor_count, TMP102_ADDR_0, TYPE_I2C, &i2c_sensor0);
   sensors[sensor_count++] = i2c_sensor0;

-  // Set heater output pin
-  pinMode(HEATER_PIN, OUTPUT);
+  // Set heater output pin and drive low
+  pinMode(HEATER_PIN, OUTPUT);
+  digitalWrite(HEATER_PIN, LOW);
 }

 void loop(void)


COH-71: WIP

COH-71: WIP

--- COHEAT2015/20160316-COHEAT-M1/COHEAT-M1/COHEAT-M1.ino
+++ COHEAT2015/20160316-COHEAT-M1/COHEAT-M1/COHEAT-M1.ino
@@ -1,3 +1,23 @@
+// Uncomment exactly one of the following CONFIG_ lines to select which board is being built for.
+//#define CONFIG_Trial2013Winter_Round2_CC1HUB // REV2 cut4 as CC1 hub.
+#define CONFIG_REV9 // REV9 as CC1 relay, cut 2 of the board.
+
+//#ifndef BAUD
+//#define BAUD 4800 // Ensure that OpenTRV 'standard' UART speed is set unless explicitly overridden.
+//#endif
+
+#include <Arduino.h>
+#include <Wire.h>
+#include <OTV0p2Base.h>
+#include <OTRadioLink.h>
+#include <OTRadValve.h>
+#include <OTV0p2_CONFIG_REV2.h>
+#include <OTV0p2_CONFIG_REV9.h>
+#include <OTV0p2_Board_IO_Config.h> // I/O pin allocation and setup: include ahead of I/O module headers.
+
+
+
+
 void setup() {
   // put your setup code here, to run once:


블링커 모듈 수정

블링커 모듈 수정

설정 순서 정렬

--- BlinkerModule/BlinkerModule.ino
+++ BlinkerModule/BlinkerModule.ino
@@ -45,9 +45,9 @@
   pinMode(REG_DATA, OUTPUT);
   pinMode(REG_LATCH, OUTPUT);
   pinMode(REG_CLOCK, OUTPUT);
-  pinMode(POT_MOSI, OUTPUT);
   pinMode(POT_SELECT, OUTPUT);
   pinMode(POT_CLOCK, OUTPUT);
+  pinMode(POT_MOSI, OUTPUT);
   pinMode(LED_L, OUTPUT);
   pinMode(LED_R, OUTPUT);


Implement logo command SE - emergency stop.  TODO: Not actually useful right now because of the command queue.

--- software/firmware/LogoBotWifiScribbler/LogoBotWifiScribbler.ino
+++ software/firmware/LogoBotWifiScribbler/LogoBotWifiScribbler.ino
@@ -302,6 +302,7 @@
   /* Unofficial extensions
       BZ n - sound buzzer for n milliseconds
       ST - stop
+      SE - emergency stop
       SIG - sign Logobots name
       TO x y
     */
@@ -325,8 +326,9 @@
     float angle = c.substring(3).toFloat();
     turn(angle);
   } else if (c.startsWith("ST")) {
-    stepperL.stop();
-    stepperR.stop();
+    stop();
+  } else if (c.startsWith("SE")) {
+    emergencyStop();
   } else if (c.startsWith("BZ")) {
     buzz(c.substring(3).toInt());
   } else if (c.startsWith("PU")) {
@@ -340,9 +342,14 @@
   }
 }

+void stop() {
+  stepperL.stop();
+  stepperR.stop();
+}
+
 void emergencyStop() {
-    stepperL.setCurrentPosition(stepperL.currentPosition());
-    stepperR.setCurrentPosition(stepperR.currentPosition());
+  stepperL.setCurrentPosition(stepperL.currentPosition());
+  stepperR.setCurrentPosition(stepperR.currentPosition());
 }

 void pushTo(float x, float y)


clean up recv remnants

clean up recv remnants

--- analogjson.ino
+++ analogjson.ino
@@ -17,7 +17,7 @@
 #define DIGITAL_IO 1        // comment out to delete raw digital I/O
 #define IR_SEND 1           // comment out to delete IR sendings

-#if defined(IR_SEND) || defined(IR_RECV)
+#if defined(IR_SEND)
 #include "IRremote.h"
 #ifdef IR_SEND
 IRsend irsend;
@@ -1165,7 +1165,6 @@
 const char P_digWrite[] PROGMEM = "/v1/digitalWrite";
 const char P_confpin[] PROGMEM = "/v1/configure/pinmode";
 const char P_sendIR[] PROGMEM = "/v1/sendIR";
-const char P_recvIR[] PROGMEM = "/v1/recvIR";
 const char P_status[] PROGMEM = "/v1/status";

 #define TRAILING_OK 1
@@ -1181,9 +1180,6 @@
 #ifdef IR_SEND
         { P_sendIR,   HTTPPARSE_POST, NO_TRAILING, do_json_send_ir },
 #endif
-#ifdef IR_RECV
-        { P_recvIR,   HTTPPARSE_GET,  NO_TRAILING, do_json_read_ir },
-#endif
         { P_status,   HTTPPARSE_GET,  NO_TRAILING, do_status },
         { P_confpin,  HTTPPARSE_POST, NO_TRAILING, do_pinmode },
         { NULL,       HTTPPARSE_NONE, NO_TRAILING, send_badrequest }


Send value through Ethernet for RIOT-SERVER

+ try to reduce the RAM footprint
+ use flash memory for static message
+ serve a single welcome HTTP page

--- MainStation/MainStation.ino
+++ MainStation/MainStation.ino
@@ -7,6 +7,7 @@
 // Adafruit Sensor https://github.com/adafruit/Adafruit_Sensor
 // LCD : https://bitbucket.org/fmalpartida/new-liquidcrystal/wiki/Home
 // Touch Sensor : https://github.com/arduino-libraries/CapacitiveSensor
+// Ethercard : https://github.com/jcw/ethercard

 #include <VirtualWire.h>
 #include <Wire.h>
@@ -15,6 +16,7 @@
 #include <CapacitiveSensor.h>
 #include <Adafruit_Sensor.h>
 #include <Adafruit_BMP085.h>
+#include <EtherCard.h>

 // LCD I2C Adress
 #define I2C_ADDR 0x27
@@ -40,17 +42,50 @@
 // Touch sensibility
 #define TOUCH_SENSIBILITY 100

+// Contact De-Bouncing
+#define TOUCH_DEBOUNCING 250
+
 // Main sensor update
-#define MAIN_SENSOR_UPDATE 10000
-
-// LCD
-//LiquidCrystal_I2C _lcd(I2C_ADDR,En_pin,Rw_pin,Rs_pin,D4_pin,D5_pin,D6_pin,D7_pin);
+#define MAIN_SENSOR_UPDATE 60000

 // Touched
 CapacitiveSensor _touch = CapacitiveSensor(touchCommonPin,touchSensPin);

 // Athmospheric Sensor
 Adafruit_BMP085 _mainSensor = Adafruit_BMP085();
+
+// MAC Address
+static byte _mymac[] = {0x74, 0x69, 0x69, 0x2D, 0x30, 0x31 };
+
+// remote website ip address and port
+static byte _ttkserver[] = { 192, 168, 0, 1 };
+
+// Arduino IP
+static byte _arduinoIP[] = { 192, 168, 0, 42 };
+
+// gateway ip address
+static byte _gwip[] = { 192, 168, 0, 254 };
+
+// Main Ethernet Buffer
+byte Ethernet::buffer[300];
+
+static BufferFiller _etherBuffFiller;  // used as cursor while filling the buffer
+
+// Page to display to user
+char _indexHTML[] PROGMEM =
+  "HTTP/1.0 200 OK\r\n"
+  "Content-Type: text/html\r\n"
+  "\r\n"
+  ""
+    "<title>"
+      "--- TTK Weather Station ---"
+    "</title>"
+    ""
+      "
I am the Weather Station
"
+      "
Up Time $D ms
"
+    ""
+  ""
+;

 // Sensor Defintion
 typedef struct SensorStruct {
@@ -93,6 +128,8 @@
   ReceiverDefinition rx; // RX receiver
   unsigned long lastTouched; // Last Touched time
   unsigned long lastMainSensorUpdated; // Last time that the main sensor was updated
+  char url[20];
+  volatile boolean isHttpRequest; // true during HTTP request
 } ApplicationDefinition;

 // Static Definition
@@ -103,7 +140,7 @@
     // Sensor #1
     {
       "Inside Temp",
-      0, // Sensor ID
+      1, // Sensor ID
       -99.0, // Initial Value
       "C"
     },
@@ -117,7 +154,7 @@
     // Sensor #3
     {
       "Pressure",
-      1, // Sensor ID
+      2, // Sensor ID
       -99.0, // Initial Value
       "hPa"
     }
@@ -143,9 +180,11 @@
   pinMode(rxLed, OUTPUT);

   // Debug
-  Serial.begin(9600);
-  Serial.println("--- TTK Weather Station ---");
-
+  Serial.begin(57600);
+  Serial.println(F("--- TTK Weather Station ---"));
+
+  displayFreeRam();
+
   // Set Up RX
   vw_set_rx_pin(rxPin);
   vw_setup(2000);
@@ -155,7 +194,7 @@
   _app.render.lcd.setBacklightPin(BACKLIGHT_PIN,POSITIVE);
   _app.render.lcd.setBacklight(HIGH);
   _app.render.lcd.clear();
-  _app.render.lcd.print("--- Welcome ---");
+  _app.render.lcd.print(F("--- Welcome ---"));

   // Start the receiver
   vw_rx_start();
@@ -164,8 +203,45 @@
   if(!_mainSensor.begin())
   {
     /* There was a problem detecting the BMP085 ... check your connections */
-    Serial.print("Ooops, no BMP085 detected ...");
-  }
+    Serial.print(F("Ooops, no BMP085 detected ..."));
+  }
+
+  //
+  // Setup Ethernet
+  if (ether.begin(sizeof Ethernet::buffer, _mymac) == 0)
+  {
+    Serial.println(F("Failed to access Ethernet controller"));
+  }
+
+  displayFreeRam();
+
+  Serial.println(F("Setting up static IP"));
+
+  // Static IP
+  ether.staticSetup(_arduinoIP,_gwip);
+
+  ether.printIp(F("My IP: "), ether.myip);
+  ether.printIp(F("Netmask: "), ether.mymask);
+  ether.printIp(F("GW IP: "), ether.gwip);
+  ether.printIp(F("DNS IP: "), ether.dnsip);
+
+  // Set Up destination IP
+  ether.copyIp(ether.hisip, _ttkserver);
+  ether.printIp(F("Destination Server: "), ether.hisip);
+
+  // Wait Gatway
+  Serial.print(F("Gateway ..."));
+  while (ether.clientWaitingGw())
+  {
+    ether.packetLoop(ether.packetReceive());
+  }
+  Serial.println("found !");
+
+  // Register Ping Callback
+  ether.registerPingCallback(pingCallback);
+
+  // No Request Yet
+  _app.isHttpRequest = false;
 }

 void loop() {
@@ -175,6 +251,9 @@

   // Check RX
   checkIncomingData();
+
+  // Check Ethernet
+  checkEthernet();

   // Update Local Sensor
   updateLocalSensors();
@@ -183,7 +262,7 @@
   render();

   // Wait some time
-  delay(20);
+  //delay(20);

 }

@@ -198,9 +277,9 @@

   unsigned long currentTime = millis();

-  if(touched>=TOUCH_SENSIBILITY)
-  {
-    Serial.print("!! Touched !! with sensibility of ");Serial.println(touched);
+  if(touched>=TOUCH_SENSIBILITY && currentTime - _app.lastTouched > TOUCH_DEBOUNCING)
+  {
+    Serial.print(F("!! Touched !! with sensibility of "));Serial.println(touched);

     _app.lastTouched = currentTime;

@@ -238,7 +317,7 @@
   // Paint ?
   if(_app.render.paint)
   {
-    Serial.print("Repaint sensor #");Serial.println(_app.render.currentSensor);
+    Serial.print(F("Repaint sensor #"));Serial.println(_app.render.currentSensor);

     _app.render.lcd.clear();
     _app.render.lcd.print(_app.sensors[_app.render.currentSensor].name);
@@ -265,7 +344,7 @@
   // Change current sensor
   _app.render.currentSensor = (_app.render.currentSensor + 1) % _app.nbrSensors;

-  Serial.print("Select Next Sensor #");Serial.println(_app.render.currentSensor);
+  Serial.print(F("Select Next Sensor #"));Serial.println(_app.render.currentSensor);

   // Force Repaint
   _app.render.paint = true;
@@ -290,7 +369,7 @@
       // DEBUG
       if(Serial)
       {
-        Serial.print("RX incomming data : ");
+        Serial.print(F("RX incomming data : "));

         // HEX DUMP
         for (int i = 0; i < messageLen; i++)
@@ -316,7 +395,7 @@
       }
       else
       {
-        Serial.println("Not enought data in transmition");
+        Serial.println(F("Not enought data in transmition"));

         // Try to restart RX module
         vw_rx_stop();
@@ -332,15 +411,15 @@

 void fireNewSensorValue(byte sensorID, float newValue)
 {
-  Serial.print("Sensor ID = ");Serial.print(sensorID);
-  Serial.print(", new value = ");Serial.println(newValue);
+  Serial.print(F("Sensor ID = "));Serial.print(sensorID);
+  Serial.print(F(", new value = "));Serial.println(newValue);

   // Find in the sensor the SensorDefinition
   for (int i = 0; i < (_app.nbrSensors); ++i)
   {
     if(_app.sensors[i].id==sensorID)
     {
-      Serial.print(" -> sensor is #");Serial.println(i);
+      Serial.print(F(" -> sensor is #"));Serial.println(i);

       // Update value
       _app.sensors[i].value = newValue;
@@ -349,21 +428,57 @@
       if(i==_app.render.currentSensor)
       {
         _app.render.paint = true;
-        Serial.println(" -> Repaint is requested");
+        Serial.println(F(" -> Repaint is requested"));
       }
-
-      // TODO Ethernet

       break; // Exit loop
     }
   }
+
+  //
+  // Send value to Web Server
+
+  // Convert to String
+  sprintf(_app.url, "%d/", sensorID);
+
+  // Convert Float to String
+  char newValueString[10];
+  dtostrf(newValue, 2, 2, newValueString);
+
+  strcat(_app.url,newValueString);
+
+  Serial.print(F("Full path = "));Serial.println(_app.url);
+
+
+  _app.isHttpRequest = true;
+
+   ether.browseUrl(PSTR("/cakephp/points/add/"), _app.url, PSTR("TTKSERVER"), requestUrlCallback);
+
+
+  //
+  // Wait end of HTTP Request
+  while(_app.isHttpRequest)
+  {
+      word len = ether.packetReceive();
+      word pos = ether.packetLoop(len);
+      //checkEthernet();
+  }
+
+  Serial.println(F("End Of Request"));
+
+  // Workaround to clean Ethernet ...
+  for(int i=0;i<100;i++)
+  {
+    word len = ether.packetReceive();
+    word pos = ether.packetLoop(len);
+  }
 }

 //
 // Update Local sensors
 //
-void updateLocalSensors()
+static void updateLocalSensors()
 {
   // Get time
   unsigned long currentTime = millis();
@@ -371,7 +486,7 @@
   // Check if we have to update the main sensor
   if(currentTime - _app.lastMainSensorUpdated > MAIN_SENSOR_UPDATE)
   {
-    Serial.println("Update Local Sensor");
+    Serial.println(F("Update Local Sensor"));

     _app.lastMainSensorUpdated = currentTime;

@@ -381,14 +496,71 @@
     _mainSensor.getTemperature(&buffer);

     // Notify new Value
-    fireNewSensorValue(0,buffer);
+    fireNewSensorValue(1,buffer);

     // Read Pressure sensor (in Pa)
     _mainSensor.getPressure(&buffer);

     // Notify new Value (in hPa)
-    fireNewSensorValue(1,buffer/100);
-
-  }
-}
-
+    fireNewSensorValue(2,buffer/100);
+  }
+}
+
+
+//
+// Check Ethernet bus
+//
+void checkEthernet()
+{
+  // check if anything has come in via ethernet
+  word len = ether.packetReceive();
+  word pos = ether.packetLoop(len);
+
+  // check if valid tcp data is received
+  if (pos) {
+
+    // Init Buffer
+    _etherBuffFiller = ether.tcpOffset();
+
+    char* data = (char *) Ethernet::buffer + pos;
+    Serial.println(F("Ethernet data received :"));
+    Serial.println(data);
+
+    // Populate Page to Buffer
+    _etherBuffFiller.emit_p(_indexHTML, millis());
+
+    ether.httpServerReply(_etherBuffFiller.position()); // send web page data
+  }
+}
+
+
+//
+// Ping Callback
+//
+static void pingCallback (byte* ptr) {
+  ether.printIp(">>> ping from: ", ptr);
+}
+
+//
+// End HTTP GET request
+//
+// called when the client request is complete
+static void requestUrlCallback (byte status, word off, word len) {
+  Serial.println("<<< reply ");
+  Serial.println((const char*) Ethernet::buffer + off);
+
+  _app.isHttpRequest = false; // Turn off HTTP request flag
+}
+
+
+static int freeRam () {
+  extern int __heap_start, *__brkval;
+  int v;
+  return (int) &v - (__brkval == 0 ? (int) &__heap_start : (int) __brkval);
+}
+
+void displayFreeRam()
+{
+  Serial.print(F("Free Ram ="));Serial.println(freeRam());
+}
+


added fixed for case when vel_est = 0 in arduino code

--- arduino/arduino_nano328_node/arduino_nano328_node.ino
+++ arduino/arduino_nano328_node/arduino_nano328_node.ino
@@ -115,6 +115,10 @@
     int FR_count = 0;
     int BL_count = 0;
     int BR_count = 0;
+    int FL_count_old = 0;
+    int FR_count_old = 0;
+    int BL_count_old = 0;
+    int BR_count_old = 0;
     float vel_FL = 0;
     float vel_FR = 0;
     float vel_BL = 0;
@@ -458,18 +462,27 @@

 void Car::calcVelocityEstimate() {

-  // vel = distance / time
-  // distance = 2*pi*R/8 since there are 8 partitions
-  if(FL_DeltaTime > 0){
-    vel_FL = 0.25*pi*R/(FL_DeltaTime/1000000.0);
-  }
-  if(FR_DeltaTime > 0){
-    vel_FR = 0.25*pi*R/(FR_DeltaTime/1000000.0);
-  }
-  if(BL_DeltaTime > 0){
-    vel_BL = 0.25*pi*R/(BL_DeltaTime/1000000.0);
-  }
-  if(BR_DeltaTime > 0){
-    vel_BR = 0.25*pi*R/(BR_DeltaTime/1000000.0);
-  }
-}
+    // vel = distance / time
+    // distance = 2*pi*R/8 since there are 8 partitions
+    if(FL_count_old != FL_count){
+        vel_FL = 0.25*pi*R/(FL_DeltaTime/1000000.0);    }
+    else{ vel_FL = 0.0; }
+
+    if(FR_count_old != FR_count){
+        vel_FR = 0.25*pi*R/(FR_DeltaTime/1000000.0);    }
+    else{ vel_FR = 0.0; }
+
+    if(BL_count_old != BL_count){
+        vel_BL = 0.25*pi*R/(BL_DeltaTime/1000000.0);    }
+    else{ vel_BL = 0.0; }
+
+    if(BR_count_old != BR_count){
+        vel_BR = 0.25*pi*R/(BR_DeltaTime/1000000.0);    }
+    else{ vel_BR = 0.0; }
+
+    // update history
+    FL_count_old = FL_count;
+    FR_count_old = FR_count;
+    BL_count_old = BL_count;
+    BR_count_old = BR_count;
+}


Refactor

Refactor

--- tree/tree.ino
+++ tree/tree.ino
@@ -1,40 +1,8 @@
 #include <Adafruit_NeoPixel.h>

 #define PIXEL_PIN   13    // Digital IO pin connected to the NeoPixels.
-
 #define PIXEL_COUNT 22
-
 #define BUTTON_PIN  3
-
-static const uint32_t WHITE = Adafruit_NeoPixel::Color(255, 255, 255);
-static const uint32_t OFF = Adafruit_NeoPixel::Color(0, 0, 0);
-
-class Tree
-{
-private:
-  Adafruit_NeoPixel pixels;
-  uint32_t target;
-  uint8_t steps;
-
-public:
-  Tree(uint16_t count, uint8_t pin)
-    : pixels(count, pin)
-    , target(Adafruit_NeoPixel::Color(0, 0, 0))
-    , steps(50)
-  {
-  }
-
-  void setup()
-  {
-    pixels.begin();
-    pixels.show();
-  }
-
-  void step()
-  {
-    pixels.show();
-  }
-};

 class Button
 {
@@ -101,10 +69,52 @@
   }
 };

+class Nightlight
+{
+private:
+  byte brightness;
+  int8_t brightnessDelta;
+
+public:
+  Nightlight()
+    : brightness(10)
+    , brightnessDelta(1)
+  {
+  }
+
+  void held()
+  {
+    if (brightnessDelta > 0 && brightness == 255) {
+      brightnessDelta = -1;
+    } else if (brightnessDelta < 0 && brightness == 0) {
+      brightnessDelta = 1;
+    }
+    brightness += brightnessDelta;
+
+    Serial.print("Brightness ");
+    Serial.println(brightness);
+  }
+
+  void released()
+  {
+    brightnessDelta = -brightnessDelta;
+  }
+
+  void reset()
+  {
+    brightness = 0;
+    brightnessDelta = 1;
+  }
+
+  uint32_t colour()
+  {
+    return Adafruit_NeoPixel::Color(brightness, brightness/2, 0);
+  }
+};
+
 Adafruit_NeoPixel pixels(PIXEL_COUNT, PIXEL_PIN);
 Button button(BUTTON_PIN);
-byte brightness = 10;
-int brightnessDelta = 1;
+Nightlight nightlight;
 byte on = false;
 byte lastHeld = false;

@@ -126,7 +136,7 @@
     if (on) {
       Serial.println("Turning on");
       for (int i = 0; i != pixels.numPixels(); ++i) {
-        pixels.setPixelColor(i, brightness, brightness/2, 0);
+        pixels.setPixelColor(i, nightlight.colour());
       }
     } else {
       Serial.println("Turning off");
@@ -138,23 +148,14 @@
   const byte held = button.held();

   if (held) {
-    Serial.println(brightnessDelta);
     if (on) {
-      if (brightnessDelta > 0 && brightness == 255) {
-        brightnessDelta = -1;
-      } else if (brightnessDelta < 0 && brightness == 0) {
-        brightnessDelta = 1;
-      }
-      brightness += brightnessDelta;
+      nightlight.held();
     } else {
       on = true;
-      brightness = 0;
-      brightnessDelta = 1;
+      nightlight.reset();
     }
-    Serial.print("Brightness ");
-    Serial.println(brightness);
     for (int i = 0; i != pixels.numPixels(); ++i) {
-      pixels.setPixelColor(i, brightness, brightness/2, 0);
+      pixels.setPixelColor(i, nightlight.colour());
     }
     pixels.show();
   }
@@ -162,7 +163,7 @@
   if (held != lastHeld) {
     lastHeld = held;
     if (!held) {
-      brightnessDelta = -brightnessDelta;
+      nightlight.released();
     }
   }


Added arduino version of the backend

Added arduino version of the backend