Fixed intermittent read problems.

Fixed intermittent read problems.

--- examples/MLX90614_demo/MLX90614_demo.ino
+++ examples/MLX90614_demo/MLX90614_demo.ino
@@ -40,34 +40,73 @@
 AsyncDelay samplingInterval;

+
+uint8_t crc8_update(uint8_t crc, uint8_t data)
+{
+  const uint16_t polynomial = 0x107;
+  crc ^= data;
+  for (uint8_t i = 8; i; --i) {
+    if (crc & 0x80)
+      crc = (uint16_t(crc) << 1) ^ polynomial;
+    else
+      crc <<= 1;
+  }
+
+  return crc;
+}
+
 float convertToDegC(uint16_t data)
 {
   // Remove MSB (error bit, ignored for temperatures)
-  return (((data & (uint16_t)0x7FFF)) / 50) - 273.15;
+  return (((data & (uint16_t)0x7FFF)) / 50.0) - 273.15;
 }

+// Switch from PWM mode (if it was enabled)
+void exitPWM(void)
+{
+  // Make SMBus request to force SMBus output instead of PWM
+  SoftWire::setSclLow(&i2c);
+  delay(3); // Must be > 1.44ms
+  SoftWire::setSclHigh(&i2c);
+  delay(2);
+}

-uint16_t readMLX90614(uint8_t command)
+uint16_t readMLX90614(uint8_t command, uint8_t &crc)
 {
   uint8_t address = 0x5A;
   uint8_t dataLow = 0;
   uint8_t dataHigh = 0;
   uint8_t pec = 0;
+
+  uint8_t errors = 0;
+  digitalWrite(LED_BUILTIN, HIGH); delayMicroseconds(50);
+  // Send command
+  errors += i2c.startWait(address, SoftWire::writeMode);
+  errors += i2c.rawWrite(command);

-  digitalWrite(LED_BUILTIN, HIGH); delayMicroseconds(50);
-  i2c.startWait(address, SoftWire::writeMode);
-  i2c.rawWrite(command);
-
-  // read
-  i2c.repeatedStart(address, SoftWire::readMode);
-  i2c.readThenAck(dataLow);  // Read 1 byte and then send ack
-  i2c.readThenAck(dataHigh); // Read 1 byte and then send ack
-  i2c.readThenNack(pec);
+  // Read results
+  errors += i2c.repeatedStart(address, SoftWire::readMode);
+  errors += i2c.readThenAck(dataLow);  // Read 1 byte and then send ack
+  errors += i2c.readThenAck(dataHigh); // Read 1 byte and then send ack
+  errors += i2c.readThenNack(pec);
   i2c.stop();
   digitalWrite(LED_BUILTIN, LOW);

+  crc = 0;
+  crc = crc8_update(crc, address << 1); // Write address
+  crc = crc8_update(crc, command);
+  crc = crc8_update(crc, (address << 1) + 1); // Read address
+  crc = crc8_update(crc, dataLow);
+  crc = crc8_update(crc, dataHigh);
+  crc = crc8_update(pec, pec);
+  //Serial.print("      crc: "); Serial.println(crc, HEX);
+
+  if (errors) {
+    crc = 0xFF;
+    return 0xFFFF;
+  }
   return (uint16_t(dataHigh) << 8) | dataLow;
 }

@@ -77,7 +116,7 @@
 void setup(void)
 {
   Serial.begin(9600);
-  Serial.println("MLX90614_demo");
+  Serial.println("MLX90614 demo: " __FILE__);

   pinMode(LED_BUILTIN, OUTPUT);

@@ -92,13 +131,15 @@

   /*
    * Uncomment if needed. Not a good idea if power switched on/off
-   * since the sensor will be parastically powered from the SDA and
+   * since the sensor will be parasitically powered from the SDA and
    * SCL control lines.
   */
-  // i2c.enablePullups();
+  //i2c.enablePullups();

   i2c.setDelay_us(5);
   i2c.begin();
+  delay(300); // Data is available 0.25s after wakeup
+  exitPWM();
 }

@@ -106,19 +147,45 @@
 {
 #ifdef CALUNIUM
   digitalWrite(powerPin, HIGH);
-  delay(1000);
+  delay(300); // Data available after 0.25s
+  exitPWM();
 #endif
-
+
+  uint8_t crcAmbient;
+  uint16_t rawAmbient = readMLX90614(cmdAmbient, crcAmbient);
+  uint8_t crcObject1;
+  uint16_t rawObject1 = readMLX90614(cmdObject1, crcObject1);
+  // Uncomment lines below for dual FoV sensors
+  // uint8_t crcObject2;
+  // uint16_t rawObject2 = readMLX90614(cmdObject2, crcObject2);
+
   Serial.print("Ambient: ");
-  Serial.print(convertToDegC(readMLX90614(cmdAmbient)));
+  if (crcAmbient)
+    Serial.print("bus error");
+  else if (rawAmbient & 0x8000)
+    Serial.print("read error");
+  else
+    Serial.print(convertToDegC(rawAmbient));
+
   Serial.print("    Object 1: ");
-  Serial.print(convertToDegC(readMLX90614(cmdObject1)));
+  if (crcObject1)
+    Serial.print("bus error");
+  else if (rawObject1 & 0x8000)
+    Serial.print("read error");
+  else
+    Serial.print(convertToDegC(rawObject1));
+
   // Uncomment lines below for dual FoV sensors
   // Serial.print("    Object 2: ");
-  // Serial.print(convertToDegC(readMLX90614(cmdObject2)));
+  // if (rawObject2 & 0x8000)
+  //   Serial.print("read error");
+  // else if (crcObject2)
+  //   Serial.print("bus error");
+  // else
+  //   Serial.print(convertToDegC(rawObject2));
   Serial.println();
 #ifdef CALUNIUM
   digitalWrite(powerPin, LOW);
 #endif
-  delay(2000);
+  delay(1000);
 }


Publish events

Publish events

--- ManeAvis.ino
+++ ManeAvis.ino
@@ -123,6 +123,8 @@
   alarmRuntime.start();
   RGB.color(0, 0, 255);

+  Particle.publish("alarm:start", Time.format(Time.now(), TIME_FORMAT_ISO8601_FULL));
+
   /*parser = new AlarmToneLanguage(song);*/
   /*player.reset();*/
 }
@@ -142,6 +144,8 @@

   RGB.color(0, 0, 0);
   RGB.brightness(0);
+
+  Particle.publish("alarm:end", Time.format(Time.now(), TIME_FORMAT_ISO8601_FULL));

   /*delete parser;*/
 }
@@ -198,10 +202,21 @@
 }*/

 int handleAlarm(String value) {
+  bool result = false;
   switch(value.charAt(0)) {
-    case '+': return alarms.add(value.substring(1)) ? 1 : -1;
-    case '-': return alarms.remove(value.substring(1)) ? 1 : -1;
-    case '#': return alarms.clear() ? 1 : -1;
-    default:  return -1;
-  }
-}
+    case '+':
+      result = alarms.add(value.substring(1));
+      Particle.publish("alarm:add", value.substring(1));
+      break;
+    case '-':
+      result = alarms.remove(value.substring(1));
+      Particle.publish("alarm:remove", value.substring(1));
+      break;
+    case '#':
+      result = alarms.clear();
+      Particle.publish("alarm:clear");
+      break;
+  }
+
+  return result ? 1 : -1;
+}


modified arduino program

modified arduino program

--- arduino/RobotControl.ino
+++ arduino/RobotControl.ino
@@ -1,11 +1,17 @@
 #include <MeetAndroid.h>
+

 #define LEFTSIDE_NEG   9
 #define LEFTSIDE_POS   10
 #define RIGHTSIDE_NEG  5
 #define RIGHTSIDE_POS  6
+#define TRIGGER_PIN    12
+#define ECHO_PIN       11
+
+

 MeetAndroid meetAndroid;
+

 void setup(){

@@ -13,7 +19,10 @@

  meetAndroid.registerFunction(forward, 'w');
  meetAndroid.registerFunction(backward, 's');
+ meetAndroid.registerFunction(leftTurn, 'a');
+ meetAndroid.registerFunction(rightTurn, 'd');
  meetAndroid.registerFunction(stopIt, 'x');
+

   pinMode(LEFTSIDE_NEG, OUTPUT);
   pinMode(LEFTSIDE_POS, OUTPUT);
@@ -26,6 +35,10 @@
 void loop(){

   meetAndroid.receive();
+
+  getSonar();
+
+  delay(100);

 }

@@ -51,8 +64,35 @@
   analogWrite(LEFTSIDE_POS,meetAndroid.getInt());
   analogWrite(RIGHTSIDE_POS,meetAndroid.getInt());
   analogWrite(LEFTSIDE_NEG,meetAndroid.getInt());
-  analogWrite(LEFTSIDE_NEG,meetAndroid.getInt());
+  analogWrite(RIGHTSIDE_NEG,meetAndroid.getInt());
+}
+
+void leftTurn(byte flag, byte numOfValues){
+  analogWrite(LEFTSIDE_POS,0);
+  analogWrite(LEFTSIDE_NEG,meetAndroid.getInt());
+  analogWrite(RIGHTSIDE_POS,meetAndroid.getInt());
+  analogWrite(RIGHTSIDE_NEG,0);
+  Serial.print(meetAndroid.getInt());
+}
+
+void rightTurn(byte flag, byte numOfValues){
+   analogWrite(LEFTSIDE_POS,meetAndroid.getInt());
+   analogWrite(LEFTSIDE_NEG,0);
+   analogWrite(RIGHTSIDE_POS,0);
+   analogWrite(RIGHTSIDE_NEG,meetAndroid.getInt());
+}
+
+void getSonar(){
+  int duration,distance;
+
+  duration = pulseIn(ECHO_PIN,HIGH);
+  distance = (duration/2)/29.1;
+
+  meetAndroid.send(distance);
+  Serial.println(distance);
+
 }

+


Initial implementation of (almost?) all hardware pwm pins on the flyduino

--- arduino/bridgehead_pwm/bridgehead_pwm.ino
+++ arduino/bridgehead_pwm/bridgehead_pwm.ino
@@ -12,6 +12,9 @@
 with frequencies up to 187kHz

 */
+
+int pin_pulse = 7;
+

 /**********************************************************
    Fast PWM on pins 9,10,11 (TIMER 1)
@@ -142,26 +145,115 @@
   pwm_5_6_configure(PWM23k);

   Serial.begin(9600);
-}
-
-int i = 0;
+
+  pinMode(pin_pulse, INPUT_PULLUP);
+}
+
+int min_int(int one, int other) {
+  if (one < other)
+    return one;
+  return other;
+}
+
+int max_int(int one, int other) {
+  if (one > other)
+    return one;
+  return other;
+}
+
+int rpm_target = 200;
+int pwm_value = 40;
+int pwm_min = 28;
+int pwm_max = 255;
+bool upwards = true;
+
+/*
+ * free air
+ * PWM - RPM - ticking
+ *   0 - off/restart
+ *   1 - off/restart
+ *   2 - off/restart
+ *   3 - off/restart
+ *   4 - off/restart
+ *   5 - off/restart
+ *   6 - off/restart
+ *   7 - off/restart
+ *   8 - off/restart
+ *   9 - off/restart
+ *  10 - off/restart
+ *  11 - off/restart
+ *  12 - off/restart
+ *  13 - off/restart
+ *  14 - off/restart
+ *  15 - off/restart
+ *  16 - off/restart
+ *  17 - off/restart
+ *  18 - off/restart
+ *  19 - off/restart
+ *  20 - off/restart
+ *  21 - off/restart
+ *  22 - off/restart
+ *  23 - off/restart
+ *  24 - off/restart
+ *  25 - off/restart
+ *  26 - off/restart
+ *  27 - off/restart
+ *  28 -  120
+ *  32 -  180 - faint
+ *  40 -  240 - yes
+ *  48 -  360 - yes
+ *  64 -  480 - yes
+ *  96 -  840 - yes
+ * 128 - 1140 - yes
+ * 130 - 1140 - yes
+ * 135 - 1140 - yes
+ * 138 - 1200 - yes
+ * 140 - 1200 - yes
+ * 150 - 1320 - faint
+ * 153 - 1320 - faint
+ * 155 - 1380 - no
+ * 160 - 1380 - no
+ * 256 - off - no
+ */

 void loop() {
-  // Variate throttle between 16 and 25 %
-  int value = 16 + i;
-  i = (i + 1) % 64;
-
+  unsigned long pulseDuration = pulseIn(pin_pulse, LOW);
+  double frequency = 1000000 / pulseDuration;
+  int rpm_current = (int) frequency / 4 * 60;
+  Serial.print("RPM:");
+  Serial.println(rpm_current);
+
+  // target rpm
+/*
+  if (rpm_current < rpm_target - 1.5 / 255.0 * rpm_target)
+    pwm_value = min_int(pwm_value + 1, 255);
+  if (rpm_current > rpm_target + 1.5 / 255.0 * rpm_target)
+    pwm_value = max_int(pwm_value - 1, 0);
+*/
+
+
+  // sweep rpm
+  if (pwm_value == pwm_min)
+    upwards = true;
+  if (pwm_value == pwm_max)
+    upwards = false;
+  if (upwards)
+    pwm_value = pwm_value + 1;
+  else
+    pwm_value = pwm_value - 1;
+
   // Those fast macros require a previous configuration
   // of the channels using the pwmSet9 and pwmSet6
   // functions
   // PWMn macros are fast to execute
-  PWM5 = 255 - value;
-  PWM6 = value;
-  PWM9 = value;
-  PWM10 = value;
-  PWM11 = value; // TODO there is no pin 11 on the leonardo clones, I am using
-
-  Serial.println(value, DEC);
+  PWM5 = 255 - pwm_value;
+  PWM6 = pwm_value;
+  PWM9 = pwm_value;
+  PWM10 = pwm_value;
+  PWM11 = pwm_value; // TODO there is no pin 11 on the leonardo clones, I am using
+
+  Serial.print("PWM:");
+  Serial.println(pwm_value, DEC);

   // Small delay
   delay(100);


Code cleaning

Code cleaning

--- trackballPro.ino
+++ trackballPro.ino
@@ -35,17 +35,17 @@
 // =================================================================================
 typedef struct ENCODER_
 {
-  int8_t  coordinate;
-  uint8_t index;
+    int8_t  coordinate;
+    uint8_t index;
 } ENCODER_;

 typedef struct BUTTON_
 {
-  boolean state;
-  boolean needUpdate;
-  char    button;
-  byte    bitmask;
-  long    lastDebounceTime;
+    boolean state;
+    boolean needUpdate;
+    char    button;
+    byte    bitmask;
+    long    lastDebounceTime;
 } BUTTON_;

 // =================================================================================
@@ -71,14 +71,14 @@
 // =================================================================================
 void setup()
 {
-  // Attach interruption to encoders channels
-  attachInterrupt(0, ISR_HANDLER_X, CHANGE);
-  attachInterrupt(1, ISR_HANDLER_X, CHANGE);
-  attachInterrupt(2, ISR_HANDLER_Y, CHANGE);
-  attachInterrupt(3, ISR_HANDLER_Y, CHANGE);
-
-  // Start the mouse function
-  Mouse.begin();
+    // Attach interruption to encoders channels
+    attachInterrupt(0, ISR_HANDLER_X, CHANGE);
+    attachInterrupt(1, ISR_HANDLER_X, CHANGE);
+    attachInterrupt(2, ISR_HANDLER_Y, CHANGE);
+    attachInterrupt(3, ISR_HANDLER_Y, CHANGE);
+
+    // Start the mouse function
+    Mouse.begin();
 }

 // =================================================================================
@@ -86,34 +86,34 @@
 // =================================================================================
 void loop()
 {
-  // Update mouse coordinates
-  if (xAxis.coordinate != 0 || yAxis.coordinate != 0)
-  {
-    Mouse.move(xAxis.coordinate, yAxis.coordinate);
-    xAxis.coordinate = 0;
-    yAxis.coordinate = 0;
-  }
+    // Update mouse coordinates
+    if (xAxis.coordinate != 0 || yAxis.coordinate != 0)
+    {
+        Mouse.move(xAxis.coordinate, yAxis.coordinate);
+        xAxis.coordinate = 0;
+        yAxis.coordinate = 0;
+    }

-  // ---------------------------------
-  // Left mouse button state update
-  // ---------------------------------
-  ReadButton(leftButton);
-  UpdateButton(leftButton);
+    // ---------------------------------
+    // Left mouse button state update
+    // ---------------------------------
+    ReadButton(leftButton);
+    UpdateButton(leftButton);

-  // ---------------------------------
-  // Right mouse button state update
-  // ---------------------------------
-  ReadButton(rightButton);
-  UpdateButton(rightButton);
-
-  // ---------------------------------
-  // Middle mouse button state update
-  // ---------------------------------
-  ReadButton(middleButton);
-  UpdateButton(middleButton);
+    // ---------------------------------
+    // Right mouse button state update
+    // ---------------------------------
+    ReadButton(rightButton);
+    UpdateButton(rightButton);

-  // Wait a little before next update
-  delay(10);
+    // ---------------------------------
+    // Middle mouse button state update
+    // ---------------------------------
+    ReadButton(middleButton);
+    UpdateButton(middleButton);
+
+    // Wait a little before next update
+    delay(10);
 }

 // =================================================================================
@@ -121,16 +121,16 @@
 // =================================================================================
 void ISR_HANDLER_X()
 {
-  // Build the LUT index from previous and new data
-  xAxis.index       = (xAxis.index << 2) | ((PIND & 0b00000011) >> 0);
-  xAxis.coordinate += lookupTable[xAxis.index & 0b00001111];
+    // Build the LUT index from previous and new data
+    xAxis.index       = (xAxis.index << 2) | ((PIND & 0b00000011) >> 0);
+    xAxis.coordinate += lookupTable[xAxis.index & 0b00001111];
 }

 void ISR_HANDLER_Y()
 {
-  // Build the LUT index from previous and new data
-  yAxis.index       = (yAxis.index << 2) | ((PIND & 0b00001100) >> 2);
-  yAxis.coordinate += lookupTable[yAxis.index & 0b00001111];
+    // Build the LUT index from previous and new data
+    yAxis.index       = (yAxis.index << 2) | ((PIND & 0b00001100) >> 2);
+    yAxis.coordinate += lookupTable[yAxis.index & 0b00001111];
 }

 // =================================================================================
@@ -138,32 +138,25 @@
 // =================================================================================
 void ReadButton(BUTTON_& button)
 {
-  // Variables
-  long    currentime;
-  boolean switchState;
-  boolean debounced;
-
-  // Get current time
-  currentime = millis();
-  debounced  = (currentime - button.lastDebounceTime > DEBOUNCE_THREASHOLD);
+    // Variables
+    long    currentime  = millis();
+    boolean switchState = !(PINB & button.bitmask);
+    boolean debounced   = (currentime - button.lastDebounceTime > DEBOUNCE_THREASHOLD);

-  // Get current switch state
-  switchState = !(PINB & button.bitmask);
-
-  // Button state acquisition
-  if ((switchState != button.state) && debounced)
-  {
-    button.lastDebounceTime = currentime;
-    button.state            = switchState;
-    button.needUpdate       = true;
-  }
+    // Button state acquisition
+    if ((switchState != button.state) && debounced)
+    {
+        button.lastDebounceTime = currentime;
+        button.state            = switchState;
+        button.needUpdate       = true;
+    }
 }

 void UpdateButton(BUTTON_& button)
 {
-  if (button.needUpdate)
-  {
-    (button.state) ? Mouse.press(button.button) : Mouse.release(button.button);
-    button.needUpdate = false;
-  }
+    if (button.needUpdate)
+    {
+        (button.state) ? Mouse.press(button.button) : Mouse.release(button.button);
+        button.needUpdate = false;
+    }
 }


The whole project works

The whole project works

--- the_whole_project/the_whole_project.ino
+++ the_whole_project/the_whole_project.ino
@@ -20,13 +20,16 @@
 #include <DS3231.h>
 #include <SPI.h>
 #include <SD.h>
+#include <sha1.h>

 #define BUTTON_PIN 42
 #define SD_PIN 4
 #define KEY_FILE "key.txt"
+#define INTERVAL 30
+#define TOKEN_LENGTH 6

 DS3231 rtc(SDA, SCL);
-String key = "";
+uint8_t key[20];
 int previousButtonState = HIGH;

 // Gets a UNIX timestamp from the RTC
@@ -42,6 +45,15 @@
   }

   return Serial.parseInt();
+}
+
+void printHash(uint8_t* hash, size_t len) {
+  int i;
+  for (i=0; i<len; i++) {
+    Serial.print("0123456789abcdef"[hash[i]>>4]);
+    Serial.print("0123456789abcdef"[hash[i]&0xf]);
+  }
+  Serial.println();
 }

 // Prompts to set the time on the RTC
@@ -72,7 +84,76 @@
   } else if (command == "set time") {
     setTime();
   } else if (command == "key") {
-    Serial.println(key);
+    printHash(key, 20);
+    Serial.println();
+  }
+}
+
+// From https://code.google.com/p/google-authenticator/source/browse/libpam/base32.c
+int base32_decode(const uint8_t *encoded, uint8_t *result, int bufSize) {
+  int buffer = 0;
+  int bitsLeft = 0;
+  int count = 0;
+  for (const uint8_t *ptr = encoded; count < bufSize && *ptr; ++ptr) {
+    uint8_t ch = *ptr;
+    if (ch == ' ' || ch == '\t' || ch == '\r' || ch == '\n' || ch == '-') {
+      continue;
+    }
+    buffer <<= 5;
+
+    // Deal with commonly mistyped characters
+    if (ch == '0') {
+      ch = 'O';
+    } else if (ch == '1') {
+      ch = 'L';
+    } else if (ch == '8') {
+      ch = 'B';
+    }
+
+    // Look up one base32 digit
+    if ((ch >= 'A' && ch <= 'Z') || (ch >= 'a' && ch <= 'z')) {
+      ch = (ch & 0x1F) - 1;
+    } else if (ch >= '2' && ch <= '7') {
+      ch -= '2' - 26;
+    } else {
+      return -1;
+    }
+
+    buffer |= ch;
+    bitsLeft += 5;
+    if (bitsLeft >= 8) {
+      result[count++] = buffer >> (bitsLeft - 8);
+      bitsLeft -= 8;
+    }
+  }
+  if (count < bufSize) {
+    result[count] = '\000';
+  }
+  return count;
+}
+
+void totp(uint8_t* secret, const size_t len, const long time, char token[TOKEN_LENGTH]) {
+  long timestamp = time / INTERVAL;
+  uint8_t input[8] = { 0x00, 0x00, 0x00, 0x00 };
+  input[4] = (timestamp >> 24) & 0xff;
+  input[5] = (timestamp >> 16) & 0xff;
+  input[6] = (timestamp >> 8) & 0xff;
+  input[7] = timestamp & 0xff;
+
+  Sha1.initHmac(secret, len);
+  Sha1.write(input, 8);
+  uint8_t* hash = Sha1.resultHmac();
+
+  uint8_t offset = hash[19] & 0xf;
+
+  unsigned long thing = ((hash[offset] & 0x7f) << 24)
+                      | ((hash[offset + 1] & 0xff) << 16)
+                      | ((hash[offset + 2] & 0xff) << 8)
+                      | ((hash[offset + 3] & 0xff));
+
+  for (int i = TOKEN_LENGTH - 1; i >= 0; i--) {
+    token[i] = (thing % 10) + '0';
+    thing /= 10;
   }
 }

@@ -97,12 +178,16 @@
     Serial.println("SD card has no key.txt");
     return;
   }
+  String keyString = "";
   while (keyFile.available()) {
     char ch = keyFile.read();
     if (ch == ' ' || ch == '\n') continue;
-    key.concat(ch);
+    keyString.concat(ch);
   }
   keyFile.close();
+  uint8_t keyText[33];
+  keyString.toCharArray((char*)keyText, 33);
+  base32_decode(keyText, key, 20);

   // Set up the keyboard
   Keyboard.begin();
@@ -118,7 +203,9 @@
   if (Serial.available()) {
     command();
   } else if (buttonState == HIGH && previousButtonState == LOW) {
-    Keyboard.print(key);
+    char token[TOKEN_LENGTH];
+    totp(key, 20, getTimestamp(), token);
+    Keyboard.print(token);
   } else {
     delay(100);
   }


3 moves

3 moves

--- src/main.ino
+++ src/main.ino
@@ -16,20 +16,29 @@
   m3.attach(4);
   m4.attach(5);
   m5.attach(6);
+
+  Serial.begin(9600);
 }

 // LOOP //
 void loop() {
-  int emg = analogRead(A0);
+  int emg = analogRead(A4);

-  if (emg < 200) {
+  Serial.println(emg);
+
+  if (emg < 50) {
     allFingers(700);
-    } else if (emg > 200) {
+    Serial.println("open");
+  } else if (emg > 50 && emg < 200) {
+    pinch();
+    Serial.println("pinch");
+  } else if (emg > 700) {
     allFingers(2300);
+    Serial.println("fisten");
   }
-  delay(1000);
-
+  delay(100);
+}

 // FUNCTIONS //
 void allFingers(int pos) {
@@ -44,11 +53,11 @@
 }

 void pinch() {
-  m1.write(90);
-  m2.write(90);
-  m3.write(180);
-  m4.write(180);
-  m5.write(180);
+  m1.writeMicroseconds(2300);
+  m2.writeMicroseconds(2300);
+  m3.writeMicroseconds(700);
+  m4.writeMicroseconds(700);
+  m5.writeMicroseconds(700);
   delay(100);
 }


Double the maximum delay for ramp

Double the maximum delay for ramp

--- code/MotorController/MotorController.ino
+++ code/MotorController/MotorController.ino
@@ -45,7 +45,7 @@
 // Settings and limits
 const int switchDebounceTime = 30;
 const int minimumDelay = 10;
-const int maximumDelay = 23;
+const int maximumDelay = 46;
 const int minimumSpeed = 26;
 // 10K ohm potentiometers probably won't get all the way to 1024
 // and we want to make sure that max feasible input = max motor speed


Arduino: Leonardo specific mod, and device identifier

--- humidity1/humidity1.ino
+++ humidity1/humidity1.ino
@@ -23,7 +23,9 @@

 void setup() {
   Serial.begin(115200);
-  Serial.println(F("Humidity sensor"));
+  while (!Serial) {
+    ; // wait for serial port to connect. Needed for Leonardo only
+  }
   pinMode(VCCPin, OUTPUT);
   t = micros();
 }
@@ -51,6 +53,7 @@
         digitalWrite(VCCPin, HIGH);

         hum = GetHumidity(res, temp);
+        Serial.print("H,");  // Device identifier
         Serial.print(hum);
         Serial.print(",");
         Serial.print(res);


Update iGPS.ino

Update iGPS.ino

修正字符串至浮点数转换

--- iGPS.ino
+++ iGPS.ino
@@ -250,43 +250,33 @@
 }

-
 /**
- * 数据转换：将字符型数据转换为浮点型数据
- * data：要转换的数组；
- * num：保留位数
+ * 字符串变浮点数
  */
-double dataTransfer(char *data, char num) {
-  double d = 0.0;
-	char zero = 0x30;
-	//负数的情况
-	if (data[0] == '-') {
-		unsigned char i = 1;
-		//数组中的字符型数据转换成整数并累加
-		while (data[i] != '.') {
-			d = d * 10 + (data[i++] - zero);
-		}
-		for (unsigned char j = 0; j < num; j++) {
-			d = d * 10 + (data[++i] - zero);
-		}
-		//将转换后的整数转换成浮点数
-		for (unsigned char j = 0; j < num; j++) {
-			d = d / 10;
-		}
-		//转换成负数
-		d = (-1) * d;
-	} else {
-		//正数情况
-		unsigned char i = 0;
-		while (data[i] != '.') {
-			d = d * 10 + (data[i++] - zero);
-		}
-		for (unsigned char j = 0; j < num; j++) {
-			d = d * 10 + (data[++i] - zero);
-		}
-		for (unsigned char j = 0; j < num; j++) {
-			d = d / 10;
-		}
-	}
-	return d;
-}
+double toDouble(String str){
+  double d = 0.000;
+  int index = str.indexOf('.');
+
+  if(index){
+    int i = str.substring(0, (index+1)).toInt();
+    String s = str.substring((index+1), str.length());
+    int f = s.toInt();
+
+    // int
+    d += i;
+
+    double t = 0.0 + f;
+    // float
+    for(int j = 0; j < s.length(); j++) {
+      t = t/10;
+    }
+
+    if(i > 0 ){
+      d += t;
+    } else {
+      d += (-1) * t;
+    }
+
+  }
+  return d;
+}


Update turtlebot3_with_open_manipulator_core.ino

--- arduino/opencr_arduino/opencr/libraries/turtlebot3/examples/turtlebot3_with_open_manipulator/turtlebot3_with_open_manipulator_core/turtlebot3_with_open_manipulator_core.ino
+++ arduino/opencr_arduino/opencr/libraries/turtlebot3/examples/turtlebot3_with_open_manipulator/turtlebot3_with_open_manipulator_core/turtlebot3_with_open_manipulator_core.ino
@@ -871,8 +871,8 @@
       sprintf(log_msg, "Connected to OpenCR board!");
       nh.loginfo(log_msg);

-      sprintf(log_msg, init_log_data);
-      nh.loginfo(log_msg);
+//       sprintf(log_msg, init_log_data);
+//       nh.loginfo(log_msg);

       sprintf(log_msg, "--------------------------");
       nh.loginfo(log_msg);
@@ -1002,4 +1002,4 @@
   DEBUG_SERIAL.print("         x : "); DEBUG_SERIAL.println(odom_pose[0]);
   DEBUG_SERIAL.print("         y : "); DEBUG_SERIAL.println(odom_pose[1]);
   DEBUG_SERIAL.print("     theta : "); DEBUG_SERIAL.println(odom_pose[2]);
-}+}


too short time for JointTrajectoryPoint

too short time for JointTrajectoryPoint

--- arduino/opencr_arduino/opencr/libraries/turtlebot3/examples/turtlebot3_with_open_manipulator/turtlebot3_with_open_manipulator_core/turtlebot3_with_open_manipulator_core.ino
+++ arduino/opencr_arduino/opencr/libraries/turtlebot3/examples/turtlebot3_with_open_manipulator/turtlebot3_with_open_manipulator_core/turtlebot3_with_open_manipulator_core.ino
@@ -634,8 +634,8 @@
   const double JOINT_CONTROL_PERIOD = 1.0f / (double)JOINT_CONTROL_FREQEUNCY;
   static uint32_t points = 0;

-  static uint8_t wait_for_write = 0;
-  static uint8_t loop_cnt = 0;
+  static uint16_t wait_for_write = 0;
+  static uint16_t loop_cnt = 0;

   if (is_moving == true)
   {


Remove comment.

Remove comment.

--- rswtch2/rswtch2.ino
+++ rswtch2/rswtch2.ino
@@ -137,7 +137,6 @@
          * packet we received */
         Udp.beginPacket(Udp.remoteIP(), Udp.remotePort());
         if (found) {
-            //Udp.write("0");
             Udp.print(0);
             found = false;
         } else {


Notion of run-once tests...

Notion of run-once tests...

--- test_SECFRAME/test_SECFRAME.ino
+++ test_SECFRAME/test_SECFRAME.ino
@@ -846,6 +846,18 @@
   testBeaconEncoding();

+  // Run-once tests.
+  // May cause wear on (eg) EEPROM, so only run once,
+  // and only after everything else has passed.
+  static bool runOnce;
+  if(!runOnce)
+    {
+    Serial.print(F("Run-once tests... "));
+    // TODO
+    runOnce = true;
+    }
+
+
   // Announce successful loop completion and count.
   ++loopCount;
   Serial.println();


Start chilled

Start chilled

--- Firmware/R2-Quadcopter/R2-Quadcopter.ino
+++ Firmware/R2-Quadcopter/R2-Quadcopter.ino
@@ -271,10 +271,21 @@
   attachInterrupt(A4, calcSignal4, CHANGE);

   //Motors init
-  esc_1.attach(MOTOR_PIN_FRONT_RIGHT);
-  esc_2.attach(MOTOR_PIN_FRONT_LEFT);
-  esc_3.attach(MOTOR_PIN_BACK_LEFT);
-  esc_4.attach(MOTOR_PIN_BACK_RIGHT);
+  esc_1.attach(MOTOR_PIN_FRONT_RIGHT, 1000, 2000);
+  esc_2.attach(MOTOR_PIN_FRONT_LEFT, 1000, 2000);
+  esc_3.attach(MOTOR_PIN_BACK_LEFT, 1000, 2000);
+  esc_4.attach(MOTOR_PIN_BACK_RIGHT, 1000, 2000);
+
+  esc_1.writeMicroseconds(1000);
+  esc_2.writeMicroseconds(1000);
+  esc_3.writeMicroseconds(1000);
+  esc_4.writeMicroseconds(1000);
+
+  Proportional_roll, Integral_roll, Derivative_roll = 0;
+  Proportional_pitch, Integral_pitch, Derivative_pitch = 0;
+  Proportional_yaw, Integral_yaw, Derivative_yaw = 0;
+
+  delay(5000);
 }

@@ -323,6 +334,7 @@
     esc_2.writeMicroseconds(motorFL);
     esc_3.writeMicroseconds(motorBL);
     esc_4.writeMicroseconds(motorBR);
+
   } else if (input4 < 1500) {
     motorFR = 1000;
     motorFL = 1000;


Fixed HamShield.h reference and indenting in FM Beacon example sketch.

--- examples/FMBeacon/FMBeacon.ino
+++ examples/FMBeacon/FMBeacon.ino
@@ -8,7 +8,7 @@

 */

-#include <HAMShield.h>
+#include <HamShield.h>
 #include <Wire.h>

 HAMShield radio;
@@ -17,18 +17,7 @@
   Serial.begin(9600);
   Serial.println("starting up..");
   Wire.begin();
-
-  pinMode(11, OUTPUT);
-
-  //testing
-  //Wire.beginTransmission(42);
-  //Wire.write('T');
-  //Wire.write('e');
-  //Wire.write('s');
-  //Wire.write('t');
-  //Wire.endTransmission();
-
-
+
   Serial.print("Radio status: ");
   int result = radio.testConnection();
   Serial.println(result,DEC);
@@ -38,16 +27,17 @@
 }

 void loop() {
-  //while(1){}
-   //if(radio.waitForChannel(30000,2000)) {     // wait up to 30 seconds for a clear channel, and then 2 seconds of empty channel
-      Serial.println("Signal is clear -- Transmitting");
-      radio.setModeTransmit();                // turn on the transmitter
-      radio.morseOut("1ZZ9ZZ/B CN87 ARDUINO HAMSHIELD");
-      radio.setModeReceive();                 // turn off the transmitter (receive mode)
-      Serial.print("TX Off");
-      //delay(30000);
-   //} else { Serial.println("The channel was busy. Waiting 10 seconds."); delay(10000); }
-   delay(10000);
+  if(radio.waitForChannel(30000,2000)) {     // wait up to 30 seconds for a clear channel, and then 2 seconds of empty channel
+    Serial.println("Signal is clear -- Transmitting");
+    radio.setModeTransmit();                // turn on the transmitter
+    radio.morseOut("1ZZ9ZZ/B CN87 ARDUINO HAMSHIELD");
+    radio.setModeReceive();                 // turn off the transmitter (receive mode)
+    Serial.print("TX Off");
+    delay(30000);
+  } else {
+    Serial.println("The channel was busy. Waiting 10 seconds.");
+    delay(10000);
+  }
 }


Remove dead comment

Remove dead comment


Realized that memcpy() is a thing

Realized that memcpy() is a thing

--- csarc/csarc.ino
+++ csarc/csarc.ino
@@ -12,6 +12,9 @@
 // TO DO: cut off timeout gradient when activity resumes
 //        implement verbosity levels
 //        evaluate memory gain from using #define for some constants
+//        store commands in structs for easy comparisons and transport
+//        implement modeswitching between I2C/serial if the default Wire interrupts are messing things up
+//        improve mode selection

 #include <stdarg.h>
 #include <Wire.h>
@@ -178,7 +181,8 @@
   flashThread.disable();
   gradientLoop = false;
   char colorInput[8];
-  arrayCopy(colorInput,&inputBuffer[1],7);
+  memcpy(colorInput,&inputBuffer[1],7);
+//  arrayCopy(colorInput,&inputBuffer[1],7);
   if (debugMode) {
     Serial.print("Serial input:");
     Serial.println(colorInput);  }
@@ -352,9 +356,9 @@
       gradPerc = 0;
       if (gradientReversingMode) {
         int temp[3]; //swap 1 and 2
-        arrayCopy(temp,gradcol1,3);
-        arrayCopy(gradcol1,gradcol2,3);
-        arrayCopy(gradcol2,temp,3);
+        memcpy(temp,gradcol1,3);
+        memcpy(gradcol1,gradcol2,3);
+        memcpy(gradcol2,temp,3);
       }
       if (debugMode) { Serial.println("Looping gradient."); }
     } else {
@@ -413,31 +417,27 @@
   }
 }

-
-
 void outputColor( int *color[]) {
   if (debugMode) {
-
     Serial.println(); // for some reason a lot of this output
     Serial.println("---Setting output:---"); // doesn't show up
-    Serial.println(*color[0]);
-    Serial.println(*color[1]);
-    Serial.println(*color[2]);
-    Serial.println(*color[3]);
+    Serial.print(*color[0]); Serial.print(", ");
+    Serial.print(*color[1]);Serial.print(", ");
+    Serial.print(*color[2]);
+    Serial.print(*color[3]);
     Serial.println("---------------------");
   }
     outputColor(*color[0],*color[1],*color[2]);
 }

 void outputColor( int color[]) {
-  if (debugMode) {
-
+  if (debugMode) {
     Serial.println(); // for some reason a lot of this output
     Serial.println("---Setting output:---"); // doesn't show up
-    Serial.println(color[0]);
-    Serial.println(color[1]);
-    Serial.println(color[2]);
-    Serial.println(color[3]);
+    Serial.print(color[0]); Serial.print(", ");
+    Serial.print(color[1]);Serial.print(", ");
+    Serial.print(color[2]);
+    Serial.print(color[3]);
     Serial.println("---------------------");
   }
     outputColor(color[0],color[1],color[2]);
@@ -505,18 +505,6 @@
   Serial.println(blue, HEX);
 }

-void arrayCopy( char recipient[], char donor[], int len) {
-  for (int x=0; x<len; x++) { // apparently takes <1ms, so whatever
-    recipient[x]=donor[x];
-  }
-}
-
-void arrayCopy( int recipient[], int donor[], int len) {
-  for (int x=0; x<len; x++) { // apparently takes <1ms, so whatever
-    recipient[x]=donor[x];
-  }
-}
-
 boolean redundantFlashCommand(const int col1[], const int col2[], int fTime) {
   for (int x=0; x<3; x++) {
     if (flashcol1[x]!=col1[x]) {return false;}
@@ -525,4 +513,3 @@
   if (flashTimePerColor_ms != fTime) {return false;}
   return true;
 }
-


Preliminary bugfixes: smooth gradients, flashing

Non-visual hardware debugging done.

--- csarc/csarc.ino
+++ csarc/csarc.ino
@@ -78,6 +78,7 @@
 void loop() {
   serialThread.check();
   gradientThread.check();
+  flashThread.check();
   timeoutThread.check();
 }

@@ -144,6 +145,7 @@

 void processColor() {
   gradientThread.disable(); // cut off anything else
+  flashThread.disable();
   gradientLoop = false;
   char colorInput[8];
   arrayCopy(colorInput,&inputBuffer[1],7);
@@ -236,17 +238,19 @@
   flashThread.reset();
   flashThread.enable();
   if (debugMode) {
-    Serial.println("Flash setup done, gradient thread enabled.");
+    Serial.println(timev);
+    Serial.println("Flash setup done; flash thread enabled.");
   }
 }

 void flash() {
+  if (debugMode) { Serial.print("Flash:");}
   outputColor( flashFirstColor ? flashcol1 : flashcol2 );
   flashFirstColor = !flashFirstColor;
+  if (debugMode) { Serial.print(red); Serial.print(green); Serial.println(blue); }
 }

 void timeoutAction() {
-
   if (debugMode) { Serial.println("Processing timeout."); }
   if (!recentActivity) {
     Serial.print("No recent activity for "); Serial.print(TIMEOUT); Serial.println(" seconds.");


Fixed speed implemetation

Fixed speed implemetation

--- firmware/node/node.ino
+++ firmware/node/node.ino
@@ -286,7 +286,7 @@
             break;

         case PACKET_SPEED:
-            g_speed = data[0];
+            g_speed = *(uint16_t *)data;
             break;

         case PACKET_CLASSES:


aggiunto un commento

aggiunto un commento

--- YunClient/function.ino
+++ YunClient/function.ino
@@ -3,7 +3,9 @@
   // Launch "curl" command and get Arduino ascii art logo from the network

   terra = analogRead(sensorPin);
-  url = server + "/acquisisci/1/" + String(terra);
+
+  //il valore 1 indica il client che invia il dato. ogni client ha un valore diverso così da differenziare i grafici
+  url = server + "/acquisisci/1/" + String(terra);

   // curl is command line program for transferring data using different internet protocols
   Process p;    // Create a process and call it "p"


Nice-looking dew point table

Nice-looking dew point table


v5.3 Enhance theme print out

v5.3 Enhance theme print out

--- PictureViewer.ino
+++ PictureViewer.ino
@@ -63,6 +63,9 @@
       themeField += (char)tempByte; // Store byte for displayFileName
     }
     themeName.close();
+  }
+  else { // No theme file, so set theme field to "?"
+    themeField = "??????";
   }

   // Print # of files and mode


got rid of a strcpy instruction

got rid of a strcpy instruction

--- jenny5-firmware/jenny5-firmware.ino
+++ jenny5-firmware/jenny5-firmware.ino
@@ -18,7 +18,7 @@

 char is_command_running;

-char firmware_version[] = "2015.12.19.1";// year.month.day.built number
+char firmware_version[] = "2015.12.20.0";// year.month.day.built number

 char current_buffer[65];

@@ -186,18 +186,19 @@
           int j = i + 1;
           for (; j < buffer_length && current_buffer[j] != '#'; j++);// parse until I find the termination char
           if (j < buffer_length){
-              char tmp_str[64];
-              strncpy(tmp_str, current_buffer + i, j - i);
-              tmp_str[j - i] = 0;

               #ifdef DEBUG
-
+                char tmp_str[64];
+                strncpy(tmp_str, current_buffer + i, j - i);
+                tmp_str[j - i] = 0;
                 Serial.write("current command is=");
                 Serial.write(tmp_str);
                 Serial.println();
               #endif

-              parse_and_execute_commands(tmp_str, j - i);
+             //parse_and_execute_commands(tmp_str, j - i);
+             parse_and_execute_commands(current_buffer + i, j - i);
+

               // remove the current executed command
               strcpy(current_buffer, current_buffer + j + 1);// not sure if this is good due to overlaps
@@ -211,7 +212,7 @@

               break; //for i
           }
-          else{// the string is not completed ... so I must wait more...
+          else{// the string is not completed ... so I must wait for more...
             break; // for i
           }
         }


Move TODOS out of code and into Issue tracking

--- cc784Arduino.ino
+++ cc784Arduino.ino
@@ -9,35 +9,6 @@
 #include "html.h"

 /*
- * TODOS: (x done, 0 dicarded, - undone)
- *
- * x add bail out logic that fails message if send rate is low (i.e. not in program mode.)
- * 0 2x crlf in all responses (to make it easier for curl users)
- * - pick a better delimiter so that comma can be used: try _, since its not allowed in sign anyway
- * x in cc7 guard against ascii values > 126 or 127 if i support delete
- * x think about just having two methods: command & string -> implemented in addition to the others
- * x collect statistics and serve them on root ("/")
- * 0 keep track of state and prevent any command from being processed if sign isn't stopped.
- * x handle sign communication errors, report back to caller
- * 0 consider a more robust protocol
- * - support graphics and colors natively
- * x fail call to sequence for >32
- * x test limit of sign and fail if attempt goes over limit
- * x make sequence always issue a stop, seq then run
- * x split colorcells logic and protocol stuff to its own class
- * x rename all usages of "control" with "logger"
- * x make /program issue "PROG" automaticaly (support "/program/3")
- * x case insensitive for C: and S:
- * x change led pin to use #define
- * x make all methods light LED during processing
- * x change all references to commands to use their #define names
- * x add a form on root "/" to submit each bank, and handl form submissions
- * x change pstring to be a circular buffer? (that's hard...) -> made it reset at the end
- * - modify Esp8266WebServer to allow streaming of response
- * 0 add feature to store results of program into eprom and api to retrieve them
- * - add feature to upload a file of 1-liners to the sign (and api)
- * x add set time feature
- *
  * Special thanks to: http://www.textfixer.com/html/compress-html-compression.php for compressing my awful html
  * Special thanks to: http://www.html.am/ for providing great templates that I destroyed with my awful html
  * Special thanks to: http://www.dirtymarkup.com/ for pretty printing my awful html


LED blink on RX when receiving, Constant on FAILSAFE

--- crossbow.ino
+++ crossbow.ino
@@ -1,7 +1,7 @@
 #define LORA_HARDWARE_SPI

-#define DEVICE_MODE_TX
-// #define DEVICE_MODE_RX
+// #define DEVICE_MODE_TX
+#define DEVICE_MODE_RX

 #define FEATURE_TX_OLED

@@ -325,6 +325,13 @@
         lastRxStateTaskTime = currentMillis;
         updateRxDeviceState(&rxDeviceState);
         ppm[RSSI_CHANNEL - 1] = map(rxDeviceState.rssi, 0, 255, 1000, 2000);
+
+        if (qsp.deviceState == DEVICE_STATE_FAILSAFE) {
+            digitalWrite(LED_BUILTIN, HIGH);
+        } else {
+            digitalWrite(LED_BUILTIN, !digitalRead(LED_BUILTIN));
+        }
+
     }

     /*


Fix for NO_FLOAT

Fix for NO_FLOAT

--- tests/BlynkBuildTest/BlynkBuildTest.ino
+++ tests/BlynkBuildTest/BlynkBuildTest.ino
@@ -72,8 +72,10 @@

   Blynk.virtualWrite(V10, (size_t)1);

+#ifndef BLYNK_NO_FLOAT
   Blynk.virtualWrite(V10, (float)1.0F);
   Blynk.virtualWrite(V10, (double)1.0);
+#endif

   Blynk.virtualWrite(V10, String("Some string as String)"));
   Blynk.virtualWrite(V10, "Some string from RAM");


bug fix windspeed

bug fix windspeed

--- mwsIWMIv3/mwsIWMIv3.ino
+++ mwsIWMIv3/mwsIWMIv3.ino
@@ -559,6 +559,9 @@
   lastWindCheck = millis();

   //windSpeed *= 1.492; //4 * 1.492 = 5.968MPH
+  windSpeed *= 1.492; //4 * 1.492 = 5.968MPH
+  windSpeed *= 1.609344; //5.968MPH * 1.609344 = 9.604564992KMPH
+  windSpeed /= 3.6; //9.604564992KMPH / 3.6 = 2.66793472MPS

   return(windSpeed);
 }
@@ -621,7 +624,7 @@
   Serial.print(",");
   Serial.print(winddir);//[6]
   Serial.print(",");
-  Serial.print(windspeedms, 1);//[7]
+  Serial.print(get_wind_speed(), 1);//[7]
   Serial.print(",");
   Serial.print(windgustms, 1);//[8]
   Serial.print(",");


added more reset protection

added more reset protection

--- src/analog_sensors_board.ino
+++ src/analog_sensors_board.ino
@@ -50,6 +50,8 @@
 #define DELAY_SLOW 5000         // slow acquisition loop
 #define DELAY_FAST 250          // fast acquisition loop

+#define INIT_COUNT 10           // initial loop count (reset protection)
+
 // Nessie LEDs and Water Sensors
 #define LED_GREEN 6
 #define LED_YELLOW 5
@@ -201,7 +203,7 @@
     // a software-triggered reset to upload a new firmware using serial bootloader

     // reset protection delay (DO NOT REMOVE)
-    for(int i=0; i<5; i++) {
+    for(int i=0; i < INIT_COUNT; i++) {
         // initial LEDs flashing
         digitalWrite(LED_GREEN, HIGH);
         digitalWrite(LED_YELLOW, HIGH);


Parameter tweaks based on prototype trials

--- code/MotorController/MotorController.ino
+++ code/MotorController/MotorController.ino
@@ -61,8 +61,8 @@

 // Settings and limits
 const int switchDebounceTime = 30;
-const int minimumDelay = 2;
-const int maximumDelay = 15;
+const int minimumDelay = 10;
+const int maximumDelay = 23;
 const int minimumSpeed = 26;
 // 10K ohm potentiometers probably won't get all the way to 1024
 // and we want to make sure that max feasible input = max motor speed
@@ -142,14 +142,8 @@

   if (currentSpeed == 0 && currentDirection != targetDirection)
   {
-    // We're at zero speed and want to switch directions.
-    // The motor spec sheet says we have to wait .5 seconds before
-    // switching to make sure that the motor has come to a full stop.
-
-    // TODO: do we need to hit the run/stop control line in order to
-    // guarentee that the motor is stopped?
-
-    delay(500);
+    // We're at zero speed and want to switch directions.
+    delay(0);
     digitalWrite(directionOutPin, targetDirection);
     currentDirection = targetDirection;
   }


minor bugfix with memory

minor bugfix with memory

--- esp-rfid.ino
+++ esp-rfid.ino
@@ -693,8 +693,7 @@

   if (deviceHostname != 0)
     free(deviceHostname);
-  deviceHostname = (char*) malloc(sizeof(l_hostname));
-  strcpy(deviceHostname, l_hostname);
+  deviceHostname = strdup(l_hostname);

   const char * bssidmac = json["bssid"];
   byte bssid[6];


Added reset Likes function.

Added reset Likes function.

Not sure if it will stay. It's obscure enough for now.

--- LikeJar_5.ino
+++ LikeJar_5.ino
@@ -221,6 +221,14 @@
   // compare the buttonState to its previous state
   if (buttonState != lastButtonState) {
     if (buttonState == LOW) {
+      // Reset Like counter if pin 6 is pulled low and the like button is pressed.
+      if (digitalRead(6) == LOW)
+      {
+        likes = 0;
+        ignorePress = 1;
+        eeprom_write_block((const void*)&likes, (void*)0, sizeof(likes));
+      }
+
       // if the current state is LOW then the button was pushed.
       if (ignorePress == 1)
       {


Display thousands.

Display thousands.

--- LikeJar_5.ino
+++ LikeJar_5.ino
@@ -63,7 +63,9 @@
 int num;
 int value;                    // The number displayed on the LEDs.
 int n = 0;
-int buttonState = 0;          // Current state of the button.
+int buttonState = 0;          // Current state of the Like button.
+int significantState = 0;     // Current state of the Significance pin. (not really a button)
+int moduloExtra = 1;          // Tot display more significant digits. (thousands)
 int lastButtonState = 0;      // Previous state of the button.
 long coolDownTicks = 0;       // Hold delay before a new button press is registered.
 long timer = 0;               // Tick counter, helps count.
@@ -213,11 +215,12 @@
   }

   //////////////
-  //Manage the button.
+  //Manage the buttons.

   // Read current button state.
   buttonState = digitalRead(buttonpin);
-
+  significantState = digitalRead(5);
+
   // compare the buttonState to its previous state
   if (buttonState != lastButtonState) {
     if (buttonState == LOW) {
@@ -251,6 +254,7 @@
       reset = 6;
     }
   }
+
   // save the current state as the last state,
   // for next time through the loop
   lastButtonState = buttonState;
@@ -282,14 +286,22 @@
   // Write a digit at a time for 20 ticks.
   n = ticks/divide;

+  if (significantState == LOW)
+  {
+    moduloExtra = 1000;
+  }
+  else
+  {
+    moduloExtra = 1;
+  }
+
   // Most significant digit
   if(n == 1)
   {
     digitalWrite(digit2pin,0);
     digitalWrite(digit3pin,0);
-    sevenSegWrite(value % 1000 / 100, 1);
+    sevenSegWrite(value % (1000*moduloExtra) / (100*moduloExtra), 1);
     digitalWrite(digit1pin,1);
-
   }

   // Middle significant digit
@@ -297,9 +309,15 @@
   {
     digitalWrite(digit1pin,0);
     digitalWrite(digit3pin,0);
-    sevenSegWrite(value % 100 / 10, 1);
+    if (significantState == LOW)
+    {
+      sevenSegWrite(value % (100*moduloExtra) / (10*moduloExtra), 0);
+    }
+    else
+    {
+      sevenSegWrite(value % (100*moduloExtra) / (10*moduloExtra), 1);
+    }
     digitalWrite(digit2pin,1);
-
   }

   // Least significant digit
@@ -309,11 +327,11 @@
     digitalWrite(digit2pin,0);
     if (coolDownTicks > 0)
     {
-      sevenSegWrite(value % 10, 0);
+      sevenSegWrite(value % (10*moduloExtra) / moduloExtra, 0);
     }
     else
     {
-      sevenSegWrite(value % 10, 1);
+      sevenSegWrite(value % (10*moduloExtra) / moduloExtra, 1);
     }
     digitalWrite(digit3pin,1);
   }


Nam is the bomb

Nam is the bomb

--- 2018-FirefighterL1/Left_Right_Follow.ino
+++ 2018-FirefighterL1/Left_Right_Follow.ino
@@ -7,6 +7,7 @@
       delay(500);         // move left diagonal
       while(rightUltrasonic.getDistance() > closeToWall) {
         moveSlightRight();
+        delay(50);
       }
       delay(500);    // move diagnol towards the wall until your close to the wall
     }
@@ -26,6 +27,24 @@
       stopRobot();
       delay(500);
     }
+  }else{
+    moveForward(5);
+    rollForward();
+    while(frontRightUltrasonic.getDistance() > closeToWall && leftUltrasonic.getDistance() < closeToWall){
+      delay(50);
+    }
+    stopRobot();
+    moveFoward(2);
+    turn(90);
+    moveForward(5);
+    rollForward();
+    while(frontRightUltrasonic.getDistance() > closeToWall && leftUltrasonic.getDistance() < closeToWall){
+      delay(50);
+    }
+    stopRobot();
+    moveForward(3);
+    turn(-90);
+    while
   }
 }

@@ -43,7 +62,9 @@
   double lateralMove = 5; //how far the robot should move to exit the lower right room

   upperRightRoom();
-  secondDogCheck();
+  if(!dog1){
+    secondDogCheck();
+  }

   if(dog2){
     //turn around and get to the lower right room the long way


Update comments.

Update comments.

--- EvilMousePrank_Sketch/EvilMousePrank_Sketch.ino
+++ EvilMousePrank_Sketch/EvilMousePrank_Sketch.ino
@@ -1,6 +1,7 @@
 // Evil Mouse Prank for Arduino Yun
 // Arduino Yun Sketch
 // Copyright 2014 Tony DiCola (tony@tonydicola.com)
+// Released under an MIT license (http://opensource.org/licenses/MIT)

 // Scale factor applied to mouse X axis.  Value of 1 is normal, -1 is inverted.
 char mouseXScale = 1;


Reorganize meteo_lcd code, add comments

Reorganize meteo_lcd code, add comments


-Show percentage above the slider.

-Show percentage above the slider.

-Only draw items on change.

-Added fontsize as third argument to drawButton().

-Added labelcolor as first argument to drawButton().

--- tfttask.ino
+++ tfttask.ino
@@ -60,11 +60,13 @@
   SLIDER_XPOS - SLIDER_WIDTH / 2, SLIDER_YPOS, SLIDER_WIDTH, SLIDER_HEIGHT
 };

-/* button used on main screen */
+/* buttons used on main screen */
 const button_t MENU_BUTTON
 {
   210, 10, TFT_BUTTON_WIDTH, TFT_BUTTON_HEIGHT, "MENU"
 };
+
+button_t tempArea[MAX_NUMBER_OF_SENSORS];

 uint16_t backlightMaxvalue;

@@ -99,10 +101,14 @@
   {
     switch ( tftState )
     {
-      case normal: showStatus();
+      case normal:
+        showStatus();
         break;
-      case menu:   showMenu();
+
+      case menu:
+        showMenu();
         break;
+
       default:     break;
     }
     vTaskDelay( tftTaskdelayTime / portTICK_PERIOD_MS );
@@ -111,7 +117,7 @@

 void showMenu()
 {
-  static lightStatus_t lastStatus;
+  static lightStatus_t currentLightStatus;

   if ( tftClearScreen )
   {
@@ -120,7 +126,7 @@
     drawBacklightSlider();
     ledcWrite( TFT_BACKLIGHT_CHANNEL, map( tftBrightness, 0, 100, 0, backlightMaxvalue ) );
     tftClearScreen = false;
-    lastStatus = lightStatus;
+    currentLightStatus = lightStatus;
   }

   /* check if tftBrightness has changed */
@@ -131,10 +137,10 @@
   }

   /* check if light status has changed */
-  if ( lastStatus != lightStatus )
+  if ( currentLightStatus != lightStatus )
   {
     drawMenuButtons();
-    lastStatus = lightStatus;
+    currentLightStatus = lightStatus;
   }

   if ( touch.tirqTouched() )
@@ -162,7 +168,6 @@
     }
     else if ( buttonPressed( EXIT_BUTTON , p ) )
     {
-      ledcWrite( TFT_BACKLIGHT_CHANNEL, 0 );
       tftClearScreen = true;
       tftState = normal;
     }
@@ -173,81 +178,96 @@
 {
   const uint16_t BARS_BOTTOM      = 190;
   const uint16_t BARS_HEIGHT      = BARS_BOTTOM;
-  const uint16_t BARS_BORDER      = 10;
-  const uint16_t BARS_WIDTH       = 200 / 5; /* note: total width is 200 px */
+  const uint16_t BARS_BORDER      = 12;
+  const uint16_t BARS_WIDTH       = 210 / 5; /* note: total width is 210 px */
   const float    HEIGHT_FACTOR    = BARS_HEIGHT / 100.0;

-  button_t TFT_CLOCK_AREA
+  static wl_status_t   currentWiFiStatus;
+  static lightStatus_t currentLightStatus;
+
+  button_t networkArea
+  {
+    140, 205, 170, 30
+  };
+
+  button_t clockArea
   {
     10, 205, 110, 30
   };

-  button_t TFT_NETWORK_AREA
-  {
-    140, 205, 170, 30
-  };
-
-  button_t tempArea[numberOfFoundSensors];
-
   uint16_t channelColor565[NUMBER_OF_CHANNELS];

   if ( tftClearScreen )
   {
     tft.fillScreen( ILI9341_BLACK );
-    drawButton( MENU_BUTTON, ILI9341_BLUE, 0 );
+    drawButton( MENU_BUTTON, ILI9341_YELLOW, ILI9341_BLUE, 0, 1 );
     tft.setTextColor( ILI9341_YELLOW, ILI9341_BLACK );
-    tft.startWrite();
+
+    showIPAddress( networkArea );
+    currentWiFiStatus = WiFi.status();
+
+    //tft.startWrite();
     for ( uint8_t thisSensor = 0; thisSensor < numberOfFoundSensors; thisSensor++ )
     {
       tempArea[thisSensor].x = 220;
       tempArea[thisSensor].y = 70 + thisSensor * 50;
       tempArea[thisSensor].w = TFT_BUTTON_WIDTH - 20;
       tempArea[thisSensor].h = 30;
-      tft.writeFastHLine( tempArea[thisSensor].x, tempArea[thisSensor].y, tempArea[thisSensor].w, ILI9341_GREEN );
-      tft.writeFastHLine( tempArea[thisSensor].x, tempArea[thisSensor].y + tempArea[thisSensor].h, tempArea[thisSensor].w, ILI9341_GREEN );
-      tft.writeFastVLine( tempArea[thisSensor].x, tempArea[thisSensor].y, tempArea[thisSensor].h, ILI9341_GREEN );
-      tft.writeFastVLine( tempArea[thisSensor].x + tempArea[thisSensor].w, tempArea[thisSensor].y, tempArea[thisSensor].h, ILI9341_GREEN );
-    }
-    tft.endWrite();
+      //tft.writeFastHLine( tempArea[thisSensor].x, tempArea[thisSensor].y, tempArea[thisSensor].w, ILI9341_GREEN );
+      //tft.writeFastHLine( tempArea[thisSensor].x, tempArea[thisSensor].y + tempArea[thisSensor].h, tempArea[thisSensor].w, ILI9341_GREEN );
+      //tft.writeFastVLine( tempArea[thisSensor].x, tempArea[thisSensor].y, tempArea[thisSensor].h, ILI9341_GREEN );
+      //tft.writeFastVLine( tempArea[thisSensor].x + tempArea[thisSensor].w, tempArea[thisSensor].y, tempArea[thisSensor].h, ILI9341_GREEN );
+    }
+    //tft.endWrite();
+
+    /* draw temp sensors */
+    tft.setTextSize( 0 );
     for ( uint8_t thisSensor = 0; thisSensor < numberOfFoundSensors; thisSensor++ )
     {
       int16_t x, y;
       uint16_t w, h;
-      tft.setTextSize( 0 );
       tft.getTextBounds( sensor[thisSensor].name, 0, 0, &x, &y, &w, &h);
       tft.setCursor( ( tempArea[thisSensor].x + tempArea[thisSensor].w / 2 ) - w / 2,
-                     ( tempArea[thisSensor].y - 10 ) );
+                     ( tempArea[thisSensor].y - 6 ) );
       tft.print( sensor[thisSensor].name );
     }
-    tftClearScreen = false;
-  }
+    drawSensors( true );
+  }
+
+  static uint16_t oldPercentage[NUMBER_OF_CHANNELS];
+  static uint16_t oldColor565[NUMBER_OF_CHANNELS];

   tft.startWrite();
   for ( uint8_t channelNumber = 0; channelNumber < NUMBER_OF_CHANNELS; channelNumber++ )
   {
-    // redraw the top part of the bar
-    tft.writeFillRect( channelNumber * BARS_WIDTH + BARS_BORDER,
-                       BARS_BOTTOM - BARS_HEIGHT,
-                       BARS_WIDTH - BARS_BORDER * 2,
-                       BARS_HEIGHT - channel[channelNumber].currentPercentage * HEIGHT_FACTOR,
-                       TFT_BACK_COLOR );
-    /*
-          //100% water mark
-          tft.drawFastHLine( channelNumber * BARS_WIDTH + BARS_BORDER,
-                             BARS_BOTTOM - BARS_HEIGHT - 1,
-                             BARS_WIDTH - BARS_BORDER * 2,
-                             tft.color565( r, g, b ) );
-    */
-
     uint32_t color = strtol( &channel[channelNumber].color[1], NULL, 16 );
     channelColor565[channelNumber] = tft.color565( ( color & 0xFF0000 ) >> 16, ( color & 0x00FF00 ) >> 8, color & 0x0000FF  );

-    // redraw the bottom part of the bar
-    tft.writeFillRect( channelNumber * BARS_WIDTH + BARS_BORDER,
-                       BARS_BOTTOM - channel[channelNumber].currentPercentage * HEIGHT_FACTOR,
-                       BARS_WIDTH - BARS_BORDER * 2,
-                       channel[channelNumber].currentPercentage * HEIGHT_FACTOR,
-                       channelColor565[channelNumber]);
+    /* only draw channels that changed percentage or color */
+    if ( tftClearScreen || oldPercentage[ channelNumber ] != channel[channelNumber].currentPercentage ||
+         oldColor565[ channelNumber ] != channelColor565[ channelNumber ] )
+    {
+      // redraw the top part of the bar
+      tft.writeFillRect( channelNumber * BARS_WIDTH + BARS_BORDER,
+                         BARS_BOTTOM - BARS_HEIGHT,
+                         BARS_WIDTH - BARS_BORDER * 2,
+                         BARS_HEIGHT - channel[channelNumber].currentPercentage * HEIGHT_FACTOR,
+                         TFT_BACK_COLOR );
+      /*
+            //100% water mark
+            tft.drawFastHLine( channelNumber * BARS_WIDTH + BARS_BORDER,
+                               BARS_BOTTOM - BARS_HEIGHT - 1,
+                               BARS_WIDTH - BARS_BORDER * 2,
+                               tft.color565( r, g, b ) );
+      */
+
+      // redraw the bottom part of the bar
+      tft.writeFillRect( channelNumber * BARS_WIDTH + BARS_BORDER,
+                         BARS_BOTTOM - channel[channelNumber].currentPercentage * HEIGHT_FACTOR,
+                         BARS_WIDTH - BARS_BORDER * 2,
+                         channel[channelNumber].currentPercentage * HEIGHT_FACTOR,
+                         channelColor565[channelNumber]);
+    }
   }
   tft.endWrite();

@@ -255,49 +275,61 @@

   for ( uint8_t channelNumber = 0; channelNumber < NUMBER_OF_CHANNELS; channelNumber++ )
   {
-    tft.setCursor( channelNumber * BARS_WIDTH + 2, BARS_BOTTOM + 4 );
-    tft.setTextSize( 1 );
-    tft.setTextColor( channelColor565[channelNumber] , TFT_BACK_COLOR );
-
-    char content[8];
-    if ( TFT_SHOW_RAW )
-    {
-      snprintf( content, sizeof( content ), "%04X", ledcRead( channelNumber ) );
-    }
-    else
-    {
-      snprintf( content, sizeof( content ), "%*" ".1f%%", 5, channel[channelNumber].currentPercentage );
-    }
-    tft.print( content );
+    /* only write percentage if changed */
+    if ( tftClearScreen || channel[channelNumber].currentPercentage != oldPercentage[channelNumber] )
+    {
+      button_t label;
+
+      char content[8];
+
+      if ( TFT_SHOW_RAW )
+      {
+        snprintf( label.text, sizeof( label.text ), "%04X", ledcRead( channelNumber ) );
+      }
+      else
+      {
+        snprintf( label.text, sizeof( label.text ), " %.1f%% ", channel[channelNumber].currentPercentage );
+      }
+
+      label.x = channelNumber * BARS_WIDTH;
+      label.y = BARS_BOTTOM + 4;
+      label.w = BARS_WIDTH;
+      label.h = 10;
+      //tft.setTextColor( channelColor565[channelNumber] , TFT_BACK_COLOR );
+      drawButton( label, channelColor565[channelNumber], 0, 0, 0 );
+    }
+    oldColor565[ channelNumber ] = channelColor565[ channelNumber];
+    oldPercentage[ channelNumber ] = channel[channelNumber].currentPercentage;
     averageLedBrightness += ledcRead( channelNumber );
   }
+  tftClearScreen = false;
+
   averageLedBrightness = averageLedBrightness / NUMBER_OF_CHANNELS;

   uint16_t rawBrightness = map( tftBrightness, 0, 100, 0, backlightMaxvalue );

   ledcWrite( TFT_BACKLIGHT_CHANNEL, ( averageLedBrightness > rawBrightness ) ? rawBrightness : averageLedBrightness );

-  if ( numberOfFoundSensors )
-  {
-    for ( uint8_t thisSensor = 0; thisSensor < numberOfFoundSensors; thisSensor++ )
-    {
-      snprintf( tempArea[thisSensor].text, sizeof( tempArea[thisSensor].text ), "%.1f%c", sensor[thisSensor].tempCelcius, char(247) );
-      drawButton( tempArea[thisSensor], 0, 0 );
-    }
-  }
+  drawSensors( false );

   struct tm timeinfo;

   getLocalTime( &timeinfo );

-  strftime( TFT_CLOCK_AREA.text, sizeof( TFT_CLOCK_AREA.text ), "%T", &timeinfo );
-  drawButton( TFT_CLOCK_AREA, 0, 0 );
-
-  tcpip_adapter_ip_info_t ip_info;
-
-  ESP_ERROR_CHECK( tcpip_adapter_get_ip_info( TCPIP_ADAPTER_IF_STA, &ip_info ) );
-  snprintf( TFT_NETWORK_AREA.text, sizeof( TFT_NETWORK_AREA.text ), "%s", ip4addr_ntoa( &ip_info.ip ) );
-  drawButton( TFT_NETWORK_AREA, 0, 0 );
+  static struct tm oldtimeinfo;
+
+  if ( timeinfo.tm_sec != oldtimeinfo.tm_sec );
+  {
+    strftime( clockArea.text, sizeof( clockArea.text ), "%T", &timeinfo );
+    drawButton( clockArea, ILI9341_YELLOW, 0, 0, 2 );
+    oldtimeinfo.tm_sec = timeinfo.tm_sec;
+  }
+
+  if ( currentWiFiStatus != WiFi.status() )
+  {
+    showIPAddress( networkArea );
+    currentWiFiStatus = WiFi.status();
+  }

   if ( touch.tirqTouched() )
   {
@@ -309,11 +341,8 @@
   }
 }

-static inline __attribute__((always_inline)) void drawButton( struct button_t button, uint16_t color, uint16_t bordercolor )
-{
-  tft.setTextSize( 2 );
-  tft.setTextColor( ILI9341_YELLOW, color );
-
+static inline __attribute__((always_inline)) void drawButton( struct button_t button, uint16_t labelcolor, uint16_t color, uint16_t bordercolor, const uint8_t fontsize )
+{
   if ( color || bordercolor )
   {
     tft.startWrite();
@@ -333,18 +362,20 @@

   int16_t x, y;
   uint16_t w, h;
+  tft.setTextSize( fontsize );
   tft.getTextBounds( button.text, 0, 0, &x, &y, &w, &h);
   tft.setCursor( ( button.x + button.w / 2 ) - w / 2,
                  ( button.y + button.h / 2 ) - h / 2 );
+  tft.setTextColor( labelcolor, color );
   tft.print( button.text );
 }

 static inline __attribute__((always_inline)) void drawMenuButtons()
 {
-  drawButton( LIGHTSON_BUTTON,     lightStatus == LIGHTS_ON  ? ILI9341_RED : ILI9341_BLUE, 0 );
-  drawButton( LIGHTSOFF_BUTTON,    lightStatus == LIGHTS_OFF ? ILI9341_RED : ILI9341_BLUE, 0 );
-  drawButton( LIGHTSAUTO_BUTTON,   lightStatus == LIGHTS_AUTO ? ILI9341_RED : ILI9341_BLUE, 0 );
-  drawButton( EXIT_BUTTON, ILI9341_BLUE, 0 );
+  drawButton( LIGHTSON_BUTTON,     ILI9341_YELLOW, lightStatus == LIGHTS_ON  ? ILI9341_RED : ILI9341_BLUE, 0, 2 );
+  drawButton( LIGHTSOFF_BUTTON,    ILI9341_YELLOW, lightStatus == LIGHTS_OFF ? ILI9341_RED : ILI9341_BLUE, 0, 2 );
+  drawButton( LIGHTSAUTO_BUTTON,   ILI9341_YELLOW, lightStatus == LIGHTS_AUTO ? ILI9341_RED : ILI9341_BLUE, 0, 2 );
+  drawButton( EXIT_BUTTON,         ILI9341_YELLOW, ILI9341_BLUE, 0, 2 );
 }

 static inline __attribute__((always_inline)) bool buttonPressed( struct button_t button, const TS_Point p )
@@ -373,7 +404,9 @@

 static inline __attribute__((always_inline)) void drawBacklightSlider()
 {
-  static button_t sliderButton;
+  const uint8_t SLIDER_BUTTON_HEIGHT = 10;
+
+  static button_t sliderButton = { SLIDER_XPOS - ( SLIDER_WIDTH / 2 ), 0, SLIDER_WIDTH, SLIDER_BUTTON_HEIGHT };

   tft.startWrite();
   tft.writeFillRect( sliderButton.x, sliderButton.y, sliderButton.w, sliderButton.h, ILI9341_BLACK);
@@ -382,9 +415,45 @@

   //drawButton( sliderArea, 0, ILI9341_GREEN ); //debug

-  uint16_t ypos = map( tftBrightness, 0, 100, SLIDER_HEIGHT, SLIDER_YPOS );
-  sliderButton = { SLIDER_XPOS - ( SLIDER_WIDTH / 2 ), ypos, SLIDER_WIDTH, 30 };
-
-  snprintf( sliderButton.text, sizeof( sliderButton.text ), "%.0f%%", tftBrightness );
-  drawButton( sliderButton, ILI9341_BLUE, 0 );
-}
+  //print percentage above the slider
+  sliderButton.y = SLIDER_YPOS - 15;
+  snprintf( sliderButton.text, sizeof( sliderButton.text ), " %.0f%% ", tftBrightness ); /* extra spaces to overwrite old value */
+  drawButton( sliderButton, ILI9341_YELLOW, 0, 0, 2 );
+
+  //draw the slider knob
+  uint16_t ypos = map( tftBrightness, 0, 100, SLIDER_HEIGHT + SLIDER_YPOS, SLIDER_YPOS );
+  sliderButton.y = ypos;
+  sliderButton.text[0] = 0;
+  drawButton( sliderButton, 0, ILI9341_BLUE, 0, 0 );
+}
+
+static inline __attribute__((always_inline)) void showIPAddress( button_t area )
+{
+  tft.startWrite();
+  tft.writeFillRect( area.x, area.y, area.w, area.h, ILI9341_BLACK );
+  tft.endWrite();
+
+  tcpip_adapter_ip_info_t ip_info;
+
+  ESP_ERROR_CHECK( tcpip_adapter_get_ip_info( TCPIP_ADAPTER_IF_STA, &ip_info ) );
+  snprintf( area.text, sizeof( area.text ), "%s", ip4addr_ntoa( &ip_info.ip ) );
+  drawButton( area, ILI9341_YELLOW, 0, 0, 2 );
+}
+
+static inline __attribute__((always_inline)) void drawSensors( const bool forceDraw )
+{
+  if ( numberOfFoundSensors )
+  {
+    static float currentTemp[MAX_NUMBER_OF_SENSORS];
+
+    for ( uint8_t thisSensor = 0; thisSensor < numberOfFoundSensors; thisSensor++ )
+    {
+      if ( sensor[ thisSensor ].tempCelcius != currentTemp[ thisSensor ] || forceDraw )
+      {
+        snprintf( tempArea[thisSensor].text, sizeof( tempArea[thisSensor].text ), "%.1f%c", sensor[thisSensor].tempCelcius, char(247) );
+        drawButton( tempArea[thisSensor], TFT_TEMP_COLOR, 0, 0, 2 );
+        currentTemp[ thisSensor ] = sensor[ thisSensor ].tempCelcius;
+      }
+    }
+  }
+}


test2

--- Atom_Node.ino
+++ Atom_Node.ino
@@ -71,6 +71,7 @@
         }
     }
     BcnDrive.beepOn();
+
     while(1);               // get 10 continus 0x55, down!!
 }


Looks like a pile driver

Looks like a pile driver

--- Arduino/easing_shift/easing_shift.ino
+++ Arduino/easing_shift/easing_shift.ino
@@ -25,7 +25,7 @@

 float ease[LED_COUNT];

-#define DELAY 2000
+#define DELAY 225
 #define FADE_RATE 0.75
 #define FADE_COUNT 20

@@ -398,24 +398,26 @@
   }

   while(true){
-    delay(DELAY);
-
-    int count = random(1,15)  * 4;
-
-    generate_elastic_ease(EASE_COUNT, EASE_EXPONENT);
-    for(int i = 0; i < EASE_COUNT; i++){
-      int pos = ease[i] * count;
-      delay(EASE_DELAY);
-      shift(pos);
-    }
-
-    delay(DELAY);
-
-    generate_power_ease(EASE_COUNT, EASE_EXPONENT);
-    for(int i = EASE_COUNT-1; i >= 0 ; i--){
-      int pos = ease[i] * count;
-      delay(EASE_DELAY);
-      shift(pos);
+    for(int j = 2; j < 16; j++){
+      delay(DELAY * 2);
+
+      int count = j  * 4;
+
+      generate_elastic_ease(EASE_COUNT, EASE_EXPONENT);
+      for(int i = 0; i < EASE_COUNT; i++){
+        int pos = ease[i] * count;
+        delay(EASE_DELAY);
+        shift(pos);
+      }
+
+      delay(DELAY);
+
+      generate_power_ease(EASE_COUNT, EASE_EXPONENT);
+      for(int i = EASE_COUNT-1; i >= 0 ; i--){
+        int pos = ease[i] * count;
+        delay(EASE_DELAY);
+        shift(pos);
+      }
     }
   }


lipsea un include

lipsea un include

--- jenny5-firmware/jenny5-firmware.ino
+++ jenny5-firmware/jenny5-firmware.ino
@@ -1,5 +1,6 @@
 #include "motors_control.h"
 #include "Ultrasonic.h"
+#include "PotentiometersController.h"

 byte potentiometers_pins[4] = {0, 1, 2, 3};


refactor

refactor

--- esp8266_160220_BYOP.ino
+++ esp8266_160220_BYOP.ino
@@ -198,15 +198,6 @@
   AQM0802_Clear();
   AQM0802_PutMessage(reply, /* x_st1=*/1, /* y_st1=*/1);

-#if 0
-  // TODO: 0a > remove Test_read_write_uint8_t() when tested
-  Test_MsgServer_SaveLoad();
-  // Test_read_write_structeredData();
-  // Test_read_write_String();
-  // Test_read_write_data();
-  // Test_read_write_uint8_t();
-#endif
-
   return true;
 }


Key bugfixes. Still doesn't work.

Key bugfixes. Still doesn't work.

--- JTAGWhisperer.ino
+++ JTAGWhisperer.ino
@@ -48,20 +48,22 @@
 // Knows how to set MCU-specific pins in a JTAG-relevant way.
 class Twiddler {
  public:
- Twiddler() : portb_(0), tdo_(0) {
+ Twiddler() : portb_(0) {
     DDRB = TMS | TDI | TCK;
   }

   inline void pulse_clock() {
     clr_port(TCK);
+    delayMicroseconds(1);
     set_port(TCK);
   }

-  void pulse_clock_and_read_tdo() {
-    tdo_ >>= 1;
+  bool pulse_clock_and_read_tdo() {
     clr_port(TCK);
+    delayMicroseconds(1);
+    uint8_t pinb = PINB;
     set_port(TCK);
-    tdo_ |= (PINB & TDO) ? 0x80 : 0;
+    return pinb & TDO;
   }

   void wait_time(unsigned long microsec) {
@@ -89,8 +91,6 @@
   void clr_tdi() {
     clr_port(TDI);
   }
-
-  uint8_t tdo() { return tdo_; }

  private:
   enum {
@@ -118,11 +118,10 @@

   // The current PORTB state. We write this only when we twiddle TCK.
   uint8_t portb_;
-
-  // Shift register. Every time the clock pulses we shift a bit into this byte.
-  uint8_t tdo_;
 };

+// These tables and the code that uses them are taken from
+// https://github.com/ben0109/XSVF-Player/.
 static const uint8_t tms_transitions[] = {
   0x01, /* STATE_TLR    */
   0x21, /* STATE_RTI    */
@@ -289,7 +288,9 @@
     XSIR,
     XSDR,
     XRUNTEST,
-    XREPEAT = 7,
+    XRESERVED_5,
+    XRESERVED_6,
+    XREPEAT,
     XSDRSIZE,
     XSDRTDO,
     XSETSDRMASKS,
@@ -407,7 +408,7 @@
   bool handle_XSDR() {
     get_next_bytes(tdi_, sdrsize_bytes_);
     DEBUG_BYTES("... sending ", tdi_, sdrsize_bytes_);
-    return sdr(true, false);
+    return sdr(true, true, true);
   }

   bool handle_XRUNTEST() {
@@ -434,7 +435,7 @@
     get_next_bytes(tdo_expected_, sdrsize_bytes_);
     DEBUG_BYTES("... sending   ", tdi_, sdrsize_bytes_);
     DEBUG_BYTES("... expecting ", tdo_expected_, sdrsize_bytes_);
-    return sdr(true, false);
+    return sdr(true, true, true);
   }

   bool is_tdo_as_expected() {
@@ -470,40 +471,42 @@

     for (int i = 0; i < byte_count; ++i) {
       uint8_t byte_out = data[i];
-      for (int j = 0; j < 8; j++) {
-        if (data_length_bits == 1 && is_end) {
+      uint8_t tdo_byte = 0;
+      for (int j = 0; j < 8 && data_length_bits-- > 0; ++j) {
+        if (data_length_bits == 0 && is_end) {
           twiddler_.set_tms();
           state_ack(1);
         }

-        if (data_length_bits--) {
-          if (byte_out & 1) {
-            twiddler_.set_tdi();
-          } else {
-            twiddler_.clr_tdi();
-          }
-          byte_out >>= 1;
-          twiddler_.pulse_clock_and_read_tdo();
+        if (byte_out & 1) {
+          twiddler_.set_tdi();
+        } else {
+          twiddler_.clr_tdi();
         }
-      }
-      tdo_[i] = twiddler_.tdo();
-    }
-  }
-
-  bool sdr(bool should_check, bool should_end) {
+        byte_out >>= 1;
+        bool tdo = twiddler_.pulse_clock_and_read_tdo();
+        tdo_byte |= tdo << j;
+      }
+      tdo_[i] = tdo_byte;
+    }
+  }
+
+  bool sdr(bool should_begin, bool should_end, bool should_check) {
     int attempts_left = repeat_;
     bool matched = false;
+
+    if (should_begin) {
+      state_goto(STATE_SHIFT_DR);
+    }
+
     while (!matched && attempts_left-- > 0) {
       shift_td(tdi_, sdrsize_bits_, should_end);
       if (should_check) {
         if (is_tdo_as_expected()) {
           matched = true;
         } else {
-          state_step(0); /* Pause-DR state */
-          state_step(1); /* Exit2-DR state */
-          state_step(0); /* Shift-DR state */
-          state_step(1); /* Exit1-DR state */
-
+          state_goto(STATE_PAUSE_DR);
+          state_goto(STATE_SHIFT_DR);
           state_goto(STATE_RTI);
           wait_time(runtest_);
           state_goto(STATE_SHIFT_DR);
@@ -522,6 +525,7 @@
   }

   void wait_time(uint32_t microseconds) {
+    DEBUG("Waiting %d microseconds...", microseconds);
     uint32_t until = micros() + microseconds;
     while (microseconds--) {
       twiddler_.pulse_clock();
@@ -566,11 +570,11 @@
   }

   Twiddler twiddler_;
-  int current_state_;
+  uint8_t current_state_;
   uint8_t sdrsize_bits_;
   uint8_t sdrsize_bytes_;
   uint8_t repeat_;
-  uint8_t runtest_;
+  uint32_t runtest_;
   bool reached_xcomplete_;

   enum {


EEPROM tweaks and app reset buttons

EEPROM tweaks and app reset buttons

--- hvacMonitor.ino
+++ hvacMonitor.ino
@@ -58,7 +58,9 @@
 unsigned long offNow = now(); // To prevent error on first Tweet after blower starts - NOT WORKING YET

 int offHour, offHour24, onHour, onHour24, offMinute, onMinute, offSecond, onSecond, offMonth, onMonth,
-    offDay, onDay, runTime, tempSplit, secondsCount, alarmTime;
+    offDay, onDay, runTime, tempSplit, secondsCount, alarmTime, startHour, startMin, startMonth, startDay;
+
+int resetLatch = 0;

 int currentRuntimeSec; // Sum of today's blower runtime in seconds
 int currentOfftimeSec = 0;
@@ -108,13 +110,14 @@
     for (int i = 1 ; i < 201 ; i++) {
       eeWBsum += EEPROM.read(i);
     }
-    //Serial.println(String(eeWBsum) + " minutes reported from EEPROM after reset.");
-    //Blynk.virtualWrite(17, eeWBsum);
-    //Serial.println(String(EEPROM.read(eeIndex)) + " is the next index location to write to.");
   }
   Blynk.virtualWrite(17, eeWBsum);
   Blynk.virtualWrite(18, EEPROM.read(eeIndex));
-
+
+  if (eeWBsum > 0) {
+    currentRuntimeSec = (eeWBsum * 60);
+  } // If there's something in EEPROM, write it to Today's Runtime
+
   rtc.begin();

   timer.setInterval(2500L, sendTemps); // Temperature sensor polling interval
@@ -124,7 +127,38 @@
   timer.setInterval(330000L, sendWUtoBlynk); // 5ish minutes between API data updates to Blynk.
   timer.setInterval(1000L, countRuntime);  // Counts blower runtime for daily accumulation displays.
   timer.setInterval(1000L, totalRuntime);  // Counts blower runtime for daily EEPROM storage.
-
+  timer.setInterval(500L, timeKeeper);
+}
+
+void loop()
+{
+  Blynk.run();
+  timer.run();
+}
+
+BLYNK_WRITE(V19) // App button to reset EEPROM stored total and address
+{
+  int pinData = param.asInt();
+
+  if (pinData == 0)
+  {
+    Serial.println("EEPROM RESET");
+    for (int i = 0 ; i < 201 ; i++) {
+      EEPROM.write(i, 0);
+    }
+    EEPROM.write(eeIndex, 1); // Defined address 1 as the starting location.
+    EEPROM.commit();
+  }
+}
+
+BLYNK_WRITE(V20) // App button to reset ESP
+{
+  int pinData = param.asInt();
+
+  if (pinData == 0)
+  {
+    ESP.restart();
+  }
 }

 static char respBuf[4096];
@@ -286,13 +320,30 @@

 void sendBlowerStatus()
 {
-  if (digitalRead(blowerPin) == HIGH && resetTattle == 0)
-  {
-    Blynk.virtualWrite(16, String("SYSTEM RESET at ") + hour() + ":" + minute());
-  }
-  else if (digitalRead(blowerPin) == LOW && resetTattle == 0)
-  {
-    Blynk.virtualWrite(16, String("SYSTEM RESET at ") + hour() + ":" + minute());
+  if (resetLatch == 0) // Sets ESP start/reset time and date to display in app until blower activity.
+  {
+    startHour = hour();
+    startMin = minute();
+    startMonth = month();
+    startDay = day();
+    resetLatch++;
+  }
+
+  if (digitalRead(blowerPin) == HIGH && resetTattle == 0 && startMin > 9)
+  {
+    Blynk.virtualWrite(16, String("SYSTEM RESET at ") + startHour + ":" + startMin + " " + startMonth + "/" + startDay);
+  }
+  else if (digitalRead(blowerPin) == HIGH && resetTattle == 0 && startMin < 10)
+  {
+    Blynk.virtualWrite(16, String("SYSTEM RESET at ") + startHour + ":0" + startMin + " " + startMonth + "/" + startDay);
+  }
+  else if (digitalRead(blowerPin) == LOW && resetTattle == 0 && startMin > 9)
+  {
+    Blynk.virtualWrite(16, String("SYSTEM RESET at ") + startHour + ":" + startMin + " " + startMonth + "/" + startDay);
+  }
+  else if (digitalRead(blowerPin) == LOW && resetTattle == 0 && startMin < 10)
+  {
+    Blynk.virtualWrite(16, String("SYSTEM RESET at ") + startHour + ":0" + startMin + " " + startMonth + "/" + startDay);
   }
   else if (digitalRead(blowerPin) == HIGH && resetTattle == 1) // Runs when blower is OFF.
   {
@@ -302,7 +353,7 @@
     }
     else if (hour() < 12 && minute() < 10)
     {
-      Blynk.virtualWrite(16, String("HVAC OFF since ") + offHour + ":" + "0" + offMinute + "AM on " + offMonth + "/" + offDay);
+      Blynk.virtualWrite(16, String("HVAC OFF since ") + offHour + ":0" + offMinute + "AM on " + offMonth + "/" + offDay);
     }
     else if (hour() > 11 && minute() > 9)
     {
@@ -310,7 +361,7 @@
     }
     else if (hour() > 11 && minute() < 10)
     {
-      Blynk.virtualWrite(16, String("HVAC OFF since ") + offHour + ":" + "0" + offMinute + "PM on " + offMonth + "/" + offDay);
+      Blynk.virtualWrite(16, String("HVAC OFF since ") + offHour + ":0" + offMinute + "PM on " + offMonth + "/" + offDay);
     }
   }
   else if (digitalRead(blowerPin) == LOW && resetTattle == 1)
@@ -321,7 +372,7 @@
     }
     else if (hour() < 12 && minute() < 10)
     {
-      Blynk.virtualWrite(16, String("HVAC ON since ") + onHour + ":" + "0" + onMinute + "AM on " + onMonth + "/" + onDay);
+      Blynk.virtualWrite(16, String("HVAC ON since ") + onHour + ":0" + onMinute + "AM on " + onMonth + "/" + onDay);
     }
     else if (hour() > 11 && minute() > 9)
     {
@@ -329,7 +380,7 @@
     }
     else if (hour() > 11 && minute() < 10)
     {
-      Blynk.virtualWrite(16, String("HVAC ON since ") + onHour + ":" + "0" + onMinute + "PM on " + onMonth + "/" + onDay);
+      Blynk.virtualWrite(16, String("HVAC ON since ") + onHour + ":0" + onMinute + "PM on " + onMonth + "/" + onDay);
     }

     /*
@@ -384,11 +435,8 @@

 }

-void loop() // Typically Blynk tasks should not be placed in void loop(), however none of these (Blynk) tasks run continuously for any reason.
-{
-  Blynk.run();
-  timer.run();
-
+void timeKeeper()
+{
   if (digitalRead(blowerPin) == HIGH) // Runs when blower is OFF.
   {
     // The following records the time the blower started.


report free RAM on startup in C64 style ;-)

--- colorduino/colorduino_serial.ino
+++ colorduino/colorduino_serial.ino
@@ -4,6 +4,12 @@
   1.5.6 - 1.5.8 don't work currently

 */
+
+int freeRam () {
+  extern int __heap_start, *__brkval;
+  int v;
+  return (int) &v - (__brkval == 0 ? (int) &__heap_start : (int) __brkval);
+}

 // Include required libraries
 #include <Adafruit_GFX.h>
@@ -146,14 +152,15 @@

 void setup() {
   Serial.begin(19200);
-  Serial.println("*** ColorDuino ***");
-  Serial.println("starting...");
-
+  Serial.println("      *** COLORDUINO ***");
+  Serial.print("2K RAM SYSTEM  ");
+  Serial.print( freeRam() );
+  Serial.println(" BYTES FREE");
   // Set port mode, load data structures and start the timer
   Colorduino.init();
   Colorduino.setWhiteBalance(36, 63, 63);

-  Serial.println("ready.");
+  Serial.println("READY.");
 }

 void loop() {


Update decodeUBX.ino

Update decodeUBX.ino

--- temp/decodeUBX.ino
+++ temp/decodeUBX.ino
@@ -1,73 +1,73 @@
-void decodeUBX(void)
-{
-  if (UBX_class == 0x01)
-  {
-    switch (UBX_id)
-    {
-      case 0x02:  //NAV-POSLLH
-        {
-          GPSdata[0] = message[4];    //longitude-0
-          GPSdata[1] = message[5];    //longitude-1
-          GPSdata[2] = message[6];    //longitude-2
-          GPSdata[3] = message[7];    //longitude-3
-
-          GPSdata[4] = message[8];    //latitude-0
-          GPSdata[5] = message[9];    //latitude-1
-          GPSdata[6] = message[10];   //latitude-2
-          GPSdata[7] = message[11];   //latitude-3
-
-          GPSdata[8] = message[16];   //height-0
-          GPSdata[9] = message[17];   //height-1
-          GPSdata[10] = message[18];  //height-2
-          GPSdata[11] = message[19];  //height-3
-
-          GPSdata[12] = message[20];  //horAcc-0
-          GPSdata[13] = message[21];  //horAcc-1
-          GPSdata[14] = message[22];  //horAcc-2
-          GPSdata[15] = message[23];  //horAcc-3
-
-          GPSdata[16] = message[24];  //vertAcc-0
-          GPSdata[17] = message[25];  //vertAcc-1
-          GPSdata[18] = message[26];  //vertAcc-2
-          GPSdata[19] = message[27];  //vertAcc-3
-
-          POSLLH = true;
-          break;
-        }
-      case 0x12:  //NAV-VELNED
-        {
-          GPSdata[20] = message[16];  //speed-0
-          GPSdata[21] = message[17];  //speed-1
-          GPSdata[22] = message[18];  //speed-2
-          GPSdata[23] = message[19];  //speed-3
-
-          GPSdata[24] = message[20];  //gSpeed-0
-          GPSdata[25] = message[21];  //gSpeed-1
-          GPSdata[26] = message[22];  //gSpeed-2
-          GPSdata[27] = message[23];  //gSpeed-3
-
-          GPSdata[28] = message[24];  //heading-0
-          GPSdata[29] = message[25];  //heading-1
-          GPSdata[30] = message[26];  //heading-2
-          GPSdata[31] = message[27];  //heading-3
-
-          GPSdata[32] = message[28];  //speedAcc-0
-          GPSdata[33] = message[29];  //speedAcc-1
-          GPSdata[34] = message[30];  //speedAcc-2
-          GPSdata[35] = message[31];  //speedAcc-3
-
-          GPSdata[36] = message[32];  //headingAcc-0
-          GPSdata[37] = message[33];  //headingAcc-1
-          GPSdata[38] = message[34];  //headingAcc-2
-          GPSdata[39] = message[35];  //headingAcc-3
-
-          VELNED = true;
-          break;
-        }
-    }
-  }
-  if (POSLLH == 1 && VELNED == 1)
-  {
-    mySerial.print("Ypa!");
-  }
+void decodeUBX(void)
+{
+  if (UBX_class == 0x01)
+  {
+    switch (UBX_id)
+    {
+      case 0x02:  //NAV-POSLLH
+        {
+          GPSdata[0] = message[4];    //longitude-0
+          GPSdata[1] = message[5];    //longitude-1
+          GPSdata[2] = message[6];    //longitude-2
+          GPSdata[3] = message[7];    //longitude-3
+
+          GPSdata[4] = message[8];    //latitude-0
+          GPSdata[5] = message[9];    //latitude-1
+          GPSdata[6] = message[10];   //latitude-2
+          GPSdata[7] = message[11];   //latitude-3
+
+          GPSdata[8] = message[16];   //height-0
+          GPSdata[9] = message[17];   //height-1
+          GPSdata[10] = message[18];  //height-2
+          GPSdata[11] = message[19];  //height-3
+
+          GPSdata[12] = message[20];  //horAcc-0
+          GPSdata[13] = message[21];  //horAcc-1
+          GPSdata[14] = message[22];  //horAcc-2
+          GPSdata[15] = message[23];  //horAcc-3
+
+          GPSdata[16] = message[24];  //vertAcc-0
+          GPSdata[17] = message[25];  //vertAcc-1
+          GPSdata[18] = message[26];  //vertAcc-2
+          GPSdata[19] = message[27];  //vertAcc-3
+
+          POSLLH = true;
+          break;
+        }
+      case 0x12:  //NAV-VELNED
+        {
+          GPSdata[20] = message[16];  //speed-0
+          GPSdata[21] = message[17];  //speed-1
+          GPSdata[22] = message[18];  //speed-2
+          GPSdata[23] = message[19];  //speed-3
+
+          GPSdata[24] = message[20];  //gSpeed-0
+          GPSdata[25] = message[21];  //gSpeed-1
+          GPSdata[26] = message[22];  //gSpeed-2
+          GPSdata[27] = message[23];  //gSpeed-3
+
+          GPSdata[28] = message[24];  //heading-0
+          GPSdata[29] = message[25];  //heading-1
+          GPSdata[30] = message[26];  //heading-2
+          GPSdata[31] = message[27];  //heading-3
+
+          GPSdata[32] = message[28];  //speedAcc-0
+          GPSdata[33] = message[29];  //speedAcc-1
+          GPSdata[34] = message[30];  //speedAcc-2
+          GPSdata[35] = message[31];  //speedAcc-3
+
+          GPSdata[36] = message[32];  //headingAcc-0
+          GPSdata[37] = message[33];  //headingAcc-1
+          GPSdata[38] = message[34];  //headingAcc-2
+          GPSdata[39] = message[35];  //headingAcc-3
+
+          VELNED = true;
+          break;
+        }
+    }
+  }
+  if (POSLLH == 1 || VELNED == 1)
+  {
+    mySerial.print("Ypa!");
+  }
 }


re-fix == typo

re-fix == typo

--- main/main.ino
+++ main/main.ino
@@ -305,7 +305,7 @@
   else if(currentMode == quad) {
     currentMode = octo;
   }
-  else if(currentMode = octo) {
+  else if(currentMode == octo) {
     currentMode = dual;
   }
   //diag mode is not implemented yet


Added aiFxn() for handling the sensors

Added aiFxn() for handling the sensors

--- Arduino/erpam/erpam.ino
+++ Arduino/erpam/erpam.ino
@@ -47,7 +47,7 @@
 int obstacleLeft = 0;

 void setup() {
-// put your setup code here, to run once:
+  // put your setup code here, to run once:
   BTserial.begin(9600);
   Serial.begin(19200);
   //Setup Channel A
@@ -72,7 +72,7 @@
 }

 void loop() {
-   switch (choice)
+  switch (choice)
   {
     case 1:
       bluetoothcontrol(BluetoothData);
@@ -111,8 +111,6 @@
       choice = 3;
       BTserial.flush();
     }
-
-    Serial.println(BluetoothData);
   }
 }

@@ -160,9 +158,168 @@
 void headSetfxn()
 {
   float nacc = acc.toFloat();
-
-  //Serial.println(ncon);
   hs.go_forward(nacc);
 }

-
+void aifxn()
+{
+  /*if (!go)
+  {
+    ai.go_forward();
+    go = true;
+    median = distanceSensor.getMedian();
+    medianLeft = sensorLeft.getMedian();
+    medianRight = sensorRight.getMedian();
+
+  }*/
+  ai.go_forward();
+  median = distanceSensor.getMedian();
+  medianLeft = sensorLeft.getMedian();
+  medianRight = sensorRight.getMedian();
+
+   if(medianLeft < TOO_CLOSE / 5)
+    {
+      ai.turn_right();
+      delay(50);
+      ai.brake();
+      ai.turn_left();
+      delay(5);
+    }else if (medianRight < TOO_CLOSE / 5)
+    {
+      ai.turn_left();
+      delay(50);
+      ai.brake();
+      ai.turn_right();
+      delay(10);
+    }
+
+
+  if (median < CLOSE * 2) // medianFront
+  {
+    ai.brake();
+    delay(500);
+    brakeFlag = true;
+    if(median < TOO_CLOSE/5)
+    {
+      ai.go_backward();
+      delay(200);
+      ai.brake();
+    }
+  }
+  else
+  {
+    brakeFlag = false;
+  }
+
+  if (brakeFlag)
+  {
+    checkObstacles();
+    brakeFlag = false;
+    go = false;
+  }
+
+  aifxn();
+}
+
+void checkObstacles()
+{
+  median = distanceSensor.getMedian();
+  medianLeft = sensorLeft.getMedian();
+  medianRight = sensorRight.getMedian();
+
+  if (medianLeft < TOO_CLOSE && medianRight < TOO_CLOSE)
+  {
+    ai.go_backward();
+    checkObstacles();
+  } else if (medianLeft < TOO_CLOSE && medianRight > TOO_CLOSE)
+  {
+
+    ai.turn_right();
+    delay(270);
+  } else if (medianLeft > TOO_CLOSE && medianRight < TOO_CLOSE)
+  {
+
+    ai.turn_left();
+    delay(220);
+  } else if (medianLeft > TOO_CLOSE && medianRight > TOO_CLOSE)
+  {
+    int r = random(2, 10);
+    if (r % 2 == 0)
+    {
+      ai.turn_left();
+      delay(220);
+    } else if (r % 2 != 0)
+    {
+      ai.turn_right();
+      delay(270);
+    }
+  }
+}
+
+
+
+// CODE TO WORK WITH ONE ULTRASONIC FRONT SENSOR ONLY
+// The method will go forward until hits an obstacle
+// When obstacle hit then turn left and see if there is obstacle there
+// if there is none continue straight, if there is an obstacle
+// turn right in order to come back to the same position
+// then turn right again and see if there is obstacle on the right
+// if there is none continue straight
+// if there is an obstacle then turn left back to the initial position
+// and start reversing and use recursive algorithm in order to check
+// when the obstacles on the left or right side are gone
+/*
+  void aifxn()
+  {
+  if (!go)
+  {
+    ai.go_forward();
+    go = true;
+    median = distanceSensor.getMedian();
+  }
+
+  cm = distanceSensor.getMedian();
+
+  if (cm < TOO_CLOSE)
+  {
+    ai.brake();
+    delay(500);
+    brakeFlag = true;
+  }
+  else
+  {
+    brakeFlag = false;
+    go = false;
+  }
+
+  if (brakeFlag)
+  {
+    checkObstacles();
+    brakeFlag = false;
+  }
+  }
+
+  void checkObstacles()
+  {
+  checkObstacleLeft();
+
+  if (obstacleLeft == true)
+  {
+    checkObstacleRight();
+    delay(500);
+    if (obstacleRight == true)
+    {
+      ai.go_backward();
+      delay(1000); // Wait a second in order to brake
+      ai.brake();
+      checkObstacles();
+    } else
+    {
+      ai.go_forward();
+    }
+  } else
+  {
+    //brakeFlag = false;
+    //go = false;
+  }
+  }*/


Update _firmware2.ino

Update _firmware2.ino

--- Arduino/_firmware2/_firmware2.ino
+++ Arduino/_firmware2/_firmware2.ino
@@ -107,8 +107,8 @@
 /////////////////////////////////////////////////////////////////////////////////////////////////////////////
 //                                                 4. LOAD WASHER 1 & 2

-int loadWasher1Pin = A5;
-int loadWasher2Pin = A6;
+int loadWasher1Pin = A4;
+int loadWasher2Pin = A5;

 //Insert Calibration Data Here: Level = AX + B format (rounded to the nearest integer N)
 //We assume that the two load washers have the same calibration curve


Working with ethernet connection, ntp updating, and sd logging

--- SDTest/SDTest.ino
+++ SDTest/SDTest.ino
@@ -8,9 +8,9 @@
 #include <SdFat.h>

 #include <MemoryFree.h>
-//#include <SPI.h>
-//#include <Ethernet.h>
-//#include <EthernetUdp.h>
+#include <SPI.h>
+#include <Ethernet.h>
+#include <EthernetUdp.h>

 SdFile myFile;
 SdFile myFile1;
@@ -27,33 +27,33 @@

  /* ******** Ethernet Card Settings ******** */
 // Set this to your Ethernet Card Mac Address
-//byte mac[] = { 0x90, 0xA2, 0xDA, 0x0D, 0xBA, 0x72 };
+byte mac[] = { 0x90, 0xA2, 0xDA, 0x0D, 0xBA, 0x72 };

 /* ******** NTP Server Settings ******** */
 /* us.pool.ntp.org NTP server
    (Set to your time server of choice) */
-//IPAddress timeServer(132, 163, 4, 101);
+IPAddress timeServer(132, 163, 4, 101);

 /* Set this to the offset (in seconds) to your local time
-   This example is GMT - 6 */
-//const long timeZoneOffset = -18000L;
+   This example is GMT - 5 */
+const long timeZoneOffset = -18000L;

 /* Syncs to NTP server every 15 seconds for testing,
    set to 1 hour or more to be reasonable */
-//unsigned int ntpSyncTime = 60;
+unsigned int ntpSyncTime = 300;

 /* ALTER THESE VARIABLES AT YOUR OWN RISK */
 // local port to listen for UDP packets
-//unsigned int localPort = 8888;
+unsigned int localPort = 8888;
 // NTP time stamp is in the first 48 bytes of the message
-//const int NTP_PACKET_SIZE= 48;
+const int NTP_PACKET_SIZE= 48;
 // Buffer to hold incoming and outgoing packets
-//byte packetBuffer[NTP_PACKET_SIZE];
+byte packetBuffer[NTP_PACKET_SIZE];
 // A UDP instance to let us send and receive packets over UDP
-//EthernetUDP Udp;
+EthernetUDP Udp;
 // Keeps track of how long ago we updated the NTP server
-//unsigned int ntpLastUpdate = 0;
+unsigned long ntpLastUpdate = 0;
 // Check last time clock displayed (Not in Production)
 //time_t prevDisplay = 0;

@@ -94,53 +94,54 @@
   archiveRRD2.resetFile();
   //digitalWrite(4,HIGH);
   //digitalWrite(10,LOW);
-  /*
+
  // Ethernet shield and NTP setup
  int i = 0;
  int DHCP = 0;
  DHCP = Ethernet.begin(mac);
  //Try to get dhcp settings 30 times before giving up

- while( DHCP == 0 && i < 30){
+ while( DHCP == 0 && i < 5){
    delay(1000);
    DHCP = Ethernet.begin(mac);
    i++;
  }

-
+ /*
  if(!DHCP){
   Serial.println("DHCP FAILED");
    //for(;;); //Infinite loop because DHCP Failed
  }
  Serial.println("DHCP Success");
- */
+
  //Try to get the date and time
-/*
- int i=0;
+*/
+ i=0;
  while(!getTimeAndDate() && i<1) {
    i++;
  }
-*/
+
 }

 void loop()
 {
   //digitalWrite(10,LOW);
     // Update the time via NTP server as often as the time you set at the top
-    /*
+
   if(now()-ntpLastUpdate > ntpSyncTime) {
+    Serial.print(now()-ntpLastUpdate);
     int trys=0;
-    while(!getTimeAndDate() && trys<1){
+    while(!getTimeAndDate() && trys<3){
       trys++;
     }
-    if(trys<1){
+    if(trys<3){
       Serial.println("ntp server update success");
     }
     else{
       Serial.println("ntp server update failed");
     }
   }
-
+ /*
   // Display the time if it has changed by more than a second.
   if( now() != prevDisplay){
     prevDisplay = now();
@@ -168,7 +169,7 @@
   //Serial.print(F("freeMemory()="));Serial.println(freeMemory());

   //myFile2.open("testArc2.txt",O_READ);
-  if(myFile2.open("testArc2.txt", O_RDWR)){
+  if(myFile2.open("testArc2.txt", O_READ)){
     while (myFile2.available()) {
   	Serial.write(myFile2.read());
     }
@@ -233,7 +234,7 @@
  timestamp[11]='/';
  timestamp[14]='/';
 }
-/*
+
 // Do not alter this function, it is used by the system
 int getTimeAndDate() {
    int flag=0;
@@ -247,6 +248,7 @@
      lowWord = word(packetBuffer[42], packetBuffer[43]);
      epoch = highWord << 16 | lowWord;
      epoch = epoch - 2208988800 + timeZoneOffset;
+     epoch = epoch + dstOffset(epoch);  //Adjust for DLT
      flag=1;
      setTime(epoch);
      ntpLastUpdate = now();
@@ -270,9 +272,31 @@
   Udp.write(packetBuffer,NTP_PACKET_SIZE);
   Udp.endPacket();
 }
+
+int dstOffset (unsigned long unixTime)
+{
+  //Receives unix epoch time and returns seconds of offset for local DST
+  //Valid thru 2099 for US only, Calculations from "http://www.webexhibits.org/daylightsaving/i.html"
+  //Code idea from jm_wsb @ "http://forum.arduino.cc/index.php/topic,40286.0.html"
+  //Get epoch times @ "http://www.epochconverter.com/" for testing
+  //DST update wont be reflected until the next time sync
+  time_t t = unixTime;
+  int beginDSTDay = (14 - (1 + year(t) * 5 / 4) % 7);
+  int beginDSTMonth=3;
+  int endDSTDay = (7 - (1 + year(t) * 5 / 4) % 7);
+  int endDSTMonth=11;
+  if (((month(t) > beginDSTMonth) && (month(t) < endDSTMonth))
+    || ((month(t) == beginDSTMonth) && (day(t) > beginDSTDay))
+    || ((month(t) == beginDSTMonth) && (day(t) == beginDSTDay) && (hour(t) >= 2))
+    || ((month(t) == endDSTMonth) && (day(t) < endDSTDay))
+    || ((month(t) == endDSTMonth) && (day(t) == endDSTDay) && (hour(t) < 1)))
+    return (3600);  //Add back in one hours worth of seconds - DST in effect
+  else
+    return (0);  //NonDST
+}

 // Clock display of the time and date (Basic)
-
+/*
 void clockDisplay(){
   Serial.print(hour());
   printDigits(minute());


Updated functions

Updated functions

--- ROD.ino
+++ ROD.ino
@@ -1,3 +1,13 @@
+#define CW 0
+#define CCW 1
+
+
+int pwmpin[2] = {5, 6}; // PWM's input
+int inApin[2] = {7, 4}; // INA: Clockwise
+int inBpin[2] = {8, 9}; // INB: Counterlockwise
+
+
+

 void setup() {
   Serial.begin(9600);
@@ -20,13 +30,15 @@
   void loop() {
     drive();//continuously drive motor
   }
-  void drive(int x, int y, int velocity)//sends control signal to motor shield
+  void drive(int x, int y)//sends control signal to motor shield
   {
     int speed0;//speed left motor
     int speed1;//speed right motor
-    int direction0;//direction left motor
-    int direction1;//direction right motor
-    calcultateSpeedDirection (x, y, velocity);//calculate parameters
+    int direction0 = CW; //direction left motor
+    int direction1 = CW; //direction right motor
+    calcultateSpeedDirection (x, y);//calculate parameters
+    speed0 = map(velocityLeft, 0, controllerMax, 0, 255);
+    speed1 = map(velocityRight, 0, controllerMax, 0, 255);
     adjustMotor(0, direction0, speed0);//run left motor
     adjustMotor (1, direction1, speed1);//run right motor
   }
@@ -34,8 +46,16 @@
   {

   }
-  void calcultateSpeedDirection (x, y, velocity)//converts input in controller-format to suitable combination of track movements
+  void calcultateSpeedDirection (x, y)//converts input in controller-format to suitable combination of track movements
   {
-
+    int velocityLeft = (x / 2) + y;//compute velociy left track
+    if (velocityLeft < 0)// if needed change left direction
+    {
+      directionLeft = CCW;
+    }
+    int velocityRight = ((-x) / 2) + y;//see Left
+    if (velocityRight < 0)
+    {
+      directionRight = CCW;//see Left
+    }
   }
-


Cleared some comments on Nano

Cleared some comments on Nano

--- Nano/nano.ino
+++ Nano/nano.ino
@@ -82,20 +82,11 @@
 	}

 	if (millis() - servoWrite > 5) {
-		//Serial.println(radioData.motor);
-		// MOTOR SERVO
-		//setServo(0, radioData.motor);
-		//setServo(1, radioData.servo[0]);
-		//setServo(2, 180-radioData.servo[0]);
-		//setServo(3, radioData.servo[1]);
-		//setServo(4, radioData.servo[2]);
 		for (uint8_t i = 0; i < 5; i++) {
 			setServo(i, transmission[i]);
 		}

-		//setServo(4, transmission[1]);
 		servoWrite = millis();
-
 	}
 }


typo - temperature vs angle

typo - temperature vs angle

--- VernierRotary/VernierRotary.ino
+++ VernierRotary/VernierRotary.ino
@@ -59,9 +59,9 @@
   Time = (ReadingNumber/1000.0*TimeBetweenReadings);
   Serial.print(Time); // print time in seconds
   Serial.print("\t"); //tab character
-  Serial.println(encoderPos*res);   // display temperature to one digit
-  delay(TimeBetweenReadings);
-  ReadingNumber++;  // Delay a bit...
+  Serial.println(encoderPos*res);   // display angle in degrees
+  delay(TimeBetweenReadings); // Delay a bit...
+  ReadingNumber++;
 }

 void doEncoderCCW()


Updated code for atmega32u2

Updated code for atmega32u2

--- nanowriter.ino
+++ nanowriter.ino
@@ -55,18 +55,19 @@
   PORTB |= B11111111;

   Keyboard.begin();
+  Serial.begin(9600);
 }

 char readButtons() {
-  return (~(PINB >> 1)) & B00111111;
+  return (~(PINB)) & B00111111;
 }

 void toggleKey(char key) {
-  if (!toggles[key >> 7]) {
-    toggles[key >> 7] = true;
+  if (!toggles[key ^ 80]) {
+    toggles[key ^ 80] = true;
     Keyboard.press(key);
   } else {
-    toggles[key >> 7] = false;
+    toggles[key ^ 80] = false;
     Keyboard.release(key);
   }
 }
@@ -83,7 +84,7 @@
   if (input & 1) {
     switch(input){
       case B000001:
-        toggleKey(KEY_LEFT_SHIFT);
+        toggleKey(KEY_LEFT_SHIFT);ute
         return 0;
       case B111101:
         resetState();
@@ -119,9 +120,9 @@
       Keyboard.release(prevCharacter);
       prevCharacter = character;
       if (character != 0) {
+        Serial.println(character);
         Keyboard.press(character);
-      }
+      }
     }
   }
 }
-


Started doing stuff

Started doing stuff

--- firefighter/firefighter.ino
+++ firefighter/firefighter.ino
@@ -105,6 +105,7 @@
 }

 bool foundRoom = false;
+bool foundFlame = false;

 void loop() {
   // put your main code here, to run repeatedly:
@@ -132,12 +133,43 @@
 	// delay(2000);
 	// turnToAngle(90, 0.3);
 	// delay(2000);
-
-	while((colour_sensor.getColor('r') > ri - 70)) {
+
+	// while((colour_sensor.getColor('r') > ri - 70)) {
+		// naviguessMaze(0.3);
+	// }
+
+	while(!foundFlame && digitalRead(flame_sensor)) {
 		naviguessMaze(0.3);
 	}

+	foundFlame = true;
+
+	fan_motor.set(1.0);
+
 	hDrive(0.0, 0.0, 0.0);
+	delay(100);
+
+	while (frontUltrasonic.getDistance() > 0.5) {
+		hDrive(0.3, 0.0, 0.0);
+		extingusher_servo.write(110);
+		delay(100);
+		extingusher_servo.write(70);
+		delay(200);
+		hDrive(0.0, 0.0, 0.0);
+		delay(200);
+	}
+
+	hDrive(0.0, 0.0, 0.0);
+
+	// while (true) {
+		// for(int i = 40; i <= 160; i += interval){
+		  // extingusher_servo.write(i);
+		// }
+
+		// for(int i = 140; i >=20; i -= interval){
+		  // extingusher_servo.write(i);
+		// }
+	// }

 	// while (!foundRoom) {
 		// driveToWhite();


update to match latest core

update to match latest core

--- nunchuck.ino
+++ nunchuck.ino
@@ -7,7 +7,7 @@

 #ifdef SOFT_I2C
 #include <SoftWire.h>
-TwoWire MyWire(MY_SCL, MY_SDA, SOFT_STANDARD);
+SoftWire MyWire(MY_SCL, MY_SDA, SOFT_STANDARD);
 #else
 #include <Wire.h>
 HardWire MyWire(1, 0); // I2C_FAST_MODE);


Calibration - again

Calibration - again

--- otto/otto.ino
+++ otto/otto.ino
@@ -1,17 +1,17 @@
 #include <limits.h>
 #include <Servo.h>

-#define RIGHT_ANKLE_POS_MIN     900
+#define RIGHT_ANKLE_POS_LEFT    900
 #define RIGHT_ANKLE_POS_MIDDLE  1510
-#define RIGHT_ANKLE_POS_MAX     1950
-
-#define LEFT_ANKLE_POS_MIN      1050
+#define RIGHT_ANKLE_POS_RIGHT   1800
+
+#define LEFT_ANKLE_POS_LEFT     1150
 #define LEFT_ANKLE_POS_MIDDLE   1490
-#define LEFT_ANKLE_POS_MAX      2200
+#define LEFT_ANKLE_POS_RIGHT    2200

 #define RIGHT_HIP_POS_MIN       960
 #define RIGHT_HIP_POS_MIDDLE    1290
-#define RIGHT_HIP_POS_MAX       1600
+#define RIGHT_HIP_POS_MAX       1620

 #define LEFT_HIP_POS_MIN        1100
 #define LEFT_HIP_POS_MIDDLE     1500
@@ -149,8 +149,8 @@
     }
 }

-Joint rightAnkle(RIGHT_ANKLE_PIN, RIGHT_ANKLE_POS_MIN, RIGHT_ANKLE_POS_MIDDLE, RIGHT_ANKLE_POS_MAX);
-Joint leftAnkle(LEFT_ANKLE_PIN, LEFT_ANKLE_POS_MIN, LEFT_ANKLE_POS_MIDDLE, LEFT_ANKLE_POS_MAX);
+Joint rightAnkle(RIGHT_ANKLE_PIN, RIGHT_ANKLE_POS_LEFT, RIGHT_ANKLE_POS_MIDDLE, RIGHT_ANKLE_POS_RIGHT);
+Joint leftAnkle(LEFT_ANKLE_PIN, LEFT_ANKLE_POS_LEFT, LEFT_ANKLE_POS_MIDDLE, LEFT_ANKLE_POS_RIGHT);
 Joint rightHip(RIGHT_HIP_PIN, RIGHT_HIP_POS_MIN, RIGHT_HIP_POS_MIDDLE, RIGHT_HIP_POS_MAX);
 Joint leftHip(LEFT_HIP_PIN, LEFT_HIP_POS_MIN, LEFT_HIP_POS_MIDDLE, LEFT_HIP_POS_MAX);