Everything working except for adding push buttons

Made some major updates, everything working better than before.  Why?
Not sure exactly!  Seems like a loose USB cable could have been a major
culprit of earlier troubles (despite having used several different ones)

--- fourtwentyclock/fourtwentyclock.ino
+++ fourtwentyclock/fourtwentyclock.ino
@@ -11,67 +11,48 @@

 // Libraries
 #include "Adafruit_LEDBackpack.h"
-#include "Adafruit_NeoMatrix.h"
 #include "Adafruit_NeoPixel.h"
 #include "Adafruit_GFX.h"
 #include "Wire.h"
 #include "RTClib.h"
 #include "Pitches.h"

-//// Debouncing Items
+//// Smoothing Variables:
 //#define DEBOUNCE 10                           // # ms (5+ ms is usually plenty)
 //#define NUMBUTTONS sizeof(buttons)            // Macro determines size of array, by checking size
 //byte buttons[] = {2, 3, 4, 5, 12};            // Pins of buttons to be doubounced
 //byte down[NUMBUTTONS], pressed[NUMBUTTONS], released[NUMBUTTONS];
-//
-
-//// Input/Output Pins
-int brightKnob =      A3;      // 7-Sebment
+
+// Input/Output Pins
+int brightKnob =          A3;      // 7-Sebment
 //int minPlusButton =     2;       // Timekeeping
 //int minMinusButton =    3;       // Timekeeping
 //int hourPlusButton =    4;       // Timekeeping
 //int hourMinusButton =   5;       // Timekeeping
-int brightSwitch = 7;
-int reminderSwitchIn =  6;       // Switch: Reminder
-
-int piezoOut =          8;      // Speaker
-//int fourTwentyLED =     9;       // LED: Green
-int neoPixelPin =       10;       // RGB-LED: Green
-
-
-//// Variables
-int reminderState;               // Switch (Reminder)
-int noteCounter;                 // Counts theme music notes
-boolean running =        false;  // Colon ON/OFF
-
-//// Hour Adjustment Variables
+int reminderSwitch =      6;       // Switch: Reminder
+int brightSwitch =        7;
+int piezoOut =            8;       // Speaker
+int neoPixelPin =         10;      // RGB-LED: Green
+
+// Variables
+int reminderState;                 // Switch (Reminder)
+int noteCounter;                   // Counts theme music notes
+boolean running =        false;    // Colon ON/OFF
+int decimalTime;                   // Overall Clock Time
+long previousMillis;
+
+// Hour Adjustment Variables
 //int hourCount;                   // | > For manual time adjustment
 //int minuteCount;                 // | ^
 //int adjustedHour;                // | ^
 //int adjustedMinute;              // | ^
-//
-//
-//// Smoothing Variables:
-//const int numReadings =  12;      // Number of readings to use (speeds/slows)
-//int readings[numReadings];        // Readings from the analog input
-//int index = 0;                    // Index of the current reading
-//int total = 0;                    // Running total
-//int average = 0;                  // Final average
-
-int decimalTime;                 // Overall Clock Time
-long previousMillis;

 // Setup Components
 RTC_DS1307 RTC;
 Adafruit_7segment disp = Adafruit_7segment();
 Adafruit_AlphaNum4 alpha4 = Adafruit_AlphaNum4();
-//Adafruit_NeoPixel strip = Adafruit_NeoPixel(60, neoPixelPin, NEO_GRB + NEO_KHZ800);
-
-// Set Neopixel strip (TRYOUT)
-Adafruit_NeoMatrix matrix = Adafruit_NeoMatrix(5, 8, neoPixelPin,
-NEO_MATRIX_TOP + NEO_MATRIX_RIGHT +
-NEO_MATRIX_ROWS + NEO_MATRIX_PROGRESSIVE,
-NEO_GRB + NEO_KHZ800);
+Adafruit_NeoPixel strip = Adafruit_NeoPixel(60, neoPixelPin, NEO_GRB + NEO_KHZ800);
+

 // ================================================================================== //
 //                                  *** SETUP ***
@@ -79,21 +60,18 @@

 void setup()
 {
-  pinMode (brightKnob, INPUT);          // Potentiometer
-  pinMode (brightSwitch, INPUT);    // Reminder Switch
-
-  pinMode (reminderSwitchIn, INPUT);    // Reminder Switch
-  pinMode (piezoOut, OUTPUT);
-
+  pinMode (brightKnob, INPUT);              // Potentiometer
+  pinMode (brightSwitch, INPUT);            // Reminder Switch
+  pinMode (reminderSwitch, INPUT);        // Reminder Switch

   //  pinMode (minPlusButton, INPUT);       // Minute +
   //  pinMode (hourPlusButton, INPUT);      // Hour +
   //  pinMode (minMinusButton, INPUT);      // Minute -
   //  pinMode (hourMinusButton, INPUT);     // Hour -
-  //
-  //  pinMode (fourTwentyLED, OUTPUT);      // Green LED
-  pinMode (neoPixelPin, OUTPUT);         // Neopixel
-  //
+
+  pinMode (piezoOut, OUTPUT);
+  pinMode (neoPixelPin, OUTPUT);            // Neopixel
+
   //  // Debounce
   //  byte buttonCount;
   //  for (buttonCount = 0; buttonCount < NUMBUTTONS; buttonCount++)
@@ -109,8 +87,8 @@
   disp.begin(0x70);                                       // Start 7 Segment
   alpha4.begin(0x71);                                     // Start Alphanumeric

-  matrix.begin();                                          // Start Neopixel
-  matrix.show();                                           // Initialize all pixels to 'off'
+  strip.begin();                                          // Start Neopixel
+  strip.show();                                           // Initialize all pixels to 'off'
 }

@@ -123,19 +101,16 @@
   disp.print(getDecimalTime());          // Show 12-Hour Time (7 Segment)
   displayDay();                          // Show Weekday: 14 Segment
   blinkColon();                          // Blink Colon
-  //  smooth();                              // Averages photocell input values
   adjustBrightness();                    // Check Switch & Adjust brightness
   fourTwentyCheck();                     // Check if 4:20pm & Run Alarm
-  //reminderSwitch();                      // LED / Reminder
+  reminderSwitchCheck();                      // LED / Reminder
   //  debounceSwitches();                   // Debounce (check state of press)
- matrix.Color(100, 55, 23);
-      matrix.show();
+
 }

 // ================================================================================== //
 //                          *** MAIN CLOCK FUNCTIONS ***
 // ================================================================================== //
-

 int getDecimalTime()                                    // Calculate and Adjust Hours
 {
@@ -253,7 +228,7 @@
   }
   else
   {
-    matrix.setBrightness(neoBrightness);                           // Use Potentiometers to Set Brightness
+    strip.setBrightness(neoBrightness);                           // Use Potentiometers to Set Brightness
   }
 }

@@ -263,15 +238,14 @@
   int decimalTime = getDecimalTime();
   if (decimalTime == 420)
   {
+    fourTwentyWords();
+    disp.print(getDecimalTime());                      // Write time again, so 4:19 isn't displayed
     disp.blinkRate(2);
-    disp.print(getDecimalTime());                      // Write time again, so 4:19 isn't displayed
     disp.writeDisplay();
-    fourTwentyWords();
     themeMusic();
   }
   else
   {
-//    analogWrite(fourTwentyLED, 0);
     noTone(piezoOut);
     disp.blinkRate(0);
     alpha4.blinkRate(0);
@@ -281,24 +255,22 @@

 void fourTwentyWords()                                     // Writes "HIGH" & Blinks Alphanumeric Display
 {
-
-  char *message = "HIGH  TIME   ";
-    for (uint8_t i=0; i<strlen(message)-4; i++) {
+  char *message = "HIGH  TIME   HIGH  TIME   HIGH  TIME   ";
+  for (uint8_t i = 0; i < strlen(message) - 4; i++) {
     alpha4.writeDigitAscii(0, message[i]);
-    alpha4.writeDigitAscii(1, message[i+1]);
-    alpha4.writeDigitAscii(2, message[i+2]);
-    alpha4.writeDigitAscii(3, message[i+3]);
+    alpha4.writeDigitAscii(1, message[i + 1]);
+    alpha4.writeDigitAscii(2, message[i + 2]);
+    alpha4.writeDigitAscii(3, message[i + 3]);
     alpha4.writeDisplay();
-//    delay(200);
-  }
-//
-//  alpha4.blinkRate(2);
-//  alpha4.writeDigitAscii(0, 'H');
-//  alpha4.writeDigitAscii(1, 'I');
-//  alpha4.writeDigitAscii(2, 'G');
-//  alpha4.writeDigitAscii(3, 'H');
-//  alpha4.writeDisplay();
-//  alpha4.clear();
+    delay(200);
+    alpha4.clear();
+  }
+  alpha4.blinkRate(2);
+  alpha4.writeDigitAscii(0, 'H');
+  alpha4.writeDigitAscii(1, 'I');
+  alpha4.writeDigitAscii(2, 'G');
+  alpha4.writeDigitAscii(3, 'H');
+  alpha4.writeDisplay();
 }

@@ -308,21 +280,21 @@
 // ================================================================================== //

-void reminderSwitch()                                   // Checks Switch & Activates LED
-{
-  int reminderState = digitalRead(reminderSwitchIn);        // Check Reminder Switch
+void reminderSwitchCheck()                                   // Checks Switch & Activates LED
+{
+  int reminderState = digitalRead(reminderSwitch);        // Check Reminder Switch
   if (reminderState == 1) rainbowCycle(20);
   else
   {
-    matrix.setBrightness(0);                              // Turning off the shield requires...
-    matrix.show();                                        // ... both of these functions
+    strip.setBrightness(0);                              // Turning off the shield requires...
+    strip.show();                                        // ... both of these functions
   }
 }

 void beep(int note, int duration)                        // Creates Individual Notes & Alternates LED's
 {
-  long interval = 50;
+  long interval = 20;
   unsigned long currentMillis = millis();
   if (currentMillis - previousMillis > interval)
   {
@@ -331,13 +303,23 @@
     tone(piezoOut, note, duration);                          //Play tone on buzzerPin
     if (noteCounter % 2 == 0)                                // Alternate Green then UV LED's
     {
-    // Do something fun with neopixel here
-    delay(duration);
+      uint16_t j;
+      for (j = 0; j < 40 ; j++)
+      {
+        strip.setPixelColor(j, 189, 43, 215);    // Purple Color
+        strip.show();
+      }
+      delay(duration);
     }
     else
     {
-    // Do something fun with neopixel here
-    delay(duration);
+      uint16_t j;
+      for (j = 0; j < 40 ; j++)
+      {
+        strip.setPixelColor(j, 143, 230, 41);    // Green Color
+        strip.show();
+      }
+      delay(duration);
     }
     noTone(piezoOut);
     noteCounter++;
@@ -345,60 +327,46 @@
 }

-void rainbowCycle(uint8_t wait)                             // Runs rainbow led setup
+void rainbowCycle(uint8_t wait)                             // Runs rainbow led fade
 {
   uint16_t i, j;

-  for (j = 0; j < 256 ; j++)                                 // *1 cycles of all colors on wheel
-  {
-    for (i = 0; i < matrix.numPixels(); i++)
+  for (j = 0; j < 256 ; j++)
+  {
+    for (i = 0; i < strip.numPixels(); i++)
     {
-      matrix.setPixelColor(i, Wheel(((i * 256 / matrix.numPixels()) + j) & 255));
+      strip.setPixelColor(i, Wheel(((i * 256 / strip.numPixels()) + j) & 255));
     }
-    matrix.show();
+    strip.show();
     delay(wait);
   }
 }

-// Required for rainbowCycle()
+                                                              // Required for rainbowCycle()
 uint32_t Wheel(byte WheelPos)                                 // Colors transition r - g - b - r - g...
 {
   if (WheelPos < 85)
   {
-    return matrix.Color(WheelPos * 3, 255 - WheelPos * 3, 0);
+    return strip.Color(WheelPos * 3, 255 - WheelPos * 3, 0);
   }
   else if (WheelPos < 170)
   {
     WheelPos -= 85;
-    return matrix.Color(255 - WheelPos * 3, 0, WheelPos * 3);
+    return strip.Color(255 - WheelPos * 3, 0, WheelPos * 3);
   }
   else
   {
     WheelPos -= 170;
-    return matrix.Color(0, WheelPos * 3, 255 - WheelPos * 3);
-  }
-}
-
-
-//// ================================================================================== //
-////                             *** OTHER FUNCTIONS ***
-//// ================================================================================== //
-//
-//
-//void smooth()                                         // Averages photocell readings
-//{
-//  total = total - readings[index];                    // subtract the last reading
-//  readings[index] = analogRead(photoCellIn);          // read from the sensor
-//  total = total + readings[index];                    // add the reading to the total
-//  index = index + 1;                                  // advance to next position in array
-//  if (index >= numReadings) index = 0;                // if we're at the end of the array...
-//  average = total / numReadings;
-//
-//  autoBrightAverage = average;
-//
-//  delay(1);                                           // stability delay in between reads
-//}
-//
+    return strip.Color(0, WheelPos * 3, 255 - WheelPos * 3);
+  }
+}
+
+
+// ================================================================================== //
+//                             *** OTHER FUNCTIONS ***
+// ================================================================================== //
+
+
 //void debounceSwitches()
 //{
 //  for (byte i = 0; i < NUMBUTTONS; i++)


*INCOMPLETE* Smoother Motion

*INCOMPLETE* Smoother Motion

Updated moveArm and slowMoveArm to operate on a pulse length basis, each
movement now is split up into a finite number of movements determined by
max pulse length difference.

--- AL5D/al5d.ino
+++ AL5D/al5d.ino
@@ -157,6 +157,7 @@
 int     ret_val, g_moveDelay = 50; // g_moveDelay is defined at global scope and is used to control speed of arm
 char    buf[MAX_BUFFER+1];
 double   number[4], current[4], actual[4], g_angle_d[4];
+int      g_pulse[5];
 double   g_radius_mm, g_height_mm, g_hand_d, g_sliderPos;
 double   g_prevRadius_mm, g_prevHeight_mm, g_prevBase_d, g_prevHand_d;

@@ -189,17 +190,17 @@
 /* FUNCTIONS */
 /*************/
 // Moves arm to specified servo angles
-int moveArm( double basAngle_d, double shlAngle_d, double elbAngle_d, double wriAngle_d )
+int moveArm( int basPulse, int shlPulse, int elbPulse, int wriPulse )
 {
    int ret_val;

-   DEBUG("moveArm("); DEBUG(basAngle_d); DEBUG(","); DEBUG(shlAngle_d); DEBUG(","); DEBUG(elbAngle_d); DEBUG(","); DEBUG(wriAngle_d); DEBUGln(")");
+   DEBUG("moveArm("); DEBUG(basPulse); DEBUG(","); DEBUG(shlPulse); DEBUG(","); DEBUG(elbPulse); DEBUG(","); DEBUG(wriPulse); DEBUGln(")");

    //Drive servos
-   if ( ( ret_val = servoWrite( BAS, basAngle_d ) ) != 0 ) return ret_val;
-   if ( ( ret_val = servoWrite( SHL, shlAngle_d ) ) != 0 ) return ret_val;
-   if ( ( ret_val = servoWrite( ELB, elbAngle_d ) ) != 0 ) return ret_val;
-   if ( ( ret_val = servoWrite( WRI, wriAngle_d ) ) != 0 ) return ret_val;
+   if ( ( ret_val = servoWritePulse( BAS, basPulse ) ) != 0 ) return ret_val;
+   if ( ( ret_val = servoWritePulse( SHL, shlPulse ) ) != 0 ) return ret_val;
+   if ( ( ret_val = servoWritePulse( ELB, elbPulse ) ) != 0 ) return ret_val;
+   if ( ( ret_val = servoWritePulse( WRI, wriPulse ) ) != 0 ) return ret_val;

    delay(g_moveDelay);

@@ -212,36 +213,41 @@
    DEBUG("slowMoveArm("); DEBUG(basAngle_d); DEBUG(","); DEBUG(shlAngle_d); DEBUG(","); DEBUG(elbAngle_d); DEBUG(","); DEBUG(wriAngle_d); DEBUGln(")");

    int ret_val;
-   double bDiff = abs( basAngle_d - g_angle_d[BAS] );
-   double sDiff = abs( shlAngle_d - g_angle_d[SHL] );
-   double eDiff = abs( elbAngle_d - g_angle_d[ELB] );
-   double wDiff = abs( wriAngle_d - g_angle_d[WRI] );
-
-   double steps = max( bDiff, sDiff );
+
+   int basPulse = degToPulse( BAS, basAngle_d );
+   int shlPulse = degToPulse( SHL, shlAngle_d );
+   int elbPulse = degToPulse( ELB, elbAngle_d );
+   int wriPulse = degToPulse( WRI, wriAngle_d );
+
+   int bDiff = abs( basPulse - g_pulse[BAS] );
+   int sDiff = abs( shlPulse - g_pulse[SHL] );
+   int eDiff = abs( elbPulse - g_pulse[ELB] );
+   int wDiff = abs( wriPulse - g_pulse[WRI] );
+
+   int steps = max( bDiff, sDiff );
    steps = max( steps, eDiff );
    steps = max( steps, wDiff );
-   steps = round(steps);
    DEBUG("Steps: "); DEBUGln(steps);

    if( steps < 2 )
    {
-      ret_val = moveArm( basAngle_d, shlAngle_d, elbAngle_d, wriAngle_d );
+      ret_val = moveArm( basPulse, shlPulse, elbPulse, wriPulse );
    }
    else
    {
-      double bStep = (basAngle_d - g_angle_d[BAS])/steps;
-      double sStep = (shlAngle_d - g_angle_d[SHL])/steps;
-      double eStep = (elbAngle_d - g_angle_d[ELB])/steps;
-      double wStep = (wriAngle_d - g_angle_d[WRI])/steps;
+      double bStep = (double)(basPulse - g_pulse[BAS])/steps;
+      double sStep = (double)(shlPulse - g_pulse[SHL])/steps;
+      double eStep = (double)(elbPulse - g_pulse[ELB])/steps;
+      double wStep = (double)(wriPulse - g_pulse[WRI])/steps;

-      double bMove = g_angle_d[BAS] + bStep;
-      double sMove = g_angle_d[SHL] + sStep;
-      double eMove = g_angle_d[ELB] + eStep;
-      double wMove = g_angle_d[WRI] + wStep;
+      double bMove = g_pulse[BAS] + bStep;
+      double sMove = g_pulse[SHL] + sStep;
+      double eMove = g_pulse[ELB] + eStep;
+      double wMove = g_pulse[WRI] + wStep;

       for(int i=0; i<steps; i++)
       {
-         if( ( ret_val = moveArm( bMove, sMove, eMove, wMove ) ) != 0 ) break;
+         if( ( ret_val = moveArm( round(bMove), round(sMove), round(eMove), round(wMove) ) ) != 0 ) break;
          bMove += bStep; sMove += sStep; eMove += eStep; wMove += wStep;
       }
    }
@@ -460,8 +466,7 @@
    if ( id == 4 ) ret_val = servoWritePulse( id, (int) round(angle_d) );
    else
    {
-     int pulseLength = round(GRADIENT[id]*angle_d + OFFSET[id]);
-     ret_val = servoWritePulse( id, pulseLength );
+     ret_val = servoWritePulse( id, degToPulse( id, angle_d ) );
    }

    if (ret_val != 0 ) return ret_val;
@@ -474,11 +479,14 @@
 // Write to servo using pulse length
 int servoWritePulse( int id, int pulseLength)
 {
+  if ( pulseLength == g_pulse[id] ) return 0;
   if ( pulseLength < SERVO_MIN[id] ) { DEBUG("Pulse too small ("); DEBUG(pulseLength); DEBUG("<"); DEBUG(SERVO_MIN[id]); DEBUGln(")"); return -1; }
   if ( pulseLength > SERVO_MAX[id] ) { DEBUG("Pulse too large ("); DEBUG(pulseLength); DEBUG(">"); DEBUG(SERVO_MAX[id]); DEBUGln(")"); return -2; }

   pwm.setPWM(id, 0, pulseLength);

+  g_pulse[id] = pulseLength;
+
   DEBUG("pwm.setPWM("); DEBUG(id); DEBUG(", 0, "); DEBUG(pulseLength); DEBUGln(")");

   return 0;
@@ -487,13 +495,23 @@
 // Calculates the cylindrical coordinates of the wrist from the servo angles
 void calcPosition()
 {
-   double s = g_angle_d[SHL], e = g_angle_d[ELB] - 180, w = g_angle_d[WRI] - 180;
+   double s = pulseToDeg( SHL, g_pulse[SHL] ), e = pulseToDeg( ELB, g_pulse[ELB] ) - 180, w = pulseToDeg( WRI, g_pulse[WRI] ) - 180;

    g_radius_mm = HUMERUS*cos( radians(s) ) + ULNA*cos( radians(s + e) ) + HAND*cos( radians(s + e + w) );

    g_height_mm = BASE_HEIGHT + HUMERUS*sin( radians(s) ) + ULNA*sin( radians(s + e) ) + HAND*sin( radians(s + e + w) );

    DEBUG("g_radius_mm: "); DEBUG(g_radius_mm); DEBUG(", g_height_mm: "); DEBUGln(g_height_mm);
+}
+
+int degToPulse ( int id, double angle_d )
+{
+  return (int) round(GRADIENT[id]*angle_d + OFFSET[id]);
+}
+
+double pulseToDeg ( int id, int pulseLength )
+{
+  return ((double)pulseLength - OFFSET[id])/GRADIENT[id];
 }

 /*********/
@@ -520,9 +538,10 @@
    servoWrite( ELB, ELB_PARK );
    servoWrite( WRI, WRI_PARK );
    servoWrite( GRI, GRI_OPEN );
-   DEBUG("Robot parked: {"); DEBUG(g_angle_d[BAS]); DEBUG(","); DEBUG(g_angle_d[SHL]); DEBUG(","); DEBUG(g_angle_d[ELB]); DEBUG(","); DEBUG(g_angle_d[WRI]); DEBUGln(",delay}");
+   //DEBUG("Robot parked: ("); DEBUG(g_pulse[BAS]); DEBUG(","); DEBUG(g_pulse[SHL]); DEBUG(","); DEBUG(g_pulse[ELB]); DEBUG(","); DEBUG(g_pulse[WRI]); DEBUG(","); DEBUG(g_pulse[GRI]); DEBUGln(")");
+   DEBUG("Robot parked: {"); DEBUG(pulseToDeg( BAS, g_pulse[BAS] )); DEBUG(","); DEBUG(pulseToDeg( SHL, g_pulse[SHL] )); DEBUG(","); DEBUG(pulseToDeg( ELB, g_pulse[ELB] )); DEBUG(","); DEBUG(pulseToDeg( WRI, g_pulse[WRI] )); DEBUGln(",delay}");
    calcPosition();
-   DEBUG("Robot parked: <"); DEBUG(g_radius_mm); DEBUG(","); DEBUG(g_height_mm); DEBUG(","); DEBUG(g_angle_d[BAS]); DEBUG(","); DEBUG(g_hand_d); DEBUGln(",delay>");
+   DEBUG("Robot parked: <"); DEBUG(g_radius_mm); DEBUG(","); DEBUG(g_height_mm); DEBUG(","); DEBUG(pulseToDeg( BAS, g_pulse[BAS] )); DEBUG(","); DEBUG(g_hand_d); DEBUGln(",delay>");
    DEBUGln("Enter r to return robot to park position\n");
    //slide(LEFT,MAX_STEPS);


v1.3 -- analog signal for rain sensing

v1.3 -- analog signal for rain sensing

--- EM27cover.ino
+++ EM27cover.ino
@@ -19,6 +19,7 @@
 // f = Open cover and try to keep it open as much as possible
 // c = Close cover
 // ? = Report cover state (open/closed & rain)
+// v = toggle verbose mode
 //
 // Event feedback:
 // If the cover closes or opens, that is sent as "closing by request" or "closing by rain"
@@ -105,6 +106,11 @@
 // input for analog rain sensor (analog)
 #define MILLIVOLTS_PER_COUNT 4.8828
 // Conversion factor to get millivolts per DIO count
+#define RAIN_THRESHOLD_MV 2900
+// Threshold for rain (from 3300 mV for true full clear sky (open circuit))
+#define NUMPNTS 50
+// set number of points to average and calc standard deviation
+#define VERBOSE_DEFAULT false

 // Global variables

@@ -112,8 +118,12 @@
 int state = STATE_UNKNOWN;
 int requeststate = STATE_CLOSED;
 int last_state = STATE_UNKNOWN;
-int fault, condition;   // global
+int condition = COND_CLEAR;
+int fault = FAULT_NONE;
+int verbose_logging = VERBOSE_DEFAULT;
 float duration, rain_mv;
+int i;
+float rain_mv_sum, rain_mv_sumsqr, rain_mv_avg, rain_mv_std;

 AccelStepper stepper(AccelStepper::DRIVER, DPIN_STEP, DPIN_DIR);  // sets up 2-wire stepper driver

@@ -121,7 +131,10 @@
 void setup() {
   // Start serial for input / output
   Serial.begin(9600);
-  Serial.println("EM27Sun Cover Driver v1.2");
+  Serial.println("EM27Sun Cover Driver v1.3");
+  Serial.print("Rain threshold set at ");
+  Serial.print(RAIN_THRESHOLD_MV);
+  Serial.println("mV");
   // Set up for the Stepper motor
   stepper.setPinsInverted(true,false,true); // sets direction and enable pins inverted
   stepper.setMaxSpeed(USTEP_DIVISOR * STEP_SPEED);
@@ -167,9 +180,9 @@
 void loop() {
   // determine current state, condition, and fault
   state = determine_state();  // open/closed
-  condition = determine_cond(); // rain or not
+// next line removed because we are going to use analog rain triggering
+// condition = determine_cond(); // rain or not
   fault = determine_fault(); // check for motor fault
-  rain_mv = MILLIVOLTS_PER_COUNT * float(analogRead(APIN_RAIN));
   // print if there is a state change
   if (state != last_state) {
     if (state==STATE_OPENED) {
@@ -210,6 +223,16 @@
         break;
       case '?':
         report_state();
+        break;
+      case 'v':
+      case 'V':
+        verbose_logging = !verbose_logging;
+        if (verbose_logging) {
+          Serial.println("User requested verbose logging");
+        }
+        else {
+          Serial.println("Verbose logging is off");
+        }
         break;
       default:
         Serial.println("Command not recognized");
@@ -257,7 +280,35 @@
         break;  // do nothing
     }
   }
-  delay(1000); // 1Hz rep of main loop
+  // Poll rain sensor and determine average and standard deviation
+  i = 0;
+  rain_mv_sum = 0;
+  rain_mv_sumsqr = 0;
+  while(i<NUMPNTS) {
+    // read rain sensor analog input
+    rain_mv = MILLIVOLTS_PER_COUNT * float(analogRead(APIN_RAIN));
+    // sum the values
+    rain_mv_sum += rain_mv;
+    rain_mv_sumsqr += rain_mv*rain_mv;
+    i+=1;
+    delay(1000/NUMPNTS); // Polling the rain sensor every 1000ms / N
+  } // repeat loop for 1 second user interaction time
+  // calculate avg and standard deviation
+  rain_mv_avg = rain_mv_sum / float(NUMPNTS);
+  rain_mv_std = sqrt((1/float(NUMPNTS-1)) * (rain_mv_sumsqr - float(NUMPNTS)*rain_mv_avg*rain_mv_avg));
+  if (verbose_logging) {
+    Serial.print("Rainsensor avg = ");
+    Serial.print(rain_mv_avg);
+    Serial.print(" std = ");
+    Serial.print(rain_mv_std);
+    Serial.println(" mV");
+  }
+  if ((rain_mv_avg+2*rain_mv_std) < RAIN_THRESHOLD_MV) {
+    condition = COND_RAIN;
+  }
+  else {
+    condition = COND_CLEAR;
+  }
 }

 void report_state() {
@@ -280,11 +331,13 @@
       Serial.print("fault = driver in fault ");
   }
   if (condition == COND_RAIN){
-    Serial.print("condition = rain ");
+    Serial.print("condition = RAIN ");
   }
   Serial.print("Analog Rain Signal = ");
-  Serial.print(int(rain_mv));
-  Serial.println("mV");
+  Serial.print(int(rain_mv_avg));
+  Serial.print(" std = ");
+  Serial.print(rain_mv_std);
+  Serial.println(" mV");
 }

 int determine_state() {


disable compilation of ethernet related code

--- sketches/Energino/Energino.ino
+++ sketches/Energino/Energino.ino
@@ -55,6 +55,7 @@

 // comment/uncomment to disable/enable debug
 //#define DEBUG
+// comment/uncomment to disable/enable ethernet support
 #define NOETH

 #define RELAY_PIN 3
@@ -74,11 +75,6 @@
 // Cosm configuration
 IPAddress HOST(216,52,233,121);
 const long PORT = 80;
-
-// This configuration is used when DHCP fails
-IPAddress IP(172,25,18,219);
-IPAddress MASK(255,255,255,0);
-IPAddress GW(172,25,18,254);

 // Energino parameters
 int R1 = 100;
@@ -91,10 +87,6 @@
 char buffer[STRING_BUFFER_SIZE];
 char r[10];

-// Server configuration parameters, energino will listen for
-// incoming requests on this port
-const long SERVER_PORT = 8180;
-
 // Accumulators
 long VRaw;
 long IRaw;
@@ -107,22 +99,38 @@
 float VFinal = 0.0;
 float IFinal = 0.0;

-// Not found page
-const char CONTENT_404[] = "HTTP/1.1 404 Not Found\n\n";
-
-// Not implemented page
-const char CONTENT_501[] = "HTTP/1.1 501 Not Implemented\n\n";
-
-// JSON response header and footer
-const char JSON_RESPONSE_BEGIN[] = "HTTP/1.1 200 OK\nContent-Type: application/json\n\n[";
-const char JSON_RESPONSE_END[] = "]\n";
+#ifndef NOETH
+
+  // Server configuration parameters, energino will listen for
+  // incoming requests on this port
+  const long SERVER_PORT = 8180;
+
+  // This configuration is used when DHCP fails
+  IPAddress IP(172,25,18,219);
+  IPAddress MASK(255,255,255,0);
+  IPAddress GW(172,25,18,254);
+
+  // Not found page
+  const char CONTENT_404[] = "HTTP/1.1 404 Not Found\n\n";
+
+  // Not implemented page
+  const char CONTENT_501[] = "HTTP/1.1 501 Not Implemented\n\n";
+
+  // JSON response header and footer
+  const char JSON_RESPONSE_BEGIN[] = "HTTP/1.1 200 OK\nContent-Type: application/json\n\n[";
+  const char JSON_RESPONSE_END[] = "]\n";
+
+  // working vars
+  EthernetServer server(SERVER_PORT);
+
+  // Minimum period for Ethernet updates
+  const long MIN_ETHERNET_PERIOD = 2000;
+
+#endif

 // magic string
 const char MAGIC[] = "Energino";
 const int REVISION = 1;
-
-// Minimum period for Ethernet updates
-const long MIN_ETHERNET_PERIOD = 2000;

 // Permanent configuration
 struct settings_t {
@@ -137,11 +145,7 @@
   long feed;
   IPAddress host;
   long port;
-}
-settings;
-
-// working vars
-EthernetServer server(SERVER_PORT);
+} settings;

 void reset() {
   DBG Serial.println("Writing defaults.");
@@ -181,13 +185,13 @@
   }
   // set sleep counter
   resetSleep(settings.period);
-  // Print hw address
-  char macstr[18];
-  snprintf(macstr, 18, "%02x:%02x:%02x:%02x:%02x:%02x", settings.mac[0], settings.mac[1], settings.mac[2], settings.mac[3], settings.mac[4], settings.mac[5]);
-  DBG Serial.print("HWAddr: ");
-  DBG Serial.println(macstr);
-  // Try to configure the ethernet using DHCP
   #ifndef NOETH
+    // Print hw address
+    char macstr[18];
+    snprintf(macstr, 18, "%02x:%02x:%02x:%02x:%02x:%02x", settings.mac[0], settings.mac[1], settings.mac[2], settings.mac[3], settings.mac[4], settings.mac[5]);
+    DBG Serial.print("HWAddr: ");
+    DBG Serial.println(macstr);
+    // Try to configure the ethernet using DHCP
     delay(2000);
     DBG Serial.println("Running DHCP...");
     if (Ethernet.begin(settings.mac) == 0) {
@@ -206,6 +210,7 @@
 }

 void loop() {
+
   // Make sure that update period is not too high
   #ifndef NOETH
     if ((settings.feed != 0) && (settings.period < MIN_ETHERNET_PERIOD)) {
@@ -365,6 +370,8 @@
   }
   eeprom_write_block((const void*)&settings, (void*)0, sizeof(settings));
 }
+
+#ifndef NOETH

 // This method accepts HTTP requests in the form GET /<cmd>/<param>/[value]
 void handleRequests() {
@@ -513,6 +520,8 @@
   strcat (buffer,"]}");
 }

+#endif
+
 void dumpToSerial() {
   // Print data also on the serial
   Serial.print("#");


arduino: don't consume too much power.

arduino: don't consume too much power.

--- arduino/home_sensors/home_sensors.ino
+++ arduino/home_sensors/home_sensors.ino
@@ -64,6 +64,9 @@
     if (next_write < millis()) {
         write();
     }
+
+    /* Don't consume too much power */
+    delay(500);
 }

 /* Sends data to the Olimex through the serial */


Implemented new gradients and offsets

Implemented new gradients and offsets

Removed maximum and minimum angles and replaced with gradients and
offsets to save calculation time

--- AL5D/al5d.ino
+++ AL5D/al5d.ino
@@ -72,19 +72,17 @@
 #define ULNA 187.325        // elbow to wrist
 #define HAND 90.0           // wrist to gripper tip

-// Gradients and offsets used to adjust servo angles so that measured angles are closer to input
-// See C:\Users\loam\Documents\Darren\Servo Angles v2.ods for derivation
-#define BAS_GRADIENT 1.011
-#define SHL_GRADIENT 0.815
-#define ELB_GRADIENT -0.880 // Elbow servo moves opposite direction to others
-#define WRI_GRADIENT 1.052
-#define GRI_GRADIENT 1
-
-#define BAS_OFFSET 5
-#define SHL_OFFSET 13.968
-#define ELB_OFFSET 165.267 // Elbow servo moves opposite direction to others
-#define WRI_OFFSET -3.758
-#define GRI_OFFSET 0
+// Gradients and offsets used to convert desired angle to pulse length required for that angle
+// See AL5D Servo Calibration spreadsheet for derivation
+#define BAS_GRADIENT -2.478
+#define SHL_GRADIENT 2.001
+#define ELB_GRADIENT -2.312
+#define WRI_GRADIENT -2.672
+
+#define BAS_OFFSET 606
+#define SHL_OFFSET 186.836
+#define ELB_OFFSET 579.134
+#define WRI_OFFSET 615.516

 // Analog references for the centre voltage from accelerometers
 #define BAS_R_REF 0
@@ -98,10 +96,10 @@
 #define WRI_H_REF 362

 // Gripper positions
-#define GRI_OPEN 90
-#define GRI_MICROPLATE 150 //500 PulseLength
-#define GRI_MICROSLIDE 150 //500 PulseLength
-#define GRI_CLOSED 180
+#define GRI_OPEN 320
+#define GRI_MICROPLATE 500 //500 PulseLength
+#define GRI_MICROSLIDE 500 //500 PulseLength
+#define GRI_CLOSED 590

 // Directional definitions for controlling slider
 #define LEFT           LOW
@@ -121,25 +119,14 @@
 // want these to be as small/large as possible without hitting the hard stop
 // for max range. You'll have to tweak them as necessary to match the servos you
 // have!
-#define BAS_MIN_D  90   // this is the 'minimum' angle in base servo range, 0 = -y direction
-#define BAS_MAX_D  180 // this is the 'maximum' angle in base servo range, 180 = +y direction
-#define SHL_MIN_D  16   // 0 = horizontal in +x direction
-#define SHL_MAX_D  165.762 // 180 = horizontal in -x direction
-#define ELB_MIN_D  11.5385   // 0 = elbow closed
-#define ELB_MAX_D  180 // 180 = elbow open, ulna parallel to humerus
-#define WRI_MIN_D  43.125 // 0 = wrist closed
-#define WRI_MAX_D  180 // 180 = wrist open, hand parallel to ulna
-#define GRI_MIN_D  90 // 100 = gripper fully open
-#define GRI_MAX_D  180 // 180 = gripper fully closed
-
-#define BAS_MIN    383 // this is the pulse length count (out of 4096) that corresponds to BAS_MIN_D
-#define BAS_MAX    160 // this is the pulse length count (out of 4096) that corresponds to BAS_MAX_D
+#define BAS_MIN    160 // this is the pulse length count (out of 4096) that corresponds to BAS_MIN_D
+#define BAS_MAX    383 // this is the pulse length count (out of 4096) that corresponds to BAS_MAX_D
 #define SHL_MIN    200 // this is the pulse length count (out of 4096) that corresponds to SHL_MIN_D
 #define SHL_MAX    540 // this is the pulse length count (out of 4096) that corresponds to SHL_MAX_D //HS805BB 186-612
-#define ELB_MIN    540 // this is the pulse length count (out of 4096) that corresponds to ELB_MIN_D
-#define ELB_MAX    175 // this is the pulse length count (out of 4096) that corresponds to ELB_MAX_D
-#define WRI_MIN    500 // this is the pulse length count (out of 4096) that corresponds to WRI_MIN_D
-#define WRI_MAX    135 // this is the pulse length count (out of 4096) that corresponds to WRI_MAX_D
+#define ELB_MIN    160 // this is the pulse length count (out of 4096) that corresponds to ELB_MIN_D
+#define ELB_MAX    540 // this is the pulse length count (out of 4096) that corresponds to ELB_MAX_D
+#define WRI_MIN    130 // this is the pulse length count (out of 4096) that corresponds to WRI_MIN_D
+#define WRI_MAX    500 // this is the pulse length count (out of 4096) that corresponds to WRI_MAX_D
 #define GRI_MIN    320 // this is the pulse length count (out of 4096) that corresponds to GRI_MIN_D
 #define GRI_MAX    590 // this is the pulse length count (out of 4096) that corresponds to GRI_MAX_D
 //WRI 375 = 90
@@ -150,7 +137,7 @@
 #define BAS_PARK 90
 #define SHL_PARK 90
 #define ELB_PARK 180
-#define WRI_PARK 180
+#define WRI_PARK 90

 /*****************/
@@ -173,15 +160,13 @@
 double   g_radius_mm, g_height_mm, g_hand_d, g_sliderPos;
 double   g_prevRadius_mm, g_prevHeight_mm, g_prevBase_d, g_prevHand_d;

-const double gradient[] = {BAS_GRADIENT, SHL_GRADIENT, ELB_GRADIENT, WRI_GRADIENT, GRI_GRADIENT};
-const double offset[] = {BAS_OFFSET, SHL_OFFSET, ELB_OFFSET, WRI_OFFSET, GRI_OFFSET};
+const double GRADIENT[] = {BAS_GRADIENT, SHL_GRADIENT, ELB_GRADIENT, WRI_GRADIENT};
+const double OFFSET[] = {BAS_OFFSET, SHL_OFFSET, ELB_OFFSET, WRI_OFFSET};
 const double R_PIN[] = {BAS_R_PIN, SHL_R_PIN, ELB_R_PIN, WRI_R_PIN};
 const double H_PIN[] = {BAS_H_PIN, SHL_H_PIN, ELB_H_PIN, WRI_H_PIN};
 const double R_REF[] = {BAS_R_REF, SHL_R_REF, ELB_R_REF, WRI_R_REF};
 const double H_REF[] = {BAS_H_REF, SHL_H_REF, ELB_H_REF, WRI_H_REF};

-const double SERVO_MIN_D[] = {BAS_MIN_D, SHL_MIN_D, ELB_MIN_D, WRI_MIN_D, GRI_MIN_D};
-const double SERVO_MAX_D[] = {BAS_MAX_D, SHL_MAX_D, ELB_MAX_D, WRI_MAX_D, GRI_MAX_D};
 const double SERVO_MIN[] = {BAS_MIN, SHL_MIN, ELB_MIN, WRI_MIN, GRI_MIN};
 const double SERVO_MAX[] = {BAS_MAX, SHL_MAX, ELB_MAX, WRI_MAX, GRI_MAX};

@@ -222,7 +207,6 @@
 }

 // Moves the arm slowly to a new position, depending on the specified delay
-// If the last input angle is negative, the function will determine the wrist angle required to achieve horizontal position
 int slowMoveArm( double basAngle_d, double shlAngle_d, double elbAngle_d, double wriAngle_d )
 {
    DEBUG("slowMoveArm("); DEBUG(basAngle_d); DEBUG(","); DEBUG(shlAngle_d); DEBUG(","); DEBUG(elbAngle_d); DEBUG(","); DEBUG(wriAngle_d); DEBUGln(")");
@@ -471,10 +455,14 @@
    //if (angle_d < SERVO_MIN_D[id]) { DEBUG(angle_d); DEBUG("<"); DEBUGln(SERVO_MIN_D[id]); return -1; }
    //if (angle_d > SERVO_MAX_D[id]) { DEBUG(angle_d); DEBUG(">"); DEBUGln(SERVO_MAX_D[id]); return -2; }

-   double gradient = (SERVO_MAX[id]-SERVO_MIN[id])/(SERVO_MAX_D[id]-SERVO_MIN_D[id]);
-   double pulseLength = angle_d*gradient + SERVO_MIN[id] - gradient*SERVO_MIN_D[id];// + map(angle_d, SERVO_MIN_D[id], SERVO_MAX_D[id], SERVO_MIN[id], SERVO_MAX[id]);
-
-   int ret_val = servoWritePulse( id, pulseLength );
+   int ret_val;
+
+   if ( id == 4 ) ret_val = servoWritePulse( id, (int) round(angle_d) );
+   else
+   {
+     int pulseLength = round(GRADIENT[id]*angle_d + OFFSET[id]);
+     ret_val = servoWritePulse( id, pulseLength );
+   }

    if (ret_val != 0 ) return ret_val;

@@ -484,10 +472,10 @@
 }

 // Write to servo using pulse length
-int servoWritePulse( int id, double pulseLength)
-{
-  if (pulseLength < min(SERVO_MIN[id], SERVO_MAX[id])) { DEBUGln(min(SERVO_MIN[id], SERVO_MAX[id])); return -1; }
-  if (pulseLength > max(SERVO_MIN[id], SERVO_MAX[id])) { DEBUGln(max(SERVO_MIN[id], SERVO_MAX[id])); return -2; }
+int servoWritePulse( int id, int pulseLength)
+{
+  if ( pulseLength < SERVO_MIN[id] ) { DEBUG("Pulse too small ("); DEBUG(pulseLength); DEBUG("<"); DEBUG(SERVO_MIN[id]); DEBUGln(")"); return -1; }
+  if ( pulseLength > SERVO_MAX[id] ) { DEBUG("Pulse too large ("); DEBUG(pulseLength); DEBUG(">"); DEBUG(SERVO_MAX[id]); DEBUGln(")"); return -2; }

   pwm.setPWM(id, 0, pulseLength);

@@ -624,7 +612,7 @@
             buf[i] = '\0';
             number[0] = atof(buf);
             g_moveDelay = 50;
-            Serial.println(servoWritePulse(WRI, number[0]));
+            Serial.println(servoWrite(ELB, number[0]));
             //Serial.println(slowMoveArm(number[0],g_angle_d[SHL],g_angle_d[ELB],g_angle_d[WRI]));
             break;


moved state query from loop() to methd _bt_queryState call from within loop

--- Bluetooth.ino
+++ Bluetooth.ino
@@ -39,6 +39,7 @@
 }

 void bt_loop() {
+  bool stateChanged = false;
   int n = digitalRead(BT_GPIO2);
   if (n != gpio2) {
     uint32_t now = millis();
@@ -50,57 +51,63 @@
       if (now <= (lastHi2Lo+100)) {
         // last hi to lo transision is less than 150ms, this is a state change

-        if(!bt_sendCommand("Q", true, false))
-          return;
+        stateChanged = true;
+        _bt_queryState();

-        int lines = 1;
-        do {
-          char *line;
-          if ((line=bt_readLine.feed(&bt_serial))) {
-            bt_iap = line[1] & 0x01;
-            bt_spp = line[1] & 0x02;
-            bt_a2dp = line[1] & 0x04;
-            bt_hfp = line[1] & 0x08;
-
-            bt_state = line[3];
-            if (bt_state >= '0' && bt_state <= '9') {
-              bt_state = bt_state - '0';
-            } else if (bt_state >= 'a' && bt_state <= 'f') {
-              bt_state = bt_state - 'a' + 10;
-            } else if (bt_state >= 'A' && bt_state <= 'F') {
-              bt_state = bt_state - 'A' + 10;
-            } else bt_state = 0;
-
-            DEBUG_BT("BT> ");
-            DEBUG_BT(line);
-            DEBUG_BT("\n");
-            bt_dumpState();
-
-            if (line[1] != lastState[0] || bt_state != lastState[1]) {
-              lastState[0] = line[1];
-              lastState[1] = bt_state;
-              bt_stateChanged();
-            }
-
-            if (bt_a2dp && bt_shallPlay && bt_state != 'D')
-              bt_play();
-
-            if (--lines == 0)
-              break;
-          }
-          if (now + 1000 < millis()) {
-            Serial.println("Timeout requesting status");
-            return;
-          }
-        } while(1);
-
-        bt_exitCmdMode();
       }
     } else {
       // pin went lo
       lastHi2Lo = now;
     }
   }
+}
+
+void _bt_queryState() {
+  if(!bt_sendCommand("Q", true, false))
+    return;
+
+  int lines = 1;
+  do {
+    char *line;
+    if ((line=bt_readLine.feed(&bt_serial))) {
+      bt_iap = line[1] & 0x01;
+      bt_spp = line[1] & 0x02;
+      bt_a2dp = line[1] & 0x04;
+      bt_hfp = line[1] & 0x08;
+
+      bt_state = line[3];
+      if (bt_state >= '0' && bt_state <= '9') {
+        bt_state = bt_state - '0';
+      } else if (bt_state >= 'a' && bt_state <= 'f') {
+        bt_state = bt_state - 'a' + 10;
+      } else if (bt_state >= 'A' && bt_state <= 'F') {
+        bt_state = bt_state - 'A' + 10;
+      } else bt_state = 0;
+
+      DEBUG_BT("BT> ");
+      DEBUG_BT(line);
+      DEBUG_BT("\n");
+      bt_dumpState();
+
+      if (line[1] != lastState[0] || bt_state != lastState[1]) {
+        lastState[0] = line[1];
+        lastState[1] = bt_state;
+        bt_stateChanged();
+      }
+
+      if (bt_a2dp && bt_shallPlay && bt_state != 'D')
+        bt_play();
+
+      if (--lines == 0)
+        break;
+    }
+    if (now + 1000 < millis()) {
+      Serial.println("Timeout requesting status");
+      break;
+    }
+  } while(1);
+
+  bt_exitCmdMode();
 }

 bool _bt_assertA2dpStateCmd(uint8_t state, const char *cmd) {


adds nonblocking countdown timer algorithm in booth_controller.ino

Not tested yet

--- booth_controller/booth_controller.ino
+++ booth_controller/booth_controller.ino
@@ -14,12 +14,22 @@
 */
 LiquidCrystal lcd(12, 11, 5, 4, 3, 2);
 const char armingPin = 6;
-char armingButtonState = 0;
+char armingButtonState = LOW;
+
+// armed indicator led pin
+const char armedPin = 8;
+
+// user trigger button pin and state
+const char triggerPin = 7;
+char triggerState = LOW;

 // the controller must be armed by an I2C message before the user button will be
 // activated. Once armed the system cannot be armed again until after a
 // countdown and I2C send
 boolean systemArmed = false;
+
+// countdown timer = 5 seconds
+const unsigned long interval = 5000;

 void setup() {
   // start I2C slave
@@ -39,6 +49,12 @@
   * temporary
   */
   pinMode(armingPin, INPUT);
+
+  // set the armedPin to OUTPUT
+  pinMode(armedPin, OUTPUT);
+
+  // set the triggerPin to INPUT
+  pinMode(triggerPin, INPUT);
 }

 void loop() {
@@ -49,12 +65,19 @@
   if (armingButtonState == HIGH) {
     receiveData(1);
   }
+
+  triggerState = digitalRead(triggerPin);
+  if (triggerState == HIGH && systemArmed) {
+    systemArmed = false;
+    digitalWrite(armedPin, LOW);
+    countdown();
+  }
 }

 void receiveData(int numBytes) {
   if (!systemArmed) {
     systemArmed = true;
-
+    digitalWrite(armedPin, HIGH);
     /*
     * temporary
     */
@@ -66,3 +89,17 @@
 void sendData() {

 }
+
+// nonblocking countdown timer
+void countdown() {
+  long curr = millis();
+  long delta = millis() - curr;
+  while (interval - delta >= 0) {
+    /*
+    * temporary
+    */
+    lcd.setCursor(0,0);
+    lcd.print((interval - delta) / 1000);
+  }
+}
+


split Tone class in own files

split Tone class in own files

--- SoundTest.ino
+++ SoundTest.ino
@@ -1,64 +1,5 @@
-
 #define DEBUG 13
-
-//TODO: this class actually ignores overflows of long's.
-class Tone
-{
-private:
-    unsigned long frequency;
-    unsigned long playTime;
-    unsigned long delayTime;
-    unsigned long lastTime;
-    unsigned long startTime;
-    bool isHigh;
-    int pin;
-
-public:
-    Tone(int p)
-    {
-        pin = p;
-        pinMode(pin, OUTPUT);
-        pinMode(4, OUTPUT);
-        isHigh = false;
-    }
-
-    void setTone(unsigned int freq, unsigned long time)
-    {
-        frequency = freq;
-        playTime = time;
-        delayTime = (1e6 / 2) / freq; //half wave length because one wave is half time high and half time low
-        lastTime = micros();
-        startTime = lastTime;
-    }
-
-    void play()
-    {
-        unsigned long now = micros();
-        if(now < startTime + playTime)
-        {
-            if(now > lastTime + delayTime)
-            {
-                if(isHigh)
-                {
-                    isHigh = false;
-                    digitalWrite(pin, LOW);
-                }
-                else
-                {
-                    isHigh = true;
-                    digitalWrite(pin, HIGH);
-                }
-                lastTime = now;
-            }
-        }
-        else    //not playing - time is out
-        {
-            digitalWrite(pin, LOW);
-            isHigh = false;
-        }
-    }
-};
-
+#include "tone.h"

 void setup()
 {


mano_v0.7

--- mano_v0.7/mano_v0.7.ino
+++ mano_v0.7/mano_v0.7.ino
@@ -45,17 +45,18 @@
   if(Serial.available()>0){
     z = Serial.read();
   }
-  if(z=='a'){
-    allopened();
+  if(z=='a'){           //Send  char 'a' trough serial monitor for open hand
+    allopnd();
   }
-  else if(z == 's'){
+  else if(z == 's'){    //Send  char 's' trough serial monitor for close hand
     allclosed();
   }
-  else if(z == 'd'){
+  else if(z == 'd'){    //Send  char 'd' trough serial monitor for grip (index and thumb)
     indexthumb();
   }
 }

+//Close hand
 void allclosed(){
   pinkie.write(pinkieH);
   ring.write(ringH);
@@ -63,8 +64,9 @@
   index.write(indexH);
   thumb.write(thumbH);
 }
-
-void allopened(){
+
+//Open hand
+void allopnd(){
   pinkie.write(pinkieL);
   ring.write(ringL);
   middle.write(middleL);
@@ -72,6 +74,7 @@
   thumb.write(thumbL);
 }

+//Grip (index and thumb)
 void indexthumb(){
   pinkie.write(pinkieL);
   ring.write(ringL);


change types; replace sprintf by strcpy

change types; replace sprintf by strcpy

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

 char is_command_running;

-const char* firmware_version = "2019.05.02.0"; // year.month.day.build number
+const char* firmware_version = "2019.05.08.0"; // year.month.day.build number

 #define MAX_BUFFER_LENGTH 65

@@ -71,7 +71,7 @@

 	while (!Serial);
 	while (Serial.available() > 0)
-		char t = Serial.read();
+		Serial.read();

 	Serial.write("T#");// initialization is over; must check for T# string (which is the alive test)
 	Serial.flush();
@@ -157,56 +157,57 @@

 	if (tmp_str[i + 1] == 'M' || tmp_str[i + 1] == 'm') {
 		// move motor
-		int motor_index, num_steps;
+		uint8_t motor_index;
+		int num_steps;
 		int num_consumed;
-		int num_read = sscanf(tmp_str + i + 2, "%d%d%n", &motor_index, &num_steps, &num_consumed);
+		int num_read = sscanf(tmp_str + i + 2, "%hhu%d%n", &motor_index, &num_steps, &num_consumed);
 		if (num_read != 2) {
-			sprintf(tmp_serial_out, "E#");
+			strcpy(tmp_serial_out, "E#");
 			i += 2;
 			return;
 		}
-			steppers_controller.move_motor(motor_index, num_steps);
-			is_command_running = 1;
-			i += 2 + num_consumed;
+		steppers_controller.move_motor(motor_index, num_steps);
+		is_command_running = 1;
+		i += 2 + num_consumed;
 	}
 	else
 		if (tmp_str[i + 1] == 'D' || tmp_str[i + 1] == 'd') {
 			// disable motor
-			int motor_index;
-			int num_read = sscanf(tmp_str + i + 2, "%d", &motor_index);
+			uint8_t motor_index;
+			int num_read = sscanf(tmp_str + i + 2, "%hhu", &motor_index);
 			if (num_read != 1) {
-				sprintf(tmp_serial_out, "E#");
+				strcpy(tmp_serial_out, "E#");
 				i += 2;
 				return;
 			}
-				steppers_controller.disable(motor_index);
-				sprintf(tmp_serial_out, "SD%d#", motor_index);
-				i += 4;
+			steppers_controller.disable(motor_index);
+			sprintf(tmp_serial_out, "SD%d#", motor_index);
+			i += 4;
 		}
 		else
 			if (tmp_str[i + 1] == 'L' || tmp_str[i + 1] == 'l') {
 				// locks motor
-				int motor_index;
-				int num_read = sscanf(tmp_str + i + 2, "%d", &motor_index);
+				uint8_t motor_index;
+				int num_read = sscanf(tmp_str + i + 2, "%hhu", &motor_index);
 				if (num_read != 1) {
-					sprintf(tmp_serial_out, "E#");
+					strcpy(tmp_serial_out, "E#");
 					i += 2;
 					return;
 				}
-					steppers_controller.lock(motor_index);
-					sprintf(tmp_serial_out, "SL%d#", motor_index);
-					i += 4;
+				steppers_controller.lock(motor_index);
+				sprintf(tmp_serial_out, "SL%d#", motor_index);
+				i += 4;

 			}
 			else
 				if (tmp_str[i + 1] == 'S' || tmp_str[i + 1] == 's') {
 					// stepper motor speed and acceleration
-					int motor_index;
+					uint8_t motor_index;
 					int motor_speed, motor_acceleration;
 					int num_consumed;
-					int num_read = sscanf(tmp_str + i + 2, "%d%d%d%n", &motor_index, &motor_speed, &motor_acceleration, &num_consumed);
+					int num_read = sscanf(tmp_str + i + 2, "%hhu%d%d%n", &motor_index, &motor_speed, &motor_acceleration, &num_consumed);
 					if (num_read != 3) {
-						sprintf(tmp_serial_out, "E#");
+						strcpy(tmp_serial_out, "E#");
 						i += 2;
 						return;
 					}
@@ -218,11 +219,11 @@
 				else
 					if (tmp_str[i + 1] == 'H' || tmp_str[i + 1] == 'h') {
 						// home
-						int motor_index;
+						uint8_t motor_index;
 						int num_consumed;
-						int num_read = sscanf(tmp_str + i + 2, "%d%n", &motor_index, &num_consumed);
+						int num_read = sscanf(tmp_str + i + 2, "%hhu%n", &motor_index, &num_consumed);
 						if (num_read != 1) {
-							sprintf(tmp_serial_out, "E#");
+							strcpy(tmp_serial_out, "E#");
 							i += 2;
 							return;
 						}
@@ -237,11 +238,12 @@
 					else
 						if (tmp_str[i + 1] == 'G' || tmp_str[i + 1] == 'g') {
 							// move motor to sensor position
-							int motor_index, sensor_position;
+							uint8_t motor_index;
+								int sensor_position;
 							int num_consumed;
-							int num_read = sscanf(tmp_str + i + 2, "%d%d%n", &motor_index, &sensor_position, &num_consumed);
+							int num_read = sscanf(tmp_str + i + 2, "%hhu%d%n", &motor_index, &sensor_position, &num_consumed);
 							if (num_read != 2) {
-								sprintf(tmp_serial_out, "E#");
+								strcpy(tmp_serial_out, "E#");
 								i += 2;
 								return;
 							}
@@ -256,17 +258,17 @@
 						else
 							if (tmp_str[i + 1] == 'T' || tmp_str[i + 1] == 't') {
 								// stop
-								int motor_index;
+								uint8_t motor_index;
 								int num_consumed;
-								int num_read = sscanf(tmp_str + i + 2, "%d%n", &motor_index, &num_consumed);
+								int num_read = sscanf(tmp_str + i + 2, "%hhu%n", &motor_index, &num_consumed);
 								if (num_read != 1) {
-									sprintf(tmp_serial_out, "E#");
+									strcpy(tmp_serial_out, "E#");
 									i += 1;
 									return;
 								}
-									steppers_controller.stop(motor_index);
-									sprintf(tmp_serial_out, "ST%d#", motor_index);
-									i += 4;
+								steppers_controller.stop(motor_index);
+								sprintf(tmp_serial_out, "ST%d#", motor_index);
+								i += 4;

 							}
 							else
@@ -308,11 +310,12 @@

 	if (tmp_str[i + 1] == 'M' || tmp_str[i + 1] == 'm') {
 		// move motor
-		int motor_index, position;
+		uint8_t motor_index;
+			int position;
 		int num_consumed;
-		int num_read = sscanf(tmp_str + i + 2, "%d%d%n", &motor_index, &position, &num_consumed);
+		int num_read = sscanf(tmp_str + i + 2, "%hhu%d%n", &motor_index, &position, &num_consumed);
 		if (num_read != 2) {
-			sprintf(tmp_serial_out, "E#");
+			strcpy(tmp_serial_out, "E#");
 			i += 1;
 			return;
 		}
@@ -341,7 +344,7 @@
 				int num_consumed;
 				int num_read = sscanf(tmp_str + i + 2, "%d%d%n", &motor_speed, &motor_acceleration, &num_consumed);
 				if (num_read != 2) {
-					sprintf(tmp_serial_out, "E#");
+					strcpy(tmp_serial_out, "E#");
 					i += 2;
 					return;
 				}
@@ -357,12 +360,12 @@
 {
 	tmp_serial_out[0] = 0;

-	int motor_index, num_sensors;
+	uint8_t motor_index, num_sensors;
 	char motor_type = tmp_str[i + 1];
-	int num_read = sscanf(tmp_str + i + 2, "%d%d", &motor_index, &num_sensors);
+	int num_read = sscanf(tmp_str + i + 2, "%hhu%hhu", &motor_index, &num_sensors);
 	// Serial.println(num_sensors);
 	if (num_read != 2) {
-		sprintf(tmp_serial_out, "E#");
+		strcpy(tmp_serial_out, "E#");
 		i += 2;
 		return;
 	}
@@ -381,14 +384,19 @@
 	int k = 0;
 	while (k < num_sensors) {
 		if (tmp_str[j] == 'P' || tmp_str[j] == 'p') {
-			int sensor_index;
+			uint8_t sensor_index;
 			int _low, _high, _home;
-			int _direction;
+			int8_t same_direction_as_motor;
 			int num_consumed;

-			int num_read = sscanf(tmp_str + j + 1, "%d%d%d%d%d%n", &sensor_index, &_low, &_high, &_home, &_direction, &num_consumed);
+			int num_read = sscanf(tmp_str + j + 1, "%hhu%d%d%d%hhd%n", &sensor_index, &_low, &_high, &_home, &same_direction_as_motor, &num_consumed);
+			if (num_read != 5) {
+				strcpy(tmp_serial_out, "E#");
+				i += 2;
+				return;
+			}
 			if (motor_type == 'S' || motor_type == 's') // attach to stepper motors controller
-				steppers_controller.add_sensor(motor_index, POTENTIOMETER, sensor_index, _low, _high, _home, _direction);
+				steppers_controller.add_sensor(motor_index, POTENTIOMETER, sensor_index, _low, _high, _home, same_direction_as_motor);
 			else
 #ifdef USE_TB6612FNG
 				if (motor_type == 'D' || motor_type == 'd') // attach to DC motors controller
@@ -399,10 +407,15 @@
 			k++;
 		}
 		else if (tmp_str[j] == 'B' || tmp_str[j] == 'b') {//buttons
-			int sensor_index;
-			int _direction;
+			uint8_t sensor_index;
+			int8_t _direction;
 			int num_consumed;
-			int num_read = sscanf(tmp_str + j + 1, "%d%d%n", &sensor_index, &_direction, &num_consumed);
+			int num_read = sscanf(tmp_str + j + 1, "%hhu%hhd%n", &sensor_index, &_direction, &num_consumed);
+			if (num_read != 2) {
+				strcpy(tmp_serial_out, "E#");
+				i += 2;
+				return;
+		}
 			if (motor_type == 'S' || motor_type == 's') // attach to stepper motors controller
 				steppers_controller.add_sensor(motor_index, BUTTON, sensor_index, 0, 0, 0, _direction);
 			else
@@ -416,8 +429,13 @@
 		}
 		else
 			if (tmp_str[j] == 'I' || tmp_str[j] == 'i') {// infrared
-				int sensor_index;
-				int num_read = sscanf(tmp_str + j + 1, "%d", &sensor_index);
+				uint8_t sensor_index;
+				int num_read = sscanf(tmp_str + j + 1, "%hhu", &sensor_index);
+				if (num_read != 1) {
+					strcpy(tmp_serial_out, "E#");
+					i += 2;
+					return;
+				}
 				if (motor_type == 'S' || motor_type == 's') // attach to stepper motors controller
 					steppers_controller.add_sensor(motor_index, INFRARED_ANALOG, sensor_index, 0, 0, 0, 0);
 				else
@@ -431,14 +449,19 @@
 			}
 			else
 				if (tmp_str[j] == 'A' || tmp_str[j] == 'a') {
-					int sensor_index;
+					uint8_t sensor_index;
 					int _low, _high, _home;
-					int _direction;
+					int8_t same_direction_as_motor;
 					int num_consumed;

-					int num_read = sscanf(tmp_str + j + 1, "%d%d%d%d%d%n", &sensor_index, &_low, &_high, &_home, &_direction, &num_consumed);
+					int num_read = sscanf(tmp_str + j + 1, "%hhu%d%d%d%hhd%n", &sensor_index, &_low, &_high, &_home, &same_direction_as_motor, &num_consumed);
+					if (num_read != 5) {
+						strcpy(tmp_serial_out, "E#");
+						i += 2;
+						return;
+					}
 					if (motor_type == 'S' || motor_type == 's') // attach to stepper motors controller
-						steppers_controller.add_sensor(motor_index, AS5147, sensor_index, _low, _high, _home, _direction);
+						steppers_controller.add_sensor(motor_index, AS5147, sensor_index, _low, _high, _home, same_direction_as_motor);
 					else
 #ifdef USE_TB6612FNG
 						if (motor_type == 'D' || motor_type == 'd') // attach to DC motors controller
@@ -461,11 +484,15 @@
 	tmp_serial_out[0] = 0;

 	if (tmp_str[i + 1] == 'S' || tmp_str[i + 1] == 's') { // gets stepper motor speed and acceleration num sensors attached
-		byte motor_index;
+		int8_t motor_index;
 		byte num_sensors_attached;
 		float motor_speed, motor_acceleration;
-		int num_read = sscanf(tmp_str + i + 2, "%u", &motor_index);
-		steppers_controller.get_speed_and_acceleration(motor_index, &motor_speed, &motor_acceleration);
+		int num_read = sscanf(tmp_str + i + 2, "%hhu", &motor_index);
+		if (num_read != 1) {
+			strcpy(tmp_serial_out, "E#");
+			i += 2;
+			return;
+		}		steppers_controller.get_speed_and_acceleration(motor_index, &motor_speed, &motor_acceleration);
 		num_sensors_attached = steppers_controller.get_num_attached_sensors(motor_index);
 		sprintf(tmp_serial_out, "GS%d %d %d %u#", motor_index, (int)motor_speed, (int)motor_acceleration, num_sensors_attached);
 		i += 4;
@@ -498,18 +525,28 @@
 			else
 #endif
 				if (tmp_str[i + 1] == 'U' || tmp_str[i + 1] == 'u') { // get ultrasound trig_pin echo_pin
-					int ultrasound_index;
+					uint8_t ultrasound_index;
 					byte trig_pin, echo_pin;
-					int num_read = sscanf(tmp_str + i + 2, "%d", &ultrasound_index);
+					int num_read = sscanf(tmp_str + i + 2, "%hhu", &ultrasound_index);
+					if (num_read != 1) {
+						strcpy(tmp_serial_out, "E#");
+						i += 2;
+						return;
+					}
 					ultrasonic_sensors_controller.get_sensor_pins(ultrasound_index, &trig_pin, &echo_pin);
 					sprintf(tmp_serial_out, "GU%d %u %u#", ultrasound_index, trig_pin, echo_pin);
 					i += 4;
 				}
 				else if (tmp_str[i + 1] == 'B' || tmp_str[i + 1] == 'b') { // get button pin direction
-					int button_index;
+					uint8_t button_index;
 					byte _pin;

-					int num_read = sscanf(tmp_str + i + 2, "%d", &button_index);
+					int num_read = sscanf(tmp_str + i + 2, "%hhu", &button_index);
+					if (num_read != 1) {
+						strcpy(tmp_serial_out, "E#");
+						i += 2;
+						return;
+					}
 					buttons_controller.get_params(button_index, &_pin);
 					sprintf(tmp_serial_out, "GB%d %u#", button_index, _pin);
 					i += 2;
@@ -523,8 +560,8 @@
 #ifdef USE_POTENTIOMETERS
 	// potentiometer
 	if (tmp_str[i + 1] == 'P' || tmp_str[i + 1] == 'p') {
-		int sensor_index;
-		int num_read = sscanf(tmp_str + i + 2, "%d", &sensor_index);
+		uint8_t sensor_index;
+		int num_read = sscanf(tmp_str + i + 2, "%hhu", &sensor_index);
 		int sensor_value = potentiometers_controller.get_position(sensor_index);
 		sprintf(tmp_serial_out, "P%d %d#", sensor_index, sensor_value);
 		i += 3;
@@ -533,8 +570,13 @@
 #endif
 		// AS5147
 		if (tmp_str[i + 1] == 'A' || tmp_str[i + 1] == 'a') {
-			int sensor_index;
-			int num_read = sscanf(tmp_str + i + 2, "%d", &sensor_index);
+			uint8_t sensor_index;
+			int num_read = sscanf(tmp_str + i + 2, "%hhu", &sensor_index);
+			if (num_read != 1) {
+				strcpy(tmp_serial_out, "E#");
+				i += 2;
+				return;
+			}
 			int sensor_value = as5147s_controller.get_position(sensor_index);
 			sprintf(tmp_serial_out, "RA%d %d#", sensor_index, sensor_value);
 			i += 3;
@@ -542,8 +584,13 @@
 		else
 			// button
 			if (tmp_str[i + 1] == 'B' || tmp_str[i + 1] == 'b') {
-				int sensor_index;
-				int num_read = sscanf(tmp_str + i + 2, "%d", &sensor_index);
+				uint8_t sensor_index;
+				int num_read = sscanf(tmp_str + i + 2, "%hhu", &sensor_index);
+				if (num_read != 1) {
+					strcpy(tmp_serial_out, "E#");
+					i += 2;
+					return;
+				}
 				// Serial.println(sensor_index);
 				int sensor_value = buttons_controller.get_state(sensor_index);
 				sprintf(tmp_serial_out, "RB%d %d#", sensor_index, sensor_value);
@@ -552,16 +599,26 @@
 			else
 				// ultrasonic
 				if (tmp_str[i + 1] == 'U' || tmp_str[i + 1] == 'u') {
-					int sensor_index;
-					int num_read = sscanf(tmp_str + i + 2, "%d", &sensor_index);
+					uint8_t sensor_index;
+					int num_read = sscanf(tmp_str + i + 2, "%hhu", &sensor_index);
+					if (num_read != 1) {
+						strcpy(tmp_serial_out, "E#");
+						i += 2;
+						return;
+					}
 					ultrasonic_sensors_controller.trigger(sensor_index);
 					i += 3;
 				}
 				else
 					// infrared
 					if (tmp_str[i + 1] == 'I' || tmp_str[i + 1] == 'i') {
-						int sensor_index;
-						int num_read = sscanf(tmp_str + i + 2, "%d", &sensor_index);
+						uint8_t sensor_index;
+						int num_read = sscanf(tmp_str + i + 2, "%hhu", &sensor_index);
+						if (num_read != 1) {
+							strcpy(tmp_serial_out, "E#");
+							i += 2;
+							return;
+						}
 						int sensor_value = infrared_analog_sensors_controller.get_signal_strength(sensor_index);
 						sprintf(tmp_serial_out, "RI%d %d#", sensor_index, sensor_value);
 						i += 3;
@@ -583,45 +640,65 @@
 {
 	if (!steppers_controller.is_running()) {
 		//stepper_motors_controller.delete_memory();
-		int num_motors = 0;
+		uint8_t num_motors = 0;

 		int num_consumed = 0;
-		int num_read = sscanf(tmp_str + i + 3, "%d%n", &num_motors, &num_consumed);
+		int num_read = sscanf(tmp_str + i + 3, "%hhu%n", &num_motors, &num_consumed);
+		if (num_read != 1) {
+			strcpy(tmp_serial_out, "E#");
+			i += 2;
+			return;
+		}

 		int total_num_consumed = 3 + num_consumed;
 		bool new_num_motors = steppers_controller.num_motors != num_motors;
 		steppers_controller.set_num_motors(num_motors);
 		for (int k = 0; k < num_motors; k++) {
-			int _step_pin, _dir_pin, _enable_pin;
-			int num_read = sscanf(tmp_str + i + total_num_consumed, "%d%d%d%n", &_dir_pin, &_step_pin, &_enable_pin, &num_consumed);
+			uint8_t _step_pin, _dir_pin, _enable_pin;
+			int num_read = sscanf(tmp_str + i + total_num_consumed, "%hhu%hhu%hhu%n", &_dir_pin, &_step_pin, &_enable_pin, &num_consumed);
+			if (num_read != 3) {
+				strcpy(tmp_serial_out, "E#");
+				i += 2;
+				return;
+			}
 			if (new_num_motors)
 				steppers_controller.set_pins(k, _dir_pin, _step_pin, _enable_pin);
 			total_num_consumed += num_consumed + 1;
 		}
 		steppers_controller.disable_all();
-		sprintf(tmp_serial_out, "CS#");
+		strcpy(tmp_serial_out, "CS#");
 		i += total_num_consumed;
 	}
 }
 //--------------------------------------------------
 void parse_and_execute_create_servo_motors_commands(char* tmp_str, byte str_length, byte &i, char *tmp_serial_out)
 {
-	int num_motors = 0;
+	uint8_t num_motors = 0;

 	int num_consumed = 0;
-	int num_read = sscanf(tmp_str + i + 3, "%d%n", &num_motors, &num_consumed);
+	int num_read = sscanf(tmp_str + i + 3, "%hhu%n", &num_motors, &num_consumed);
+	if (num_read != 1) {
+		strcpy(tmp_serial_out, "E#");
+		i += 2;
+		return;
+	}

 	int total_num_consumed = 3 + num_consumed;
 	bool new_num_motors = servos_controller.get_num_servos() != num_motors;
 	servos_controller.set_num_servos(num_motors);
 	for (int k = 0; k < num_motors; k++) {
-		int _pin;
-		int num_read = sscanf(tmp_str + i + total_num_consumed, "%d%n", &_pin, &num_consumed);
+		uint8_t _pin;
+		int num_read = sscanf(tmp_str + i + total_num_consumed, "%hhu%n", &_pin, &num_consumed);
+		if (num_read != 1) {
+			strcpy(tmp_serial_out, "E#");
+			i += 2;
+			return;
+		}
 		if (new_num_motors)
 			servos_controller.set_params(k, _pin);
 		total_num_consumed += num_consumed + 1;
 	}
-	sprintf(tmp_serial_out, "CV#");
+	strcpy(tmp_serial_out, "CV#");
 	i += total_num_consumed;
 }
 //--------------------------------------------------
@@ -651,21 +728,31 @@
 //--------------------------------------------------
 void parse_and_execute_create_ultrasonic_commands(char* tmp_str, byte str_length, byte &i, char *tmp_serial_out)
 {
-	int num_sonars = 0;
+	uint8_t num_sonars = 0;

 	int num_consumed = 0;
-	int num_read = sscanf(tmp_str + i + 3, "%d%n", &num_sonars, &num_consumed);
+	int num_read = sscanf(tmp_str + i + 3, "%hhu%n", &num_sonars, &num_consumed);
+	if (num_read != 1) {
+		strcpy(tmp_serial_out, "E#");
+		i += 2;
+		return;
+	}

 	int total_num_consumed = 3 + num_consumed;
 	ultrasonic_sensors_controller.set_num_sensors(num_sonars);
 	for (int k = 0; k < num_sonars; k++) {
-		int _trig_pin, _echo_pin;
-		int num_read = sscanf(tmp_str + i + total_num_consumed, "%d%d%n", &_trig_pin, &_echo_pin, &num_consumed);
+		uint8_t _trig_pin, _echo_pin;
+		int num_read = sscanf(tmp_str + i + total_num_consumed, "%hhu%hhu%n", &_trig_pin, &_echo_pin, &num_consumed);
+		if (num_read != 2) {
+			strcpy(tmp_serial_out, "E#");
+			i += 2;
+			return;
+		}
 		ultrasonic_sensors_controller.set_sensor_pins(k, _trig_pin, _echo_pin);
 		total_num_consumed += num_consumed + 1;
 	}

-	sprintf(tmp_serial_out, "CU#");
+	strcpy(tmp_serial_out, "CU#");
 	i += total_num_consumed;
 }
 //--------------------------------------------------
@@ -693,10 +780,15 @@
 //--------------------------------------------------
 void parse_and_execute_create_as5147_commands(char* tmp_str, byte str_length, byte &i, char *tmp_serial_out)
 {
-	int num_as5147 = 0;
+	uint8_t num_as5147 = 0;

 	int num_consumed = 0;
-	int num_read = sscanf(tmp_str + i + 3, "%d%n", &num_as5147, &num_consumed);
+	int num_read = sscanf(tmp_str + i + 3, "%hhu%n", &num_as5147, &num_consumed);
+	if (num_read != 1) {
+		strcpy(tmp_serial_out, "E#");
+		i += 2;
+		return;
+	}

 	int total_num_consumed = 3 + num_consumed;
 	as5147s_controller.set_num_sensors(num_as5147);
@@ -706,61 +798,91 @@
 	pinMode(CLK, OUTPUT);

 	for (int k = 0; k < num_as5147; k++) {
-		int _out_pin;
-		int num_read = sscanf(tmp_str + i + total_num_consumed, "%d%n", &_out_pin, &num_consumed);
+		uint8_t _out_pin;
+		int num_read = sscanf(tmp_str + i + total_num_consumed, "%hhu%n", &_out_pin, &num_consumed);
+		if (num_read != 1) {
+			strcpy(tmp_serial_out, "E#");
+			i += 2;
+			return;
+		}
 		as5147s_controller.set_params(k, _out_pin);
 		total_num_consumed += num_consumed + 1;
 	}

-	sprintf(tmp_serial_out, "CA#");
+	strcpy(tmp_serial_out, "CA#");
 	i += total_num_consumed;
 }
 //--------------------------------------------------
 void parse_and_execute_create_infrared_commands(char* tmp_str, byte str_length, byte &i, char *tmp_serial_out)
 {
-	int num_infrareds = 0;
+	uint8_t num_infrareds = 0;

 	int num_consumed = 0;
-	int num_read = sscanf(tmp_str + i + 3, "%d%n", &num_infrareds, &num_consumed);
+	int num_read = sscanf(tmp_str + i + 3, "%hhu%n", &num_infrareds, &num_consumed);
+	if (num_read != 1) {
+		strcpy(tmp_serial_out, "E#");
+		i += 2;
+		return;
+	}

 	int total_num_consumed = 3 + num_consumed;
 	infrared_analog_sensors_controller.set_num_sensors(num_infrareds);
 	for (int k = 0; k < num_infrareds; k++) {
-		int out_pin;
-		int num_read = sscanf(tmp_str + i + total_num_consumed, "%d%n", &out_pin, &num_consumed);
+		uint8_t out_pin;
+		int num_read = sscanf(tmp_str + i + total_num_consumed, "%hhu%n", &out_pin, &num_consumed);
+		if (num_read != 1) {
+			strcpy(tmp_serial_out, "E#");
+			i += 2;
+			return;
+		}
 		infrared_analog_sensors_controller.set_params(k, out_pin);
 		total_num_consumed += num_consumed + 1;
 	}
-	sprintf(tmp_serial_out, "CI#");
+	strcpy(tmp_serial_out, "CI#");
 	i += total_num_consumed;
 }
 //--------------------------------------------------
 void parse_and_execute_create_buttons_commands(char* tmp_str, byte str_length, byte &i, char *tmp_serial_out)
 {
-	int num_buttons = 0;
+	uint8_t num_buttons = 0;
 	int num_consumed = 0;
-	int num_read = sscanf(tmp_str + i + 3, "%d%n", &num_buttons, &num_consumed);
+	int num_read = sscanf(tmp_str + i + 3, "%hhu%n", &num_buttons, &num_consumed);
+	if (num_read != 1) {
+		strcpy(tmp_serial_out, "E#");
+		i += 2;
+		return;
+	}

 	int total_num_consumed = 3 + num_consumed;
 	buttons_controller.set_num_sensors(num_buttons);
 	for (int k = 0; k < num_buttons; k++) {
-		int _pin;
-		int num_read = sscanf(tmp_str + i + total_num_consumed, "%d%n", &_pin, &num_consumed);
+		uint8_t _pin;
+		int num_read = sscanf(tmp_str + i + total_num_consumed, "%hhu%n", &_pin, &num_consumed);
+		if (num_read != 1) {
+			strcpy(tmp_serial_out, "E#");
+			i += 2;
+			return;
+		}
 		buttons_controller.set_params(k, _pin);
 		total_num_consumed += num_consumed + 1;
 	}
-	sprintf(tmp_serial_out, "CB#");
+	strcpy(tmp_serial_out, "CB#");
 	i += total_num_consumed;
 }
 //--------------------------------------------------
 void parse_and_execute_create_LIDAR_commands(char* tmp_str, byte str_length, byte &i, char *tmp_serial_out)
 {
 	int num_consumed = 0;
-	int _dir_pin, _step_pin, _enable_pin, _infrared_pin;
-	int num_read = sscanf(tmp_str + i + 2, "%d%d%d%d%n", &_dir_pin, &_step_pin, &_enable_pin, &_infrared_pin, &num_consumed);
+	uint8_t _dir_pin, _step_pin, _enable_pin, _infrared_pin;
+	int num_read = sscanf(tmp_str + i + 2, "%hhu%hhu%hhu%hhu%n", &_dir_pin, &_step_pin, &_enable_pin, &_infrared_pin, &num_consumed);
+	if (num_read != 4) {
+		strcpy(tmp_serial_out, "E#");
+		i += 2;
+		return;
+	}
 	tera_ranger_one_lidar = new t_tera_ranger_one_lidar(_dir_pin, _step_pin, _enable_pin, _infrared_pin);

-	sprintf(tmp_serial_out, "CL#");
+	strcpy(tmp_serial_out, "CL#");
 	i += num_consumed + 2;
 }
 //--------------------------------------------------


added comments of new commands

added comments of new commands

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

 char is_command_running;

-char firmware_version[] = "2015.11.20.2";// year.month.day.version
+char firmware_version[] = "2015.11.22.0";// year.month.day.version

 char current_buffer[65];

@@ -37,7 +37,9 @@
   Serial.println("Lx#  // Lock motor x.");
   Serial.println("Sx y# // Sets speed of motor x to y.");
   Serial.println("Ax y# // Sets acceleration of motor x to y.");
-  Serial.println("Ux# // Gets the distance as measured by ultrasonic sensor x.");
+  Serial.println("Ux# // Gets the distance as measured by the ultrasonic sensor x.");
+  Serial.println("Bx# // Gets the status of the button x.");
+  Serial.println("Px# // Gets the position of the potentiometer x.");
   Serial.println("Motor index is between 0 and num_motors - 1");

   Serial.println();


change the call of the t_motors_control constructor

--- jenny5-firmware/jenny5-firmware.ino
+++ jenny5-firmware/jenny5-firmware.ino
@@ -2,7 +2,7 @@
 #include "Ultrasonic.h"

 Ultrasonic ultrasonic(53,52);
-t_motors_control motor_control;
+t_motors_control motors_control(4);

 char is_command_running;

@@ -15,7 +15,7 @@
 //--------------------------------------------------------------------------------------------
 void setup()
 {
-  motor_control.reset_pins();
+  motors_control.reset_pins();

   Serial.begin(9600); //Open Serial connection

@@ -34,7 +34,7 @@

   Serial.println();

-  current_buffer[0] = 0;//'\0';
+  current_buffer[0] = 0;
   is_command_running = 0;
 }
 //--------------------------------------------------------------------------------------------
@@ -77,45 +77,36 @@
               if (current_buffer[i] == 'M' || current_buffer[i] == 'm'){// moves motor
                 int motor_index, num_steps;
                 sscanf(tmp_str, "%d%d", &motor_index, &num_steps);
-                motor_control.move_motor(motor_index, num_steps);
+                motors_control.move_motor(motor_index, num_steps);
                 is_command_running = 1;
               }
               else
                 if (current_buffer[i] == 'D' || current_buffer[i] == 'd'){// disables motor
                   int motor_index;
                   sscanf(tmp_str, "%d", &motor_index);
-                  motor_control.disable_motor(motor_index);
+                  motors_control.disable_motor(motor_index);
                 }
                 else
                   if (current_buffer[i] == 'L' || current_buffer[i] == 'l'){// locks motor
                     int motor_index;
                     sscanf(tmp_str, "%d", &motor_index);
-                    motor_control.lock_motor(motor_index);
+                    motors_control.lock_motor(motor_index);
                   }
                 else
                   if (current_buffer[i] == 'U' || current_buffer[i] == 'u'){// ultrasonic
-                    int i = 0;
-                    while (i != 3)
-                    {
                       Serial.print(ultrasonic.Ranging());
-                      //Serial.print("");
-                      //delay(1000);
-                      ++i;
-                    }
                   }
                 else
                   if (current_buffer[i] == 'S' || current_buffer[i] == 's'){// motor speed
                     int motor_index, motor_speed;
                     sscanf(tmp_str, "%d%d", &motor_index, &motor_speed);
-                    motor_control.set_motor_speed(motor_index, motor_speed);
-                    is_command_running = 1;
+                    motors_control.set_motor_speed(motor_index, motor_speed);
                   }
                 else
                   if (current_buffer[i] == 'A' || current_buffer[i] == 'a'){// motor acceleration
                     int motor_index, motor_acceleration;
                     sscanf(tmp_str, "%d%d", &motor_index, &motor_acceleration);
-                    motor_control.set_motor_acceleration(motor_index, motor_acceleration);
-                    is_command_running = 1;
+                    motors_control.set_motor_acceleration(motor_index, motor_acceleration);
                   }

               // remove the current executed command
@@ -139,13 +130,13 @@

 // run motors
   bool is_one_motor_running = false;
-  for (int m = 0; m < num_motors; m++)
-    if (motor_control.steppers[m]->distanceToGo()){
-      motor_control.steppers[m]->run();
+  for (int m = 0; m < motors_control.num_motors; m++)
+    if (motors_control.steppers[m]->distanceToGo()){
+      motors_control.steppers[m]->run();
       is_one_motor_running = true;
     }
     else{
-      motor_control.steppers[m]->setCurrentPosition(0);
+      motors_control.steppers[m]->setCurrentPosition(0);
     }
   if (!is_one_motor_running)
     is_command_running = 0;


changed xbee baud to 57600

changed xbee baud to 57600

--- master/master.ino
+++ master/master.ino
@@ -1051,7 +1051,6 @@

 extern "C" int main(void){
 	Serial.begin(115200);
-	XBEE.begin(9600);

 	// begin i2c at 400kHz
 	Wire.begin(I2C_MASTER, 0x00, I2C_PINS_18_19, I2C_PULLUP_EXT, I2C_RATE_400);
@@ -1061,6 +1060,8 @@
 	SPI.begin();

 	delay(1000);
+
+	XBEE.begin(57600);
 	tft.begin();
 	drawPiLogo();


Implemented dutycycle heating

Implemented dutycycle heating


attempt with states and if

attempt with states and if

didn’t work

--- arduino_control/arduino_control.ino
+++ arduino_control/arduino_control.ino
@@ -29,8 +29,14 @@
 #define Pre_Operational     2
 #define Operational         3

+// Define CANDataRead States
+#define Current_State       1
+#define Position_State      2
+#define Amplification_State 3
+
 // Statemachine State variable and initial value
 byte State = Startup;
+byte DataReadState = Current_State;

 // the cs pin of the version after v1.1 is default to D9
 // v0.9b and v1.0 is default D10
@@ -319,10 +325,14 @@
   {
     CAN.readMsgBuf(&len, buf);    // read data,  len: data length, buf: data buf
     unsigned int canId = CAN.getCanId();
-
-    switch (canId)
+    Serial.println("Entrou Leitura");
+
+    switch (DataReadState)
     {
-      case 0x181:
+      case Current_State:
+        Serial.println("Entrou Current State");
+        if(canId == 0x381)
+        {
         Serial.println("-----------------------------");
         Serial.print("CORRENTE: ");
         Serial.println(canId, HEX);
@@ -333,30 +343,40 @@
             Serial.print("\t");
         }
         Serial.println();
+        DataReadState = Position_State;
+        }
         break;
-      case 0x381:
-        Serial.println("-----------------------------");
-        Serial.print("POSICAO: ");
-        Serial.println(canId, HEX);
-
-        for(int i = 0; i<len; i++)    // print the data
+      case Position_State:
+        if(canId == 0x181)
         {
-            Serial.print(buf[i], HEX);
-            Serial.print("\t");
+          Serial.println("-----------------------------");
+          Serial.print("POSICAO: ");
+          Serial.println(canId, HEX);
+
+          for(int i = 0; i<len; i++)    // print the data
+          {
+              Serial.print(buf[i], HEX);
+              Serial.print("\t");
+          }
+          Serial.println();
+          DataReadState = Amplification_State;
         }
-        Serial.println();
         break;
-      case 0x321:
-        Serial.println("-----------------------------");
-        Serial.print("AMPLIFICACAO: ");
-        Serial.println(canId, HEX);
-
-        for(int i = 0; i<len; i++)    // print the data
+      case Amplification_State:
+        if(canId == 0x321)
         {
-            Serial.print(buf[i], HEX);
-            Serial.print("\t");
+          Serial.println("-----------------------------");
+          Serial.print("AMPLIFICACAO: ");
+          Serial.println(canId, HEX);
+
+          for(int i = 0; i<len; i++)    // print the data
+          {
+              Serial.print(buf[i], HEX);
+              Serial.print("\t");
+          }
+          Serial.println();
+          DataReadState = Current_State;
         }
-        Serial.println();
         break;
       }
   }
@@ -379,7 +399,7 @@
       // positionSetpoint(encoder_data);
       break;
   }
-  delay(100);
+  delay(50);
 }

 /*********************************************************************************************************


updated LCD display

updated LCD display

--- mwsLCD/mwsLCD.ino
+++ mwsLCD/mwsLCD.ino
@@ -139,8 +139,8 @@
 //int windgustdir_10m = 0; // [0-360 past 10 minutes wind gust direction]
 //float humidity = 0; // [%]
 //float tempc = 0; // [temperature C]
-float rainin = 0; // [rain inches over the past hour)] -- the accumulated rainfall in the past 60 min
-float rainin_5m = 0; // [rain inches over the past hour)] -- the accumulated rainfall in the past 60 min
+//float rainin = 0; // [rain inches over the past hour)] -- the accumulated rainfall in the past 60 min
+//float rainin_5m = 0; // [rain inches over the past hour)] -- the accumulated rainfall in the past 60 min
 volatile float dailyrainin = 0; // [rain inches so far today in local time]
 //float baromin = 30.03;// [barom in] - It's hard to calculate baromin locally, do this in the agent
 //float pressure;
@@ -479,11 +479,11 @@
   //Total rainfall for the day is calculated within the interrupt
   //Calculate amount of rainfall for the last 60 minutes
   //Niroshan Stop the gathering hourly rain fall data
-  rainin = 0;
+  float rainin = 0;
   for(int i = 0 ; i < 60 ; i++) //change to 60 mnts
     rainin += rainHour[i];

-  rainin_5m = 0;
+  float rainin_5m = 0;
   for(int i = 0 ; i < 5 ; i++) //change to 5 mnts
     rainin_5m += rain5m[i];


Se añade algoritmo para la recepcion de tiempo generado por el transmisor

--- hardware/transceiver-rx-mode/src/transceiver-rx-mode.ino
+++ hardware/transceiver-rx-mode/src/transceiver-rx-mode.ino
@@ -1,34 +1,50 @@
 /*  ----------------------------------------------------------------
-    http://www.prometec.net/nrf2401
-    Prog_79_1_Receptor
+    http://www.prometec.net/duplex-nrf2401
+    Prog_79B_Emisor

-    Programa para recibir numeros mediante radios NRF2401
+    Usando un NRF2401 para comunicar dos Arduinos en modo Duplex
+    Programa Receptor:
 --------------------------------------------------------------------
 */
-
-#include <nRF24L01.h>
-#include <RF24.h>
-#include <RF24_config.h>
 #include <SPI.h>
-
-int msg[1];
+#include "nRF24L01.h"
+#include "RF24.h"

 RF24 radio(9,10);
-const uint64_t pipe = 0xE8E8F0F0E1LL;
+const uint64_t pipes[2] = { 0xF0F0F0F0E1LL, 0xF0F0F0F0D2LL };

-void setup(void){
-  Serial.begin(9600);
-  radio.begin();
-  radio.openReadingPipe(1,pipe);
-  radio.startListening();
+void setup(void)
+{
+    pinMode(10, OUTPUT);
+    Serial.begin(9600);
+
+    radio.begin();
+    radio.setRetries(15,15);
+    //radio.setPayloadSize(8);
+    radio.startListening();
+    radio.openWritingPipe(pipes[1]);
+    radio.openReadingPipe(1,pipes[0]);
 }

-void loop(void){
-  if (radio.available())
-  {
-    // bool done = false;
-    int done = radio.read(msg, 1);
-    // lastmsg = msg[0];
-    Serial.println(msg[0]);
-  }
+void loop(void)
+{
+    if ( radio.available() )  // Si hay datos disponibles
+    {
+        unsigned long got_time;
+        bool done = false;
+        while (!done)        // Espera aqui hasta recibir algo
+           {
+
+              done = radio.read( &got_time, sizeof(unsigned long) );
+              Serial.print("Dato Recibido =");
+              Serial.println(got_time);
+              delay(20);	// Para dar tiempo al emisor
+           }
+
+      radio.stopListening();	// Dejamos d escuchar para poder hablar
+
+      radio.write( &got_time, sizeof(unsigned long) );
+      Serial.println("Enviando Respuesta");
+      radio.startListening();    // Volvemos a la escucha para recibir mas paquetes
+    }
 }


eliminate the annoying flashing effects

eliminate the annoying flashing effects

--- html/examples/chibitronics/neopixel/neopixel.ino
+++ html/examples/chibitronics/neopixel/neopixel.ino
@@ -133,11 +133,11 @@
   colorWipe(strip.Color(0, 0, 255), 50); // Blue
 //colorWipe(strip.Color(0, 0, 0, 255), 50); // White RGBW
   // Send a theater pixel chase in...
-  theaterChase(strip.Color(127, 127, 127), 50); // White
-  theaterChase(strip.Color(127, 0, 0), 50); // Red
-  theaterChase(strip.Color(0, 0, 127), 50); // Blue
+//  theaterChase(strip.Color(127, 127, 127), 50); // White
+//  theaterChase(strip.Color(127, 0, 0), 50); // Red
+//  theaterChase(strip.Color(0, 0, 127), 50); // Blue

   rainbow(20);
   rainbowCycle(20);
-  theaterChaseRainbow(50);
+//  theaterChaseRainbow(50);
 }


Need to fix ts print routine (has jitter in the us range) and figure out the INTB timeout, but otherwise this should build and run.

--- TICC/TICC.ino
+++ TICC/TICC.ino
@@ -1,7 +1,7 @@
 // TICC.ino - master sketch file

 // TICC Time interval Counter based on TICC Shield using TDC7200
-// version 0.60 -- 29 July 2016
+// version 0.60 -- 30 July 2016

 // Copyright John Ackermann N8UR 2016
 // Portions Copyright George Byrkit K9TRV 2016
@@ -23,8 +23,9 @@
 #include "TICC.h"     // Register and structure definitions

 //#include <stdio.h>    // format strings for printing. Eliminate???
+
 // use BigNumber library from http://www.gammon.com.au/Arduino/BigNumber.zip
-#include <BigNumber.h>
+// #include <BigNumber.h>

 volatile unsigned long long PICcount;  //volatile because in ISR

@@ -139,7 +140,7 @@
   delay(5);  // 1.5ms minimum recommended to allow chip LDO to stabilize

-  write(CONFIG2, 0x81);  // was 0x83 Cal2 is 20 clocks, 1 meas cycle, 1 stop
+  write(CONFIG2, 0x81);  // SHOULD BE 0x80 for Cal2 (20 clocks, 1 meas cycle, 1 stop) but that doesn't work
  // write(INT_MASK, 0x01);  // was 0x01 disable clock overflow interrupts, allow only measurement interrupt

@@ -149,8 +150,8 @@
  // write(COARSE_CNTR_OVF_H, 0xFF);  //was 0xF0
  // write(COARSE_CNTR_OVF_L, 0xFF);

- // write(CLOCK_CNTR_OVF_H, 0xF0);  // was 0xF0
- // write(CLOCK_CNTR_OVF_L, 0x00);  // was 0x00
+ write(CLOCK_CNTR_OVF_H, 0xF0);   // was 0xF0
+ write(CLOCK_CNTR_OVF_L, 0x00);  // was 0x00

 }

@@ -158,8 +159,8 @@
 void tdc7200Channel::ready_next() {
     // needs to set the enable bit (START_MEAS in CONFIG1)
     // clears interrupt bits
-    delayMicroseconds(1000);  // was 10ms
-    write(CONFIG1, 0x83);  // was 0x83 Measurement mode 2 - force cal
+    delayMicroseconds(1);  // was 10ms
+    write(CONFIG1, 0x83);     // was 0x83 Measurement mode 2 - force cal
 }


Add semicolon

Add semicolon

--- moteino/node_heater/node_heater.ino
+++ moteino/node_heater/node_heater.ino
@@ -68,7 +68,7 @@
   radio.sendWithRetry(GATEWAY_ID, buff, 1);
   radio.receiveDone();

-  DEBUG_PRINT("send REQ\n")
+  DEBUG_PRINT("send REQ\n");

   delay(40); // round trip delay

@@ -99,17 +99,17 @@
         break;
     }

-    DEBUG_PRINT("send DONE\n")
+    DEBUG_PRINT("send DONE\n");
     buff[0] = DONE;
     radio.sendWithRetry(GATEWAY_ID, buff, 1);

     radio.receiveDone();
     delay(100);

-    DEBUG_PRINT("listening\n")
+    DEBUG_PRINT("listening\n");
   }

-  DEBUG("no response, going back to sleep\n");
+  DEBUG_PRINT("no response, going back to sleep\n");

   radio.sleep();
   delay(40);


thro in a space particle process because otherwise we get pulsing greed

--- firmware/examples/readTag/readtag.ino
+++ firmware/examples/readTag/readtag.ino
@@ -28,4 +28,5 @@
         }
     }
     delay(5000);
+    Particle.process();
 }


final fixes after reparing the hardware

final fixes after reparing the hardware

--- TWANG.ino
+++ TWANG.ino
@@ -1,13 +1,11 @@
 // Required libs
 //#include <EEPROM.h>
 //#include <LiquidCrystal.h>
-#define FASTLED_FORCE_SOFTWARE_SPI 0
 #include "FastLED.h"
 #include "I2Cdev.h"
 #include "MPU6050.h"
 #include "Wire.h"
 #include "toneAC.h"
-#include "iSin.h"
 #include "RunningMedian.h"

 // Included libs
@@ -33,7 +31,7 @@
 #define DATA_PIN                   3
 #define LED_TYPE                   WS2812B
 #define LED_COLOR_ORDER            GRB
-#define BRIGHTNESS                 170
+#define BRIGHTNESS                 250
 #define DIRECTION                  1         // 0 = right to left, 1 = left to right
 #define MIN_REDRAW_INTERVAL        20        // Min redraw interval (ms) 33 = 30fps / 16 = 63fps
 #define USE_GRAVITY                0         // 0/1 use gravity (LED strip going up wall)
@@ -594,7 +592,7 @@
 	int A, B, p, i, brightness, flicker;
 	long mm = millis();
 	for (i = 0; i < lavaCount; ++i) {
-		flicker = random8(3);
+		flicker = random8(5);
 		Lava &LP = lavaPool[i];
 		if (LP.Alive()) {
 			A = getLED(LP._left);
@@ -605,7 +603,7 @@
 					LP._lastOn = mm;
 				}
 				for (p = A; p <= B; ++p) {
-					leds[p].setRGB(30 + flicker, 15 + flicker, 0);
+					leds[p].setRGB(150 + flicker, 100 + flicker, 0);
 				}
 			}
 			else {
@@ -613,9 +611,8 @@
 					LP._isOn = true;
 					LP._lastOn = mm;
 				}
-				flicker /= 1.75;
 				for (p = A; p <= B; ++p) {
-					leds[p].setRGB(4 + flicker, (3 + flicker) / 1.75, 0);
+					leds[p].setRGB(3 + flicker, (3 + flicker) / 1.5, 0);
 				}
 			}
 		}


add: serial key rebinding capability

add: serial key rebinding capability

added ability to use serial communication to rebind a keyboard in real
time, no recompiling necessary

--- animus/animusmaster/serial.ino
+++ animus/animusmaster/serial.ino
@@ -27,6 +27,30 @@
   {
     Serial.println(KBINFO);
   }
+  else if (input.startsWith("uniqueksetkey"))
+  {
+    input = input.substring(input.indexOf('(')+1);
+    byte x = input.substring(0, input.indexOf('(')).toInt();
+    input = input.substring(input.indexOf('(')+1);
+    byte y = input.substring(0, input.indexOf('(')).toInt();
+    input = input.substring(input.indexOf('(')+1);
+    byte z = input.substring(0, input.indexOf('(')).toInt();
+    input = input.substring(input.indexOf('(')+1);
+    byte val = input.substring(0, input.indexOf('(')).toInt();
+    input = input.substring(input.indexOf('(')+1);
+    byte type = input.toInt();
+    setEEPROM(x, y, z, val, type);
+    Serial.print("key set: ");
+    Serial.print(x);
+    Serial.print(", ");
+    Serial.print(y);
+    Serial.print(", ");
+    Serial.print(z);
+    Serial.print(", ");
+    Serial.print(val);
+    Serial.print(", ");
+    Serial.println(type);
+  }
 }

 // serial functions end


Fixed to work with 6DOF and to read values from the servos and print them to serial

--- ZUArm.ino
+++ ZUArm.ino
@@ -8,8 +8,8 @@
 theta3 => 3
 theta4 => 5
 */
-int thetaPin[] = {9,11,3,5};
-const int numberOfMotors = 4;
+int thetaPin[] = {3,5,6,9,10,11};
+const int numberOfMotors = 6;
 //We define a servo instance for each motor
 Servo thetaServo[numberOfMotors];

@@ -17,8 +17,11 @@
   //Initialize Serial Com
   Serial.begin(9600);
   //Attach each instance with the corresponding pin
-  for (int i; i < numberOfMotors; i++) {
-    thetaServo[i].attach(i);
+  for (int i = 0; i < numberOfMotors; i++) {
+    thetaServo[i].attach(thetaPin[i]);
+  }
+  for (int i = 0; i < numberOfMotors; i++) {
+    thetaServo[i].write(0);
   }
 }
 int Angle;
@@ -31,6 +34,16 @@
    if (servoNo < numberOfMotors) {
      Angle = Serial.readStringUntil(':').toInt();
      thetaServo[servoNo].write(Angle);
+     Serial.print("Theta ");
+   Serial.print(servoNo);
+   Serial.print(" Was sent an angle of ");
+   Serial.println(Angle);
+   } else {
+    Serial.println("HERE");
+    for (int i = 0; i < numberOfMotors; i++) {
+      int val = thetaServo[i].read();
+      Serial.println(val);
+    }
    }
   }
 }


minor bug fix

minor bug fix

--- flugkatze_slave/flight_controller/flight_controller.ino
+++ flugkatze_slave/flight_controller/flight_controller.ino
@@ -30,7 +30,7 @@
     channel 4      <----- o ----->
     ROLL                  |
                           |
-*/
+*/

 ///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
 //PID gain and limit settings
@@ -88,13 +88,13 @@
     float ax;
     float ay;
     float az;
-
+
     float temp;
-
+
     float gx;
     float gy;
     float gz;
-
+
     int throttle;
     int roll;
     int pitch;
@@ -150,7 +150,7 @@
         PORTD &= B00001111;                                        //Set digital poort 4, 5, 6 and 7 low.
         delay(3);                                                  //Wait 3 milliseconds before the next loop.
     }
-
+
     //Now that we have 2000 measures, we need to devide by 2000 to get the average gyro offset.
     gyro_roll_cal /= N_SAMPLES;                                       //Divide the roll total by 2000.
     gyro_pitch_cal /= N_SAMPLES;                                      //Divide the pitch total by 2000.
@@ -171,7 +171,7 @@

     //Wait until the receiver is active and the throtle is set to the lower position.
     while(receiver_input_channel_2 < 900 || receiver_input_channel_2 > 1040 || receiver_input_channel_1 < 1400){
-      start ++;
+      start ++;
                                                  //While waiting increment start whith every loop.
         //We don't want the esc's to be beeping annoyingly. So let's give them a 1000us puls while waiting for the receiver inputs.
         PORTD |= B11110000;                                        //Set digital poort 4, 5, 6 and 7 high.
@@ -196,7 +196,7 @@
 void loop(){
     //Let's get the current gyro data and scale it to degrees per second for the pid calculations.
     imu();
-
+
     flight_data.throttle = receiver_input_channel_2;
     flight_data.roll = receiver_input_channel_4;
     flight_data.pitch = receiver_input_channel_3;
@@ -217,11 +217,11 @@
     //print_signals();

     //For starting the motors: throttle low and yaw left (step 1).
-    if(receiver_input_channel_2 < 1050 && receiver_input_channel_1 < 1090) {
+    if(receiver_input_channel_2 < 1050 && receiver_input_channel_1 < 1090) {
         start = 1;
         Serial.print(" stage 1 ");
     }
-
+
     //When yaw stick is back in the center position start the motors (step 2).
     if(start == 1 && receiver_input_channel_2 < 1050 && receiver_input_channel_1 > 1450){
         start = 2;
@@ -234,7 +234,7 @@
         pid_i_mem_yaw = 0;
         pid_last_yaw_d_error = 0;
     }
-
+
     //Stopping the motors: throttle low and yaw right.
     if (start == 2 && receiver_input_channel_2 < 1050 && receiver_input_channel_1 > 1800) {
         start = 0;
@@ -244,7 +244,7 @@
     //The PID set point in degrees per second is determined by the roll receiver input.
     //In the case of deviding by 3 the max roll rate is aprox 164 degrees per second ( (500-8)/3 = 164d/s ).
     pid_roll_setpoint = 0;
-
+
     //We need a little dead band of 16us for better results.
     if (receiver_input_channel_4 > 1508) {
         pid_roll_setpoint = (receiver_input_channel_4 - 1508)/3.0;
@@ -305,14 +305,14 @@
         if (throttle > THROTTLE_MAX) {
             throttle = THROTTLE_MAX;                                   //We need some room to keep full control at full throttle.
         }
-
+
         // switched the signes brfore pid_output_roll!
         //    esc_1 = throttle - pid_output_pitch - pid_output_roll - pid_output_yaw; //Calculate the pulse for esc 1 (front-right - CCW)
         //    esc_2 = throttle + pid_output_pitch - pid_output_roll + pid_output_yaw; //Calculate the pulse for esc 2 (rear-right - CW)
         //    esc_3 = throttle + pid_output_pitch + pid_output_roll - pid_output_yaw; //Calculate the pulse for esc 3 (rear-left - CCW)
         //    esc_4 = throttle - pid_output_pitch + pid_output_roll + pid_output_yaw; //Calculate the pulse for esc 4 (front-left - CW)
         // old version
-
+
         esc_1 = throttle - pid_output_pitch + pid_output_roll - pid_output_yaw; //Calculate the pulse for esc 1 (front-right - CCW)
         esc_2 = throttle + pid_output_pitch + pid_output_roll + pid_output_yaw; //Calculate the pulse for esc 2 (rear-right - CW)
         esc_3 = throttle + pid_output_pitch - pid_output_roll - pid_output_yaw; //Calculate the pulse for esc 3 (rear-left - CCW)
@@ -328,31 +328,31 @@
         if (esc_1 < THROTTLE_THRESHOLD) {
             esc_1 = THROTTLE_THRESHOLD;                                         //Keep the motors running.
         }
-
+
         if (esc_2 < THROTTLE_THRESHOLD) {
             esc_2 = THROTTLE_THRESHOLD;                                         //Keep the motors running.
         }
-
+
         if (esc_3 < THROTTLE_THRESHOLD) {
             esc_3 = THROTTLE_THRESHOLD;                                         //Keep the motors running.
         }
-
+
         if (esc_4 < THROTTLE_THRESHOLD) {
             esc_4 = THROTTLE_THRESHOLD;                                         //Keep the motors running.
         }
-
+
         if(esc_1 > THROTTLE_MAX) {
             esc_1 = THROTTLE_MAX;                                           //Limit the esc-1 pulse to 2000us.
         }
-
+
         if(esc_2 > THROTTLE_MAX) {
             esc_2 = THROTTLE_MAX;                                           //Limit the esc-2 pulse to 2000us.
         }
-
+
         if(esc_3 > THROTTLE_MAX) {
             esc_3 = THROTTLE_MAX;                                           //Limit the esc-3 pulse to 2000us.
         }
-
+
         if(esc_4 > THROTTLE_MAX) {
             esc_4 = THROTTLE_MAX;                                           //Limit the esc-4 pulse to 2000us.
         }
@@ -368,7 +368,7 @@
     //All the information for controlling the motor's is available.
     //The refresh rate is 250Hz. That means the esc's need there pulse every 4ms.
     while(micros() - loop_timer < 4000);                                      //We wait until 4000us are passed.
-
+
     loop_timer = micros();                                                    //Set the timer for the next loop.

     PORTD |= B11110000;                                                       //Set digital outputs 4,5,6 and 7 high.
@@ -378,21 +378,21 @@
     timer_channel_4 = esc_4 + loop_timer;                                     //Calculate the time of the faling edge of the esc-4 pulse.

     while(PORTD >= 16){                                                       //Stay in this loop until output 4,5,6 and 7 are low.
-
+
         esc_loop_timer = micros();                                              //Read the current time.
-
+
         if(timer_channel_1 <= esc_loop_timer) {
             PORTD &= B11101111;                //Set digital output 4 to low if the time is expired.
         }
-
+
         if(timer_channel_2 <= esc_loop_timer) {
             PORTD &= B11011111;                //Set digital output 5 to low if the time is expired.
         }
-
+
         if(timer_channel_3 <= esc_loop_timer) {
             PORTD &= B10111111;                //Set digital output 6 to low if the time is expired.
         }
-
+
         if(timer_channel_4 <= esc_loop_timer) {
             PORTD &= B01111111;                //Set digital output 7 to low if the time is expired.
         }
@@ -414,7 +414,7 @@
         last_channel_1 = 0;                                        //Remember current input state
         receiver_input_channel_1 = current_time - timer_1;         //Channel 1 is current_time - timer_1
     }
-
+
     //Channel 2=========================================
     if(PINB & B00000010 ){                                       //Is input 9 high?
         if(last_channel_2 == 0){                                   //Input 9 changed from 0 to 1
@@ -425,7 +425,7 @@
         last_channel_2 = 0;                                        //Remember current input state
         receiver_input_channel_2 = current_time - timer_2;         //Channel 2 is current_time - timer_2
     }
-
+
     //Channel 3=========================================
     if(PINB & B00000100 ){                                       //Is input 10 high?
         if(last_channel_3 == 0){                                   //Input 10 changed from 0 to 1
@@ -436,7 +436,7 @@
         last_channel_3 = 0;                                        //Remember current input state
         receiver_input_channel_3 = current_time - timer_3;         //Channel 3 is current_time - timer_3
     }
-
+
     //Channel 4=========================================
     if(PINB & B00001000 ){                                       //Is input 11 high?
         if(last_channel_4 == 0){                                   //Input 11 changed from 0 to 1
@@ -456,7 +456,7 @@
     Wire.write(0x3B);  // starting with register 0x3B (ACCEL_XOUT_H)
     Wire.endTransmission(false);
     Wire.requestFrom(MPUADDR, 14, true);  // request a total of 14 registers
-    flight_data.ax = (Wire.read() << 8) | Wire.read();  // 0x3B (ACCEL_XOUT_H) & 0x3C (ACCEL_XOUT_L)
+    flight_data.ax = (Wire.read() << 8) | Wire.read();  // 0x3B (ACCEL_XOUT_H) & 0x3C (ACCEL_XOUT_L)
     flight_data.ay = (Wire.read() << 8) | Wire.read();  // 0x3D (ACCEL_YOUT_H) & 0x3E (ACCEL_YOUT_L)
     flight_data.az = (Wire.read() << 8) | Wire.read();  // 0x3F (ACCEL_ZOUT_H) & 0x40 (ACCEL_ZOUT_L)

@@ -469,7 +469,7 @@
     if (cal_int == N_SAMPLES) {
         flight_data.gx -= gyro_roll_cal;
         flight_data.gy -= gyro_pitch_cal;
-        gyro_yaw -= gyro_yaw_cal;
+        flight_data.gz -= gyro_yaw_cal;
     }
 }

@@ -492,7 +492,7 @@
         pid_i_mem_roll = pid_max_roll * -1;
     }

-    pid_output_roll = (( pid_p_gain_roll * pid_error_temp ) + pid_i_mem_roll + ( pid_d_gain_roll * (pid_error_temp - pid_last_roll_d_error))) * -1; // maybe *-1 ?
+    pid_output_roll = (( pid_p_gain_roll * pid_error_temp ) + pid_i_mem_roll + ( pid_d_gain_roll * (pid_error_temp - pid_last_roll_d_error))) * -1; // maybe *-1 ?
     // old version
     if(pid_output_roll > pid_max_roll) {
         pid_output_roll = pid_max_roll;


Comments modified

Comments modified

--- SlideBright.ino
+++ SlideBright.ino
@@ -2,6 +2,7 @@
 ** SlideBright - Firmware for the overengineered Hexbright flashlight.
 **               Hexbright: http://hexbright.com/
 **                                ~ Tobias Jäger <Tobias.Jaeger@slidetex.de>
+**
 **
 **
 ** Based on darcbright by Robert Quattlebaum <darco@deepdarc.com>


Improve playing of sound

Improve playing of sound

--- Valokepakko.ino
+++ Valokepakko.ino
@@ -29,17 +29,18 @@
     } else {
       Serial.println("off");
     }
+    // Small delay to avoid bouncing of the signal.
+    delay(50);
   }
   lastButtonState = buttonState;

   if (buttonState == HIGH) {
     // Play a tone
-    tone(PIEZO_PIN, 200, 20);
+    tone(PIEZO_PIN, 200);
     // Light the LED.
     digitalWrite(LED_PIN, HIGH);
-    // Delay a little bit to avoid bouncing.
-    delay(50);
   } else {
+    noTone(PIEZO_PIN);
     digitalWrite(LED_PIN, LOW);
   }
 }