Working servos

Working servos

--- serial2ws.ino
+++ serial2ws.ino
@@ -1,20 +1,35 @@
-const int ledPin = 3;
+#include <Servo.h>
+
+const int ledPin = 13;
+Servo servo1; // Create a servo object
+Servo servo2; // Create a servo object
+Servo servo3; // Create a servo object

 HardwareSerial *port;

 void setup() {

-#ifdef __AVR_ATmega32U4__
-   port = &Serial1; // Arduino Yun
-#else
-   port = &Serial;  // Arduino Mega and others
-#endif
+   servo1.attach(9); // Attaches the servo on Pin 5
+   servo2.attach(10); // Attaches the servo on Pin 6
+   servo3.attach(11);
+
+   #ifdef __AVR_ATmega32U4__
+      port = &Serial1; // Arduino Yun
+   #else
+      port = &Serial;  // Arduino Mega and others
+   #endif

    port->begin(9600);

    pinMode(ledPin, OUTPUT);
    digitalWrite(ledPin, LOW);
+
+   //Reset Servo positions
+   servo1.write(0);
+   servo2.write(0);
+   servo3.write(0);
+
 }

@@ -24,12 +39,28 @@
       int inByte = port->read();

       if (inByte == '0') {
+         digitalWrite(ledPin, HIGH);
+         servo1.write(140);
+         servo2.write(180);
+         servo3.write(90);
          digitalWrite(ledPin, LOW);
       } else if (inByte == '1') {
          digitalWrite(ledPin, HIGH);
+         servo1.write(10);
+         servo2.write(20);
+         servo3.write(10);
+         digitalWrite(ledPin, LOW);
       }else if (inByte == '2') {
          digitalWrite(ledPin, HIGH);
+         servo1.write(30);
+         servo2.write(10);
+         servo3.write(30);
+         digitalWrite(ledPin, LOW);
       }else if (inByte == '3') {
+         digitalWrite(ledPin, HIGH);
+         servo1.write(80);
+         servo2.write(80);
+         servo3.write(10);
          digitalWrite(ledPin, LOW);
       }
    }


change deviceId number

change deviceId number

--- arduino/project.ino
+++ arduino/project.ino
@@ -60,7 +60,7 @@
   } else {
     jsonBuffer = StaticJsonBuffer<400>();
     JsonObject& root = jsonBuffer.createObject();
-    root["deviceId"] = "494101363422774";
+    root["deviceId"] = "0x14100000-0x2341-0x8036";
     root["sensorPir"] = stateSensor;
     root["carBlocked"] = false;
     root["triggeredAlarm"] = false;


Rearrange functions and update comments

Rearrange functions and update comments

--- Guzheng/Guzheng.ino
+++ Guzheng/Guzheng.ino
@@ -37,38 +37,25 @@
 int note2 = 0x3E;
 int note1 = 0x3C;

-/* Flag values for each laser. This may need some explanation. These
- * values will operate on the bit levels, directly with binary. They
- * work together with the lastNote variable to keep track of blocked
- * lasers. Here, I use an AND operator to read if the value has been
+/* Flag values for each laser. These values will operate on the bit
+ * levels, directly with binary. They work together with the
+ * lastNote variable to keep track of blocked lasers.
+ * Here, I use an AND operator to read if the value has been
  * set, and OR to set the value. */
 uint8_t laserArray[8] = {0x01, 0x02, 0x04, 0x08, 0x10, 0x20, 0x40, 0x80};

-// Variable to keep track of which set of notes (lower or upper 4)
-// Needed to work around limited lasers
-int noteSet = 1;
-/* Variable to keep track of the last played instrument. Used to
- * prevent continuous striking sounds on string and piano instruments
- * . Set to -1 when all strings have not been blocked, and 314 when
- * the noteSet laser is pressed. Otherwise, it is set to the last
- * playing laser, which will cause the Arduino to ignore the laser
- * until it is released again, thus preventing multiple hits */
-// TODO: Switch to a bit flag, and support multiple strings
+/* Variable to keep track of the last played instrument. The real
+ * data shows up when converted to binary, since we use binary
+ * operator tricks. When the first laser is hit, it is 00000001. If
+ * the second one is hit, then it is 00000010, and the third one is
+ * 00000100, and so on. */
 uint8_t lastNote = 0;

-void setup()
-{
-  // Initialize serial at 115200 baud
-  Serial.begin(115200);
-  // Wait 1 second for ttymidi to come up
-  delay(1000);
-  // Set instrument to trumpet
-  // 0xC0 is the change instrument command
-  // 0x39 is the instrument ID in hex
-#ifdef WIND
-  Serial.write(CHANGEINSTRUMENT);
-  Serial.write(INSTRUMENT);
-#endif
+// Function to write notes over serial
+void noteOn(int cmd, int pitch, int velocity) {
+  Serial.write(cmd);
+  Serial.write(pitch);
+  Serial.write(velocity);
 }

 // Function for playing note based on ID
@@ -99,6 +86,7 @@
     noteOn(NOTEON, note8, VOLUME);
     break;
   default:
+    // WTF? It shouldn't reach here, because that's an invalid ID
     noteOn(NOTEOFF, note1, 0x00);
     break;
   }
@@ -133,22 +121,37 @@
     noteOn(NOTEOFF, note8, 0x7F);
     break;
   default:
+    // WTF? It shouldn't reach here, because that's an invalid ID
     noteOn(NOTEOFF, note1, 0x00);
     break;
   }
 }

+void setup()
+{
+  // Initialize serial at 115200 baud
+  Serial.begin(115200);
+  // Wait 1 second for ttymidi to come up
+  delay(1000);
+  // Set instrument to trumpet
+  // 0xC0 is the change instrument command
+  // 0x39 is the instrument ID in hex
+#ifdef WIND
+  Serial.write(CHANGEINSTRUMENT);
+  Serial.write(INSTRUMENT);
+#endif
+}
+
 void loop()
 {
   // Main loop
-  // 5 ports, from 0 to 4
+  // 8 ports, from 0 to 7
   for (int i = 0; i <= LASTPORT; i++) {
     if(analogRead(i) > THRESHOLD) {
 #ifndef WIND
       if (!(lastNote & (laserArray[i]))) {
 #endif
         // Beam has been cut
-        // i+1 is because i is 0 indexed, but the ID starts with 1
         musicOn(i);
 #ifndef WIND
         lastNote |= (laserArray[i]);
@@ -167,11 +170,3 @@
     delay(DELAY);
   }
 }
-
-// Function to write notes over serial
-void noteOn(int cmd, int pitch, int velocity) {
-  Serial.write(cmd);
-  Serial.write(pitch);
-  Serial.write(velocity);
-}
-


Change Pins

Change Pins

--- testing/arduino/self-driving-v6.ino
+++ testing/arduino/self-driving-v6.ino
@@ -36,11 +36,11 @@
 Adafruit_NeoPixel LEDStrip = Adafruit_NeoPixel(26, ledPin, NEO_GRB + NEO_KHZ800);

 // Motor / Wheels
-const uint8_t motorPin1_1 = 4;
-const uint8_t motorPin1_2 = 5;
-
-const uint8_t motorPin2_1 = 7;
-const uint8_t motorPin2_2 = 6;
+const uint8_t motorPin1_1 = A7;
+const uint8_t motorPin1_2 = A6;
+
+const uint8_t motorPin2_1 = A5;
+const uint8_t motorPin2_2 = A4;

 const uint8_t motorEnablePin = 3;

@@ -78,7 +78,7 @@
     rangeLimit_Timestamp = millis();

     pinMode(motorEnablePin, OUTPUT);
-    analogWrite(motorEnablePin, 255);
+    analogWrite(motorEnablePin, motorSpeed);

     // Motor
     pinMode(motorPin1_1, OUTPUT);


Update motor_2.ino

Update motor_2.ino

--- arduino/motor_2.ino
+++ arduino/motor_2.ino
@@ -1,7 +1,8 @@
 #include <Wire.h>

+
 double potcurval;    // variable to read the value from the analog pin
-int angel; //Integer value of angle
+
 double angle =0;

 double curangle,kP=28.00,kI=42,kD=4,Last=0;
@@ -29,7 +30,9 @@
   pinMode(12,OUTPUT);
   pinMode(11,OUTPUT);
   Wire.begin(2);
+  Wire.onReceive(receiveEvent);
   Serial.begin(9600);
+  pinMode(13, OUTPUT);
 }
  void Errorcalc()
  {
@@ -40,8 +43,10 @@
  }
 void loop()
 {
-
+  Serial.print("got: ");
   Serial.println(angle);
+  if(angle > 127) digitalWrite(13, HIGH);
+	   else digitalWrite(13, LOW);

                  Errorcalc();
                 if (abs(Error) <.8){ // prevent integral 'windup'


Start implementantion of Android-moved turning

--- Arduino/Arduino.ino
+++ Arduino/Arduino.ino
@@ -45,7 +45,7 @@
 SOFT = false;

 // Motors definition
-//Ch A = LEFT, Ch B = RIGTH
+//Ch A = LEFT, Ch B = RIGHT
 const int
 PWM_LEFT   = 3,
 DIR_LEFT   = 12,
@@ -132,10 +132,10 @@
         }
         switch (command) {
           case CMD_LEFT:
-          turnLeft(140);//param1
+          turnLeft(param1);//param1
           break;
           case CMD_RIGHT:
-          turnRight(140);//param1
+          turnRight(param1);//param1
           break;
           case CMD_STOP:
           stop(HARD);
@@ -290,18 +290,58 @@
     break;
   }
 }
+
+void turnLeft(int velocity){
+  if (lastCommand!=CMD_LEFT){
+    stop(HARD);
+  }
+
+  setDirection(RIGHT, FORWARD);
+  setDirection(LEFT, BACKWARD);
+  //analogWrite(PWM_LEFT, velocity);
+  releaseBrake(RIGHT);
+  analogWrite(PWM_RIGHT, velocity);
+}
+
+void turnRight(int velocity){
+  if (lastCommand!=CMD_RIGHT){
+   stop(HARD);
+
+ }
+ setDirection(RIGHT, BACKWARD);
+ setDirection(LEFT, FORWARD);
+ releaseBrake(LEFT);
+ analogWrite(PWM_LEFT, velocity);
+    //analogWrite(PWM_RIGHT, velocity);
+  }
+
+// with method = HARD = true it uses brakes, otherwise stop by inertia
+void stop(bool method) {
+  if (method){
+    brake(BOTH);
+    analogWrite(PWM_LEFT, LOW);
+    analogWrite(PWM_RIGHT, LOW);
+  }
+  else{
+    analogWrite(PWM_LEFT, LOW);
+    analogWrite(PWM_RIGHT, LOW);
+  }
+  delay(DELAY / 10);
+}
+
+
 void setSpeedAndGo(int velocityLeft, int velocityRight) {
   releaseBrake(BOTH);
-
+
   if (millis()-coldTimerStart>100 ) {
     if ( currentLeftVelocity<velocityLeft+10 && currentLeftVelocity!=LOW){
-    currentLeftVelocity= currentLeftVelocity+velocityStep/5;
+      currentLeftVelocity= currentLeftVelocity+velocityStep/5;
     }
     if (currentRightVelocity<velocityRight){

-    currentRightVelocity= currentRightVelocity+velocityStep/5;
-
+      currentRightVelocity= currentRightVelocity+velocityStep/5;
+
     }
     analogWrite(PWM_LEFT, currentLeftVelocity);
     analogWrite(PWM_RIGHT, currentRightVelocity);
@@ -315,32 +355,32 @@
 }

-  void turnLeft(int velocity){
-    if (lastCommand!=CMD_LEFT){
-      stop(HARD);
-      coldTimerStart=millis();
-      currentLeftVelocity=LOW;
-      currentRightVelocity=baseVelocity;
-    }
-    setDirection(RIGHT, FORWARD);
-    setDirection(LEFT, BACKWARD);
-    setSpeedAndGo(LOW,velocity);
-  }
-
-  void turnRight(int velocity){
-    if (lastCommand!=CMD_RIGHT){
-     stop(HARD);
-     coldTimerStart=millis();
-     currentRightVelocity=LOW;
-     currentLeftVelocity=baseVelocity;
-   }
-   setDirection(RIGHT, BACKWARD);
-   setDirection(LEFT, FORWARD);
-   setSpeedAndGo(velocity,LOW);
+void turnLeft2(int velocity){
+  if (lastCommand!=CMD_LEFT){
+    stop(HARD);
+    coldTimerStart=millis();
+    currentLeftVelocity=LOW;
+    currentRightVelocity=baseVelocity;
+  }
+  setDirection(RIGHT, FORWARD);
+  setDirection(LEFT, BACKWARD);
+  setSpeedAndGo(LOW,velocity);
+}
+
+void turnRight2(int velocity){
+  if (lastCommand!=CMD_RIGHT){
+   stop(HARD);
+   coldTimerStart=millis();
+   currentRightVelocity=LOW;
+   currentLeftVelocity=baseVelocity;
  }
+ setDirection(RIGHT, BACKWARD);
+ setDirection(LEFT, FORWARD);
+ setSpeedAndGo(velocity,LOW);
+}

 // with method = HARD = true it uses brakes, otherwise stop by inertia
-void stop(bool method) {
+void stop2(bool method) {
   if (method){
     brake(BOTH);
     currentRightVelocity=currentLeftVelocity=LOW;


removed redundant include

removed redundant include

--- V0p2_Main/V0p2_Main.ino
+++ V0p2_Main/V0p2_Main.ino
@@ -50,7 +50,6 @@
 #include <SPI.h>
 #include <Wire.h>
 #include <OTRadioLink.h>
-//#include <OTNullRadioLink.h> // as in separate library to OTRadioLink
 #include <OTSIM900Link.h>
 #include <OTRN2483Link.h>
 #include <OTRadValve.h>


SPI pin assignment

SPI pin assignment

--- attiny85/transmitter/transmitter.ino
+++ attiny85/transmitter/transmitter.ino
@@ -23,8 +23,6 @@
 //                  +----+
 // see http://www.gammon.com.au/forum/?id=11488&reply=9#reply9

-// i2c http://playground.arduino.cc/Code/USIi2c
-// library from http://playground.arduino.cc/uploads/Code/TinyWireS.zip

 #include <util/delay.h>
@@ -33,20 +31,17 @@
 #include <avr/power.h>    // Power management
 #include <VirtualWire.h>

-#include <TinyWireS.h>
-#include <usiTwiSlave.h>

 #define LED_DEBUG 0
 #define PIN_TX 3 // PB3

-#define PIN_WAKEUP_MASTER 1 // PB1 Connected to the atmega328 external interupt pin.
+#define PIN_MISO 1 // PB1  (DO)  -> atmega MISO & external interupt
+#define PIN_MOSI 0 // PB0  (DI)  -> atmega MOSI
+#define PIN_SCL  2 // PB2 (USCK) -> atmega SCL

-#define PIN_WAKEUP_SELF 4   // PB4 / pin 3 / LDR attached
-//#define PIN_LDR 2           // PB4 / pin 3 / A2 - NB: ANALOG pin 2 not digital pin 2
+#define PIN_WAKEUP_SELF 4   // PB4 / pin 3 / LDR attached - HIGH = wakeup

-//#define THRESHOLD_DARK 200 // A reading below this is considered dark.

-#define I2C_SLAVE_ADDR 100

 byte msgId = 0;
 int ldr_val = 0;
@@ -59,15 +54,17 @@

 void setup()
 {
+  ADCSRA = 0; // turn off ADC
+
   pinMode(LED_DEBUG, OUTPUT);
   pinMode(PIN_TX, OUTPUT);
   pinMode(PIN_WAKEUP_SELF, INPUT);
-  pinMode(PIN_WAKEUP_MASTER, OUTPUT);
+  pinMode(PIN_MISO, OUTPUT);

-
-  digitalWrite(PIN_WAKEUP_MASTER, LOW);
+  // Low on MISO tells atmega to sleep
+  digitalWrite(PIN_MISO, LOW);

-  //TinyWireS.begin(I2C_SLAVE_ADDR);
+

   // pin change interrupt (example for D4)
   PCMSK  |= bit (PCINT4);  // want pin D4 / pin 3
@@ -106,13 +103,13 @@
   if (!ldr_val) {
     // Too dark (LDR is reading low)
     // Let atmega328p know it should be asleep
-    digitalWrite(PIN_WAKEUP_MASTER, LOW);
+    digitalWrite(PIN_MISO, LOW);

     // Sleep untill enough light
     goToSleep();
   } else if (vcc >= 3300) {
     // Tell the Atmega328p that it should be awake now.
-    digitalWrite(PIN_WAKEUP_MASTER, HIGH);
+    digitalWrite(PIN_MISO, HIGH);
   }

@@ -140,7 +137,7 @@

   set_sleep_mode(SLEEP_MODE_PWR_DOWN);
   cli();
-  ADCSRA = 0;            // turn off ADC
+
   power_all_disable();  // power off ADC, Timer 0 and 1, serial interface
   sleep_enable();
   sleep_bod_disable();
@@ -150,7 +147,7 @@
   MCUSR = 0; // clear the reset register
   power_all_enable();    // power everything back on

-  ADCSRA = (1 << ADEN); // ADC back on
+  //ADCSRA = (1 << ADEN); // ADC back on

 }


Update displayonly.ino

Update displayonly.ino

--- Modules/displayonly/displayonly.ino
+++ Modules/displayonly/displayonly.ino
@@ -206,7 +206,6 @@

 void messages(int numbmsg){
   if (numbmsg != 0){
-    lastRow = 0;
     display.drawBitmap(0, rowStartY[lastRow], msg716, 16, 7, BLACK);
     display.setCursor(18, rowStartY[lastRow]);
     display.print(numbmsg);


Move parameters into contiguous struct/union for efficient EEPROM storage.

--- examples/seq/seq.ino
+++ examples/seq/seq.ino
@@ -109,83 +109,75 @@
     display->fill_rect(122, 1, 5, 5, DUINO_SSD1306::White);

     // load settings
-    load_params(0, stage_pitch, 8);
-    load_params(8, stage_steps, 8);
-    load_params(16, stage_gate, 8);
-    load_params(24, &stage_slew, 1);
-    load_params(25, (uint8_t *)&stage_count, 1);
-    load_params(26, &diradd_mode, 1);
-    load_params(27, (uint8_t *)&slew_rate, 1);
-    load_params(28, (uint8_t *)&gate_time, 1);
-    load_params(29, (uint8_t *)&clock_bpm, 1);
+    load_params(0, params.bytes, 30);

     // verify settings and export to function parameters
     for(uint8_t i = 0; i < 8; ++i)
     {
-      if(stage_pitch[i] < 0)
-      {
-        stage_pitch[i] = 0;
-      }
-      if(stage_pitch[i] > 119)
-      {
-        stage_pitch[i] = 119;
-      }
-      seq_values.stage_cv[i] = note_to_cv(stage_pitch[i]);
+      if(params.vals.stage_pitch[i] < 0)
+      {
+        params.vals.stage_pitch[i] = 0;
+      }
+      if(params.vals.stage_pitch[i] > 119)
+      {
+        params.vals.stage_pitch[i] = 119;
+      }
+      seq_values.stage_cv[i] = note_to_cv(params.vals.stage_pitch[i]);
     }

     for(uint8_t i = 0; i < 8; ++i)
     {
-      if(stage_steps[i] < 1 || stage_steps[i] > 8)
-      {
-        stage_steps[i] = 8;
-      }
-      seq_values.stage_steps[i] = stage_steps[i];
+      if(params.vals.stage_steps[i] < 1 || params.vals.stage_steps[i] > 8)
+      {
+        params.vals.stage_steps[i] = 8;
+      }
+      seq_values.stage_steps[i] = params.vals.stage_steps[i];
     }

     for(uint8_t i = 0; i < 8; ++i)
     {
-      if(stage_gate[i] < 0 || stage_gate[i] > 5)
-      {
-        stage_gate[i] = 2;
-      }
-      seq_values.stage_gate[i] = (GateMode)stage_gate[i];
+      if(params.vals.stage_gate[i] < 0 || params.vals.stage_gate[i] > 5)
+      {
+        params.vals.stage_gate[i] = 2;
+      }
+      seq_values.stage_gate[i] = (GateMode)params.vals.stage_gate[i];
     }

     for(uint8_t i = 0; i < 8; ++i)
     {
-      seq_values.stage_slew[i] = (bool)((stage_slew >> i) & 1);
-    }
-
-    if(stage_count < 1 || stage_count > 8)
-    {
-      stage_count = 8;
-    }
-    seq_values.stage_count = stage_count;
-
-    seq_values.diradd_mode = (bool)diradd_mode;
+      seq_values.stage_slew[i] = (bool)((params.vals.stage_slew >> i) & 1);
+    }
+
+    if(params.vals.stage_count < 1 || params.vals.stage_count > 8)
+    {
+      params.vals.stage_count = 8;
+    }
+    seq_values.stage_count = params.vals.stage_count;
+
+    seq_values.diradd_mode = (bool)params.vals.diradd_mode;

-    if(slew_rate < 0 || slew_rate > 16)
-    {
-      slew_rate = 8;
-    }
-    seq_values.slew_rate = (float)slew_rate / 16.0;
-
-    if(gate_time < 0 || gate_time > 16)
-    {
-      gate_time = 8;
-    }
-    seq_values.gate_time = (float)gate_time / 16.0;
+    if(params.vals.slew_rate < 0 || params.vals.slew_rate > 16)
+    {
+      params.vals.slew_rate = 8;
+    }
+    seq_values.slew_rate = (float)params.vals.slew_rate / 16.0;
+
+    if(params.vals.gate_time < 0 || params.vals.gate_time > 16)
+    {
+      params.vals.gate_time = 8;
+    }
+    seq_values.gate_time = (float)params.vals.gate_time / 16.0;

-    if(clock_bpm < 0 || clock_bpm > 30)
-    {
-      clock_bpm = 0;
-    }
-    seq_values.clock_period = bpm_to_ms(clock_bpm);
-    seq_values.clock_ext = !(bool)clock_bpm;
+    if(params.vals.clock_bpm < 0 || params.vals.clock_bpm > 30)
+    {
+      params.vals.clock_bpm = 0;
+    }
+    seq_values.clock_period = bpm_to_ms(params.vals.clock_bpm);
+    seq_values.clock_ext = !(bool)params.vals.clock_bpm;

     // draw global elements
-    display->draw_char(38, 2, '0' + stage_count, DUINO_SSD1306::White);
-    display->draw_char(47, 2, diradd_mode ? 'A' : 'D', DUINO_SSD1306::White);
+    display->draw_char(38, 2, '0' + params.vals.stage_count, DUINO_SSD1306::White);
+    display->draw_char(47, 2, params.vals.diradd_mode ? 'A' : 'D', DUINO_SSD1306::White);
     for(uint8_t i = 0; i < 2; ++i)
     {
       display->draw_vline(56 + i * 22, 2, 7, DUINO_SSD1306::White);
@@ -193,26 +185,26 @@
       display->draw_hline(57 + i * 22, 8, 16, DUINO_SSD1306::White);
       display->draw_vline(73 + i * 22, 2, 7, DUINO_SSD1306::White);
     }
-    display_slew_rate(57, 3, slew_rate, DUINO_SSD1306::White);
-    display_gate_time(79, 3, gate_time, DUINO_SSD1306::White);
-    display_clock(100, 2, clock_bpm, DUINO_SSD1306::White);
+    display_slew_rate(57, 3, params.vals.slew_rate, DUINO_SSD1306::White);
+    display_gate_time(79, 3, params.vals.gate_time, DUINO_SSD1306::White);
+    display_clock(100, 2, params.vals.clock_bpm, DUINO_SSD1306::White);

     // draw step elements
     for(uint8_t i = 0; i < 8; ++i)
     {
       // pitch
-      display_note(16 * i, 9, stage_pitch[i], DUINO_SSD1306::White);
+      display_note(16 * i, 9, params.vals.stage_pitch[i], DUINO_SSD1306::White);
       // steps
-      for(uint8_t j = 0; j < stage_steps[i]; ++j)
+      for(uint8_t j = 0; j < params.vals.stage_steps[i]; ++j)
       {
         display->draw_hline(16 * i + 2, 40 - j * 2, 5, DUINO_SSD1306::White);
         display->draw_hline(16 * i + 9, 40 - j * 2, 5, DUINO_SSD1306::White);
       }
       // gate mode
-      display->draw_icon_16(16 * i, 43, gate_mode_icons, (GateMode)stage_gate[i], DUINO_SSD1306::White);
+      display->draw_icon_16(16 * i, 42, gate_mode_icons, (GateMode)params.vals.stage_gate[i], DUINO_SSD1306::White);
       // slew
       display->fill_rect(16 * i + 1, 59, 14, 4, DUINO_SSD1306::White);
-      display->fill_rect(16 * i + 2 + 6 * (~(stage_slew >> i) & 1), 60, 6, 2, DUINO_SSD1306::Black);
+      display->fill_rect(16 * i + 2 + 6 * (~(params.vals.stage_slew >> i) & 1), 60, 6, 2, DUINO_SSD1306::Black);
     }

     invert_current_selection();
@@ -238,15 +230,7 @@
       switch(main_selected)
       {
         case 0: // save
-          save_params(0, stage_pitch, 8);
-          save_params(8, stage_steps, 8);
-          save_params(16, stage_gate, 8);
-          save_params(24, &stage_slew, 1);
-          save_params(25, (uint8_t *)&stage_count, 1);
-          save_params(26, &diradd_mode, 1);
-          save_params(27, (uint8_t *)&slew_rate, 1);
-          save_params(28, (uint8_t *)&gate_time, 1);
-          save_params(29, (uint8_t *)&clock_bpm, 1);
+          save_params(0, params.bytes, 30);
           display->fill_rect(123, 2, 3, 3, DUINO_SSD1306::Black);
           break;
         case 1: // top
@@ -277,136 +261,136 @@
           switch(top_selected)
           {
             case 0: // count
-              stage_count += v;
-              if(stage_count < 1)
-              {
-                stage_count = 1;
-              }
-              else if(stage_count > 8)
-              {
-                stage_count = 8;
-              }
-              seq_values.stage_count = stage_count;
+              params.vals.stage_count += v;
+              if(params.vals.stage_count < 1)
+              {
+                params.vals.stage_count = 1;
+              }
+              else if(params.vals.stage_count > 8)
+              {
+                params.vals.stage_count = 8;
+              }
+              seq_values.stage_count = params.vals.stage_count;
               display->fill_rect(37, 1, 7, 9, DUINO_SSD1306::White);
-              display->draw_char(38, 2, '0' + stage_count, DUINO_SSD1306::Black);
+              display->draw_char(38, 2, '0' + params.vals.stage_count, DUINO_SSD1306::Black);
               break;
             case 1: // dir/add
               if(v < 0)
               {
-                diradd_mode = 0;
+                params.vals.diradd_mode = 0;
               }
               else if(v > 0)
               {
-                diradd_mode = 1;
-              }
-              seq_values.diradd_mode = (bool)diradd_mode;
+                params.vals.diradd_mode = 1;
+              }
+              seq_values.diradd_mode = (bool)params.vals.diradd_mode;
               display->fill_rect(46, 1, 7, 9, DUINO_SSD1306::White);
-              display->draw_char(47, 2, diradd_mode ? 'A' : 'D', DUINO_SSD1306::Black);
+              display->draw_char(47, 2, params.vals.diradd_mode ? 'A' : 'D', DUINO_SSD1306::Black);
               break;
             case 2: // slew
-              slew_rate += v;
-              if(slew_rate < 0)
-              {
-                slew_rate = 0;
-              }
-              else if(slew_rate > 16)
-              {
-                slew_rate = 16;
-              }
-              seq_values.slew_rate = (float)slew_rate / 16.0;
+              params.vals.slew_rate += v;
+              if(params.vals.slew_rate < 0)
+              {
+                params.vals.slew_rate = 0;
+              }
+              else if(params.vals.slew_rate > 16)
+              {
+                params.vals.slew_rate = 16;
+              }
+              seq_values.slew_rate = (float)params.vals.slew_rate / 16.0;
               display->fill_rect(57, 3, 16, 5, DUINO_SSD1306::White);
-              display_slew_rate(57, 3, slew_rate, DUINO_SSD1306::Black);
+              display_slew_rate(57, 3, params.vals.slew_rate, DUINO_SSD1306::Black);
               break;
             case 3: // gate
-              gate_time += v;
-              if(gate_time < 0)
-              {
-                gate_time = 0;
-              }
-              else if(gate_time > 16)
-              {
-                gate_time = 16;
-              }
-              seq_values.gate_time = (float)gate_time / 16.0;
+              params.vals.gate_time += v;
+              if(params.vals.gate_time < 0)
+              {
+                params.vals.gate_time = 0;
+              }
+              else if(params.vals.gate_time > 16)
+              {
+                params.vals.gate_time = 16;
+              }
+              seq_values.gate_time = (float)params.vals.gate_time / 16.0;
               display->fill_rect(79, 3, 16, 5, DUINO_SSD1306::White);
-              display_gate_time(79, 3, gate_time, DUINO_SSD1306::Black);
+              display_gate_time(79, 3, params.vals.gate_time, DUINO_SSD1306::Black);
               break;
             case 4: // clock
-              clock_bpm += v;
-              if(clock_bpm < 0)
-              {
-                clock_bpm = 0;
-              }
-              else if(clock_bpm > 30)
-              {
-                clock_bpm = 30;
-              }
-              seq_values.clock_period = bpm_to_ms(clock_bpm);
-              seq_values.clock_ext = !(bool)clock_bpm;
+              params.vals.clock_bpm += v;
+              if(params.vals.clock_bpm < 0)
+              {
+                params.vals.clock_bpm = 0;
+              }
+              else if(params.vals.clock_bpm > 30)
+              {
+                params.vals.clock_bpm = 30;
+              }
+              seq_values.clock_period = bpm_to_ms(params.vals.clock_bpm);
+              seq_values.clock_ext = !(bool)params.vals.clock_bpm;
               display->fill_rect(99, 1, 19, 9, DUINO_SSD1306::White);
-              display_clock(100, 2, clock_bpm, DUINO_SSD1306::Black);
+              display_clock(100, 2, params.vals.clock_bpm, DUINO_SSD1306::Black);
               break;
           }
           break;
         case 2: // pitch
-          stage_pitch[stage_selected] += v;
-          if(stage_pitch[stage_selected] < 0)
-          {
-            stage_pitch[stage_selected] = 0;
-          }
-          else if(stage_pitch[stage_selected] > 119)
-          {
-            stage_pitch[stage_selected] = 119;
-          }
-          seq_values.stage_cv[stage_selected] = note_to_cv(stage_pitch[stage_selected]);
+          params.vals.stage_pitch[stage_selected] += v;
+          if(params.vals.stage_pitch[stage_selected] < 0)
+          {
+            params.vals.stage_pitch[stage_selected] = 0;
+          }
+          else if(params.vals.stage_pitch[stage_selected] > 119)
+          {
+            params.vals.stage_pitch[stage_selected] = 119;
+          }
+          seq_values.stage_cv[stage_selected] = note_to_cv(params.vals.stage_pitch[stage_selected]);
           display->fill_rect(16 * stage_selected, 10, 16, 15, DUINO_SSD1306::White);
-          display_note(16 * stage_selected, 9, stage_pitch[stage_selected], DUINO_SSD1306::Black);
+          display_note(16 * stage_selected, 9, params.vals.stage_pitch[stage_selected], DUINO_SSD1306::Black);
           break;
         case 3: // steps
-          stage_steps[stage_selected] += v;
-          if(stage_steps[stage_selected] < 1)
-          {
-            stage_steps[stage_selected] = 1;
-          }
-          else if(stage_steps[stage_selected] > 8)
-          {
-            stage_steps[stage_selected] = 8;
-          }
-          seq_values.stage_steps[stage_selected] = stage_steps[stage_selected];
+          params.vals.stage_steps[stage_selected] += v;
+          if(params.vals.stage_steps[stage_selected] < 1)
+          {
+            params.vals.stage_steps[stage_selected] = 1;
+          }
+          else if(params.vals.stage_steps[stage_selected] > 8)
+          {
+            params.vals.stage_steps[stage_selected] = 8;
+          }
+          seq_values.stage_steps[stage_selected] = params.vals.stage_steps[stage_selected];
           display->fill_rect(16 * stage_selected, 25, 16, 17, DUINO_SSD1306::White);
-          for(uint8_t j = 0; j < stage_steps[stage_selected]; ++j)
+          for(uint8_t j = 0; j < params.vals.stage_steps[stage_selected]; ++j)
           {
             display->draw_hline(16 * stage_selected + 2, 40 - j * 2, 5, DUINO_SSD1306::Black);
             display->draw_hline(16 * stage_selected + 9, 40 - j * 2, 5, DUINO_SSD1306::Black);
           }
           break;
         case 4: // gate
-          stage_gate[stage_selected] += v;
-          if(stage_gate[stage_selected] < 0)
-          {
-            stage_gate[stage_selected] = 0;
-          }
-          else if(stage_gate[stage_selected] > 5)
-          {
-            stage_gate[stage_selected] = 5;
-          }
-          seq_values.stage_gate[stage_selected] = (GateMode)stage_gate[stage_selected];
+          params.vals.stage_gate[stage_selected] += v;
+          if(params.vals.stage_gate[stage_selected] < 0)
+          {
+            params.vals.stage_gate[stage_selected] = 0;
+          }
+          else if(params.vals.stage_gate[stage_selected] > 5)
+          {
+            params.vals.stage_gate[stage_selected] = 5;
+          }
+          seq_values.stage_gate[stage_selected] = (GateMode)params.vals.stage_gate[stage_selected];
           display->fill_rect(16 * stage_selected, 42, 16, 16, DUINO_SSD1306::White);
-          display->draw_icon_16(16 * stage_selected, 43, gate_mode_icons, (GateMode)stage_gate[stage_selected],
-              DUINO_SSD1306::Black);
+          display->draw_icon_16(16 * stage_selected, 42, gate_mode_icons,
+              (GateMode)params.vals.stage_gate[stage_selected], DUINO_SSD1306::Black);
           break;
         case 5: // slew
           if(v < 0)
           {
-            stage_slew &= ~(1 << stage_selected);
+            params.vals.stage_slew &= ~(1 << stage_selected);
           }
           else if(v > 0)
           {
-            stage_slew |= (1 << stage_selected);
-          }
-          seq_values.stage_slew[stage_selected] = (bool)((stage_slew >> stage_selected) & 1);
+            params.vals.stage_slew |= (1 << stage_selected);
+          }
+          seq_values.stage_slew[stage_selected] = (bool)((params.vals.stage_slew >> stage_selected) & 1);
           display->fill_rect(16 * stage_selected + 1, 59, 14, 4, DUINO_SSD1306::Black);
-          display->fill_rect(16 * stage_selected + 2 + 6 * (~(stage_slew >> stage_selected) & 1), 60, 6, 2,
+          display->fill_rect(16 * stage_selected + 2 + 6 * (~(params.vals.stage_slew >> stage_selected) & 1), 60, 6, 2,
               DUINO_SSD1306::White);
           break;
       }
@@ -544,15 +528,24 @@

   bool display_changed;

-  int8_t stage_pitch[8];
-  int8_t stage_steps[8];
-  int8_t stage_gate[8];
-  uint8_t stage_slew;
-  int8_t stage_count;
-  uint8_t diradd_mode;
-  int8_t slew_rate;
-  int8_t gate_time;
-  int8_t clock_bpm;
+  struct DU_SEQ_Parameter_Values {
+    int8_t stage_pitch[8];
+    int8_t stage_steps[8];
+    int8_t stage_gate[8];
+    uint8_t stage_slew;
+    int8_t stage_count;
+    uint8_t diradd_mode;
+    int8_t slew_rate;
+    int8_t gate_time;
+    int8_t clock_bpm;
+  };
+
+  union DU_SEQ_Parameters {
+    DU_SEQ_Parameter_Values vals;
+    uint8_t bytes[30];
+  };
+
+  DU_SEQ_Parameters params;
 };

 DU_SEQ_Function * function;


fixed #16

fixed #16

--- Modules/Sensor/LightSensor/ArduinoCodes/LightSensorATtiny/LightSensorATtiny.ino
+++ Modules/Sensor/LightSensor/ArduinoCodes/LightSensorATtiny/LightSensorATtiny.ino
@@ -49,8 +49,8 @@

   if(photoresistor_value < 150)
     photoresistor_value = 150;
-  else if(photoresistor_value > 800)
-    photoresistor_value = 800;
+  else if(photoresistor_value > 850)
+    photoresistor_value = 850;

   //We are only mapping 0-1023 from ADC to 0-255
   int output_value = map(photoresistor_value, 150, 850, 0, input_val/4);


Log a 'starting' event at startup

Log a 'starting' event at startup

--- firmware/dht-logger.ino
+++ firmware/dht-logger.ino
@@ -167,6 +167,18 @@
 #if ADAFRUIT_ENABLED
     aio.begin();
 #endif
+
+#if PARTICLE_EVENT
+    // startup event
+    sprintf(payload,
+            "{\"device\":\"%s\",\"state\":\"starting\"}",
+            DEVICE_NAME);
+
+    Spark.publish(PARTICLE_EVENT_NAME, payload, 60, PRIVATE);
+#endif
+
+    // run the first measurement
+    loop();
 }

 /**


enabled debugger

enabled debugger

--- T1/src/AFE-MQTT-listener.ino
+++ T1/src/AFE-MQTT-listener.ino
@@ -13,7 +13,8 @@

   char _mqttTopic[70];
   Led.on();
-   Serial << endl << "INFO: MQTT message recieved: " << topic << " \\ ";
+
+  Serial << endl << "INFO: MQTT message recieved: " << topic << " \\ ";

   if (length >= 1) { // command arrived


Update fingerprint.ino

Update fingerprint.ino

Fix for SPARK compiler directive

--- firmware/examples/fingerprint/fingerprint.ino
+++ firmware/examples/fingerprint/fingerprint.ino
@@ -19,7 +19,7 @@

 #include "Adafruit_Fingerprint.h"

-#ifdef SPARK_CORE
+#if defined (SPARK)
 //
 #else
 #if ARDUINO >= 100
@@ -31,7 +31,7 @@

 int getFingerprintIDez();

-#ifdef SPARK_CORE
+#if defined (SPARK)
 Adafruit_Fingerprint finger = Adafruit_Fingerprint(&Serial1);
 #else
 // pin #2 is IN from sensor (GREEN wire)


Add flash of LEDs; longer start-up delay

 - I was having a problem where the log time was off a bit; increasing
   the startup delay to avoid this

 - flash all of the LEDs (green/red/yellow) for 1 sec before trying to
   connect the "Bridge"

--- RouterReset_Yun/RouterReset_Yun.ino
+++ RouterReset_Yun/RouterReset_Yun.ino
@@ -21,7 +21,7 @@
 const int resetRouterTimeSec = 30;
 const int secBetweenPings_Up = 5;
 const int secBetweenPings_Down = 1;
-const int startUpDelaySec = 5;
+const int startUpDelaySec = 8;
 const int switchPin = 12;

 String internetStatus;
@@ -37,6 +37,14 @@
     analogWrite(routerLED, routerLEDlevel);
     pinMode(switchPin, INPUT);
     digitalWrite(switchPin, HIGH);
+
+    digitalWrite(redLED, HIGH);
+    digitalWrite(greenLED, HIGH);
+    digitalWrite(yellowLED, HIGH);
+    delay(1000);
+    digitalWrite(redLED, LOW);
+    digitalWrite(greenLED, LOW);
+    digitalWrite(yellowLED, LOW);

     Bridge.begin();  // make contact with the linux processor


calibration

calibration

--- _06-power_meter/_06-power_meter.ino
+++ _06-power_meter/_06-power_meter.ino
@@ -1,3 +1,5 @@
+// CPU : 160MHz
+// FLASH : 4M/1M
 #include <PubSubClient.h>
 #include <ESP8266WiFi.h>
 #include <ESP8266mDNS.h>
@@ -36,7 +38,7 @@

 // ********** change MQTT_KEEPALIVE to 60 at PubSubClient.h *****************
 EnergyMonitor emon1;
-Average<float> ave(10);
+Average<float> ave(4);

 // mqtt
 char* topic = "esp8266/arduino/s07";
@@ -225,18 +227,6 @@
   revValue  = 0 ;
   oldrevMills = 0 ;
   oldrevValue = 0 ;
-
-  pinMode(IRPIN, INPUT);
-  pinMode(DOORPIN, INPUT_PULLUP);
-
-  doorStatus = digitalRead(DOORPIN);
-  olddoorStatus = doorStatus;
-
-  attachInterrupt(4, IRCHECKING_START, RISING);
-  attachInterrupt(5, DOORCHECKING, CHANGE);
-
-  emon1.current(A0, 75);
-  oldirStatus = LOW ;

   //OTA
@@ -261,16 +251,29 @@
   });
   ArduinoOTA.onError([](ota_error_t error) {
     //ESP.restart();
-      if (error == OTA_AUTH_ERROR) abort();
-      else if (error == OTA_BEGIN_ERROR) abort();
-      else if (error == OTA_CONNECT_ERROR) abort();
-      else if (error == OTA_RECEIVE_ERROR) abort();
-      else if (error == OTA_END_ERROR) abort();
-
+    /*
+    if (error == OTA_AUTH_ERROR) abort();
+    else if (error == OTA_BEGIN_ERROR) abort();
+    else if (error == OTA_CONNECT_ERROR) abort();
+    else if (error == OTA_RECEIVE_ERROR) abort();
+    else if (error == OTA_END_ERROR) abort();
+    */
   });

   ArduinoOTA.begin();

+  pinMode(IRPIN, INPUT);
+  pinMode(DOORPIN, INPUT_PULLUP);
+
+  doorStatus = digitalRead(DOORPIN);
+  olddoorStatus = doorStatus;
+
+  attachInterrupt(4, IRCHECKING_START, FALLING);
+  attachInterrupt(5, DOORCHECKING, CHANGE);
+
+  //emon1.current(A0, 60.6);
+  emon1.current(A0, 85);
+  oldirStatus = LOW ;
 }

 void DOORCHECKING() {
@@ -279,7 +282,7 @@

 void IRCHECKING_START() {
   detachInterrupt(4);
-  attachInterrupt(4, count_powermeter, RISING);
+  attachInterrupt(4, count_powermeter, FALLING);
   startMills = millis();
   oldirStatus = HIGH ;
 }
@@ -304,9 +307,10 @@
     wifi_connect();
   }

-  if ((millis() - sentMills) > ( REPORT_INTERVAL / 2) ) {
+  if ((millis() - sentMills) > ( 700) ) {
     unsigned long emonmillis = millis();
-    VIrms = emon1.calcIrms(1480) * 220.0;
+    //VIrms = emon1.calcIrms(1480) * 220.0;
+    VIrms = emon1.calcIrms(2960) * 220.0;
     calcIrmsmillis = millis() - emonmillis;

     ave.push(VIrms);
@@ -363,12 +367,12 @@
     olddoorStatus = doorStatus ;
   }

-  if (((millis() - sentMills) > REPORT_INTERVAL ) && ( irStatus == oldirStatus ) &&  ( revMills > 600 )) {
+  if (((millis() - sentMills) > REPORT_INTERVAL ) && ( irStatus == oldirStatus )) {
     sendmqttMsg(topic, payload);
     sentMills = millis();
   }

-  if (( irStatus != oldirStatus ) && ( revMills > 600 )) {
+  if ( irStatus != oldirStatus ) {
     sendmqttMsg(topic, payload);
     sentMills = millis();
     oldirStatus = irStatus ;
@@ -423,21 +427,14 @@
     return;
   }

-  /*
-    if (( millis() - startMills ) < ( revMills / 5 )) {
+  if (( millis() - startMills ) < ( revMills / 3 )) {
     return;
-    } else {
+  } else {
     revMills   = (millis() - startMills)  ;
     startMills = millis();
     irStatus   = !irStatus ;
     revCounts++;
-    }
-  */
-
-  revMills   = (millis() - startMills)  ;
-  startMills = millis();
-  irStatus   = !irStatus ;
-  revCounts++;
+  }

 }


removed conflicting error messages

removed conflicting error messages

--- arduino/brew_kettle/brew_kettle.ino
+++ arduino/brew_kettle/brew_kettle.ino
@@ -99,7 +99,6 @@
   char temp[5];
   itoa(temperatureToInt(temperature), temp, 10);
   cmdMessenger.sendCmd(kTEMPERATURE, temp);
-  Serial << temperature;
 }

 void arduino_ready() {
@@ -201,7 +200,9 @@
   pinMode(heaterPin, OUTPUT);
   dutyCycle = 0;
   setpoint = 40;
+
   temperaturePID.SetMode(MANUAL);
+  temperaturePID.SetOutputLimits(0, 100);

   Serial.begin(57600);
   cmdMessenger.print_LF_CR();
@@ -228,8 +229,6 @@
     previousMillis = currentMillis;
     slowCount++;
     if (slowCount > 50) {
-      Serial << temperature << ENDMSG;
-      Serial << analogRead(A0) << ENDMSG;
       Serial << STATMSG << "Duty Cycle is " << dutyCycle << ENDMSG;
       slowCount = 0;
     }


Update ReadSensorData.ino

Update ReadSensorData.ino

--- firmware/examples/ReadSensorData.ino
+++ firmware/examples/ReadSensorData.ino
@@ -4,13 +4,15 @@
 I2CSensorParticle sensor;

 void setup() {
+  Particle.publish("setup", "Start setup", 300, PRIVATE);
   Serial.begin(9600);

   sensor.begin(); // reset sensor
+  Particle.publish("setup", "sensor.begin() done", 300, PRIVATE);
   delay(1000); // give some time to boot up
   String address = String(sensor.getAddress());
   String version = String(sensor.getVersion());
-
+
   // publish sensors info
   Particle.publish("setup", "I2C Soil Moisture Sensor Address: " + address, 300, PRIVATE);
   Particle.publish("setup", "Sensor Firmware version: " + version, 300, PRIVATE);


fixed boot animation

fixed boot animation

Former-commit-id: 418ed83a4bd4ddaae79bf41de7fd9fb0794f8239

--- dependencies/LightberryHDUSBAPA1021.1/LightberryHDUSBAPA1021.1.ino
+++ dependencies/LightberryHDUSBAPA1021.1/LightberryHDUSBAPA1021.1.ino
@@ -135,10 +135,10 @@
   // green, blue, then off.  Once you're confident everything is working
   // end-to-end, it's OK to comment this out and reprogram the Arduino.
   uint8_t testcolor[] = { 0, 0, 0, 255, 0, 0 };
-  for (int i = 0; i < 4; i++) { //Start Frame
-    for (SPDR = 0x00; !(SPSR & _BV(SPIF)); );
-  }
   for (char n = 3; n >= 0; n--) {
+    for (int i = 0; i < 4; i++) { //Start Frame
+      for (SPDR = 0x00; !(SPSR & _BV(SPIF)); );
+    }
     for (c = 0; c < 25000; c++) {
       for (SPDR = 0xFF; !(SPSR & _BV(SPIF)); ); //Brightness byte
       for (i = 0; i < 3; i++) {
@@ -148,9 +148,10 @@
     for (int i = 0; i < 4; i++) { //Stop Frame
       for (SPDR = 0xFF; !(SPSR & _BV(SPIF)); );
     }
+
     delay(1); // One millisecond pause = latch
-    digitalWrite(SPI_LED, spi_out_led = !spi_out_led);
   }
+  digitalWrite(SPI_LED, spi_out_led = !spi_out_led);

   Serial.print("Ada\n"); // Send ACK string to host


Bugfix to set correct mode, when "off"

Bugfix to set correct mode, when "off"

https://github.com/toblum/McLighting/issues/9

--- Arduino/McLighting/McLighting.ino
+++ Arduino/McLighting/McLighting.ino
@@ -360,7 +360,7 @@
   if (mode == OFF) {
     strip.setColor(0,0,0);
     strip.setMode(FX_MODE_STATIC);
-    mode = HOLD;
+    // mode = HOLD;
   }
   if (mode == ALL) {
     strip.setColor(main_color.red, main_color.green, main_color.blue);


reduce excess newlines. fix header

reduce excess newlines. fix header

--- examples/GPS_HardwareSerial_Parsing/GPS_HardwareSerial_Parsing.ino
+++ examples/GPS_HardwareSerial_Parsing/GPS_HardwareSerial_Parsing.ino
@@ -36,7 +36,7 @@
   // connect at 115200 so we can read the GPS fast enough and echo without dropping chars
   // also spit it out
   Serial.begin(115200);
-  Serial.println("Adafruit GPS library basic test!");
+  Serial.println("Adafruit GPS library basic parsing test!");

   // 9600 NMEA is the default baud rate for Adafruit MTK GPS's- some use 4800
   GPS.begin(9600);
@@ -72,7 +72,7 @@
     // a tricky thing here is if we print the NMEA sentence, or data
     // we end up not listening and catching other sentences!
     // so be very wary if using OUTPUT_ALLDATA and trying to print out data
-    Serial.println(GPS.lastNMEA()); // this also sets the newNMEAreceived() flag to false
+    Serial.print(GPS.lastNMEA()); // this also sets the newNMEAreceived() flag to false
     if (!GPS.parse(GPS.lastNMEA())) // this also sets the newNMEAreceived() flag to false
       return; // we can fail to parse a sentence in which case we should just wait for another
   }
@@ -110,4 +110,4 @@
       Serial.print("Satellites: "); Serial.println((int)GPS.satellites);
     }
   }
-}
+}


added reader code for the mains current sensor

--- ardesp/waterelf/waterelf.ino
+++ ardesp/waterelf/waterelf.ino
@@ -12,6 +12,7 @@
 #include <Adafruit_TSL2591.h>
 #include <RCSwitch.h>
 #include "Adafruit_MCP23008.h"
+#include "EmonLib.h" // Emon Library, see openenergymonitor.org

 /////////////////////////////////////////////////////////////////////////////
 // resource management stuff ////////////////////////////////////////////////
@@ -189,6 +190,7 @@
 String ANALOG_SENSOR_PRESSURE = "analog_pressure";
 String analogSensor = ANALOG_SENSOR_NONE;
 boolean GOT_ANALOG_SENSOR = false; // change later if we config a sensor
+EnergyMonitor emon1; // instance of energy monitor, for mains current sensor

 /////////////////////////////////////////////////////////////////////////////
 // valves and flow control //////////////////////////////////////////////////
@@ -846,12 +848,15 @@
     // tsl.setTiming(TSL2591_INTEGRATIONTIME_600MS); // longest (dim)
   }

-  //Wire.begin();
   Wire.beginTransmission(pH_Add);
   error = Wire.endTransmission();
   if(error==0){
     GOT_PH_SENSOR = true;
     dln(monitorDBG, "Found pH sensor");
+  }
+
+  if(GOT_ANALOG_SENSOR && analogSensor == "analog_mains") {
+    emon1.current(A0, 111.1); // current: input pin, calibration
   }
 }

@@ -1030,7 +1035,7 @@
   if(! GOT_ANALOG_SENSOR) {
     (*a) = 0.0;
   } else if(analogSensor == "analog_mains") {
-    (*a) = 1.0;
+    (*a) = (float) emon1.calcIrms(1480);
   } else if(analogSensor == "analog_pressure") {
     int analogValue = analogRead(A0);


calibrated for denny sys

calibrated for denny sys

--- ardesp/waterelf/waterelf.ino
+++ ardesp/waterelf/waterelf.ino
@@ -210,7 +210,7 @@
   // in beds with overflows can be 0; else will be cycle time minus fill time
   long startTime = -1;          // when to start cycling (after boot)
   bool gotOverflow = false;     // does the growbed have an overflow?
-  int fillLevel = 5;            // cms below the level sensor: drain point
+  int fillLevel = 10;           // cms below the level sensor: drain point
   bool filling = false;         // true when closed / on
   long lastFlip = -1;           // millis at last state change

@@ -266,7 +266,7 @@
 class FlowController { // the set of valves and their config ////////////////
   public:
   int numValves = 3;         // WARNING! call init if resetting!
-  int cycleMins = 6;//TODO   // how long is a flood/drain cycle?
+  int cycleMins = 21;        // how long is a flood/drain cycle?
   int maxSimultDrainers = 1; // how many beds can drain simultaneously?
   int minBedsWet = 1;        // min beds that are full or filling
   int maxBedsWet = 2;        // max beds that are full or filling


Fix keyword.txt

Fix keyword.txt

--- examples/tap/tap.ino
+++ examples/tap/tap.ino
@@ -2,22 +2,19 @@
 #include <Wire.h>

 void setup() {
-	initialize();
-
-	led1.on();
-	led1.color(10, 10, 0);
-	led2.off();
-	led1.color(20, 0, 20);
+  initialize();
 }

 void loop() {
-	if (accel.tap()) {
-		led1.randomcolor();
-	}
-
-	if (accel.doubletap()) {
-		led2.flip();
-	}
-
-	wait(200);
+  led2.on();
+  if (accel.doubletap()) {
+     led2.randomcolor();
+  }
+
+  if (accel.tap()) {
+    led1.on();
+  } else {
+    led1.off();
+  }
+  wait(20);
 };


Updated controller firmware

Updated controller firmware

In debug state. Currently, xbee command is being read and sent to
serial, but it intentionally being overwritten and forced into "forward"
position before the command is interpreted and converted to motor drive,
for debugging purposes.

Motor drive works, although left wheels spin in the opposite direction
of the right... currently full speed is 255 (which is the max), and turn
speed is about half of this, 125. Tested so far is forward position at
20 counts, 200 counts, and 255 counts.

Xbee receives command, but data sent via serial is "ascii adjusted",
i.e. printing 48 instead of 0, etc. Also, data being sent appears to
have a very long lag, more than 5s... not sure why...


Slå av radioen på rfduino etter 10 sek. Forsøk på å spare batteri

--- rfduino/Device0/Device0.ino
+++ rfduino/Device0/Device0.ino
@@ -2,6 +2,8 @@
 #include "OneButton.h"

 device_t role = DEVICE0;
+
+int gzllTimeout = 10000;

 int button_a = 5;
 int button_b = 6;
@@ -10,6 +12,9 @@
 OneButton buttonB(button_b, false);

 bool shouldSleep = false;
+
+bool gzllRunning = false;
+long gzllLastCommandTime = 0;

 void setup()
 {
@@ -24,9 +29,6 @@
   buttonB.attachDoubleClick(onDoubleClickB);
   buttonA.attachLongPressStop(onLongPressA);
   buttonB.attachLongPressStop(onLongPressB);
-
-  // start the GZLL stack
-  RFduinoGZLL.begin(role);

   resetAndSleep();
 }
@@ -76,8 +78,27 @@

 void sendToHost(int command)
 {
+  startGzll();
   RFduinoGZLL.sendToHost(command);
-  Serial.println("sent " + String(command));
+  // Serial.println("sent " + String(command));
+  gzllLastCommandTime = millis();
+  delay(10);
+}
+
+void startGzll()
+{
+  if(!gzllRunning){
+    gzllRunning = true;
+    RFduinoGZLL.begin(role);
+  }
+}
+
+void stopGzll()
+{
+  if(gzllRunning){
+    RFduinoGZLL.end();
+    gzllRunning = false;
+  }
 }

 void tick()
@@ -88,12 +109,24 @@

 void loop()
 {
+  // Hvis GZLL har kjrt lengre enn timeout, avslutt GZLL-stacken.
+  if(gzllLastCommandTime != 0 && (millis() - gzllLastCommandTime) > gzllTimeout){
+    stopGzll();
+  }
+
   tick();
+
   if (shouldSleep) {
-      delay(10); // Ekstra delay for aa forsikre seg at data blir sendt.
-      RFduino_ULPDelay(INFINITE);
-      shouldSleep = false;
+      // Hvis GZLL-stacken er paa, sov i 1 sek og sjekk s p nytt om stacken kan slaas av.
+      if(gzllRunning) {
+        RFduino_ULPDelay(1000);
+      }
+      else {
+        RFduino_ULPDelay(INFINITE);
+        shouldSleep = false;
+      }
   }
+
   delay(10); // Kan ikke kalle tick for ofte...
 }


04 #kidSerie - Arduino + HC06 + MIT App Inventor 2 + Sliding Leds

04 #kidSerie - Arduino + HC06 + MIT App Inventor 2 + Sliding Leds

--- _04_kidSerie_sketch_01_bluetooth_SlidingLeds.ino
+++ _04_kidSerie_sketch_01_bluetooth_SlidingLeds.ino
@@ -15,7 +15,7 @@
    MCU:       Arduino 1.6.12 - @16MHz       http://www.arduino.cc/
    IC Chip:   Bluetooth Datasheet - HC-06   https://goo.gl/s9ZcNC
    Connections:
-      See Official youtube channel vids:
+      See Official youtube channel vids: https://youtu.be/ze7X0j8DtBA
    Based on:   Control 5 leds using arduino and app inventor.
                https://youtu.be/8CjL5JB6YfI
    Code by Mohamed Aly


adding support for A5 edge case

adding support for A5 edge case

--- Arduino/Arduino.ino
+++ Arduino/Arduino.ino
@@ -30,24 +30,41 @@
 {
     int msg_len = getAndroidMessage();

-    if (msg_len != 2)
+    if (msg_len != 2 && msg_len != 1)
     {
         // TODO: ERROR? HOW?
     }
     else
     {
-        /****************** Parse ******************/
-        // LeftDir(1) + LeftSpeed(3) + RightDir(1) + RightSpeed(3) + ArmDir(1) + ArmSpeed(3) + Knife(1) + Nitro(1) + Padding(2)
-        int LDir = (AndroidMessage[0] & 0x80) >> 7;
-        int LSpeed = (AndroidMessage[0] & 0x70) >> 4;
-        int RDir = (AndroidMessage[0] & 0x08) >> 3;
-        int RSpeed = (AndroidMessage[0] & 0x07) >> 0;
+        int index = 0;

-        int ADir = (AndroidMessage[1] & 0x80) >> 7;
-        int ASpeed = (AndroidMessage[1] & 0x70) >> 4;
-        int K = (AndroidMessage[1] & 0x08) >> 3;
-        int N = (AndroidMessage[1] & 0x04) >> 2;
-        int Padding = (AndroidMessage[1] & 0x03) >> 0;
+        int LDir, LSpeed, RDir, RSpeed;
+
+        // Special case of A5 in first byte
+        if (msg_len == 1)
+        {
+            LDir = 1;
+            LSpeed = 2;
+            RDir = 0;
+            RSpeed = 5;
+        }
+        else
+        {
+            /****************** Parse ******************/
+            // LeftDir(1) + LeftSpeed(3) + RightDir(1) + RightSpeed(3) + ArmDir(1) + ArmSpeed(3) + Knife(1) + Nitro(1) + Padding(2)
+            LDir = (AndroidMessage[0] & 0x80) >> 7;
+            LSpeed = (AndroidMessage[0] & 0x70) >> 4;
+            RDir = (AndroidMessage[0] & 0x08) >> 3;
+            RSpeed = (AndroidMessage[0] & 0x07) >> 0;
+
+            index += 1;
+        }
+
+        int ADir = (AndroidMessage[index] & 0x80) >> 7;
+        int ASpeed = (AndroidMessage[index] & 0x70) >> 4;
+        int K = (AndroidMessage[index] & 0x08) >> 3;
+        int N = (AndroidMessage[index] & 0x04) >> 2;
+        int Padding = (AndroidMessage[index] & 0x03) >> 0;

         /****************** Handle ******************/
         Mvmnt.MoveWheel(LeftWheel, WheelSpeeds[LSpeed], (LDir*2)-1);


Update the servo reading procedure to increase efficiency

--- Arduino/Arduino.ino
+++ Arduino/Arduino.ino
@@ -25,8 +25,8 @@

 char statusReport = 'A'; // one-byte status report to controller

-bool sensorReportingOn = false;
-bool fligthRecorderOn = false;
+bool sensorReportingOn = false;   // stores whether the sensor reporting feature is on
+bool flightRecorderOn = false;    // stores whether the Arduino should record flight data

 bool batteryLow = false;
 bool batteryOk = true;
@@ -37,8 +37,9 @@

 // CONSTANTS

-const int LOOP_DELAY = 100;
+const int LOOP_DELAY = 100;       // Delay of the loop cycle in milliseconds

+//   Pins
 const int LED_PIN = 5;
 const int THROTTLE_PIN = 9;
 const int FRONT_PIN = 10;
@@ -82,10 +83,11 @@
   // Get information from Serial
   if( Serial.available() > 0 )
   {
+    // Loop through all bytes available
+    char Read = '0';
     for ( int currentByte = 0; currentByte < Serial.available(); currentByte++ )
     {
-      char Read = Serial.read();
-      int newPosition = 0;
+      Read = Serial.read();
       switch (Read)
       {
         // CONTROL SERVOS
@@ -149,15 +151,20 @@
   leftRight.write(pos4);
   upDown.write(pos5);

-  // Send information to Serial
+  // Send status to Serial
   Serial.write(statusReport);
-  Serial.write(pos1);
-  Serial.write(pos2);
-  Serial.write(pos3);
-  Serial.write(pos4);
-  Serial.write(pos5);

-
+  // Send sensor data to serial
+  if ( sensorReportingOn )
+  {
+    // Nothing here yet
+  }
+
+  // Record flight data
+  if ( flightRecorderOn )
+  {
+    // Nothing here yet
+  }

   // Update LEDs
   // Nothing here yet


don't send if it's target exp msg

don't send if it's target exp msg

--- glass/glass.ino
+++ glass/glass.ino
@@ -145,9 +145,15 @@
     delay(10);
     DEBUG_PRINT("[XBee]: ");
     readStringfromSerial(&XBee, message);
-    DEBUG_PRINT("[BT]: send ");
-    DEBUG_PRINTLN(message);
-    BT.println(message);
+
+    if(message[6] == 'T' && message[7] == 'A' && message[8] == 'R') {
+      //if ends with TAR => target experiment msg, no need to send to Glass
+    } else {
+      DEBUG_PRINT("[BT]: send ");
+      DEBUG_PRINTLN(message);
+      BT.println(message);
+
+    }
   }
   delay(10);
 }


Arms now move simultaneously

Arms now move simultaneously

--- serialmovements/serialmovements.ino
+++ serialmovements/serialmovements.ino
@@ -1,86 +1,45 @@
-#include <Wire.h>
-#include <Adafruit_MotorShield.h>
-#include "utility/Adafruit_MS_PWMServoDriver.h"
+#include<Servo.h>

-Adafruit_MotorShield AFMS = Adafruit_MotorShield();
-Adafruit_DCMotor *arm1 = AFMS.getMotor(1);
-Adafruit_DCMotor *legs = AFMS.getMotor(2);
-Adafruit_DCMotor *arm2 = AFMS.getMotor(3);
+Servo arm1;
+Servo arm2;
+Servo leg1;
+Servo leg2;

-
-unsigned long lastMillis = 0;
-unsigned long currentMillis = 0;
-
 String cmd = "";
+int pos = 0;
+int pos2 = 0;

 void setup () {
   // start serial communication.
   Serial.begin (9600);
-
-  AFMS.begin();  // create with the default frequency 1.6KHz

-//  arm1->setSpeed(50);
-//  arms->run(FORWARD);
-//  // turn on motor
-//  arms->run(RELEASE);
+  arm1.attach(9);
+  arm2.attach(10);

-  arm2->setSpeed(50);
-//  leg1->run(FORWARD);
-//  // turn on motor
-//  leg2->run(RELEASE);
-
-  legs->setSpeed(50);
-//  leg2->run(FORWARD);
-//  // turn on motor
-//  leg2->run(RELEASE);

 }

-// loop the main sketch.
 void loop () {
+  arm1.write(0);
+  arm2.write(0);

-  while(Serial.available()>0) {
+  while(Serial.available()>0) {
     char input = Serial.read();
     cmd.concat(input);
   }
-//    Serial.println(cmd);
-
-    Serial.print("Last");
-    Serial.println(lastMillis);

     if (cmd == "walk") {
-//      arm1->run(FORWARD);
-      arm2->run(FORWARD);
-      currentMillis = millis();
-      Serial.println(currentMillis);
-
-      if (currentMillis - lastMillis > 500){
-//        arm1->run(RELEASE);
-        arm2->run(RELEASE);
-        Serial.println("rewind");
+      armswing(arm1,arm2);
+    }
+}
+
+void armswing(Servo servo1, Servo servo2) {
+      for (pos = 0; pos <= 180; pos += 1) { // goes from 0 degrees to 180 degrees
+          servo1.write(pos);
+          servo2.write(pos);
+          delay(15);
+
       }
+}

-      currentMillis = millis();
-      if (currentMillis - lastMillis > 500) {
-//        arm1->run(BACKWARD);
-        arm2->run(BACKWARD);
-
-        Serial.println("stop walk");
-
-        lastMillis = currentMillis;
-
-      }
-
-
-
-
-
-
-
-
-
-
-  }
-
-}


Theoretically in a state of finishment

Theoretically in a state of finishment

--- src/arduino/RoomControl.ino
+++ src/arduino/RoomControl.ino
@@ -31,7 +31,6 @@
 }

 void testCmd(Vector<char*> args) {
-  debug.debug("Running test command");
   String argsStr = "";
   for (int i = 0; i < args.size(); i++) {
       argsStr += args[i];
@@ -53,7 +52,7 @@

   debug.begin(Debug::DEBUG, BITRATE);

-  raspi.begin(DOG_SIGNATURE, Debug::DEBUG, DOG_DEBUG_PREFIX);
+  raspi.begin(DOG_SIGNATURE, Debug::INFO, DOG_DEBUG_PREFIX);
   raspi.registerCommand("lights", lightsCmd);
   raspi.registerCommand("test", testCmd);

@@ -76,5 +75,4 @@
   } else {
     digitalWrite(LEDPIN, LOW);
   }
-
 }


Added retries to send SMS and POST messages

--- rede-firmware.ino
+++ rede-firmware.ino
@@ -32,7 +32,9 @@

 #include "FreqCount.h"

-#define SEND_INTERVAL 60 // Interval between consecutive data sends (in seconds)
+// Interval between consecutive data sends (in seconds)
+#define SEND_INTERVAL 60
+#define NUM_RETRIES 5

 // Defines to enable or disable sensors
 #define HUMIDITY_SENSOR 0
@@ -190,13 +192,15 @@
 }

 void loop() {
+  int i;
+  boolean fona_enabled = false;
   if (time_elapsed >= SEND_INTERVAL) {
     time_elapsed = 0;
     // Get readings from weather shield.
     calc_sensors();

     // Enable fona
-    enable_fona();
+    fona_enabled = enable_fona();
     // Get time.
     fona.getTime(buffer+1, 25);

@@ -207,7 +211,7 @@
     buffer[1] = '0';
     int len = strlen(buffer);
     // Convert the date received to ISO format.
-    for (int i = 0; i < len; i++) {
+    for (i = 0; i < len; i++) {
       if (buffer[i] == '/')
         buffer[i] = '-';
       else if (buffer[i] == ',')
@@ -316,14 +320,30 @@
     Serial.print("Size: ");
     Serial.println(strlen(buffer));

+    if (!fona_enabled) {
+      fona_enabled = enable_fona();
+    }
+
     // Send message
-    if (!fona.sendSMS(destination, buffer)) {
+    for (i = 0; i < NUM_RETRIES; i++) {
+      if (fona.sendSMS(destination, buffer)) {
+        break;
+      }
+      delay(1000);
+    }
+    if (i >= NUM_RETRIES) {
       Serial.println(F("SMS failed"));
     } else {
       Serial.println(F("SMS sent!"));
     }

-    if (!send_http_post(http_post_url, id, buffer)) {
+    for (i = 0; i < NUM_RETRIES; i++) {
+      if (send_http_post(http_post_url, id, buffer)) {
+        break;
+      }
+      delay(1000);
+    }
+    if (i >= NUM_RETRIES) {
       Serial.println(F("HTTP POST Failed"));
     } else {
       Serial.println(F("HTTP POST Sent!"));
@@ -350,6 +370,7 @@

 boolean enable_fona() {
   // Set key pin to low
+  int i;
   pinMode(FONA_KEY, OUTPUT);
   digitalWrite(FONA_KEY, LOW);

@@ -358,7 +379,13 @@
   digitalWrite(FONA_EN_BAT, HIGH);

   // See if the FONA is responding
-  if (!fona.begin(Serial2)) {
+  for (i = 0; i < NUM_RETRIES; i++) {
+    if (fona.begin(Serial2)) {
+      break;
+    }
+    delay(1000);
+  }
+  if (i >= NUM_RETRIES) {
     Serial.println(F("FONA not found"));
     return false;
   }
@@ -371,10 +398,13 @@
   // We need to wait the initialization in order to enable GPRS
   // So...
   delay(10000);
-  for (int i = 0; i < 4 && !fona.enableGPRS(true); i++)
-  {
+  for (i = 0; i < NUM_RETRIES && !fona.enableGPRS(true); i++) {
     Serial.println("FONA GPRS not enabled!");
     delay(10000);
+  }
+  if (i >= NUM_RETRIES) {
+    Serial.println("Failed to enable GPRS!");
+    return false;
   }

   if (!fona.enableNetworkTimeSync(true)) {


Very simple reading of encoders

Very simple reading of encoders

--- Pianist/Pianist.ino
+++ Pianist/Pianist.ino
@@ -4,32 +4,76 @@
 short E2 = 6;
 short M2 = 7;

-short ST = 2;
+short ST = 8;
+
+#include <PinChangeInt.h> // necessary otherwise we get undefined reference errors.
+#include <AdaEncoder.h>
+
+int8_t clicks=0;
+long pos = 0;
+char id=0;
+
+char buf [20];

 signed int motorSpeed = 0;

-#include <Wire.h>
+#include <Encoder.h>
+
+Encoder encoder(10, 12);

 void setup()
 {
     Serial.begin(57600);
-    Wire.begin();
     pinMode(M1, OUTPUT);
     pinMode(M2, OUTPUT);
     pinMode(E1, OUTPUT);
     pinMode(E2, OUTPUT);
     pinMode(ST, INPUT);
+
+    AdaEncoder::addEncoder('a', 2, 3);
 }

 void loop()
 {
+  encoder *thisEncoder;
   Serial.println("Hallo Welt!.");
   delay(3000);
   Serial.println("Calibrating...");
   delay(3000);
   Calibrate();
   Serial.println("Done.");
-  while(true);
+
+  thisEncoder=AdaEncoder::genie(&clicks, &id);
+
+  int oldPos = 0;
+  while(true)
+  {
+    thisEncoder=AdaEncoder::genie(&clicks, &id);
+    if (thisEncoder != NULL) {
+      pos += clicks;
+      if (clicks != 0)
+      {
+        Serial.println(pos);
+      }
+    }
+  }
+
+    /*
+    int i = digitalRead(Enc1);
+    int j = digitalRead(Enc2);
+    sprintf(buf, "%d %d", i, j);
+    Serial.println(buf);
+    */
+
+   /*
+    int newPos = encoder.read();
+    if (newPos != oldPos)
+    {
+      Serial.println(newPos);
+      oldPos = newPos;
+    }
+    */
+  }
 }

 void Calibrate()
@@ -52,6 +96,7 @@
   {
     ;
   }
+  encoder.write(0);
   }
   SetMotorSpeed(0);
 }


optimized multisone

optimized multisone

--- multisone/multisone.ino
+++ multisone/multisone.ino
@@ -8,9 +8,9 @@
 #include <ros/time.h>
 #include <sensor_msgs/Range.h>

-#define sensNumber 3
-#define firstTrigPin 3
-#define firstEchoPin 9
+#define sensNumber 4
+#define firstTrigPin 2
+#define firstEchoPin 8

 ros::NodeHandle  nh;
@@ -18,8 +18,8 @@
 ros::Publisher pub_range( "/ultrasound", &range_msg);
 char frameid[] = "/ultrasound";

-int trigPin=firstTrigPin;
-int echoPin=firstEchoPin;
+ int trigPin=firstTrigPin;
+ int echoPin=firstEchoPin;

 void increasepins(){
   trigPin++;
@@ -55,13 +55,12 @@
   //publish the adc value every 50 milliseconds
   //since it takes that long for the sensor to stablize
      long duration, distance;
-  digitalWrite(trigPin, LOW);  // Added this line
   delayMicroseconds(2); // Added this line
   digitalWrite(trigPin, HIGH);
 //  delayMicroseconds(1000); - Removed this line
   delayMicroseconds(10); // Added this line
   digitalWrite(trigPin, LOW);
-  distance = pulseIn(echoPin, HIGH)/ 58.2;
+  distance = pulseIn(echoPin, HIGH,100000)/ 58.2; //change timeout value, increase for more range decrease for higher sample rate

     range_msg.range = distance;


Fixed buffer too small for api call '/api/status'.

--- webserver.ino
+++ webserver.ino
@@ -387,7 +387,7 @@

   server.on( "/api/status", []()
   {
-    char content[40];
+    char content[50];
     int charCount = 0;
     for ( uint8_t channelNumber = 0; channelNumber < NUMBER_OF_CHANNELS; channelNumber++ )
     {


Fixed some version control errors

Fixed some version control errors

I made a mistake using an incorrect version of the program, which
accidentally reverted some other changes.
It's all fixed now! And motor levels have been changed to a constant
array.

--- embedded/Crossfire_Program/Crossfire_Program.ino
+++ embedded/Crossfire_Program/Crossfire_Program.ino
@@ -1,360 +1,358 @@
-//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 100 //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
+
+#define motorLevel1 255 //PWM levls for the motors
+#define motorLevel2 255
+#define motorLevel3 255
+
+// 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,motorLevel1,motorLevel2,motorLevel3}; //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]); //Set the PWM signal
+    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);
+
+
+  //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);
+  }
+  else {
+    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
-}
-


Code cleanliness updates per A's suggestions

--- TimingController.ino
+++ TimingController.ino
@@ -79,6 +79,21 @@
   return 0;
 }

+
+//returns the run time of the current sequence (unsigned long)
+unsigned long sequencetime()
+{
+  unsigned long totaltime = 0;
+  for (byte i = 0; i < maxsteps; i++)  //quick calc the sequence time
+  {
+    totaltime += sequence[i][0];
+    if (sequence[i][1] == 0xff)
+      break;
+  }
+  return totaltime;
+}
+
+
 //load a saved sequence
 //takes in which sequence to load
 //returns the number of steps
@@ -139,12 +154,11 @@
   delay(50);
   Serial1.write("oller?\r\n");
   delay(50);
-  Serial1.write("ENT-> Yes  ESC-> No \r\n");
+  Serial1.write("ENT->Yes  Other-> No\r\n");
   Serial1.write(0x07);  //send bell character.
   Serial1.write(0x07);  //send bell character.
   Serial1.write(0x07);  //send bell character.
-//Clear off the input buffer
-  while (((Serial1.read()) != -1));
+  while (((Serial1.read()) != -1));  //Clear off the input buffer
   for (int i = 0; ((i < 10000) && (Serial1.available() == 0)); i++)
     delay(1);   //wait here until get a key, or timeout at 10sec
   if (Serial1.read() == ENTERkey)
@@ -442,12 +456,11 @@
   Serial1.write("?\r\n");
   Serial1.write("ENT-");
   delay(50);
-  Serial1.write("> Yes  ");
+  Serial1.write("> Yes ");
   delay(150);
-  Serial1.write("ESC-> No \r\n");
+  Serial1.write("Other-> No\r\n");
   delay(100);
-//Clear off the input buffer
-  while (((Serial1.read()) != -1));
+  while (((Serial1.read()) != -1));  //Clear off the input buffer
   for (int i = 0; ((i < 10000) && (Serial1.available() == 0)); i++)
     delay(1);   //wait here until get a key, or timeout at 10sec
   if (Serial1.read() == ENTERkey)
@@ -473,11 +486,10 @@
   Serial1.print(number);
   Serial1.write("?\r\n");
   delay(100);
-  Serial1.write("ENT-> Yes  ");
+  Serial1.write("ENT-> Yes ");
   delay(100);
-  Serial1.write("ESC-> No \r\n");
-//Clear off the input buffer
-  while (((Serial1.read()) != -1));
+  Serial1.write("Other-> No\r\n");
+  while (((Serial1.read()) != -1));  //Clear off the input buffer
   for (int i = 0; ((i < 10000) && (Serial1.available() == 0)); i++)
     delay(1);   //wait here until get a key, or timeout at 10sec
   if (Serial1.read() == ENTERkey)
@@ -1188,5 +1200,13 @@
   UpdateButtonLEDs(); //update button LEDs.
   delay(1);  //Small loop delay to support debounce.  This defines minimum debounce sample time.

-}
-
+ //need management of L/R button LEDs.
+ //Need test mode in order to test out hardware
+ //Then need lockout
+//testmode needs fixing/needs password
+//left/right button leds
+//need to add password at bootup
+//add pin change interrupt to left button so if it is realeased, turn off solenoid immediately.
+//need to confirm if delay can get messed up at loop of millis.
+//consider turning off trigger led when arm is disabled.
+}


Closes #4: Adding colors !!! Closes #5, now 2 colors merge when they encounter each other

--- _2048no/_2048no.ino
+++ _2048no/_2048no.ino
@@ -87,10 +87,40 @@

   switch (value) {
     case 2:
-      color = _matrix.Color(255, 0, 0);
+      color = _matrix.Color(237, 255, 209);
       break;
     case 4:
-      color = _matrix.Color(0, 255, 0);
+      color = _matrix.Color(255, 250, 114);
+      break;
+    case 8:
+      color = _matrix.Color(255, 229, 4);
+      break;
+    case 16:
+      color = _matrix.Color(255, 177, 0);
+      break;
+    case 32:
+      color = _matrix.Color(255, 110, 2);
+      break;
+    case 64:
+      color = _matrix.Color(255, 47, 0);
+      break;
+    case 128:
+      color = _matrix.Color(255, 0, 96);
+      break;
+    case 256:
+      color = _matrix.Color(206, 3, 255);
+      break;
+    case 512:
+      color = _matrix.Color(85, 26, 255);
+      break;
+    case 1024:
+      color = _matrix.Color(0, 136, 255);
+      break;
+    case 2048:
+      color = _matrix.Color(0, 246, 255);
+      break;
+    case 4096:
+      color = _matrix.Color(0, 255, 115);
       break;
     default:
       color = _matrix.Color(0, 0, 0);
@@ -141,6 +171,11 @@

     if ((_grid[pos] != 0) && (_grid[pos + nextFrame] == 0)) {
       _grid[pos + nextFrame] = _grid[pos];
+      _grid[pos] = 0;
+      hasMoved = true;
+    }
+    else if ((_grid[pos] != 0) && (_grid[pos] == _grid[pos + nextFrame])) {
+      _grid[pos + nextFrame] = _grid[pos] * 2;
       _grid[pos] = 0;
       hasMoved = true;
     }


Фикс рекурсии

Фикс рекурсии

--- main.ino
+++ main.ino
@@ -317,8 +317,6 @@
 	}
 }

-byte key_pressed(bool);
-
 bool sys_watch() {
 	if ((system_mode != SLEEP_MODE) && (bit_seted(btc_config.system_byte, AUTO_HEADLIGHT)) && (analog_to_byte(analogRead(LIGHT_SENSOR)) > btc_config.lux_light_on)) {	// Следилка за фарой
 		digitalWrite(HEADLIGHT, LOW);
@@ -340,7 +338,7 @@
 		return false;
 	}

-	if ((deep_sleep) && (key_pressed(false) == BUT_OK_SIGNAL)) {
+	if ((deep_sleep) && (analog_to_byte(analogRead(ACTION_BUTTON)) > (btc_config.button_ok_signal + 2)) && (analog_to_byte(analogRead(ACTION_BUTTON)) < (btc_config.button_ok_signal - 2))) {
 		return false;
 	}


Modified the default loopt times

Modified the default loopt times

--- photo_temp_sensor/PhotoTempSensor.ino
+++ photo_temp_sensor/PhotoTempSensor.ino
@@ -17,8 +17,8 @@
 double currentTempC = 0;
 int counter = 0;

-int LOOP_DELAY_MS = 2500; // 2.5 sec
-int FORCE_SEND_TEMP_INTERVAL_MS = 120000; // 2 min
+int LOOP_DELAY_MS = 5000; // 2.5 sec
+int FORCE_SEND_TEMP_INTERVAL_MS = 300000; // 5 min

 int TEMP_LOOP_CNT_THRESHOLD;

@@ -173,8 +173,10 @@
     double diff = currentTempC - celcius;
     if (abs_d(diff) > .5 || counter > TEMP_LOOP_CNT_THRESHOLD) {
       led.setColor(BLUE);
+
       Serial.print("Main> Sending current temp data to server.");
       Serial.printlnf("Previous temp: %f C, Current temp: %f C", currentTempC, celcius);
+
       currentTempC = celcius;
       if (! client.SendTemperatureData(celcius, fahrenheit)) {
         Serial.println("Main> Failed to send data to server, will try again next time");


All Responses Reliable

All Responses Reliable

Needs some commenting and code cleaning but it all works

--- Code/CodeVersion_1_27_2015/CodeVersion_1_27_2015.ino
+++ Code/CodeVersion_1_27_2015/CodeVersion_1_27_2015.ino
@@ -28,7 +28,7 @@
 Adafruit_NeoPixel strip = Adafruit_NeoPixel(PIXEL_COUNT, PIXEL_PIN, NEO_GRB + NEO_KHZ800);
 DHT dht(DHTPIN, DHTTYPE);
 TSL2561 tsl(TSL2561_ADDR_FLOAT);
-GSM gsmAccess;
+GSM gsmAccess(true);
 GSM_SMS sms;

 // Array to hold the number a SMS is retreived from
@@ -37,6 +37,7 @@

 void setup()
 {
+  Serial.begin(9600);
   pinMode( motorPin, OUTPUT); // Motor pin Setup
   strip.begin(); // Neopixel Setup
   strip.show(); // Initialize all pixels to 'off'
@@ -69,6 +70,7 @@
   char c;
   String inputcommand="";
   // Check for available SMS
+  delay(1000);
   if (sms.available())
   {

@@ -78,68 +80,61 @@
     // Read message bytes and print them
     while(c=sms.read())
       inputcommand+=c;
-
     sms.beginSMS(senderNumber);
-    delay(100);

     if(findWord("water",inputcommand)){
       colorWipe(strip.Color(0, 0, 255), 50);  // Blue
       activateWatering(motorPin,3);
       sms.print("Thanks for the drink!");
+      sms.endSMS();
     }
     else if(findWord("light",inputcommand)){
       colorWipe(strip.Color(0, 0, 0), 50);    // Black/off
       uint16_t x = tsl.getLuminosity(TSL2561_VISIBLE);
       String stringOne = "The lumosity is: " ;
       String stringThree = stringOne + x;
-      // Put code to activate motor pin here & blink light
-      //delay(200);
       sms.print(stringThree);
-      delay(400);
+      delay(1000);
+      sms.endSMS();
+      //delay(400);
     }
     else if(findWord("temp",inputcommand)){
+      colorWipe(strip.Color(0, 0, 0), 50);
       char buffer[10];
       float h = dht.readHumidity();
       float f = dht.readTemperature(true); // Read temperature as Fahrenheit
       String dht_stringOne = "The temp is: " ;
       String dht_stringThree = dht_stringOne + dtostrf(f, 5, 1, buffer);
-      sms.print(dht_stringThree);
-      colorWipe(strip.Color(0, 0, 0), 50);
-      delay(400);
+      sms.print(dht_stringThree);
+      delay(1000);
+      sms.endSMS();
     }

     else if(findWord("hello",inputcommand)){
+      colorWipe(strip.Color(255, 128, 255), 50);
       sms.print("Hello my name is Erb, lets grow some plants!");
-      colorWipe(strip.Color(255, 128, 255), 50);
-      delay(400);
+      //delay(1000);
+      sms.endSMS();

     }
     else if(findWord("error",inputcommand)){
+      colorWipe(strip.Color(255, 0, 0), 50);
       sms.print("You are experiencing an error....");
-      colorWipe(strip.Color(255, 0, 0), 50);
-      delay(400);
+      delay(1000);
+      sms.endSMS();
     }
     else {
+      colorWipe(strip.Color(255, 0, 0), 50);
+      //sms.beginSMS(senderNumber);
       sms.print("I dont know what that means :( ");
-      colorWipe(strip.Color(255, 0, 0), 50);
-      delay(400);
+      delay(1000);
+      sms.endSMS();
+
     }

-    // delay and send
-    //delay(250);
-    sms.endSMS();
-    delay(100);
+    sms.flush();

-    //Serial.print("After Text:");
-    //Serial.println(sms.ready())
-    //Serial.println("\nCOMPLETE!\n");
   }
-  //Serial.print("Before delay: ");
-  //Serial.println(sms.ready());
-  //delay(1000);
-  //Serial.print("After delay:");
-  //Serial.println(sms.ready());
-  sms.flush();
   }

@@ -183,6 +178,7 @@
     noTone(8);
   }
  }
+

 /* Initialization Notes


this is the main file

this is the main file

--- MyBlinkySketch/MyBlinkySketch.ino
+++ MyBlinkySketch/MyBlinkySketch.ino
@@ -35,7 +35,7 @@
 uint8_t brightnesSteps[brightnessCount] = {93,70,40,15,5,15,40,70,93};
 uint8_t currentBrightness;
 uint8_t lastBrightness;
-//
+
 // For fading in a new sketch
 long lastTime;


adjusted shake probability

adjusted shake probability

--- Pan_Tilt_laser/Pan_Tilt_laser.ino
+++ Pan_Tilt_laser/Pan_Tilt_laser.ino
@@ -88,7 +88,7 @@

   panTilt.updateAngles();

-  if(markovState(20, 80) == 2){
+  if(markovState(20, 70) == 2){
     shake();
   }


try to read data

try to read data

--- NFCReader/NFCReader.ino
+++ NFCReader/NFCReader.ino
@@ -1,34 +1,8 @@
-/**************************************************************************/
-/*!
-    @file     iso14443a_uid.pde
-    @author   Adafruit Industries
-    @license  BSD (see license.txt)
-
-    This example will attempt to connect to an ISO14443A
-    card or tag and retrieve some basic information about it
-    that can be used to determine what type of card it is.
-
-    Note that you need the baud rate to be 115200 because we need to print
-    out the data and read from the card at the same time!
-
-    This is an example sketch for the Adafruit PN532 NFC/RFID breakout boards
-    This library works with the Adafruit NFC breakout
-    ----> https://www.adafruit.com/products/364
-
-    Check out the links above for our tutorials and wiring diagrams
-    These chips use I2C to communicate, 4 pins required to interface:
-    SDA (I2C Data) and SCL (I2C Clock), IRQ and RESET (any digital line)
-
-    Adafruit invests time and resources providing this open source code,
-    please support Adafruit and open-source hardware by purchasing
-    products from Adafruit!
-*/
-/**************************************************************************/
 #include <Wire.h>
 #include <Adafruit_NFCShield_I2C.h>

 #define IRQ   (2)
-#define RESET (3)  // Not connected by default on the NFC Shield
+#define RESET (3)

 Adafruit_NFCShield_I2C nfc(IRQ, RESET);

@@ -52,7 +26,7 @@
   // Set the max number of retry attempts to read from a card
   // This prevents us from waiting forever for a card, which is
   // the default behaviour of the PN532.
-  nfc.setPassiveActivationRetries(0xFF);
+  //nfc.setPassiveActivationRetries(0xFF);

   // configure board to read RFID tags
   nfc.SAMConfig();
@@ -68,33 +42,26 @@
   // Wait for an ISO14443A type cards (Mifare, etc.).  When one is found
   // 'uid' will be populated with the UID, and uidLength will indicate
   // if the uid is 4 bytes (Mifare Classic) or 7 bytes (Mifare Ultralight)
-  success = nfc.readPassiveTargetID(PN532_MIFARE_ISO14443A, &uid[0], &uidLength);
+  success = nfc.readPassiveTargetID(PN532_MIFARE_ISO14443A, uid, &uidLength);

   if (success) {
     //Serial.println("Found a card!");
     //Serial.print("UID Length: ");Serial.print(uidLength, DEC);Serial.println(" bytes");
     //Serial.print("UID Value: ");
-    Serial.print("[");
-    for (uint8_t i=0; i < uidLength; i++)
-    {
-      //Serial.print(uid[i], HEX);
-      if (uid[i] < 16)
-      {
-        Serial.print("0");
-      }
-      Serial.print(uid[i], HEX);
-      if (i<uidLength-1)
-      {
-        Serial.print(':');
-      }
-    }
-    Serial.println("]");
+    nfc.PrintHex(uid, uidLength);
+    uint8_t keya[6] = { 0xD3, 0xF7, 0xD3, 0xF7, 0xD3, 0xF7 };
+    success = nfc.mifareclassic_AuthenticateBlock(uid, uidLength, 4, 0, keya);
+    //if (success)
+    //{
+    //  Serial.println("Authentication work");
+    //}
+    //uint8_t data[16];
+    uint8_t data[16];
+    success = nfc.mifareclassic_ReadDataBlock(4, data);
+    //success = nfc.mifareultralight_ReadPage (32, data);
+    nfc.PrintHexChar(data, 16);
     // Wait 1 second before continuing
-    //delay(5000);
+    delay(1000);
   }
-  //else
-  //{
-    // PN532 probably timed out waiting for a card
-    //Serial.println("Timed out waiting for a card");
-  //}
+
 }