These pin defs may or may not be correct.

--- Project/servo_sweep/servo_sweep.ino
+++ Project/servo_sweep/servo_sweep.ino
@@ -14,10 +14,10 @@

 #include <Servo.h>

-#define boomArmPin 11
-#define mainArmPin 10
-#define clawPin 9       // max 140, min 69
-#define swivelPin 6     // max 180, min 10
+#define boomArmPin 9
+#define mainArmPin 6
+#define clawPin 5       // max 140, min 69
+#define swivelPin 3     // max 180, min 10

 #define angleMin 60
 #define angleMax 110


Renamed feed vars

Renamed feed vars

--- sketch_02_dht11_graph/sketch_02_dht11_graph.ino
+++ sketch_02_dht11_graph/sketch_02_dht11_graph.ino
@@ -55,8 +55,8 @@
 /************************ Example Starts Here *******************************/

 // set up the 'graph' feed
-AdafruitIO_Feed * hiGraphFeed = io.feed("hi");
-AdafruitIO_Feed * kiGraphFeed = io.feed("ki");
+AdafruitIO_Feed * graphHIFeed = io.feed("graphHI");
+AdafruitIO_Feed * graphKIFeed = io.feed("graphKI");

 void setup() {
 	// use serial port for printing messages
@@ -119,6 +119,6 @@
 	Serial.print(HI);
   Serial.print(" KI = ");
   Serial.println(KI);
-	hiGraphFeed->save(HI);
-  kiGraphFeed->save(KI);
+	graphHIFeed->save(HI);
+  graphKIFeed->save(KI);
 }


Add files via upload

Add files via upload

Semester Final

--- arduino/arduinoSetup/arduinoSetup.ino
+++ arduino/arduinoSetup/arduinoSetup.ino
@@ -8,7 +8,7 @@

   DS3231 clock;
   clock.begin();
-  clock.setDateTime(2016, 11, 25, 12, 44, 00);
+  clock.setDateTime(2017, 3, 16, 22, 12, 30);

 }


main_control now fully functionally. Waits for you to arm the robot with the tx, then llaunches and currently just drives straight ahead but in auto mode. Any input on the TX takes over the robot. Great starting point, phase 1 complete

--- arduino/main_control/main_control.ino
+++ arduino/main_control/main_control.ino
@@ -1,28 +1,70 @@
 /*
- * Be sure to first calibrate the ESC
+ * Be sure to first calibrate the ESC. This program controls a Traxxas Slash 2 wheel drive
+ * with XL5 speed controller
  */
 #include <Servo.h>

+
+const int STEER_IN = 5;
+const int STEER_OUT = 9;
+const int STEER_BASE = 1475;
+const int STEER_MIN = 970;
+const int STEER_MAX = 1930;
+const int STEER_BIAS = 2; //set this to adjust steering
+
+const int THROTTLE_IN = 6;
+const int THROTTLE_OUT = 11;
+const int THROTTLE_BASE = 1462;
+const int THROTTLE_MIN = 975;
+const int THROTTLE_MAX = 1962;
+
+const int LED_GREEN = 2;
+const int LED_RED = 3;
+
+
+
+
+//servos
 Servo steering_servo;
 Servo throttle_servo;

-
+int steer_input;
+int throttle_input;
+
+//make sure we have a transmitter so that we can safety stop the car
+bool TX_found, TX_high, TX_low;
+bool manual_mode = false;
+
+
+
+//sets the steering angle between -45, 45 for full left /right respectively. set to zero for straight ahead
 void set_steer_angle(int angle){
-  int map_angle = map(angle, -90, 90, 0, 180);
+  angle = angle + STEER_BIAS;
+  int map_angle = map(angle, -45, 45, 0, 180);
   steering_servo.write(map_angle);
 }

+//when using the transmitter, map the steering to the TX output
+void set_steer_angle_manual(int sp){
+  int map_angle = map(sp, STEER_MIN, STEER_MAX, -45, 45);
+  set_steer_angle(map_angle);
+}
+
+//controls the acceleration/deccelration of the robot. -100 is full break to 100 full gas
 void set_throttle_position(int sp){
-  //Add 1 to the position so that zero is actually 1. This seems to keep the ESC alive.
-  if(sp==0){
-    sp = 0;
-  }
-
   int map_throttle = map(sp, -100, 100, 1000, 2000);
   throttle_servo.writeMicroseconds(map_throttle);
 }

-
+//when using the transmitter, map the throttle to the TX output
+void set_throttle_position_manual(int sp){
+  int map_throttle = map(sp, THROTTLE_MIN, THROTTLE_MAX, -100, 100);
+  set_throttle_position(map_throttle);
+}
+
+
+//set a reverse speed, 3 second delay to make sure the vehicle is stopped,
+//range is 0 to 100 for min max reverse
 void reverse(int sp){
   set_throttle_position(-100);
   delay(3000);
@@ -34,16 +76,16 @@
 }

-
+//Sweeps the steering servo
 void sweep(){
   set_steer_angle(0);
   delay(100);
   //sweep steering
-  for(int i=-90;i<90;i++){
+  for(int i=-45;i<45;i++){
     set_steer_angle(i);
     delay(10);
   }
-  for(int i=90;i>=-90;i--){
+  for(int i=45;i>=-45;i--){
     set_steer_angle(i);
     delay(10);
   }
@@ -51,7 +93,9 @@
   delay(100);
 }

+//This method launches the vehicle off the start line!
 void launch(){
+  Serial.println("Vector79: launching (wish me luck)...");
   set_throttle_position(0);
   delay(100);
   set_throttle_position(-50);
@@ -60,31 +104,105 @@
   delay(600);
 }

+void toggle_LED(int led, bool visable){
+  if(visable){
+    digitalWrite(led, HIGH);
+  }
+  else{
+    digitalWrite(led, LOW);
+  }
+
+}
+
+void enter_manual_mode(){
+  Serial.println("Vector79: Manual mode triggered from TX");
+  manual_mode = true;
+  toggle_LED(LED_GREEN, false);
+  toggle_LED(LED_RED, true);
+}

 void setup() {
-  steering_servo.attach(9);  // attaches the servo on pin 9 to the servo object
-  throttle_servo.attach(11);  // attaches the servo on pin 9 to the servo object
+  Serial.begin(9600);
+  Serial.println("Vector79: starting...");
+
+  //set up red/green led indicators
+  pinMode(2, OUTPUT);
+  pinMode(3, OUTPUT);
+  toggle_LED(LED_GREEN, false);
+  toggle_LED(LED_RED, true);
+
+  //read from the controller
+  pinMode(5, INPUT);
+  pinMode(6, INPUT);
+
+  steering_servo.attach(STEER_OUT);  // attaches the servo on pin 9 to the servo object
+  throttle_servo.attach(THROTTLE_OUT);  // attaches the servo on pin 9 to the servo object

   delay(1);
   sweep();
-  launch();
-  //WHOAH stop this bad boy
-  set_throttle_position(-100);
+  Serial.println("Vector79: setup complete in 3s");
   delay(3000);
 }

+
 void loop() {

-  set_steer_angle(90);
-  delay(10);
-  set_throttle_position(20);
-  delay(5000);
-  reverse(20);
-  delay(5000);
-
-  set_throttle_position(0);
-  delay(1000);
-  sweep();
-
-}
+  //loop until the transmitter is toggled full throttle forward and reverse
+  while (!TX_found){
+      //read in the from the controller
+      throttle_input = pulseIn(THROTTLE_IN, HIGH, 25000);
+      Serial.println(throttle_input);
+
+      //toggle red led while waiting to arm
+      toggle_LED(LED_RED, true);
+      delay(10);
+      toggle_LED(LED_RED, false);
+      delay(10);
+
+      if(throttle_input > THROTTLE_MAX - 100){
+        Serial.println("HIGH RX");
+        TX_high = true;
+      }
+      if(throttle_input < THROTTLE_MIN  + 100){
+        Serial.println("LOW RX");
+        TX_low = true;
+      }
+
+      if(TX_low && TX_high){
+        TX_found = true;
+        toggle_LED(LED_RED, false);
+        for(int i=0;i<30;i++){
+          toggle_LED(LED_GREEN, true);
+          delay(80);
+          toggle_LED(LED_GREEN, false);
+          delay(80);
+        }
+        toggle_LED(LED_GREEN, true);
+
+          //WARNING: Uncommenting this will lanuch the robot
+        launch();
+        //WHOAH stop this bad boy (NOTICE, setting the throttle position to -100 is full breaks,
+        //to go in reverse, use the reverse method
+        set_throttle_position(-100);
+        delay(3000);
+        set_throttle_position(20);
+      }
+  }//end while init transmitter
+
+  steer_input = pulseIn(STEER_IN, HIGH, 25000);
+  throttle_input = pulseIn(THROTTLE_IN, HIGH, 25000);
+
+  //if ever the transmitter is used, go into manual mode
+  if(!manual_mode){
+    if((abs(steer_input - STEER_BASE) > 100) || (abs(throttle_input - THROTTLE_BASE) > 100)){
+      enter_manual_mode();
+    }
+  }
+
+
+  if(manual_mode){
+    set_steer_angle_manual(steer_input);
+    set_throttle_position_manual(throttle_input);
+  }
+}


fix nasty crash recovery bug

fix nasty crash recovery bug

--- arduino/motor_driver/motor_driver.ino
+++ arduino/motor_driver/motor_driver.ino
@@ -325,6 +325,8 @@
 // setupEncoder will check if encoder position is retained in RAM after a crash
 // and return true if so
 bool setupEncoder() {
+  bool recovered = false;
+
   if (EEPROM.read(EEPROM_REMEMBER_POSITION) == 1) {
     // check if encoder value can be recovered after crash
     if (encoder0Pos ^ encoder0ChecksumKey == encoder0Checksum) {
@@ -332,7 +334,7 @@
       if (encoder0Pos > 10 && encoder0Pos < 100000) {
         // yes! let's claim we're homed
         reboots++;
-        return true;
+        recovered = true;
       }
     }
   }
@@ -345,7 +347,7 @@
   // encoder pin on interrupt 0 (pin 2)
   attachInterrupt(0, doEncoderA, RISING);

-  return false;
+  return recovered;
 }

 void setupMotorDriver(bool poweron) {


Disable adc to save an undetectable amount of power. Real power draw is from the CC1101

--- arduino/rfglow_slave/rfglow_slave.ino
+++ arduino/rfglow_slave/rfglow_slave.ino
@@ -1,3 +1,25 @@
+#define power_adc_enable()      (PRR &= (uint8_t)~(1 << PRADC))
+#define power_adc_disable()     (PRR |= (uint8_t)(1 << PRADC))
+
+#define power_spi_enable()      (PRR &= (uint8_t)~(1 << PRSPI))
+#define power_spi_disable()     (PRR |= (uint8_t)(1 << PRSPI))
+
+#define power_usart0_enable()   (PRR &= (uint8_t)~(1 << PRUSART0))
+#define power_usart0_disable()  (PRR |= (uint8_t)(1 << PRUSART0))
+
+#define power_timer0_enable()   (PRR &= (uint8_t)~(1 << PRTIM0))
+#define power_timer0_disable()  (PRR |= (uint8_t)(1 << PRTIM0))
+
+#define power_timer1_enable()   (PRR &= (uint8_t)~(1 << PRTIM1))
+#define power_timer1_disable()  (PRR |= (uint8_t)(1 << PRTIM1))
+
+#define power_timer2_enable()   (PRR &= (uint8_t)~(1 << PRTIM2))
+#define power_timer2_disable()  (PRR |= (uint8_t)(1 << PRTIM2))
+
+#define power_twi_enable()      (PRR &= (uint8_t)~(1 << PRTWI))
+#define power_twi_disable()     (PRR |= (uint8_t)(1 << PRTWI))
+
+
 #include <EEPROM.h>
 #include "cc1101.h"
 //#include "regtable.h"
@@ -53,13 +75,11 @@
  */
 void setup()
 {
+
+  power_adc_disable();
+
   Serial.begin(38400);
   Serial.println("Setup started");
-  // Init panStamp
-  //panstamp.init();
-
-  // Transmit product code
-  //getRegister(REGI_PRODUCTCODE)->getData();

   // Init CC1101
   cc1101.init();
@@ -84,7 +104,7 @@

   cc1101.setChannel(RFCHANNEL, true);
-  cc1101.setSyncWord(syncWord, false);
+  cc1101.setSyncWord(syncWord, true);

   cc1101.setDevAddress(receiverAddress, false);
   cc1101.disableAddressCheck();
@@ -95,12 +115,13 @@
   ShiftPWM.SetAmountOfRegisters(numRegisters);
   ShiftPWM.SetPinGrouping(1);
   ShiftPWM.Start(pwmFrequency, maxBrightness);
-  //ShiftPWM.SetAll(0);
+  ShiftPWM.SetAll(0);
   ShiftPWM.OneByOneFast();
-  ShiftPWM.PrintInterruptLoad();
+  //ShiftPWM.PrintInterruptLoad();
   Serial.println(ShiftPWM.m_ledFrequency);
   Serial.println(ShiftPWM.m_maxBrightness);
   Serial.println("Setup complete");
+
 }

 /**


Clean up comments.

Clean up comments.

--- SmartAlarmClock/SmartAlarmClock.ino
+++ SmartAlarmClock/SmartAlarmClock.ino
@@ -37,13 +37,13 @@
 // Options to specify when running madplay command.
 #define ALARM_OPTIONS     "--attenuate=-36"
 // Minutes to wait between calendar refreshes:
-#define ALARM_REFRESH_MINS  60
+#define ALARM_REFRESH_MINS  120
 // Meetings after this hour (0-23) will be ignored.  Set to 24 to disable this behavior.
-#define ALARM_LATEST_HOUR   12
+#define ALARM_LATEST_HOUR   12
 // Amount of time before the first meeting to fire the alarm.
 #define ALARM_BUFFER_MINS   60
 // Minutes to wait before checking for new wake up emails.
-#define ALARM_KEYWORD_MINS  10
+#define ALARM_KEYWORD_MINS  120

 // Touchscreen calibration.
 // You don't need to change these values.


Allow easy switch of credentials for DE & DHD!

--- dev/dev.ino
+++ dev/dev.ino
@@ -52,10 +52,23 @@
  */

 static const int baud = 19200;  // don't chage this - may break softwareserial
+
+#define CREDS 2 // Choose set of hardwired credentials and target address.
+
+
+#if 1 == CREDS // DE
 static const char apn[] = "internet"; // "m2mkit.telefonica.com"
 static const char pin[] = "7634";
 static const char UDP_ADDR[] = "46.101.52.242";
 static const char UDP_PORT[] = "9999";
+#elif 2 == CREDS // DHD
+static const char apn[] = "m2mkit.telefonica.com";
+static const char pin[] = "0000";
+static const char UDP_ADDR[] = "79.135.97.66";
+static const char UDP_PORT[] = "9999";
+#endif
+
+
 static const char UDP_SEND_STR[] = "The cat in the hat";

 void setup()
@@ -146,4 +159,4 @@
     default:
     break;
   }
-}
+}


CyclopPlusPlus: - ensure to call updateSoftPositions in ReadEEPROM - fixes non-applied soft positions after power on

--- src/cyclop_plus_plus/cyclop_plus_plus.ino
+++ src/cyclop_plus_plus/cyclop_plus_plus.ino
@@ -388,6 +388,7 @@
   currentChannel =   EEPROM.read(EEPROM_CHANNEL);
   for (i = 0; i < MAX_OPTIONS; i++)
     options[i] = EEPROM.read(EEPROM_OPTIONS + i);
+  updateSoftPositions();
   return true;
 }


fix compilation

fix compilation

--- Arduino/hardware/REV10/REV10SecureBHR/REV10SecureBHR.ino
+++ Arduino/hardware/REV10/REV10SecureBHR/REV10SecureBHR.ino
@@ -755,7 +755,7 @@
     const uint8_t nearOverrunThreshold = OTV0P2BASE::GSCT_MAX - 8; // ~64ms/~32 serial TX chars of grace time...

     // Update internal boiler hub state and
-    BoilerHub.processCallsForHeat(second0, hubManager.inHubMode());
+    BoilerHub.processCallsForHeat((0 == TIME_LSD), hubManager.inHubMode());

     // Sleep in low-power mode (waiting for interrupts) until seconds roll.
     // NOTE: sleep at the top of the loop to minimise timing jitter/delay from Arduino background activity after loop() returns.


Added some additional comments to FMBeacon example sketch.

--- examples/FMBeacon/FMBeacon.ino
+++ examples/FMBeacon/FMBeacon.ino
@@ -1,5 +1,6 @@
 /* Hamshield
  * Example: Morse Code Beacon
+ *
  * Test beacon will transmit and wait 30 seconds.
  * Beacon will check to see if the channel is clear before it
  * will transmit.
@@ -8,12 +9,8 @@
  * power and then to your computer via USB. After uploading
  * this program to your Arduino, open the Serial Monitor to
  * monitor the status of the beacon. To test, set a HandyTalkie
- * to 438MHz. You should hear the message " KC7IBT HAMSHIELD"
+ * to 438MHz. You should hear the message " CALLSIGN HAMSHIELD"
  * in morse code.
-
- * NOTE: Radio chip audio AGC too slow in responding to tones,
- * worked around by playing a 6khz tone between actual dits/dahs.
- * Should work on adjusting AGC to not require this.
 */

 #define DDS_REFCLK_DEFAULT 9600
@@ -51,12 +48,15 @@

   // Tell the HamShield to start up
   radio.initialize();
+
+  // Set the transmit power level (0-8)
   radio.setRfPower(0);
-
+
+  // Set the morse code characteristics
   radio.setMorseFreq(600);
   radio.setMorseDotMillis(100);

-  // Configure the HamShield to transmit and recieve on 446.000MHz
+  // Configure the HamShield to operate on 438.000MHz
   radio.frequency(438000);

   Serial.println("Radio Configured.");
@@ -74,7 +74,7 @@
     radio.setModeTransmit();

     // Send a message out in morse code
-    radio.morseOut(" KC7IBT HAMSHIELD");
+    radio.morseOut(" CALLSIGN HAMSHIELD");

     // We're done sending the message, set the radio back into recieve mode.
     radio.setModeReceive();
@@ -85,6 +85,6 @@
     Serial.println(radio.readRSSI());
   }

-  // Wait 10 seconds before we send our beacon again.
+  // Wait 30 seconds before we send our beacon again.
   delay(30000);
 }


updated odometer example for clarity

updated odometer example for clarity

--- examples/Odometer/Odometer.ino
+++ examples/Odometer/Odometer.ino
@@ -3,10 +3,12 @@
 Odometer encoder;
 unsigned long startTime;
 unsigned int timeOver = 20000; //20 seconds
+const int encoderPin = 19; //digital pin 19 (interrupt 4 on arduino mega)
+

 void setup() {
   Serial.begin(9600);
-  encoder.attach(19);
+  encoder.attach(encoderPin);
   encoder.begin();
   startTime = millis();
 }


Update selftest.ino

Update selftest.ino

--- examples/selftest/selftest.ino
+++ examples/selftest/selftest.ino
@@ -3,7 +3,7 @@
 #include <tsunami.h>

 #define LED_PIN 13
-#define RUN_REPEATEDLY true
+#define RUN_REPEATEDLY false

 char err[255];


Fixing IP assignment

Fixing IP assignment

--- arduino/arduino.ino
+++ arduino/arduino.ino
@@ -105,7 +105,7 @@
 #ifdef USE_STROMBEWUSST_SERVER
   // UDP Format: <16xkey><1xtimeframe><1xticks>
   byte udpBuffer[18] = STROMBEWUSST_KEY;
-  IPAddress strombewusstIP = STROMBEWUSST_SERVER;
+  IPAddress strombewusstIP STROMBEWUSST_SERVER;
 #endif

 // stores the # of bytes needed to store the information


Trying to read target temp from eerom and default low start

--- remote_thermostat/remote_thermostat.ino
+++ remote_thermostat/remote_thermostat.ino
@@ -1,18 +1,20 @@
 #include <PubSubClient.h>
 #include <ESP8266WiFi.h>
 #include <DHT.h>
+#include <EEPROM.h>
 #include "relayr.h"

-#define SSID "lok"
-#define PASSWORD "rem1000"
+#define SSID "ssid"
+#define PASSWORD "password"

+#define DEFAULT_TARGET_TEMP 19

-#define COOL_PIN 12
-#define HEAT_PIN 2
-#define DHTPIN 13
+#define COOL_PIN 13
+#define HEAT_PIN 14
+#define DHTPIN 12

 #define TEMPERATURE_CONTROL_RANGE 1
-#define COMPRESSER_DELAY 2000
+#define COMPRESSER_DELAY 20000

 unsigned long lastTime = 0;

@@ -22,7 +24,8 @@

 boolean cooling = false;
 boolean heating = false;
-float targetTemp = 32.0;
+float targetTemp = 0;
+int eeAddress = 0;

 DHT dht;
@@ -36,45 +39,58 @@
     lastCoolingTime = lastCoolingTime < 1 ? millis() : lastCoolingTime;

    if (millis() - lastCoolingTime > COMPRESSER_DELAY) {
-     digitalWrite(HEAT_PIN, LOW);
-     digitalWrite(COOL_PIN, HIGH);
+     digitalWrite(COOL_PIN, LOW);
      lastCoolingTime = millis();
    }
+
+   digitalWrite(HEAT_PIN, HIGH);
 }

 void heat() {
-  digitalWrite(HEAT_PIN, HIGH);
-  digitalWrite(COOL_PIN, LOW);
+  digitalWrite(HEAT_PIN, LOW);
+  digitalWrite(COOL_PIN, HIGH);
   lastCoolingTime = 0;
 }

 void stop() {
   lastCoolingTime = 0;
-  digitalWrite(HEAT_PIN, LOW);
-  digitalWrite(COOL_PIN, LOW);
+  digitalWrite(HEAT_PIN, HIGH);
+  digitalWrite(COOL_PIN, HIGH);
 }

 void control(float temp) {
-  if (temp - TEMPERATURE_CONTROL_RANGE < targetTemp) {
+  if (temp + TEMPERATURE_CONTROL_RANGE < targetTemp) {
     heating = true;
     cooling = false;
-  }
-  if (temp + TEMPERATURE_CONTROL_RANGE > targetTemp) {
+  } else if (temp - TEMPERATURE_CONTROL_RANGE > targetTemp) {
     heating = false;
     cooling = true;
+  } else {
+    heating = false;
+    cooling = false;
   }
 };

 void setTargetTemp(float message) {
   Serial.println("set target");
   targetTemp = message;
+  EEPROM.put(eeAddress, targetTemp);
+  EEPROM.commit();
 };

 void setup() {
     Serial.begin(9600);
+    EEPROM.begin(512);
+
+    if (targetTemp == 0) {
+      EEPROM.get(eeAddress, targetTemp);
+      targetTemp = targetTemp == NAN ? DEFAULT_TARGET_TEMP : targetTemp;
+    }

     pinMode(HEAT_PIN, OUTPUT);
     pinMode(COOL_PIN, OUTPUT);
+    digitalWrite(HEAT_PIN, HIGH);
+    digitalWrite(COOL_PIN, HIGH);

     publishingPeriod = publishingPeriod > 200 ? publishingPeriod : 200;


refactor date parser to use a union

refactor date parser to use a union

--- SmartAlarm.ino
+++ SmartAlarm.ino
@@ -47,6 +47,9 @@

 DateTime now = DateTime(0);

+/**
+ * converts a three letter english abbreviation for a month into the months number
+ */
 uint8_t parseMonth (char *mo) {
   if (!strcmp(mo, "Jan")) {
     return 1;
@@ -77,7 +80,28 @@
   }
 }

+
+/**
+ * connects to a web server and parses its HTTP Date: header to get the current DateTime
+ */
 DateTime parseHeader(uint32_t ip, uint16_t port, char *host, char *path) {
+  #define LINELEN 256
+  /**
+   * holds the HTTP Date header line, which fortunately has fixed with fields
+   * Date: Tue 15 Nov 1994 08:12:31 GMT
+   */
+  typedef union dateline
+  {
+    char line[LINELEN];
+    struct fields {
+      char date[6];
+      char dow[4]; char pad;
+      char dom[3]; char mmm[4]; char yyyy[5];
+      char hh[3]; char mm[3]; char ss[3];
+      char tz[4];
+    } fields;
+  } dateline;
+
   // first connect to the site we're gonna leech the datetime from
   Adafruit_CC3000_Client www = cc3000.connectTCP(ip, port);
   if (www.connected()) {
@@ -93,27 +117,33 @@
   }

   // try to read the Date line in the http headers
-  char line[256];
+  dateline l;
   size_t pos = 0;
   bool wehaveadate = 0;
   unsigned long lastRead = millis();
   while (www.connected() && (millis() - lastRead < IDLE_TIMEOUT_MS)) {
     while (www.available()) {
       char c = www.read();
-      if (c == '\n') { // we've reached a newline
-        line[pos++] = 0;
+      if (c == '\n' || pos > LINELEN-2) { // we've reached a newline
         pos = 0;
         // now we need to see whether this is the 'Date:' line
-        if (line[0] == 'D' &&
-            line[1] == 'a' &&
-            line[2] == 't' &&
-            line[3] == 'e' &&
-            line[4] == ':') { // seriously? TODO: fix this shit
+        if (!strcmp(l.fields.date, "Date:")) {
           wehaveadate = 1;
         }
       } else if (!wehaveadate) { // if we haven't reached a newline, put it in the buffer
-        line[pos] = c;
-        line[pos + 1] = 0;
+        if (pos == 5 ||
+            pos == 9 ||
+            pos == 13||
+            pos == 17||
+            pos == 22||
+            pos == 25||
+            pos == 28||
+            pos == 31) { // putting the nulls in the right place for field seperators
+          l.line[pos] = 0;
+        } else {
+          l.line[pos] = c;
+        }
+        l.line[pos + 1] = 0;
         pos++;
       }
       lastRead = millis();
@@ -121,23 +151,12 @@
   }
   www.close();
   if (wehaveadate) {
-    // please fucking refactor this shit
-    // this is the fucking worst way to parse shit
-    // TODO: refactor this into an union or something less fucking terrible
-    line[10] = 0; // null after dow
-    line[13] = 0; // null after dom
-    line[17] = 0; // null after month
-    line[22] = 0; // null after year
-    line[25] = 0; // null after hour
-    line[28] = 0; // null after minute
-    line[31] = 0; // null after second
-    char *s_year = line+18;
-    char *s_month = line+14;
-    char *s_day = line+11;
-    char *s_hour = line+23;
-    char *s_minute = line+26;
-    char *s_second = line+29;
-    return DateTime(atoi(s_year), parseMonth(s_month), atoi(s_day), atoi(s_hour), atoi(s_minute), atoi(s_second));
+    return DateTime(atoi(l.fields.yyyy),
+                    parseMonth(l.fields.mmm),
+                    atoi(l.fields.dom),
+                    atoi(l.fields.hh),
+                    atoi(l.fields.mm),
+                    atoi(l.fields.ss));
   } else {
     return NULL;
   }
@@ -223,6 +242,10 @@
   }

   lcd.setCursor(0,3);
-  lcd.print("uptime: ");
-  lcd.print(millis()/1000);
-}
+  lcd.print(now.year()); lcd.print('-');
+  lcd.print(now.month()); lcd.print('-');
+  lcd.print(now.day()); lcd.print(' ');
+  lcd.print(now.hour()); lcd.print(':');
+  lcd.print(now.minute()); lcd.print(':');
+  lcd.print(now.second());
+}


triggering travis ci

triggering travis ci

--- examples/mqtt_ethernet/mqtt_ethernet.ino
+++ examples/mqtt_ethernet/mqtt_ethernet.ino
@@ -34,6 +34,7 @@
 #define AIO_SERVERPORT  1883
 #define AIO_USERNAME    "...your AIO username (see https://accounts.adafruit.com)..."
 #define AIO_KEY         "...your AIO key..."
+

 /************ Global State (you don't need to change this!) ******************/


Update wake_on_lan.ino

Update wake_on_lan.ino

--- arduino_ide/wake_on_lan/wake_on_lan.ino
+++ arduino_ide/wake_on_lan/wake_on_lan.ino
@@ -50,7 +50,7 @@
     // For security reason, only the final byte of the IP can be edited from the web
     // this should prevent this device to be used for DDoS attacks

-    if(server.arg("mac").length() <= 12 && server.arg("p").length() <= 200 && server.arg("bcast").length() <= 3) {
+    if(server.arg("mac").length() <= 12 && server.arg("pwd").length() <= 200 && server.arg("bcast").length() <= 3) {
       String mac = server.arg("mac");
       String p = server.arg("pwd");
       int bcast = server.arg("bcast").toInt();


No pullup on pin 16

No pullup on pin 16

--- examples/SmokeTest/SmokeTest.ino
+++ examples/SmokeTest/SmokeTest.ino
@@ -19,7 +19,7 @@

   // Switches
   pinMode(DENBIT_SW1, INPUT_PULLUP);
-  pinMode(DENBIT_SW2, INPUT_PULLUP);
+  pinMode(DENBIT_SW2, INPUT);

   Serial.begin(115200);
 }


issue angle mapping solved

issue angle mapping solved

position setpoint function created
status: strain gauge needs reading

--- send/send.ino
+++ send/send.ino
@@ -80,7 +80,7 @@
 // System Variables
 // *****************

-int enconder_resolution = 2000; //2000 counts per turn
+int encoder_resolution = 2000; //2000 counts per turn
 int reduction = 100; // harmonic drive reduction

 void setup()
@@ -123,22 +123,35 @@
 //*******************
 // POSITION SETPOINT
 //*******************
-void positionSetpoint(void)
+void positionSetpoint(double position)
 {
   unsigned char len = 0;
   unsigned char buf[8];

-    Serial.println("Enviei a mensagem");
-    // Serial.println(setpoint_position,HEX);
-    // clear the string:
-    CAN.sendMsgBuf(0x601, 0, 8, setpoint_position);
-    delay(10);
+  uint32_t angulo = (position/4096)*200000;
+
+  setpoint_position[4] = angulo & 0xFF;
+  setpoint_position[5] = (angulo >> 8) & 0xFF;
+  setpoint_position[6] = (angulo >> 16) & 0xFF;
+  setpoint_position[7] = (angulo >> 24) & 0xFF;
+
+  Serial.println("Position: ");
+  Serial.println(position);
+
+  Serial.println("Angulo: ");
+  Serial.println(angulo);
+
+  Serial.println("Enviei a mensagem");
+  // Serial.println(setpoint_position,HEX);
+  // clear the string:
+  CAN.sendMsgBuf(0x601, 0, 8, setpoint_position);
+  delay(10);
 }

 //***************
 // DATA READ
 //***************
-void dataRead(void)
+float dataRead()
 {
   unsigned char len = 0;
   unsigned char buf[8];
@@ -153,12 +166,6 @@
     encoder_data = buf[4];
     encoder_data <<= 8;
     encoder_data = encoder_data | buf[5];
-
-    // 200000 qc is one
-    encoder_data
-
-    setpoint_position[4] = buf[5]; // swaps data because for CAN, the Least Significant Bit comes first
-    setpoint_position[5] = buf[4]; // swaps data because for CAN, the Least Significant Bit comes first

     // // load cell information is read from buf[1], buf[2] and buf[3] and converted to decimal
     // loadcell_data = buf[1];
@@ -178,6 +185,7 @@
     // Serial.println(loadcell_data/1000, DEC);

     // delay(400);
+       return(encoder_data);
   }

 }
@@ -191,7 +199,7 @@
       break;
     case Operational:
       dataRead();
-      positionSetpoint();
+      positionSetpoint(encoder_data);
       break;
   }
   delay(100);


add barometer update call to loop as per API change

--- examples/APM_Barometer/APM_Barometer.ino
+++ examples/APM_Barometer/APM_Barometer.ino
@@ -17,6 +17,8 @@
     baro.calibrate();
 }
 void loop(){
+    baro.update();
+
     float temp = baro.getCelsius();
     float bar  = baro.getMilliBar();
     float alt  = baro.getAltitude();


fixed handleApiCommands()

fixed handleApiCommands()

replaced assignment with comparison operator

--- sw-machine-control/module-template/src/main.ino
+++ sw-machine-control/module-template/src/main.ino
@@ -74,10 +74,10 @@

 // Handle API commands
 void handleApiCommands(String command) {
-  if (command = "pickup();") {
+  if (command == "pickup();") {
     moduleJob = JOB_PICKUP;
   }
-  if (command = "drop();") {
+  if (command == "drop();") {
     moduleJob = JOB_DROP;
   }
 }


Added explanation of the PLL deviders

Added explanation of the PLL deviders

--- src/Arduino/_23cm-trx/PLL.ino
+++ src/Arduino/_23cm-trx/PLL.ino
@@ -1,5 +1,28 @@
 /*
  * Routines for setting the PLL frequency.
+ *
+ * The PLL is working as follows:
+ *
+ * fvco = (P*B + A)*REFin/R
+ *
+ * where
+ *  fvco = output frequency of external voltage controlled oscillator (VCO).
+ *     P = preset modulus of dual-modulus prescaler. (16 in our case)
+ *     B = preset divide ratio of binary 13-bit counter (3 to 8191).
+ *     A = preset divide ratio of binary 6-bit swallow counter (0 to 63).
+ * REFin = output frequency of the external reference frequency oscillator (12.8 MHz)
+ *     R = preset divide ratio of binary 14-bit programmable reference counter (1 to 16,383).
+ *         The devide ratio is chosen to match the step/raster size e.g 25000, but this is arbitrary.
+ *
+ * If P = 16, and R = 25000, we need to do two calculations to get B and A from fvco:
+ *
+ * B = (fvco/R) / P (note: int, so truncated at decimal point)
+ * A = (fvco/R) % P (the remainer to do without prescaler P)
+ *
+ * If we want fvco to be 1298.375 MHz, we need to set A and B to:
+ *
+ * B = (1298375000 / 25000) / 16 = 3245
+ * A = (1298375000 / 25000) % 16 = 15
  *
  */


fix char to int conversion

fix char to int conversion

--- Arduino/ODriveArduino/examples/ODriveArduinoTest/ODriveArduinoTest.ino
+++ Arduino/ODriveArduino/examples/ODriveArduinoTest/ODriveArduinoTest.ino
@@ -46,19 +46,20 @@

     // Run calibration sequence
     if (c == '0' || c == '1') {
+      int motornum = c-'0';
       int requested_state;

       requested_state = ODriveArduino::AXIS_STATE_MOTOR_CALIBRATION;
       Serial << "Axis" << c << ": Requesting state " << requested_state << '\n';
-      odrive.run_state(atoi(c), requested_state, true);
+      odrive.run_state(motornum, requested_state, true);

       requested_state = ODriveArduino::AXIS_STATE_ENCODER_OFFSET_CALIBRATION;
       Serial << "Axis" << c << ": Requesting state " << requested_state << '\n';
-      odrive.run_state(atoi(c), requested_state, true);
+      odrive.run_state(motornum, requested_state, true);

       requested_state = ODriveArduino::AXIS_STATE_CLOSED_LOOP_CONTROL;
       Serial << "Axis" << c << ": Requesting state " << requested_state << '\n';
-      odrive.run_state(atoi(c), requested_state, false); // don't wait
+      odrive.run_state(motornum, requested_state, false); // don't wait
     }

     // Sinusoidal test move


Fix DP[] in multiple-read example

Fix DP[] in multiple-read example

--- examples/multiple-read/multiple-read.ino
+++ examples/multiple-read/multiple-read.ino
@@ -69,11 +69,11 @@
   //when value is available, display
   if( myVitoWifi.getStatus() == RETURN ){
       //Display value and move to next DP
-      currentDP++;
       myVitoWifi.getLogger().print("Name: ");
-      myVitoWifi.getLogger().println(DP.name);
+      myVitoWifi.getLogger().println(DP[currentDP].name);
       myVitoWifi.getLogger().print("Value: ");
       myVitoWifi.getLogger().println(myVitoWifi.getValue());
       myVitoWifi.getLogger().println();
+      currentDP++;
   }
 }


fix code

fix code

--- little-switches/arduino/galoppo/galoppo.ino
+++ little-switches/arduino/galoppo/galoppo.ino
@@ -1,16 +1,105 @@
+#include <PS2Keyboard.h>
+
+const int DataPin = 9;
+const int IRQpin =  3;
+
+#define pot A3
+
+#define zampaAS 8
+#define zampaAD 6
+#define zampaPS 7
+#define zampaPD 5
+
+#define piede A0
+#define tamburo 2
+
+PS2Keyboard keyboard;
+
+long t1 = 0;
+long t2 = 0;
+long t3 = 0;
+long t4 = 0;
+long t5 = 0;
+long t6 = 0;
+
+int tempo = 0;

 void setup() {
-  pinMode(5,OUTPUT);
-  pinMode(6,OUTPUT);
+  delay(1000);
+  keyboard.begin(DataPin, IRQpin);
+  Serial.begin(9600);
+  Serial.println("Keyboard Test:");
+
+  pinMode(zampaAS,OUTPUT);
+  pinMode(zampaAD,OUTPUT);
+  pinMode(zampaPS,OUTPUT);
+  pinMode(zampaPD,OUTPUT);
+
+  pinMode(piede,OUTPUT);
+  pinMode(tamburo,OUTPUT);
+
+  digitalWrite(zampaAS,LOW);
+  digitalWrite(zampaAD,LOW);
+  digitalWrite(zampaPS,LOW);
+  digitalWrite(zampaPD,LOW);
+
+  digitalWrite(piede,LOW);
+  digitalWrite(tamburo,LOW);
+
 }

 void loop() {
-  digitalWrite(5,HIGH);
-  delay(1000);
-  digitalWrite(5,LOW);
-  delay(1000);
-  digitalWrite(6,HIGH);
-  delay(1000);
-  digitalWrite(6,LOW);
-  delay(1000);
+  tempo = map(analogRead(pot),0,1023,50,200);
+  Serial.print("tempo: ");
+  Serial.print(tempo);
+  Serial.println(" ms");
+
+  if (keyboard.available()) {
+
+    char c = keyboard.read();
+    Serial.println
+
+    if (c == '1') {
+      digitalWrite(zampaAS,HIGH);
+      t1 = millis();
+    } else if (c == '2') {
+      digitalWrite(zampaAD,HIGH);
+      t2 = millis();
+    } else if (c == '3') {
+      digitalWrite(zampaPS,HIGH);
+      t3 = millis();
+    } else if (c == '4') {
+      digitalWrite(zampaPD,HIGH);
+      t4 = millis();
+    } else if (c == 'p') {
+      digitalWrite(piede,HIGH);
+      t5 = millis();
+    } else if (c == 't') {
+      digitalWrite(tamburo,HIGH);
+      t6 = millis();
+    }
+
+
+  }
+
+  else {
+    if ((millis() - t1) > tempo) {
+      digitalWrite(zampaAS,LOW);
+    }
+    if ((millis() - t2) > tempo) {
+      digitalWrite(zampaAD,LOW);
+    }
+    if ((millis() - t3) > tempo) {
+      digitalWrite(zampaPS,LOW);
+    }
+    if ((millis() - t4) > tempo) {
+      digitalWrite(zampaPD,LOW);
+    }
+    if ((millis() - t5) > tempo) {
+      digitalWrite(piede,LOW);
+    }
+    if ((millis() - t6) > tempo) {
+      digitalWrite(tamburo,LOW);
+    }
+  }
 }


Use imperative tense in code comments

Use imperative tense in code comments

--- arduino/ControlProgram/ControlProgram.ino
+++ arduino/ControlProgram/ControlProgram.ino
@@ -4,14 +4,14 @@

 void setup()
 {
-    // Initializes car's servo motors.
+    // Initialize car's servo motors.
     car = new Vehicle(2, 3);

-    // Opens a serial connection through USB.
+    // Open a serial connection through USB.
     Serial.begin(9600);
     while (!Serial);

-    // Prints help text.
+    // Print help text.
     Serial.println("Known commands:");
     Serial.println("  move <number>     Drive at speed 0-100 (pos == forward, neg == backward)");
     Serial.println("  left <number>     Stop and turn left at speed 0-100");


Create VL53L1X_robust.ino

Create VL53L1X_robust.ino


Fixed timer. But need to check with design to see if this is what they want.

--- BackEnd/BackEnd.ino
+++ BackEnd/BackEnd.ino
@@ -147,11 +147,12 @@
   int is_timer_on;
   float timer_value;
   unsigned long timer_start_time;
+  boolean timer_running;
   int damping;
   int prev_damping;
   boolean connections[TOTAL_NUM_OF_PINS];
 //  float past_values[TOTAL_NUM_OF_PAST_VALUES];
-  float prev_values;
+  float prev_value;
 }
 Pin;

@@ -780,11 +781,12 @@

  //   for(int j=0; j<TOTAL_NUM_OF_PAST_VALUES; j++)
   //    g_aPins[i].past_values[j] = 0.0;
-    g_aPins[i].prev_values = 0.0;
+    g_aPins[i].prev_value = 0.0;

     g_aPins[i].is_timer_on = false;
     g_aPins[i].timer_value = 0.0;
     g_aPins[i].timer_start_time = 0;
+    g_aPins[i].timer_running = false;
     g_aPins[i].damping = 0;
     g_aPins[i].prev_damping = 0;

@@ -902,21 +904,49 @@
     fPinValSum = g_aPins[_iOutPinNum].value;
   else
     g_aPins[_iOutPinNum].value = fPinValSum;
-
-  //Serial.print("Analog Pin #: "); Serial.print(_iOutPinNum); Serial.print(" Total Value: "); Serial.println(fPinValSum);
-
+
+  // Run timer when a timer_on command has been received and a positive edge is detected
+  if( g_aPins[_iOutPinNum].is_timer_on && g_aPins[_iOutPinNum].prev_value < DIGITAL_VOLTAGE_THRESHOLD && g_aPins[_iOutPinNum].value >= DIGITAL_VOLTAGE_THRESHOLD )
+    g_aPins[_iOutPinNum].timer_running = true;
+
+  // IF timer_is_on && Timer_Running
+    // IF timer expired
+      // Set timer_is_on == false
+      //
+   // ELSE
+     // Set pin to HIGH (Over write the output)
+ // ELSE
+   // Set pin to VALUE
+
+  // Set pin value to zero if timer expired
+  if( g_aPins[_iOutPinNum].timer_running )
+  {
+    if( !((millis() - g_aPins[_iOutPinNum].timer_start_time) >= (g_aPins[_iOutPinNum].timer_value-1)*1000) ) // Not expired
+    {
+      fPinValSum = 1.0;
+      g_aPins[_iOutPinNum].value = fPinValSum;
+    }
+    else // Timer expired
+    {
+      g_aPins[_iOutPinNum].timer_running = false;
+    }
+  }
+
+ /*
   // Set pin value to zero if timer expired
   if( g_aPins[_iOutPinNum].is_timer_on )
   {
-//    Serial.print("Pin ");Serial.print(_iOutPinNum);Serial.print(" timer ON");
-//    Serial.print(" Start Time: ");Serial.println(g_aPins[_iOutPinNum].timer_start_time);
     if( (millis() - g_aPins[_iOutPinNum].timer_start_time) >= (g_aPins[_iOutPinNum].timer_value-1)*1000 ) // Timer expired
-    {
+    {
 //      Serial.println("EXPIRED...!!!");
       fPinValSum = 0.0;
       g_aPins[_iOutPinNum].value = fPinValSum;
     }
   }
+  */
+
+  // Updating prev value
+  g_aPins[_iOutPinNum].prev_value = g_aPins[_iOutPinNum].value;

   return fPinValSum;
 }


Updated sketch with transmission code

Updated sketch with transmission code

--- Balloon/Balloon.ino
+++ Balloon/Balloon.ino
@@ -1,6 +1,8 @@
 #include <OneWire.h>
 #include <Wire.h>
 #include <SoftwareSerial.h>
+#include <string.h>
+#include <util/crc16.h>

 // *********************************************************************
@@ -58,6 +60,19 @@
 float CurrentTimeStamp;

+// *********************************************************************
+// NTX2 Transmitter settings
+#define RADIO_PIN 4
+#define CALL_SIGN "KD8VZA"
+#define TRANSMIT_EVERY_Nth_READING 10
+char TimeStampBuffer[20], AltitudeBuffer[20], LatitudeBuffer[20], LongitudeBuffer[20];
+char TransmitBuffer[100];
+char TransmitBufferChecksum[6];
+int TransmitNumber;
+
+
+// *********************************************************************
+// Sketch initialization
 void setup(void) {
   Serial.begin(9600);

@@ -78,9 +93,14 @@

   HasGoodGPSReading = false;
   HasGoodTempReading = false;
-}
-
-
+
+  pinMode(RADIO_PIN,OUTPUT);
+  TransmitNumber = 0;
+}
+
+
+// *********************************************************************
+// Main loop
 void loop(void) {

   if(!HasGoodGPSReading)
@@ -143,9 +163,12 @@
     PrintToSerialOutput(CurrentTimeStamp, CurrentTemp, CurrentPressure, CurrentAltitude, CurrentLatitude, CurrentLongitude);
     WriteDataToLogger(CurrentTimeStamp, CurrentTemp, CurrentPressure, CurrentAltitude, CurrentLatitude, CurrentLongitude);

-    // TODO: What data do we write to the radio?
-    // TODO: How frequently should we write data to the radio?
-    // TODO: Write data to radio
+    if(TransmitNumber > TRANSMIT_EVERY_Nth_READING) {
+      TransmitDataToGround(CurrentTimeStamp, CurrentAltitude, CurrentLatitude, CurrentLongitude);
+      TransmitNumber = 0;
+    } else {
+      TransmitNumber++;
+    }

     HasGoodGPSReading = false;
     HasGoodTempReading = false;
@@ -195,6 +218,60 @@
 }

+void TransmitDataToGround(float TimeStamp, float Altitude, float Latitude, float Longitude) {
+  dtostrf(TimeStamp, 20, 3, TimeStampBuffer);
+  dtostrf(Altitude, 20, 3, AltitudeBuffer);
+  dtostrf(Latitude, 20, 5, LatitudeBuffer);
+  dtostrf(Longitude, 20, 5, LongitudeBuffer);
+
+  int TransmitIndex = 0;
+  TransmitIndex = TransferBuffer(CALL_SIGN, sizeof(CALL_SIGN), TransmitBuffer, TransmitIndex, true);
+  TransmitIndex = TransferBuffer(TimeStampBuffer, sizeof(TimeStampBuffer), TransmitBuffer, TransmitIndex, true);
+  TransmitIndex = TransferBuffer(AltitudeBuffer, sizeof(AltitudeBuffer), TransmitBuffer, TransmitIndex, true);
+  TransmitIndex = TransferBuffer(LatitudeBuffer, sizeof(LatitudeBuffer), TransmitBuffer, TransmitIndex, true);
+  TransmitIndex = TransferBuffer(LongitudeBuffer, sizeof(LongitudeBuffer), TransmitBuffer, TransmitIndex, true);
+
+
+  unsigned int CHECKSUM = gps_CRC16_checksum(TransmitBuffer);  // Calculates the checksum for this datastring
+  sprintf(TransmitBufferChecksum, "*%04X\n", CHECKSUM);
+  TransmitIndex = TransferBuffer(TransmitBufferChecksum, sizeof(TransmitBufferChecksum), TransmitBuffer, TransmitIndex, false);
+
+  // TODO: Write data to radio
+  //Serial.println(TransmitBuffer);
+  rtty_txstring (TransmitBuffer);
+}
+
+
+
+
+// *********************************************************************
+// General subroutines
+
+
+// This copies the SourceBuffer into DestBuffer starting at DestIndex,
+// but trims out any leading spaces in SourceBuffer
+int TransferBuffer(char* SourceBuffer, int SourceBufferSize, char* DestBuffer, int DestIndex, boolean ShouldAddComma) {
+  int BufferIndex = 0;
+
+  // Skip all characters from 0-32, but don't count carriage returns, chr(13)
+  while (BufferIndex < SourceBufferSize-1
+          && SourceBuffer[BufferIndex] <= 32 && SourceBuffer[BufferIndex] != 13) { BufferIndex++; }
+  while (BufferIndex < SourceBufferSize-1) {
+    DestBuffer[DestIndex] = SourceBuffer[BufferIndex];
+    DestIndex++;
+    BufferIndex++;
+  }
+
+  if(ShouldAddComma) {
+    TransmitBuffer[DestIndex] = ',';
+    DestIndex++;
+  }
+
+  return DestIndex;
+}
+
+
+
 // *********************************************************************
 // Temperature sensor subroutines
 float GetTemp(){
@@ -445,3 +522,97 @@
   buffer[fieldPos] = '\0';
 }

+
+
+// *********************************************************************
+// NTX2 subroutines
+void rtty_txstring (char * string)
+{
+
+  /* Simple function to sent a char at a time to
+   	** rtty_txbyte function.
+   	** NB Each char is one byte (8 Bits)
+   	*/
+
+  char c;
+
+  c = *string++;
+
+  while ( c != '\0')
+  {
+    rtty_txbyte (c);
+    c = *string++;
+  }
+}
+
+
+void rtty_txbyte (char c)
+{
+  /* Simple function to sent each bit of a char to
+   	** rtty_txbit function.
+   	** NB The bits are sent Least Significant Bit first
+   	**
+   	** All chars should be preceded with a 0 and
+   	** proceded with a 1. 0 = Start bit; 1 = Stop bit
+   	**
+   	*/
+
+  int i;
+
+  rtty_txbit (0); // Start bit
+
+  // Send bits for for char LSB first
+
+  for (i=0;i<7;i++) // Change this here 7 or 8 for ASCII-7 / ASCII-8
+  {
+    if (c & 1) rtty_txbit(1);
+
+    else rtty_txbit(0);
+
+    c = c >> 1;
+
+  }
+
+  rtty_txbit (1); // Stop bit
+  rtty_txbit (1); // Stop bit
+}
+
+void rtty_txbit (int bit)
+{
+  if (bit)
+  {
+    // high
+    digitalWrite(RADIO_PIN, HIGH);
+  }
+  else
+  {
+    // low
+    digitalWrite(RADIO_PIN, LOW);
+
+  }
+
+  //                  delayMicroseconds(3370); // 300 baud
+  delayMicroseconds(10000); // For 50 Baud uncomment this and the line below.
+  delayMicroseconds(10150); // You can't do 20150 it just doesn't work as the
+                            // largest value that will produce an accurate delay is 16383
+                            // See : http://arduino.cc/en/Reference/DelayMicroseconds
+
+}
+
+uint16_t gps_CRC16_checksum (char *string)
+{
+  size_t i;
+  uint16_t crc;
+  uint8_t c;
+
+  crc = 0xFFFF;
+
+  // Calculate checksum ignoring the first two $s
+  for (i = 2; i < strlen(string); i++)
+  {
+    c = string[i];
+    crc = _crc_xmodem_update (crc, c);
+  }
+
+  return crc;
+}


Adjusted comment.

Adjusted comment.

Adjusted comment.

--- firmware/examples/RUSK-Basic.ino
+++ firmware/examples/RUSK-Basic.ino
@@ -365,7 +365,7 @@
     Serial.begin(9600);

     // Set I2C speed
-    // --> 400Khz seems to help stabilize I2C bus operation with packaged sensors
+    // --> 400Khz seems to work best with the Photon with the packaged I2C sensors
     Wire.setSpeed(CLOCK_SPEED_400KHZ);

     // Disable Interrupts


PoC set up with temp and flow

PoC set up with temp and flow

--- firmware/interlock/interlock.ino
+++ firmware/interlock/interlock.ino
@@ -1,115 +1,108 @@
 #include "./OneWire.h"
+#include "./DallasTemperature.h"

-OneWire  ds(2);  // on pin 2
+OneWire  ds(3);  // on pin 2
+DallasTemperature temps(&ds);

-uint8_t temp1_ID[8] = {0x28, 0xFF, 0x6C, 0xF3, 0x64, 0x15, 0x2, 0x15};
-uint8_t temp2_ID[8] = {0x28, 0xFF, 0xD2, 0xE1, 0x64, 0x15, 0x2, 0xC7};
-uint8_t temp3_ID[8] = {0x28, 0xFF, 0xDB, 0x8D, 0x64, 0x15, 0x2, 0xB6};
+#define TEMPERATURE_PRECISION 9
+
+DeviceAddress inflowTemp 	= {0x28, 0xFF, 0x6C, 0xF3, 0x64, 0x15, 0x2, 0x15};
+DeviceAddress outflowTemp  	= {0x28, 0xFF, 0xD2, 0xE1, 0x64, 0x15, 0x2, 0xC7};
+DeviceAddress tankTemp		= {0x28, 0xFF, 0xDB, 0x8D, 0x64, 0x15, 0x2, 0xB6};
+
+#define FLOW_RATE_MEASURE_INTERVAL 1000.0
+
+byte flowInterrupt = 0; // digital 2
+byte flowPin = 2; //
+
+volatile byte pulseCount;
+
+uint16_t pulsesPerLitre = 450;
+float flowPeriods = 60000.0 / FLOW_RATE_MEASURE_INTERVAL; // used to calc flow per min.
+
+float flowRate;
+uint32_t flowOldTime;

 void setup() {
     Serial.begin(9600);
     Serial.println("Interlock stuff");
+
+    // temperature sensors
+    temps.begin();
+    Serial.print("Locating sensors...");
+    Serial.print("found ");
+    Serial.print(temps.getDeviceCount());
+    Serial.println(" devices");
+
+	temps.setResolution(inflowTemp, TEMPERATURE_PRECISION);
+	temps.setResolution(outflowTemp, TEMPERATURE_PRECISION);
+	temps.setResolution(tankTemp, TEMPERATURE_PRECISION);
+
+    delay(5000);
+    // flow meter.
+    pulseCount = 0;
+    flowOldTime = 0;
+    flowRate = 0;
+
+    attachInterrupt(flowInterrupt, pulseCounter, FALLING);
 }

+void loop() {

-void loop() {
-  byte i;
-  byte present = 0;
-  byte type_s;
-  byte data[12];
-  byte addr[8];
-  float celsius;
+    if ((millis() - flowOldTime) > FLOW_RATE_MEASURE_INTERVAL) {
+        calculate_flow_rate();

-  if ( !ds.search(addr)) {
-    Serial.println("No more addresses.");
-    Serial.println();
-    ds.reset_search();
-    delay(10000);
-    return;
+		temps.requestTemperatures();
+		Serial.print("Out ");
+		printTemperature(outflowTemp);
+		Serial.println();
+    }
+}
+
+void calculate_flow_rate() {
+    // does the actual checking to see what the flow rate is and updates flowrate
+    // global var appropriately
+
+    detachInterrupt(flowInterrupt);
+
+    Serial.print("pc: ");
+    Serial.println(pulseCount);
+    // calculate flow rate.
+    // this normalises the pulse count to a standardised time period,
+    // namely FLOW_RATE_MEASURE_INTERVAL.
+    float pcn = (float)FLOW_RATE_MEASURE_INTERVAL / (millis() - flowOldTime) * pulseCount;
+    float litres_counted = pcn / pulsesPerLitre;
+    flowRate = flowPeriods * litres_counted;
+
+    Serial.print("Flow Rate ");
+    Serial.println(flowRate, DEC);
+
+    flowOldTime = millis();
+
+    pulseCount = 0;
+
+    attachInterrupt(flowInterrupt, pulseCounter, FALLING);
+}
+
+/** ISR for pulsecounter **/
+void pulseCounter() {
+    // just increment, don't do anything else.
+    pulseCount++;
+}
+
+void printAddress(DeviceAddress deviceAddress)
+{
+  for (uint8_t i = 0; i < 8; i++)
+  {
+    // zero pad the address if necessary
+    if (deviceAddress[i] < 16) Serial.print("0");
+    Serial.print(deviceAddress[i], HEX);
   }
+}

-  Serial.print("ROM =");
-  for( i = 0; i < 8; i++) {
-    Serial.write(' ');
-    Serial.print(addr[i], HEX);
-  }
-
-  if (OneWire::crc8(addr, 7) != addr[7]) {
-      Serial.println("CRC is not valid!");
-      return;
-  }
-  Serial.println();
-
-
-	if (memcmp(addr, temp1_ID, sizeof(addr)) == 0) {
-        Serial.println("ARRAYS EQUAL");
-    } else {
-        Serial.println("ARRAYS UNEQUAL");
-    }
-
-/**  // the first ROM byte indicates which chip
-  switch (addr[0]) {
-    case 0x10:
-      Serial.println("  Chip = DS18S20");  // or old DS1820
-      type_s = 1;
-      break;
-    case 0x28:
-      Serial.println("  Chip = DS18B20");
-      type_s = 0;
-      break;
-    case 0x22:
-      Serial.println("  Chip = DS1822");
-      type_s = 0;
-      break;
-    default:
-      Serial.println("Device is not a DS18x20 family device.");
-      return;
-  }**/
-
-  ds.reset();
-  ds.select(addr);
-  ds.write(0x44, 1);        // start conversion, with parasite power on at the end
-
-  delay(1000);     // maybe 750ms is enough, maybe not
-  // we might do a ds.depower() here, but the reset will take care of it.
-
-  present = ds.reset();
-  ds.select(addr);
-  ds.write(0xBE);         // Read Scratchpad
-
-  Serial.print("  Data = ");
-  Serial.print(present, HEX);
-  Serial.print(" ");
-  for ( i = 0; i < 9; i++) {           // we need 9 bytes
-    data[i] = ds.read();
-    Serial.print(data[i], HEX);
-    Serial.print(" ");
-  }
-  Serial.print(" CRC=");
-  Serial.print(OneWire::crc8(data, 8), HEX);
-  Serial.println();
-
-  // Convert the data to actual temperature
-  // because the result is a 16 bit signed integer, it should
-  // be stored to an "int16_t" type, which is always 16 bits
-  // even when compiled on a 32 bit processor.
-  int16_t raw = (data[1] << 8) | data[0];
-  if (type_s) {
-    raw = raw << 3; // 9 bit resolution default
-    if (data[7] == 0x10) {
-      // "count remain" gives full 12 bit resolution
-      raw = (raw & 0xFFF0) + 12 - data[6];
-    }
-  } else {
-    byte cfg = (data[4] & 0x60);
-    // at lower res, the low bits are undefined, so let's zero them
-    if (cfg == 0x00) raw = raw & ~7;  // 9 bit resolution, 93.75 ms
-    else if (cfg == 0x20) raw = raw & ~3; // 10 bit res, 187.5 ms
-    else if (cfg == 0x40) raw = raw & ~1; // 11 bit res, 375 ms
-    //// default is 12 bit resolution, 750 ms conversion time
-  }
-  celsius = (float)raw / 16.0;
-  Serial.print("  Temperature = ");
-  Serial.print(celsius);
-  Serial.println(" Celsius ");
+void printTemperature(DeviceAddress deviceAddress)
+{
+  float tempC = temps.getTempC(deviceAddress);
+  Serial.print("Temp C: ");
+  Serial.print(tempC);
 }


make buttons recycle their mode in order to loop

--- motorcycle/motorcycle.ino
+++ motorcycle/motorcycle.ino
@@ -21,7 +21,11 @@
 }

 void startShow() {
-  switch (getButtonsState()) {
+  int buttons = getButtonsState();
+  if (buttons == 0) {
+    buttons = mode;
+  }
+  switch (buttons) {
     case 1: // left
       colorWipe(strip1, KTM_ORANGE, 50);
       break;
@@ -38,6 +42,7 @@
       colorWipe(strip1, (RGB){0, 255, 0}, 50);
       break;
   }
+  mode = buttons;
 }

 void loop() {


cleanup

cleanup

--- examples/rainbowLamp/rainbowLamp.ino
+++ examples/rainbowLamp/rainbowLamp.ino
@@ -54,9 +54,6 @@

   strip.begin();
   strip.show(); // Initialize all pixels to 'off'
-
-  Serial.begin(9600);
-
 }

 void loop() {


few more logged events

few more logged events

--- climact/climact.ino
+++ climact/climact.ino
@@ -310,6 +310,8 @@
   log_rules();
 #endif
   Serial.print("DBG:RESTART:\n");
+
+  log_event("restart",0,0,-1);

 //    evaluate();
 }
@@ -1089,7 +1091,10 @@
                         digitalWrite(relays[i].r.pin,HIGH);
                         lis_hall_amp();

-                        log_event("probe_fail",i,0,0);
+                        log_event("probe_fail",relays[i].r.pin,i,0);
+                    }
+                    else {
+                        log_event("probe_success",relays[i].r.pin,i,0);
                     }
                 }
             }


general code cleanup - moved functionality from main loop in functions

--- Arduino_codeline/fairytale25/fairytale25.ino
+++ Arduino_codeline/fairytale25/fairytale25.ino
@@ -518,52 +518,50 @@
 //       PP        RR    RR  OO    OO     TT     OO    OO     TT        YY     PP        EE          SS
 //       PP        RR    RR   OOOOOO      TT      OOOOOO      TT        YY     PP        EEEEEE  SSSSS
 //
-// these are the prototypes to retrieve and set directory and track to play - aka work on the tagdb
-static boolean getDirAndTrackToPlay(boolean);  // retrieves the directory and track number
-static boolean writeTrackDbEntry(void);        // store Tag UID, plrCurrentFolder and firstTrackToPlay in the trackDb (files on SD)
-
-
-// prototype for NFC check for tag presence
-#ifdef NFCTRACKDB
-  static boolean checkTag(void);        // check if the tag is still on the reader - returns true or falce
-#endif
-
-// prototype for volume control via potentiometer
-#ifdef VOLUMEPOT
-  static void plrAdjustVolume(void);    // function to check for changes on the volume control and adjust volume accrodingly
-#endif
-
-
-// these are the prototypes for the mp3 player controller
-static void plrStop(void);              // stops the player
-static void plrTogglePause(void);       // pause and unpause the player
-static char playAlbum(uint8_t);         // plays the album from plrCurrentFolder: returns -1 for error or a higher
-                                        // calls playTrack to actually play a track and check if that was successful and which
-                                        // track number to play next
-static char playTrack(uint8_t);         // plays a track as defined by the global var filename.
-                                        // returns -1 for error, 0 for success and track number to play next
-                                        // this can either be provided char+1 or char-1
-
-
-// prototype for warning
+static boolean checkForTagPresence(void);       // checks if there is a tag on the reader, either Speedmaster or Adafruit style
+static boolean checkForSameTag(void);           // checks if the same tag as the one for currently played album is still on the reader
+                                                // this one can only be used with the Adafruit library and TrackDB implementation
+
+static void plrAdjustVolume(void);              // function to check for changes on the volume control and adjust volume accrodingly
+
+                                                // these are the prototypes for the mp3 player controller
+static void plrStop(void);                      // stops the player
+static void plrTogglePause(void);               // pause and unpause the player
+static char playAlbum(uint8_t);                 // plays the album from plrCurrentFolder: returns -1 for error or a higher
+                                                // calls playTrack to actually play a track and check if that was successful and which
+                                                // track number to play next
+static char playTrack(uint8_t);                 // plays a track as defined by the global var filename.
+                                                // returns -1 for error, 0 for success and track number to play next
+                                                // this can either be provided char+1 or char-1
+
+
+                                                // these are the prototypes to work on files and general helpers
+static uint8_t countFiles(File);                // return the number of files in a directory passed as a File descriptor
+static boolean checkIfFileExists(void);         // returns true if the file from global vars plrCurrentFolder and plrCurrentFile exists on sd
+
+
+                                                // helper functions to set global vars
+static void setFileNameToPlay(byte);            // sets filename of the track to play from global vars plrCurrentFolder and plrCurrentFile
+
+
+                                                // helper functions for the TrackDb
+                                                // these are the prototypes to retrieve and set directory and tracks to play
+static boolean getDirAndTrackToPlay(boolean);   // retrieves the directory and track number
+
+static void checkAndSetCurTrack(byte, uint8_t); // function called from playAlbum for every file played. it checks if the current track is
+                                                // the last in the album and if so sets firstTrackToPlay to 1. Otherwise firstTrackToPlay is set
+                                                // to curTrack and afterwards setTrackDbEntry is called to store the track
+static void setTrackDbEntry(void);              // setTrackDbEntry stores the currently played file in the TrackDb plus (plus optionally the AlbumNFC
+                                                // file) to allow resuming a played album on the current track in case the box is turned off
+static boolean writeTrackDbEntry(void);         // store Tag UID, plrCurrentFolder and firstTrackToPlay in the trackDb (files on SD)
+
+
 static void issueWarning(const char[], const char[], boolean); // the new warning method

-// these are the prototypes to work on files and general helpers
-static uint8_t countFiles(File);        // return the number of files in a directory passed as a File descriptor
-
-
-// helper functions to set global vars
-static boolean setFileNameToPlay(byte); // sets filename of the track to play from global vars plrCurrentFolder and plrCurrentFile and returns true if it exists
-static void setTrackDbEntry(void);
-
-
-// these are the prototypes for the led
-#ifdef OPRLIGHT
-  // switch the boolean var lightOn from true to false and vice versa
-  // - in case light is lightOn is set to true, lightStartUpTime is set to millis()
-  static void switchLightState(void);
-#endif
+                                                // these are the prototypes for the led
+static void switchLightState(void);             // switch the boolean var lightOn from true to false and vice versa
+                                                // - in case light is lightOn is set to true, lightStartUpTime is set to millis()

@@ -720,18 +718,11 @@
   #ifdef DEBUG
     Serial.print(F("."));
   #endif
-
+

   // check for tag presence
-  #ifdef NFCNDEF
-    // this implementation uses the Speedmaster Library and Don's NDEF lib
-    weHaveATag = nfc.tagPresent(1000);
-  #endif
-  #ifdef NFCTRACKDB
-    // this implementation uses the Adafruit PN532 library alone
-    weHaveATag = nfc.readPassiveTargetID(PN532_MIFARE_ISO14443A, uid, &uidLength);
-  #endif
-
+  weHaveATag = checkForTagPresence();
+

   // this allows for the pause/resume button to be pressed without a tag being present
   // in this case the last played album is resumed - given there was one.
@@ -869,33 +860,33 @@
 //  BELOW THIS LINE THE MP3 PLAYER CONTROL IS DEFINED
 //
 // included in while loop of playTrack() for checks for volume changes
-#ifdef VOLUMEPOT
 static void plrAdjustVolume() {
-  // volume control functions
-  const byte volSensorDrift = 7;    // difference to last received sensor value that must be exceeded to activate a change in the volume
-  word volCompareValue      = 0;    // just a convenience variable to make comparison easier
-
-  // read the input on analog pin 0 and check if we have a change in volume.
-  const word volSensorValue = analogRead(volPotPin);
-  if (lastVolSensorValue > volSensorValue) {
-    volCompareValue = lastVolSensorValue - volSensorValue;
-  } else {
-    volCompareValue = volSensorValue - lastVolSensorValue;
-  }
-
-  // If we have a high enough difference in the sensor reading, calculate it so we may set it on the player
-  if (volCompareValue > volSensorDrift) {
-    const byte soundVolume = volSensorValue / 10; // map the sensor value to a sound volume
-    #ifdef DEBUG
-      Serial.print(F("old sensor: ")); Serial.print(lastVolSensorValue);
-      Serial.print(F(", new sensor: ")); Serial.print(volSensorValue);
-      Serial.print(F(", vol: -")); Serial.println(soundVolume);
-    #endif
-    lastVolSensorValue = volSensorValue;
-    musicPlayer.setVolume(soundVolume, soundVolume);
-  } // end of change sound volume
-}
-#endif
+  #ifdef VOLUMEPOT
+    // volume control functions
+    const byte volSensorDrift = 7;    // difference to last received sensor value that must be exceeded to activate a change in the volume
+    word volCompareValue      = 0;    // just a convenience variable to make comparison easier
+
+    // read the input on analog pin 0 and check if we have a change in volume.
+    const word volSensorValue = analogRead(volPotPin);
+    if (lastVolSensorValue > volSensorValue) {
+      volCompareValue = lastVolSensorValue - volSensorValue;
+    } else {
+      volCompareValue = volSensorValue - lastVolSensorValue;
+    }
+
+    // If we have a high enough difference in the sensor reading, calculate it so we may set it on the player
+    if (volCompareValue > volSensorDrift) {
+      const byte soundVolume = volSensorValue / 10; // map the sensor value to a sound volume
+      #ifdef DEBUG
+        Serial.print(F("old sensor: ")); Serial.print(lastVolSensorValue);
+        Serial.print(F(", new sensor: ")); Serial.print(volSensorValue);
+        Serial.print(F(", vol: -")); Serial.println(soundVolume);
+      #endif
+      lastVolSensorValue = volSensorValue;
+      musicPlayer.setVolume(soundVolume, soundVolume);
+    } // end of change sound volume
+  #endif
+}

 //
@@ -937,14 +928,17 @@
     Serial.print(F("Folder: ")); Serial.print(plrCurrentFolder); Serial.print(F(" / Files: ")); Serial.println(numberOfFiles);
   #endif
   #ifdef OPRLIGHTTIME
-    lightStartUpTime = millis(); // store the time in millis when the  playback-for-loop started, so we can later check, whether or not the light shall continue to be on
+    lightStartUpTime = millis(); // store the time in millis when the  playback-for-loop started, so we can later check,
+                                 // whether or not the light shall continue to be on
   #endif
   for (byte curTrack = firstTrackToPlay; curTrack <= numberOfFiles; curTrack++) {
     digitalWrite(warnLedPin, LOW); // in each for-loop, we make sure that the warning LED is NOT lit up

     // set the filename we want to play in the global variable so the playTrack() function knows what to play
-    if (!setFileNameToPlay(curTrack)) {
-      // set filename does not exit on SD card :-(
+    setFileNameToPlay(curTrack);
+    // and if it exists, lets play it
+    if (!checkIfFileExists()) {
+      // set filename does not exit on SD card :-(  issue a warning
       if (loopWarningMessageFileNotFound) {
         loopWarningMessageFileNotFound = false; // set loop warning message so we don't show this warning in the next loop
         issueWarning("file not found", "/system00/filnotfn.mp3", true);
@@ -957,20 +951,7 @@

     // make sure we remember the just started track to be the new track, in case player is stopped
     // this works only with the NFC TrackDb and not with the NFC NDEF implementation
-    #ifdef NFCTRACKDB
-      if (curTrack != firstTrackToPlay) {
-        // in case we are on the last track, choose the first track, so we start playback all from the beginning.
-        if (curTrack == numberOfFiles) firstTrackToPlay = 1; else firstTrackToPlay = curTrack;
-
-        // now store this new first track in the TrackDB
-        // first create the new trackDb entry:
-        setTrackDbEntry();
-        // second store this entry in the TrackDb files, plus optional in the albumnfc.tdb file
-        if (!writeTrackDbEntry()) {
-          issueWarning("trackdb update error", "", false);
-        }
-      }
-    #endif
+    checkAndSetCurTrack(curTrack, checkAndSetCurTrack);

     // play the track on the music maker shield and retrieve the nextTrackToPlay from global variable (it is set by playTrack())
     //        -1  errors trying to play the file (like file not found)
@@ -1075,7 +1056,7 @@

       // check if we can still read the tag and if not, stop/pause the playback
       #ifdef NFCTRACKDB
-        if (!checkTag()) plrTogglePause();
+        if (!checkForSameTag()) plrTogglePause();
       #endif

       checkTime = millis(); // reset checktime so we can wait another 10 seconds aka 10000 ms
@@ -1286,80 +1267,100 @@
 }

+// make sure we remember the just started track to be the new track, in case player is stopped
+static void checkAndSetCurTrack(byte curTrack, uint8_t numberOfFiles){
+  #ifdef NFCTRACKDB
+    if (curTrack != firstTrackToPlay) {
+      // in case we are on the last track, choose the first track, so we start playback all from the beginning.
+      if (curTrack == numberOfFiles) firstTrackToPlay = 1; else firstTrackToPlay = curTrack;
+
+      // now store this new first track in the TrackDB
+      // first create the new trackDb entry:
+      setTrackDbEntry();
+      // second store this entry in the TrackDb files, plus optional in the albumnfc.tdb file
+      if (!writeTrackDbEntry()) {
+        issueWarning("trackdb update error", "", false);
+      }
+    }
+  #endif
+}
+
+
 // write the created trackDbEntry into the Track DB on SD
-#ifdef NFCTRACKDB
 static boolean writeTrackDbEntry() {
   boolean success = true;
-  byte bytesWritten;
-
-  #ifdef DEBUG
-    Serial.print(F("saving nfc <-> album: "));Serial.println(trackDbEntry);
-  #endif
-
-  // FIRST (if set) write the AlbumNFC file  --> ALBUMNFC.TDB
-  #ifdef ALBUMNFC
-    File file = SD.open(albumNfcFile, FILE_WRITE);
+
+  #ifdef NFCTRACKDB
+    byte bytesWritten;
+
+    #ifdef DEBUG
+      Serial.print(F("saving nfc <-> album: "));Serial.println(trackDbEntry);
+    #endif
+
+    // FIRST (if set) write the AlbumNFC file  --> ALBUMNFC.TDB
+    #ifdef ALBUMNFC
+      File file = SD.open(albumNfcFile, FILE_WRITE);
+      bytesWritten = file.write(trackDbEntry, sizeof(trackDbEntry));
+      file.close();                                      // and make sure everything is clean and save
+
+      // now check if the write was successful - means we wrote the number of bytes of the trackDb entry to the file
+      if (bytesWritten == sizeof(albumNfcFile)) {
+        #ifdef DEBUG
+          Serial.print(F("  ok. "));Serial.print(bytesWritten);Serial.print(F(" byte(s) written to "));Serial.println(albumNfcFile);
+        #endif
+        success = true;
+      } else {
+        #ifdef DEBUG
+          Serial.print(F("  error writing "));Serial.println(albumNfcFile);
+        #endif
+        digitalWrite(warnLedPin, HIGH);
+        success = false;
+      }
+    #endif
+
+    // SECOND write the TrackDb-File --> e.g. larsrent.txt
+    memset(trackDbFile, 0, sizeof(trackDbFile));       // make sure var to hold path to track db file is empty
+    strcat(trackDbFile, trackDbDir);                   // add the trackDb Directory to the
+    strcat(trackDbFile, "/");                          // a /
+    strcat(trackDbFile, plrCurrentFolder);             // and the filename
+    strcat(trackDbFile, ".txt");                       // plus of course a txt extension
+    SD.remove(trackDbFile);                            // we want the file to be empty prior writing directory and track to it, so we remove it
+
+    // used in case the albumnfc.tdb file is written first - redeclare file var
+    #ifdef ALBUMNFC
+      file = SD.open(trackDbFile, FILE_WRITE);
+    #endif
+    // used in case we only write the TrackDB file - need to initially declare file var
+    #ifndef ALBUMNFC
+      File file = SD.open(trackDbFile, FILE_WRITE);
+    #endif
     bytesWritten = file.write(trackDbEntry, sizeof(trackDbEntry));
-    file.close();                                      // and make sure everything is clean and save
-
+    file.close();
+
     // now check if the write was successful - means we wrote the number of bytes of the trackDb entry to the file
-    if (bytesWritten == sizeof(albumNfcFile)) {
+    if (bytesWritten == sizeof(trackDbEntry)) {
       #ifdef DEBUG
-        Serial.print(F("  ok. "));Serial.print(bytesWritten);Serial.print(F(" byte(s) written to "));Serial.println(albumNfcFile);
+        Serial.print(F("  ok. "));Serial.print(bytesWritten);Serial.print(F(" byte(s) written to "));Serial.println(trackDbFile);
       #endif
       success = true;
     } else {
       #ifdef DEBUG
-        Serial.print(F("  error writing "));Serial.println(albumNfcFile);
+        Serial.print(F("  error writing "));Serial.println(trackDbFile);
       #endif
       digitalWrite(warnLedPin, HIGH);
       success = false;
     }
-  #endif
-
-  // SECOND write the TrackDb-File --> e.g. larsrent.txt
-  memset(trackDbFile, 0, sizeof(trackDbFile));       // make sure var to hold path to track db file is empty
-  strcat(trackDbFile, trackDbDir);                   // add the trackDb Directory to the
-  strcat(trackDbFile, "/");                          // a /
-  strcat(trackDbFile, plrCurrentFolder);             // and the filename
-  strcat(trackDbFile, ".txt");                       // plus of course a txt extension
-  SD.remove(trackDbFile);                            // we want the file to be empty prior writing directory and track to it, so we remove it
-
-  // used in case the albumnfc.tdb file is written first - redeclare file var
-  #ifdef ALBUMNFC
-    file = SD.open(trackDbFile, FILE_WRITE);
-  #endif
-  // used in case we only write the TrackDB file - need to initially declare file var
-  #ifndef ALBUMNFC
-    File file = SD.open(trackDbFile, FILE_WRITE);
-  #endif
-  bytesWritten = file.write(trackDbEntry, sizeof(trackDbEntry));
-  file.close();
-
-  // now check if the write was successful - means we wrote the number of bytes of the trackDb entry to the file
-  if (bytesWritten == sizeof(trackDbEntry)) {
-    #ifdef DEBUG
-      Serial.print(F("  ok. "));Serial.print(bytesWritten);Serial.print(F(" byte(s) written to "));Serial.println(trackDbFile);
-    #endif
-    success = true;
-  } else {
-    #ifdef DEBUG
-      Serial.print(F("  error writing "));Serial.println(trackDbFile);
-    #endif
-    digitalWrite(warnLedPin, HIGH);
-    success = false;
-  }
-
-  // THIRD (if set) write the plrCurrentFolder (aka the album directory) to the file /trackdb0/LASTPLAY.TDB
-  #ifdef RESUMELAST
-    file = SD.open(resumeLastFile, FILE_WRITE);
-    bytesWritten = file.write(plrCurrentFolder, sizeof(plrCurrentFolder));
-    file.close();
+
+    // THIRD (if set) write the plrCurrentFolder (aka the album directory) to the file /trackdb0/LASTPLAY.TDB
+    #ifdef RESUMELAST
+      file = SD.open(resumeLastFile, FILE_WRITE);
+      bytesWritten = file.write(plrCurrentFolder, sizeof(plrCurrentFolder));
+      file.close();
+    #endif
   #endif

   return (success);
 }
-#endif

 //
@@ -1371,13 +1372,24 @@
 //
 // check Tag presence is used in the loop() (to populate the char array with the uid of the tag) and in function playTrack() to see
 // if the tag is still on the reader - this can only be used with the Adafruit NFC library
-#ifdef NFCTRACKDB
-boolean checkTag() {
+boolean checkForSameTag() {
   boolean sameTagPresent = true;

   return(sameTagPresent);
 }
-#endif
+
+boolean checkForTagPresence(void) {
+  boolean weHaveATag = false;
+  #ifdef NFCNDEF
+    // this implementation uses the Speedmaster Library and Don's NDEF lib
+    weHaveATag = nfc.tagPresent(1000);
+  #endif
+  #ifdef NFCTRACKDB
+    // this implementation uses the Adafruit PN532 library alone
+    weHaveATag = nfc.readPassiveTargetID(PN532_MIFARE_ISO14443A, uid, &uidLength);
+  #endif
+  return(weHaveATag);
+}

 //
@@ -1388,7 +1400,7 @@
 //      HH    HH  EEEEEE  LLLLLL  PP        EEEEEE  RR   RR
 //
 // stores the file to play in the global var filename - it is created from the gloal vars plrCurrentFolder and current track
-static boolean setFileNameToPlay(byte trackNo) {
+static void setFileNameToPlay(byte trackNo) {
   // convert the trackNo to a char array - we need it next to create the filename of the track
   char curTrackCharNumber[4];
   sprintf(curTrackCharNumber, "%03d", trackNo);
@@ -1401,35 +1413,37 @@
   strcat(filename, "track");
   strcat(filename, curTrackCharNumber);
   strcat(filename, ".mp3");
-
-  // return true or false for the filename created - this is checked
+}
+
+// return true or false for the filename created - this is checked
+static boolean checkIfFileExists(void){
   return (SD.exists(filename));
 }
-

 // store uid, plrCurrentFolder and firstTrackToPlay in the char array trackDbEntry[]
 // so we may write it to the track Db file
-#ifdef NFCTRACKDB
 static void setTrackDbEntry() {
-  char tmpbuf[4];                                 // temp buffer for one number of the uid
-
-  // create the entry for the  "Tag UID <-> directory + track number"  connection
-  memset(trackDbEntry, 0, sizeof(trackDbEntry));
-  for (byte i = 0; i <= uidLength ; i++) {
-    sprintf( tmpbuf, "%d", uid[i] );              // print one byte of the uid as decimal into tmpbuf, so
-    strcat( charUid, tmpbuf );                    // we can add it to the charUid
-  }
-
-  memcpy(trackDbEntry, charUid, sizeof(charUid)); // finally we add the charUid to the trackDbENtry
-  strcat(trackDbEntry, ":");                      // add a seperator :
-  strcat(trackDbEntry, plrCurrentFolder);         // the folder of the album this tag is connected with
-  char cstr[4];                                   // a new char array that will hold firstTrackToPlay as a char array
-  itoa(firstTrackToPlay, cstr, 10);               // converting firstTrackToPlay to char and place it in cstr
-  strcat(trackDbEntry, ":");                      // and the number of the track
-  strcat(trackDbEntry, cstr);                     // and the number of the track
-  strcat(trackDbEntry, "\n");                     // and a newline :-)
-}
-#endif
+  #ifdef NFCTRACKDB
+    char tmpbuf[4];                                 // temp buffer for one number of the uid
+
+    // create the entry for the  "Tag UID <-> directory + track number"  connection
+    memset(trackDbEntry, 0, sizeof(trackDbEntry));
+    for (byte i = 0; i <= uidLength ; i++) {
+      sprintf( tmpbuf, "%d", uid[i] );              // print one byte of the uid as decimal into tmpbuf, so
+      strcat( charUid, tmpbuf );                    // we can add it to the charUid
+    }
+
+    memcpy(trackDbEntry, charUid, sizeof(charUid)); // finally we add the charUid to the trackDbENtry
+    strcat(trackDbEntry, ":");                      // add a seperator :
+    strcat(trackDbEntry, plrCurrentFolder);         // the folder of the album this tag is connected with
+    char cstr[4];                                   // a new char array that will hold firstTrackToPlay as a char array
+    itoa(firstTrackToPlay, cstr, 10);               // converting firstTrackToPlay to char and place it in cstr
+    strcat(trackDbEntry, ":");                      // and the number of the track
+    strcat(trackDbEntry, cstr);                     // and the number of the track
+    strcat(trackDbEntry, "\n");                     // and a newline :-)
+  #endif
+}
+

 #ifdef RAMCHECK
@@ -1499,22 +1513,22 @@
 //  LLLLLL  EEEEEE  DDDDDD
 //
 // switches the value of lightOn between true and false - only needed in case there is a LED attached
-#ifdef OPRLIGHT
 static void switchLightState(void) {
-  if (!lightOn) {
-    #ifdef DEBUG
-      Serial.println(F("Switching light off -> ON"));
-    #endif
-    lightOn = true;
-    #ifdef OPRLIGHTTIME
-      lightStartUpTime = millis(); // also sets the lightStartUpTime
-    #endif
-  } else {
-    #ifdef DEBUG
-      Serial.println(F("Switching light on -> OFF"));
-    #endif
-    lightOn = false;
-    digitalWrite(infoLedPin, LOW);   // also turns off the info led
-  }
-}
-#endif
+  #ifdef OPRLIGHT
+    if (!lightOn) {
+      #ifdef DEBUG
+        Serial.println(F("Switching light off -> ON"));
+      #endif
+      lightOn = true;
+      #ifdef OPRLIGHTTIME
+        lightStartUpTime = millis(); // also sets the lightStartUpTime
+      #endif
+    } else {
+      #ifdef DEBUG
+        Serial.println(F("Switching light on -> OFF"));
+      #endif
+      lightOn = false;
+      digitalWrite(infoLedPin, LOW);   // also turns off the info led
+    }
+  #endif
+}


acceleration print pt2

acceleration print pt2

--- xBeeMegaRobot_func/xBeeMegaRobot_func.ino
+++ xBeeMegaRobot_func/xBeeMegaRobot_func.ino
@@ -41,9 +41,9 @@

 int tempPk[24] = {};

-int acccX;
-int acccY;
-int acccZ;
+int accX;
+int accY;
+int accZ;

 void setup() {
   Serial2.begin(SERVO_BAUDRATE);
@@ -87,18 +87,18 @@
 int accZ;
 int accY;
 int accX;
-
+
 void loop() {
   for(int i = 0; i < 50; i++){
   xBee.readPacket(tempPk);
   xBee.decodePacket(tempPk);
   //for(int i = 13; i < 23; i++){
   Serial.print("Z = ");
-  Serial.print(acccZ);
+  Serial.print(accZ);
    // Serial.print(tempPk[i], DEC);  // Printing the read package
   Serial.print(" ");
   //}
-
+
   if(xBee.checkPacket(tempPk)){ //Check and print if the package passed
     Serial.println("| INT -- PASS |");
     pass++;
@@ -109,7 +109,7 @@
   Serial.println(fail);
   rate = (float)pass/(pass+fail);
   Serial.println(rate*100);
-
+

 /*  xBee.readPacket(charPk); //Trying reading, printing and checking with char packages
   for(int i = 0; i < 24; i++){


Dont include the .%s field

Dont include the .%s field

--- WxShield2/measurements.ino
+++ WxShield2/measurements.ino
@@ -66,7 +66,7 @@
 }

 void sqlinsert(struct frame frame) {
-  Serial.print("INSERT INTO %s.%s (indx, pressure, tempa, tempb, humidity, ptemp, htemp, battery) VALUES (");
+  Serial.print("INSERT INTO %s (indx, pressure, tempa, tempb, humidity, ptemp, htemp, battery) VALUES (");
   Serial.print(frame.index);
   niceSql(frame.pressure);
   niceSql(frame.tempA);


Updated main

Updated main

--- oktopus-autopilote/oktopus-autopilote.ino
+++ oktopus-autopilote/oktopus-autopilote.ino
@@ -14,8 +14,9 @@
 #include "ProximitySensor.h"
 #include "RudderServo.h"
 #include "Temperature.h"
-#include <LiquidCrystal.h>
 #include "EmergencyHandler.h"
+#include "XbeeReceiver.h"
+#include "Trajectory.h"

 /*
  * Defines
@@ -23,10 +24,11 @@
 #define SECONDS 1000
 #define TEST_DELAY 15*SECONDS
 #define __BOAT__ 1
-#define MOTOR_SPEED 30
+#define MOTOR_SPEED 22
 #define TEMPERATURE_THRESHOLD 50
 #define SONAR_THRESHOLD 1
 #define PROXIMITY_THRESHOLD 1
+#define STATIONNARY_DELAY 5*SECONDS
 /********************************************/

@@ -35,16 +37,18 @@
  */
 #if __BOAT__>0
   PIDController PIDController;
-  ESC esc(1500, 2000, 3);
+  ESC esc(1500, 2000, 12);
   Gyroscope gyroscope;
   Moisture moistureSensor;
   ProximitySensor proximitySensorArray;
   RudderServo rudderServo;
   Temperature temperatureSensor;
+  Trajectory trajectory;
   EmergencyHandler emergencyHandler("Dry", TEMPERATURE_THRESHOLD, SONAR_THRESHOLD, PROXIMITY_THRESHOLD);
 #endif
-LiquidCrystal lcd(8, 9, 4, 5, 6, 7);
+
 GPS gps;
+XbeeReceiver xbee;
 /********************************************/

@@ -64,76 +68,115 @@
   uint8_t count = 0;
   double theta = 0.0;
   double rudder = 0.0;
+  int servoValue = 0;
+  int escValue = 0;
+  int gpsValue = 0;
   uint32_t timer1;
   uint32_t timer2;
   double distanceToTarget = 0.00;
+  double destinationPoint[1][2] = { 45.379184, 71.9239 }; //test campus
+  double startPoint[1][2];
+  int gpsListCounter = 2;
+  double listPointsX[10] = {0};
+  double listPointsY[10] = {0};
 #endif /* __BOAT__ */

+const char GPS = 'G';
+const char Manuel = 'M';
+char mode = 'E';
 NMEAData currentGpsData;
 /********************************************/

 void setup() {
-
+  Serial.begin(115200);
   /*
    * Sensor initialization
    */
   gps.enable();
-
-#if __BOAT__>0
-  Serial.begin(115200);
+  xbee.begin();
+
+  delay(2*SECONDS);
+
+#if __BOAT__>0
+
   gyroscope.enable();
   moistureSensor.enable();
   rudderServo.enable();
   temperatureSensor.enable();
   proximitySensorArray.enable();
-  /*  Uncomment when xbee is integrated
-  basecampGPSData = xbee.getGPSDataFromBasecamp();
-  gpsError = getGPSError(basecamp GPSData);
-  */
-  lcd.begin(16, 2);
-  lcd.clear();
-  lcd.setCursor(0, 0);
-  lcd.print("Oktopus");
-  lcd.setCursor(0, 1);
-  lcd.print("autopilot");
+
+  PIDController.enableCruisingMode();
+
+  currentGpsData = gps.getData();
+  while(currentGpsData.latitude < 4500 && currentGpsData.longitude < 7000){
+    currentGpsData = gps.getData();
+  }
+  startPoint[0][0] = ((currentGpsData.latitude-4500)/60)+45;
+  startPoint[0][1] = ((currentGpsData.longitude-7100)/60)+71;
+  trajectory.getData(startPoint,destinationPoint,listPointsX,listPointsY);
+
+  nextGpsData.longitude = listPointsY[2];
+  nextGpsData.latitude = listPointsX[2];
+
   delay(TEST_DELAY);
   timer1 = millis();
   timer2 = millis();

   moisture = moistureSensor.getData();
   temperature = temperatureSensor.getData();
-
-  currentEmergencyState = emergencyHandler.testConditions(moisture, temperature, sonar, proximitySensorData);
+  rudderServo.setAngle(0);
+
+  //currentEmergencyState = emergencyHandler.testConditions(moisture, temperature, sonar, proximitySensorData);

 #endif /* __BOAT__ */
  /********************************************/
 }

 void loop() {
+
   currentGpsData = gps.getData();
-
-#if __BOAT__>0
-
-  currentEmergencyState = emergencyHandler.testConditions(moisture, temperature, sonar, proximitySensorData);
+
+
+#if __BOAT__>0
+
+  xbee.receiveData(); //Update les valeurs du servo, esc et GPS de la sation fixe
+  mode = xbee.getMode();  //Retourne le mode de communication de la station fixe (Manuel,GPS)
+  Serial.print("xbee: ");
+  Serial.print(mode);
+  if(mode == Manuel){
+    servoValue = xbee.getServoValue();
+    escValue = xbee.getEscValue();
+    rudderServo.setAngle(servoValue);
+    esc.setSpeed(escValue, 0, 100);
+  }
+  else if(mode == GPS){
+    gpsValue = xbee.getGPSValue();
+    esc.setSpeed(MOTOR_SPEED, 0, 100);
+  }
+  /*currentEmergencyState = emergencyHandler.testConditions(moisture, temperature, sonar, proximitySensorData);
   while (currentEmergencyState != 0) {
     emergencyHandler.handleEmergency(currentEmergencyState);
     Serial.println("In emergency state loop.");
-    lcd.clear();
-    lcd.setCursor(0, 0);
-    lcd.print("In emergency state loop.");
     currentEmergencyState = emergencyHandler.testConditions(moisture, temperature, sonar, proximitySensorData);
   }
-
-  esc.setSpeed(MOTOR_SPEED, 0, 100);
-
-  nextGpsData.longitude = currentGpsData.longitude + 5;
-  nextGpsData.latitude = currentGpsData.latitude + 5;
-  /*  Uncomment when xbee is integrated
-  basecampGPSData = xbee.getGPSDataFromBasecamp();
-  gpsError = getGPSError(basecamp GPSData);
   */
+  if (getDistanceBetweenGPSPoints(currentGpsData, nextGpsData) < PIDController.InertialDerivationDistance && gpsListCounter < listPointsX[0]+1){
+    gpsListCounter = gpsListCounter + 1;
+    nextGpsData.longitude = listPointsY[gpsListCounter];
+    nextGpsData.latitude = listPointsX[gpsListCounter];
+    esc.setSpeed(0, 0, 100);
+    delay(STATIONNARY_DELAY);
+  }
+  else if (getDistanceBetweenGPSPoints(currentGpsData, nextGpsData) < PIDController.InertialDerivationDistance && gpsListCounter == listPointsX[0]+1){
+    esc.setSpeed(0, 0, 100);
+    delay(STATIONNARY_DELAY);
+  }
+  else{
+    esc.setSpeed(MOTOR_SPEED, 0, 100);
+  }
+
   if (timer1 > millis())  timer1 = millis();
   if (timer2 > millis())  timer2 = millis();

@@ -144,8 +187,7 @@
     theta = PIDController.compute_theta(currentGpsData, nextGpsData, heading);
     rudder = PIDController.control_rudder(theta);
     rudderServo.setAngle(rudder);
-
-    cycleDataOnLCD();
+    Serial.println(getDistanceBetweenGPSPoints(currentGpsData, nextGpsData));
   }

   if (millis() - timer2 > 5000) {
@@ -159,28 +201,3 @@
   }
 #endif /* __BOAT__ */
 }
-
-void cycleDataOnLCD() {
-
-  lcd.clear();
-  lcd.setCursor(0, 0);
-
-#if __BOAT__>0
-  lcd.print("GYR:");
-  lcd.print((int)heading);
-  lcd.print(" SAF:");
-  lcd.print((int)rudder);
-  lcd.setCursor(0, 1);
-  lcd.print("TTA:");
-  lcd.print((int)theta);
-  lcd.print(" HUM:");
-  lcd.print(moisture);
-  lcd.print(" TMP: ");
-  lcd.print(temperature);
-#endif /* __BOAT__ */
-
-  lcd.print(" LAT:");
-  lcd.print((int)currentGpsData.latitude);
-  lcd.print(" LON:");
-  lcd.print((int)currentGpsData.longitude);
-}


Add filtering by message ID

Add filtering by message ID

--- Arduino/can_bus_reader/can_bus_reader.ino
+++ Arduino/can_bus_reader/can_bus_reader.ino
@@ -13,6 +13,11 @@
 #include <global.h>
 #include <mcp2515.h>
 #include <mcp2515_defs.h>
+
+byte incomingByte;
+char message[255] = {};
+int index = 0;
+int messageId;

 //********************************Setup Loop*********************************//

@@ -32,27 +37,67 @@
 //********************************Main Loop*********************************//

 void loop(){
-
+//  printBuffer();
+  initFilter();
   tCAN message;
 if (mcp2515_check_message())
   {
     if (mcp2515_get_message(&message))
-  {
-        //if(message.id == 0x620 and message.data[2] == 0xFF)  //uncomment when you want to filter
-             //{
+    {
+        if(message.id == messageId || messageId == NULL)
+        {

                Serial.print("ID: ");
                Serial.print(message.id,HEX);
                Serial.print(", ");
-               Serial.print("Data: ");
+               Serial.print("Data [");
                Serial.print(message.header.length,DEC);
+               Serial.print(" bytes]: ");
                for(int i=0;i<message.header.length;i++)
                 {
                   Serial.print(message.data[i],HEX);
                   Serial.print(" ");
                 }
                Serial.println("");
-             //}
-           }}
+        }
+     }
+  }
+}

+void initFilter() {
+if (Serial.available() > 0) {
+    incomingByte = Serial.read();
+    if ((int)incomingByte == 10) {
+        // ignore space
+    } else if ((char)incomingByte == '!') {
+        memset(message, 0, sizeof(message));
+        index = 0;
+        messageId = NULL;
+        Serial.println("=============================");
+        Serial.println("=== Filter disabled =========");
+        Serial.println("=============================");
+    } else if ((char)incomingByte == '*') {
+        message[index] = '\0';
+        sscanf(message, "%x", &messageId);
+
+        memset(message, 0, sizeof(message));
+        index = 0;
+        Serial.println("=== Filter enabled ==============");
+        Serial.print("=== Filter on message ID: ");
+        Serial.print(messageId, HEX);
+        Serial.println(" ===");
+        Serial.println("===============================");
+    } else {
+        message[index] = (char)incomingByte;
+        index++;
+    }
+  }
 }
+
+void printBuffer() {
+  int i;
+  for(i = 0; i < sizeof(message); i++) {
+    Serial.print(message[i]);
+    }
+    Serial.println();
+}


Fixed uint and int comparison compile warnings.

--- ROVMain/ROVMain.ino
+++ ROVMain/ROVMain.ino
@@ -247,7 +247,7 @@
 	else
 	{
 	  // Check what value is coming next strings
-	  for(int actuatorI=0;actuatorI<sizeof(actuators)/sizeof(actuators[0]);actuatorI++)
+	  for(long int actuatorI=0;actuatorI<sizeof(actuators)/sizeof(actuators[0]);actuatorI++)
 	  {
 	  	if (strcmp(token, actuators[actuatorI]->getIdentifier()) == 0)
 	  	{
@@ -269,7 +269,7 @@
  */
 {
 	outputDataBuffer += OUTPUT_START_CHAR; // Start the message.
-	for(int i=0;i<sizeof(sensors)/sizeof(sensors[0]);i++)
+	for(long int i=0;i<sizeof(sensors)/sizeof(sensors[0]);i++)
 	{
 		outputDataBuffer += String( sensors[i]->getIdentifier() );
 		outputDataBuffer += DATA_DELIMITER;
@@ -312,12 +312,12 @@
  */
 {
 	int setupDelay(0); // By default wait for 0 seconds, i.e. arm nothing.
-	for(int i=0;i<sizeof(actuators)/sizeof(actuators[0]);i++) // Arm all actuators.
+	for(long int i=0;i<sizeof(actuators)/sizeof(actuators[0]);i++) // Arm all actuators.
 	{
 		int delayRequested = actuators[i]->arm();
 		if (delayRequested > setupDelay) setupDelay = delayRequested;
 	}
-	for(int i=0;i<sizeof(sensors)/sizeof(sensors[0]);i++) // Arm all sensors.
+	for(long int i=0;i<sizeof(sensors)/sizeof(sensors[0]);i++) // Arm all sensors.
 	{
 		int delayRequested = sensors[i]->arm();
 		if (delayRequested > setupDelay) setupDelay = delayRequested;


Compute gear orientations

Compute gear orientations

--- crypt-gears/gear_arduino/gear_arduino.ino
+++ crypt-gears/gear_arduino/gear_arduino.ino
@@ -1,4 +1,6 @@
 // hard-coded pin numbers for input/output
+// TODO(benkraft): I am assuming for the sake of argument that these start at
+// the top and go clockwise; fix once we know the correct positions.
 int gear_connections[3][12] = {{ 2,  3,  4,  5,  6,  7,  8,  9, 10, 11, 12, 13},
                                {14, 15, 16, 17, 18, 19, 20, 21, 22, 23, 24, 25},
                                {26, 27, 28, 29, 30, 31, 32, 33, 34, 35, 36, 37}};
@@ -132,18 +134,39 @@

 // Return the type and orientation of the gear in the nth position, or -1 for
 // both if no gear is lodged.
+// Type is 0, 1, 2, in order of the correct solution.
+// Orientation is 0 in the correct solution, 1 if we are one step clockwise
+// from it, and so on.
 void getOrientationAndTypeForGear(int gear_num, int* type, int* orientation)
 {
-  // TODO(benkraft): Implement.
-  // so the basic idea here is that each gear is attached in 12 places
-  // a pair of them will be connected
-  // on gear A, they're consecutive
-  // on gear B, they're 1 away
-  // on gear C, they're 2 away
-  // since they're flip symmetric(yay!) this will uniquely identify each gear + its orientation
-
-  // example: check whether slots 0 and 1 are connected on gear #0
-  getConnection(gear_connections[0][0], gear_connections[0][1]);
+  *type = -1;
+  *orientation = -1;
+  for (int i=0; i<12; i++) {
+    if (getGearConnection(gear_num, i, (i + 3) % 12))
+    {
+      *type = 0;
+      *orientation = (4 + i) % 12;  // actually equivalent mod 3
+      return;
+    }
+    else if (getGearConnection(gear_num, i, (i + 6) % 12))
+    {
+      *type = 1;
+      *orientation = i % 6;  // actually equivalent mod 3
+      return;
+    }
+    else if (getGearConnection(gear_num, i, (i + 2) % 12))
+    {
+      *type = 2;
+      *orientation = (4 + i) % 12;  // actually equivalent mod 4
+      return;
+    }
+  }
+}
+
+boolean getGearConnection(int gear_num, int slot1, int slot2)
+{
+  return getConnection(gear_connections[gear_num][slot1],
+                       gear_connections[gear_num][slot2]);
 }

 // all pins are tied to ground with a 12kOhm resistor


光センサーの値を返す時の文字列の形式を変更

光センサーの値を返す時の文字列の形式を変更

jsonデータとして認識されるようにした

--- util/doorLight.ino
+++ util/doorLight.ino
@@ -48,7 +48,7 @@
     lightCount++;
     if(lightCount > 3000){
         lightVal = analogRead(0)/4;
-        Serial.print("{lightSensor: ");
+        Serial.print("{\"lightSensor\": ");
         Serial.print(lightVal);//センサの値
         Serial.print("}\n");


Adding comments

Adding comments

Added comments and removed unused reverseEngaged variable

--- Arduino/Tamiya_Control/Tamiya_Control.ino
+++ Arduino/Tamiya_Control/Tamiya_Control.ino
@@ -33,8 +33,6 @@
 int angle=0;
 int vehicle_speed=0;

-int reverseEngaged=0;
-
 void setup() {
   //Setup serial port
   Serial.begin(115200);
@@ -58,28 +56,37 @@
     control_message[index] = command;
     index++;
   }
+
+  //If 8 characters have been received
   if (index >= 8)
   {
+    //Decompose array to calculate the steering angle specified
    angle =  100 * control_message[1] + 10 * control_message[2] + control_message[3];
    //Serial.print(angle);
+    //Decompose array to calculate the throttle value specified
    throttle = 100 * control_message[5] + 10 * control_message[6] + control_message[7];
    //Serial.print(throttle);

+    //Scale angle to 50 degrees of turn
     turnAngle = angle*50/255;
     if (control_message[0] == 1)
     {
+      //Change sign if it's a left turn
       turnAngle = turnAngle * -1;
     }
+    //Send command to steering servo
     turnMotor.write(90 + turnAngle + trimAngle);

+    //Scale throttle to 30 units from neutral (90)
     vehicle_speed = throttle*30/255;
     if (control_message[4] == 0)
     {
+      //Driving forwards
       driveMotor.write(90 - vehicle_speed);
-      reverseEngaged=0;
     }
     else
     {
+      //Driving reverse
       driveMotor.write(90 + vehicle_speed);
     }


You make me happy

You make me happy

--- 2018-FirefighterL1/Left_Right_Follow.ino
+++ 2018-FirefighterL1/Left_Right_Follow.ino
@@ -3,7 +3,7 @@
   if(!dog1){
     moveForward(3);
     rollForward();
-    while(frontRightUltrasonic.getDistance() > closeToWall && RightUltrasonic.getDistance() < closeToWall){
+    while(frontRightUltrasonic.getDistance() > closeToWall && rightUltrasonic.getDistance() < closeToWall){
       delay(50);
     }
     stopRobot();
@@ -28,7 +28,7 @@
       delay(50);
     }
     stopRobot();
-    moveFoward(2);
+    moveForward(2);
     turn(90);
     moveForward(5);
     rollForward();
@@ -38,7 +38,6 @@
     stopRobot();
     moveForward(3);
     turn(-90);
-    while
   }
 }

@@ -67,7 +66,7 @@
     turn(90); //turn downward
     moveForward(36);  //move down past upperRightRoom
     turn(90); //turn left
-    moveFoward(60); //move back into position for lowerRightRoom
+    moveForward(60); //move back into position for lowerRightRoom
     turn(-90);
     rollForward();
     while(rightUltrasonic.getDistance() < closeToWall) {


changed max client count to a lower amount, because only one client will keep it's connection ultimately also removed the ; in the macro replacement, because it's not needed to make it work

--- rp6control/rp6control.ino
+++ rp6control/rp6control.ino
@@ -25,7 +25,7 @@
 #if DEBUG == 1
 #define DEBUGCODE(x) (x) // add ; to the end, because it did not look good if ; was between the () of the macro
 #else
-#define DEBUGCODE(x) ; // nothing
+#define DEBUGCODE(x) // nothing
 #endif

 enum class State { Forward, Backward, Left, Right, Startup };
@@ -38,7 +38,7 @@
 const int serverPortnumber = 80;
 WiFiServer server(serverPortnumber);

-const uint32_t maxClientCount = 20;
+const uint32_t maxClientCount = 10;
 WiFiClient client[maxClientCount];
 const size_t clientsize = sizeof(client) / sizeof (client[0]);


fix typo

fix typo

--- BlackLED.ino
+++ BlackLED.ino
@@ -41,7 +41,7 @@
 #endif

 #ifdef _use_octoWS2811
-#ifndef #define octo_has_4_channel
+#ifndef octo_has_4_channel
 #warning "OctoWS2811 version 1.2.1 from https://github.com/alex-Arc/OctoWS2811.git"
 #endif
 #warning "using less than 8 outputs, octoWS2811 will stil runs 8 outputs"


Update Keypad.ino

Update Keypad.ino

--- ComboKeypad/Keypad.ino
+++ ComboKeypad/Keypad.ino
@@ -136,7 +136,7 @@
          doonce = false;
           delay(50);
         }
-}   //Function pressButton end
+}/*----(Function pressButton end)----*/

 // Functions "Reset"
 void reset() {


Check for valid spiffs data on boot.

Check for valid spiffs data on boot.

Checks if 'index.htm' is present.
If not, shows an error 'NO INDEX!' on the OLED.

Solve this by (re)uploading the spiff disk image.

--- controllerv91_esp8266.ino
+++ controllerv91_esp8266.ino
@@ -187,6 +187,19 @@
       delay(100); /* wait forever */
       yield();
     };
+  }
+
+  //check if index.htm is present and stop if it is not
+  if ( !SPIFFS.exists( "/index.htm" ) ) {
+    OLED.clear();
+    OLED.setTextAlignment( TEXT_ALIGN_CENTER );
+    OLED.setFont( ArialMT_Plain_16 );
+    OLED.drawString( 64, 30, F("NO INDEX!" ) );
+    OLED.display();
+    while (true) {
+      delay(100); /* wait forever */
+      yield();
+    };
   }

   //now we have a spiffs disk and can setup WiFi


Update ArduinoSmartShieldIrrigationController.ino

Improves handling of queue when station times are null or zero.  When station times are null or zero, they are not added to the queue and an updated status is returned to the SmartThings hub on the next cycle of the void loop().

--- ArduinoSmartShieldIrrigationController.ino
+++ ArduinoSmartShieldIrrigationController.ino
@@ -169,10 +169,12 @@
     inValue [i] = strtok(NULL, delimiters); //remove remaining substrings as incoming values
     i++;
   }
-  if (strcmp(inValue[0],"on")==0 && strcmp(inValue[2],"0")!=0) {   // add new station to queue
-    int addStation=atoi(inValue[1]);
-    queue[addStation]=1;
-    stationTime[addStation]=atol(inValue[2])*60L*1000L;
+  if (strcmp(inValue[0],"on")==0)  {   // add new station to queue
+    if (strcmp(inValue[2],"0")!=0 && strcmp(inValue[2],"null")!=0) {  //do not add to queue if zero time
+      int addStation=atoi(inValue[1]);
+      queue[addStation]=1;
+      stationTime[addStation]=atol(inValue[2])*60L*1000L;
+    }
     scheduleUpdate();
   }
   if (strcmp(inValue[0],"off")==0) {
@@ -190,8 +192,10 @@
   if (strcmp(inValue[0],"allOn")==0) {
     int i=1;
     while (i<stations+1) {
-      if (i != trafficCop && (strcmp(inValue[i],"0")!=0)) {
-        queue[i]=1;
+      if (i != trafficCop) {
+        if (strcmp(inValue[i],"0")!=0 && strcmp(inValue[i],"null")!=0) {  //do not add to queue if zero time
+          queue[i]=1;
+        }
       }
       stationTime[i]=atoi(inValue[i])*60L*1000L;
       i++;


missed rename

missed rename

--- hardware/esp8266com/esp8266/libraries/Hash/examples/sha1.ino
+++ hardware/esp8266com/esp8266/libraries/Hash/examples/sha1.ino
@@ -2,7 +2,7 @@
  * simple demo to show sha1 calculation
  */
 #include <Arduino.h>
-#include <hash.h>
+#include <Hash.h>

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


Revert "remove mqtt cert"

Revert "remove mqtt cert"

This reverts commit b0061a696f73f3985e871476636015dbbec1f3fe.