Add sensorboard switch control variable and functions

--- SensorBoard.ino
+++ SensorBoard.ino
@@ -7,6 +7,8 @@
 const uint64_t pipes[2] = { 0xF0F0F0F001LL, 0xF0F0F0F002LL };
 const byte shortAddr = 0x02;
 int led = 13;
+char switchStatus = 0;
+char lampStatus = 0;
 void setup(void)
 {
   Serial.begin(57600);
@@ -58,16 +60,12 @@
     case 0:
       break;
     case 1:
+    {
       if (ptr[12]== 0x00){
-        switchOnLight(ptr);
+        switchLight(ptr);
       }
       break;
-    case 2:
-      if (ptr[12]== 0x00)
-      {
-        switchOffLight(ptr);
-      }
-      break;
+    }
   }

 }
@@ -75,6 +73,8 @@
   readTemp(ptr);
   readHum(ptr);
   readLum(ptr);
+  readSwitch(ptr);
+  readLamp(ptr);

 }
 void readTemp(char* ptr){
@@ -90,14 +90,28 @@
   ptr[15] = 0xFF;

 }
-void switchOnLight(char* ptr)
+
+void readSwitch(char* ptr){
+  ptr[12] = 0xFF;
+  ptr[15] = switchStatus;
+
+}
+
+void readLamp(char* ptr){
+  ptr[12] = 0xFF;
+  ptr[15] = lampStatus;
+
+}
+
+void switchLight(char* ptr)
 {
-  digitalWrite(led, HIGH);
+  lampStatus = ptr[16];
+  if(lampStatus == 0xFF){
+    digitalWrite(led, HIGH);
+  }
+  else{
+    digitalWrite(led, LOW);
+  }
   ptr[12] = 0xFF;
-  ptr[16] = 0xFF;
 }
-bool switchOffLight(char* ptr){
-  digitalWrite(led, LOW);
-  ptr[12] = 0xFF;
-  ptr[16] = 0xFF;
-}
+


Handle millis() wraparound

Handle millis() wraparound

--- time.ino
+++ time.ino
@@ -18,7 +18,7 @@

 void update_time(void) {
     unsigned long current_millis = millis();
-    while (current_millis > previous_millis)
+    while (current_millis - previous_millis > 1000)
         current_timestamp++, previous_millis += 1000;

     if (next_sync_threshold <= current_timestamp && time_requester != NULL)


changed voltage inc/dec steps

changed voltage inc/dec steps

--- Testsystem/Testsystem03/Voltage/Voltage.ino
+++ Testsystem/Testsystem03/Voltage/Voltage.ino
@@ -1,15 +1,18 @@

-int voltagePin = 9;
-int voltageValue = 0;
+#define MAX_VOLTAGE 500
+#define N 3
+int voltagePins[N] = { 8, 9, 10 };
+int voltageValue = MAX_VOLTAGE;
 byte voltageTargetValue = 0;
-
-#define MAX_VOLTAGE 50

 void setup()
 {
-  pinMode(voltagePin, OUTPUT);
+  for(uint8_t i=0; i < N; ++i)
+    pinMode(voltagePins[i], OUTPUT);
   Serial.begin(9600);
   Serial.println("Ready... enter: + -");
+
+  voltageTargetValue = map(voltageValue, 0, MAX_VOLTAGE, 0, 255);
 }

 void checkSerial()
@@ -17,9 +20,14 @@
   if(Serial.available())
   {
     byte character = (char)Serial.read();
-    if(character == '+')
+    if(character == '\n')
+      return;
+    if(character == '\r')
+      return;
+
+    if(character == '-')
       voltageValue += 1;
-    else if(character == '-')
+    else if(character == '+')
       voltageValue -= 1;

     if(voltageValue < 0)
@@ -32,7 +40,7 @@
     Serial.print("New Voltage: ");
     Serial.print(voltageTargetValue);
     Serial.print("  ");
-    Serial.print(voltageValue/10.f);
+    Serial.print((MAX_VOLTAGE/100) - voltageValue/100.f);
     Serial.println("V");
   }
 }
@@ -40,8 +48,9 @@
 void loop()
 {
   checkSerial();
-
-  analogWrite(voltagePin, voltageTargetValue);
+
+  for(uint8_t i = 0; i < N; ++i)
+    analogWrite(voltagePins[i], voltageTargetValue);

   delay(30);
 }


migrated to using ESP8266 library, runs slowly

--- uArm.ino
+++ uArm.ino
@@ -11,10 +11,15 @@

 #include <VarSpeedServo.h>

+#include "uartWIFI.h"
+
+// MicroView
 int SCREEN_WIDTH = uView.getLCDWidth();
 int SCREEN_HEIGHT = uView.getLCDHeight();
 MicroViewWidget *widgetL, *widgetR, *widgetRot, *widgetHRot, *widgetH;

+
+// Servos
 const int servoPinL = 2;
 const int servoPinR = 3;
 const int servoPinRot = 5;
@@ -40,6 +45,13 @@
 #define	moveServoHRot(degrees, servoSpeed, wait, updateDisplay)	moveServo(servoHRot, widgetHRot, degrees, servoSpeed, wait, updateDisplay)
 #define	moveServoH(degrees, servoSpeed, wait, updateDisplay)	moveServo(servoH, widgetH, degrees, servoSpeed, wait, updateDisplay)

+// ESP8266
+#define SSID		"ssid"
+#define PASSWORD	"password"
+#define SERVER_PORT	2222
+WIFI wifi;
+extern int8_t chlID;
+
 // helper functions
 void softwareReset(void) {
 	wdt_enable(WDTO_15MS);
@@ -83,10 +95,14 @@
 	servoH.detach();
 }

+void setupESP8266(void) {
+	while (!wifi.begin());
+	wifi.Initialize(AP_STA, SSID, PASSWORD);
+	wifi.confMux(1);
+	wifi.confServer(1, SERVER_PORT);
+}
+
 void setup() {
-	// setup serial port
-	Serial.begin(9600);
-
 	// setup MicroView
 	setupMicroView();

@@ -99,6 +115,8 @@
 	moveServoRot(defaultServoPos, servoSpeed, false, false);
 	moveServoHRot(defaultServoPos, servoSpeed, false, false);
 	moveServoH(defaultServoPos, servoSpeed, true, true);
+
+	setupESP8266();
 }

 /*
@@ -124,8 +142,13 @@
 	if (!speedControl)
 		servoSpeedLocal = 0;

+	wifi.Send(chlID,F("parseCommandGServo"));
+	wifi.Send(chlID,*buf);
+	wifi.Send(chlID,String(*buf[0]));
+
 	if (*buf[0] == '\0')
 		return false;
+
 	switch(*buf[0]) {
 		case 'L': case 'l':
 			pos = strtoul(buf[1], &endptr, 10);
@@ -141,7 +164,7 @@
 					moveServoL(defaultServoPos, servoSpeedLocal, false, false);
 				}
 			} else {
-				Serial.println(F("ERROR: invalid servoL position"));
+				wifi.Send(chlID,F("ERROR: invalid servoL position"));
 			}
 			return true;
 		case 'R': case 'r':
@@ -158,7 +181,7 @@
 					moveServoR(defaultServoPos, servoSpeedLocal, false, false);
 				}
 			} else {
-				Serial.println(F("ERROR: invalid servoR position"));
+				wifi.Send(chlID,F("ERROR: invalid servoR position"));
 			}
 			return true;
 		case 'O': case 'o':
@@ -175,7 +198,7 @@
 					moveServoRot(defaultServoPos, servoSpeedLocal, false, false);
 				}
 			} else {
-				Serial.println(F("ERROR: invalid servoRot position"));
+				wifi.Send(chlID,F("ERROR: invalid servoRot position"));
 			}
 			return true;
 		case 'T': case 't':
@@ -192,7 +215,7 @@
 					moveServoHRot(defaultServoPos, servoSpeedLocal, false, false);
 				}
 			} else {
-				Serial.println(F("ERROR: invalid servoHRot position"));
+				wifi.Send(chlID,F("ERROR: invalid servoHRot position"));
 			}
 			return true;
 		case 'H': case 'h':
@@ -209,11 +232,11 @@
 					moveServoH(defaultServoPos, servoSpeedLocal, false, false);
 				}
 			} else {
-				Serial.println(F("ERROR: invalid servoH position"));
+				wifi.Send(chlID,F("ERROR: invalid servoH position"));
 			}
 			return true;
 		default:
-			Serial.println(F("ERROR: invalid servo identifier"));
+			wifi.Send(chlID,F("ERROR: invalid servo identifier"));
 			return false;
 	};
 	return false;
@@ -228,11 +251,14 @@

 	if (len == 0) return false;

+	wifi.Send(chlID,F("processCommand"));
+	wifi.Send(chlID,cmd);
+
 	switch (buf[0]) {
 		case 'G': case 'g':
 			code = strtoul(&buf[1], &endptr, 10);
 			if (endptr == &buf[1]) {
-				Serial.println(F("ERROR: missing G command code"));
+				wifi.Send(chlID,F("ERROR: missing G command code"));
 				return false;
 			}
 			if (code == 0) {
@@ -242,11 +268,11 @@
 				// speed control move
 				speedControl = true;
 			} else {
-				Serial.println(F("ERROR: invalid G command code"));
+				wifi.Send(chlID,F("ERROR: invalid G command code"));
 				return false;
 			}
 			// absorb spaces
-			for (; *endptr == ' ' && *endptr == '\t'; ++endptr);
+			for (; *endptr == ' ' || *endptr == '\t'; ++endptr);
 			// check for wait flag
 			wait = true;
 			if (*endptr == 'W' || *endptr == 'w') {
@@ -258,89 +284,71 @@
 					} else if (code == 1) {
 						wait = true;
 					} else {
-						Serial.println(F("ERROR: invalid G command wait flag (bad number)"));
+						wifi.Send(chlID,F("ERROR: invalid G command wait flag (bad number)"));
 						return false;
 					}
 				} else {
-					Serial.println(F("ERROR: invalid G command wait flag (no number)"));
+					wifi.Send(chlID,F("ERROR: invalid G command wait flag (no number)"));
 					return false;
 				}
 			}
 			do {
 				// absorb spaces
-				for (; *endptr == ' ' && *endptr == '\t'; ++endptr);
+				for (; *endptr == ' ' || *endptr == '\t'; ++endptr);
+				wifi.Send(chlID,endptr);
 			} while (parseCommandGServo(&endptr, speedControl, wait));
 			break;
 		case 'F': case 'f':
 			code = strtoul(&buf[1], &endptr, 10);
 			if (endptr == &buf[1]) {
-				Serial.println(F("ERROR: missing F speed parameter"));
+				wifi.Send(chlID,F("ERROR: missing F speed parameter"));
 				return false;
 			}
 			if (code >= 0 && code <= 255) {
 				servoSpeed = code;
+				wifi.Send(chlID,F("OK"));
 				return true;
 			} else {
-				Serial.println(F("ERROR: invalid F speed parameter"));
+				wifi.Send(chlID,F("ERROR: invalid F speed parameter"));
 				return false;
 			}
 			break;
 		case 'M': case 'm':
 			code = strtoul(&buf[1], &endptr, 10);
 			if (endptr == &buf[1]) {
-				Serial.println(F("ERROR: missing M address parameter"));
+				wifi.Send(chlID,F("ERROR: missing M address parameter"));
 				return false;
 			}
 			switch (code) {
 				case 100:
-					Serial.println(F("OK"));
+					wifi.Send(chlID,F("OK"));
 					softwareReset();
 					break;
 				case 101:
-					Serial.println(freeRam(), DEC);
+					wifi.Send(chlID,String(freeRam(), DEC));
 					break;
 				case 112:
 					detachServos();
-					Serial.println(F("OK"));
+					wifi.Send(chlID,F("OK"));
 					break;
 				default:
-					Serial.println(F("ERROR: invalid M address parameter"));
+					wifi.Send(chlID,F("ERROR: invalid M address parameter"));
 					return false;
 			};
 			break;
 		default:
-			Serial.println(F("ERROR: invalid command"));
+			wifi.Send(chlID,F("ERROR: invalid command"));
 			return false;
 	};
 }

-const uint8_t MAX_CMD_LEN = 32;
+const uint8_t MAX_CMD_LEN = 128;
+char buf[MAX_CMD_LEN + 1], c;
+uint8_t len = 0;

 void loop() {
-	char buf[MAX_CMD_LEN + 1], c;
-	bool suspendStore = false;
-	uint8_t i = 0;
-
-	// read to newline
-	// ignore any line that has over 32 characters
-	if (Serial.available() > 0) {
-		c = Serial.read();
-		if (c == '\n' || c == '\r') {
-			if (suspendStore == false) {
-				buf[i] = '\0';
-				processCommand(buf);
-			} else {
-				suspendStore = false;
-			}
-			i = 0;
-		} else {
-			if (i < MAX_CMD_LEN) {
-				buf[i] = c;
-				++i;
-			} else {
-				Serial.println(F("ERROR: command line too long"));
-				suspendStore = true;
-			}
-		}
+	len = wifi.ReceiveMessage(buf);
+	if (len > 0) {
+		processCommand(buf);
 	}
 }


Added comment before the Button class

Added comment before the Button class

--- examples/functions_menu/functions_menu.ino
+++ examples/functions_menu/functions_menu.ino
@@ -5,11 +5,11 @@
  * "lines" in the menu.
  *
  * Attaching functions to the different "lines" in the menu makes it
- * possible to execute an action while browsing the menu (e.g. dimming
- * an LED, adjusting preferences...). To attach a function to a line
- * you need to create with signature "void functionName(void)". After
- * creating it, the function is ready to be attached to a line. To do
- * that call bool LiquidLine::attach_function(uint8_t number, void (*function)(void)).
+ * possible to execute an action through the menu (e.g. dimming an LED,
+ * adjusting preferences...). To attach a function to a line you need
+ * to create with signature "void functionName(void)". After creating it,
+ * the function is ready to be attached to a line. To dothat call bool
+ * LiquidLine::attach_function(uint8_t number, void (*function)(void)).
  * LiquidLine is the line object you wish to attach the function to,
  * number is the "id" of the function for that line, void (*function)(void)
  * is just the name of the function without the "()". The "id" of the function
@@ -60,14 +60,6 @@
 #include <LiquidMenu.h>
 #include "Button.h"

-// // An array holding linearized 8bit PWM values.
-// const uint8_t log_8bit[11] PROGMEM = {0, 1, 2, 3, 6, 12, 22, 40, 74, 138, 255};
-
-// // PWM function using the above array.
-// void PWM_log(uint8_t pin, uint8_t level) {
-// 	analogWrite(pin, pgm_read_byte_near(log_8bit + level));
-// }
-
 // Pin mapping for the display
 const byte LCD_RS = 12;
 const byte LCD_E = 11;
@@ -76,13 +68,19 @@
 const byte LCD_D6 = 3;
 const byte LCD_D7 = 2;
 //LCD R/W pin to ground
-//10K potentiometer to VO
+//10K potentiometer wiper to VO
 LiquidCrystal lcd(LCD_RS, LCD_E, LCD_D4, LCD_D5, LCD_D6, LCD_D7);

 // This variable can be passed to the LiquidMenu object to set the starting screen.
 const byte startingScreen = 2;

 // Button objects instantiation
+/*
+ * The Button class is not a part of the LiquidMenu library. The first
+ * parameter is the button's pin, the second enables or disables the
+ * internal pullup resistor (not required) and the third is the debounce
+ * time (not required).
+ */
 const bool pullup = true;
 Button left(A0, pullup);
 Button right(7, pullup);


Adding a comment to the example

Adding a comment to the example

--- examples/esp/example.ino
+++ examples/esp/example.ino
@@ -12,6 +12,10 @@

 #include <TimeLib.h>
 #include <sunset.h>
+
+/**
+ * This library only works for 32 bit platforms. It will not work for 8 bit AVR platforms
+ */

 /* I'm in the midwest, so this is what I use for my home */
 #define LATITUDE        41.12345


Update sonar.ino

Update sonar.ino

Agregado boton de test

--- sonar.ino
+++ sonar.ino
@@ -47,7 +47,7 @@
     while (estado) {
       sonar = ultrasonido();
       Serial.println(sonar);
-      if (sonar > 15) {
+      if (sonar > 16) {
         contador++;
         delay(100);
         //Serial.println(contador);


fixing

fixing

--- coni/arduino/main/master/multi_master.ino
+++ coni/arduino/main/master/multi_master.ino
@@ -1,35 +1,45 @@
-#define SWITCH 12
-
-#define RE 6
-#define DE 7
-
-uint8_t tracks[16] = {53,52,51,50,49,48,47,46,45,44,43,42,41,40,39,38};
-
 void setup() {
+  // put your setup code here, to run once:
+  pinMode(53, OUTPUT);
+  pinMode(52, OUTPUT);
+  pinMode(51, OUTPUT);
+  pinMode(50, OUTPUT);

   Serial.begin(9600);
   Serial2.begin(4800);

-  pinMode(SWITCH, INPUT_PULLUP);
-
-  pinMode(RE, OUTPUT);
-  pinMode(DE, OUTPUT);
-  digitalWrite(RE, HIGH);
-  digitalWrite(DE, HIGH);
+  pinMode(12, INPUT_PULLUP);
+
+  pinMode(6, OUTPUT);
+  pinMode(7, OUTPUT);
+  digitalWrite(6, HIGH);
+  digitalWrite(7, HIGH);

 }

+bool oki = false;
 uint32_t dataOut[5] = {0,0,0,0,0};
 long dataIn = 0;
-
 char tag;
 bool inv = false;
+
 uint8_t completo = 0;

 String inString = "";

 void loop() {
-
+  /*// put your main code here, to run repeatedly:
+    if (digitalRead(12)) {
+    digitalWrite(52,HIGH);
+    if (oki) {
+      Serial2.println("ciao");
+      oki = false;
+    }
+    }
+    else {
+    digitalWrite(52,LOW);
+    oki = true;
+    }*/
   if (Serial.available() > 0) {
     int inChar = Serial.read();
     if (isDigit(inChar)) {
@@ -55,14 +65,10 @@
       switch (tag) {
         case 'a':   //pos A
           dataOut[completo] = dataIn * (100800 / 360) + 500000;
-          Serial.println(tag);
-
-          Serial.print(dataIn);
-          Serial.print(" // ");
-          Serial.print(dataOut[completo]);
-          Serial.print(" // ");
-          Serial.println(completo);
-
+          Serial.print(tag);
+          Serial.print(dataIn);
+          Serial.print(" // ");
+          Serial.println(dataOut[completo]);
           completo++;
           break;
         case 'A':
@@ -73,25 +79,17 @@
             dataOut[completo] = dataIn * (100800 / 360) + 16500000;
           }
           Serial.print(tag);
-
-          Serial.print(dataIn);
-          Serial.print(" // ");
-          Serial.print(dataOut[completo]);
-          Serial.print(" // ");
-          Serial.println(completo);
-
-          completo = 6;
+          Serial.print(dataIn);
+          Serial.print(" // ");
+          Serial.println(dataOut[completo]);
+          completo++;
           break;
         case 'b':   //pos B
           dataOut[completo] = dataIn * (100800 / 360) + 2500000;
           Serial.print(tag);
-
-          Serial.print(dataIn);
-          Serial.print(" // ");
-          Serial.print(dataOut[completo]);
-          Serial.print(" // ");
-          Serial.println(completo);
-
+          Serial.print(dataIn);
+          Serial.print(" // ");
+          Serial.println(dataOut[completo]);
           completo++;
           break;
         case 'B':   //vel B
@@ -102,25 +100,17 @@
             dataOut[completo] = dataIn * (100800 / 360) + 17500000;
           }
           Serial.print(tag);
-
-          Serial.print(dataIn);
-          Serial.print(" // ");
-          Serial.print(dataOut[completo]);
-          Serial.print(" // ");
-          Serial.println(completo);
-
-          completo = 6;
+          Serial.print(dataIn);
+          Serial.print(" // ");
+          Serial.println(dataOut[completo]);
+          completo++;
           break;
         case 'c':   //pos C
           dataOut[completo] = dataIn * (100800 / 360) + 6500000;
           Serial.print(tag);
-
-          Serial.print(dataIn);
-          Serial.print(" // ");
-          Serial.print(dataOut[completo]);
-          Serial.print(" // ");
-          Serial.println(completo);
-
+          Serial.print(dataIn);
+          Serial.print(" // ");
+          Serial.println(dataOut[completo]);
           completo++;
           break;
         case 'C':
@@ -131,11 +121,17 @@
             dataOut[completo] = dataIn * (100800 / 360) + 18500000;
           }
           Serial.print(tag);
-          completo = 6;
+          Serial.print(dataIn);
+          Serial.print(" // ");
+          Serial.println(dataOut[completo]);
+          completo++;
           break;
         case 'd':   //pos D
           dataOut[completo] = dataIn * (100800 / 360) + 8500000;
           Serial.print(tag);
+          Serial.print(dataIn);
+          Serial.print(" // ");
+          Serial.println(dataOut[completo]);
           completo++;
           break;
         case 'D':
@@ -146,11 +142,17 @@
             dataOut[completo] = dataIn * (100800 / 360) + 19500000;
           }
           Serial.print(tag);
-          completo = 6;
+          Serial.print(dataIn);
+          Serial.print(" // ");
+          Serial.println(dataOut[completo]);
+          completo++;
           break;
         case 'e':   //pos E
           dataOut[completo] = dataIn * (100800 / 360) + 10500000;
           Serial.print(tag);
+          Serial.print(dataIn);
+          Serial.print(" // ");
+          Serial.println(dataOut[completo]);
           completo++;
           break;
         case 'E':
@@ -161,39 +163,54 @@
             dataOut[completo] = dataIn * (100800 / 360) + 20500000;
           }
           Serial.print(tag);
+          Serial.print(dataIn);
+          Serial.print(" // ");
+          Serial.println(dataOut[completo]);
           completo++;
           break;
         case 's':
           dataOut[completo] = 15500000;
-          completo = 6;
+          Serial.print("Stop // ");
+          Serial.println(dataOut[completo]);
+          Serial2.print(dataOut[completo]);
+          completo++;
           break;
         case 'z':
+          Serial.println("z");
+          Serial.println(dataOut[completo]);
           switch (dataIn) {
             case 1:
-              dataOut[completo] = 4500000;
-              completo = 6;
+              Serial.print("zerosA // ");
+              Serial.println(4500000);
               break;
             case 2:
-              dataOut[completo] = 5500000;
-              completo = 6;
+              Serial.print("zerosB // ");
+              Serial.println(5500000);
               break;
             case 3:
-              dataOut[completo] = 12500000;
-              completo = 6;
+              Serial.print("zerosC // ");
+              Serial.println(12500000);
               break;
             case 4:
-              dataOut[completo] = 13500000;
-              completo = 6;
+              Serial.print("zerosD // ");
+              Serial.println(13500000);
               break;
             case 5:
-              dataOut[completo] = 14500000;
-              completo = 6;
+              Serial.print("zerosE // ");
+              Serial.println(14500000);
               break;
             default:
               Serial.println("motore non esistente");
               break;
-          }
-          break;
+          completo++;
+          }
+          break;
+        case 'g':
+          for (uint8_t i = 0; i<completo; i++) {
+            Serial.println(dataOut[completo]);
+            Serial2.print(dataOut[completo]);
+          }
+
         default:
           Serial.println("comando inesistente");
           break;
@@ -201,19 +218,7 @@

       inString = "";

-    }
-  }
-
-  if (completo == 5) {
-    for (int i=0; i<5; i++) {
-      Serial2.print(dataOut[i]);
-    }
-    Serial2.print(666);
-    completo = 0;
-  }
-  if (completo == 6) {
-    Serial2.print(dataOut[0]);
-    completo = 0;
-  }
-
+    } //chiudo if inChar == '\n'
+
+  } // chiudo if serial available
 }


Outlining drive and articulation drivers for the Transporter device.

--- src/SabertoothDriverROS/SabertoothDriverROS.ino
+++ src/SabertoothDriverROS/SabertoothDriverROS.ino
@@ -27,6 +27,13 @@
 const unsigned char MIDDLE_RIGHT_DRIVE_MOTOR_ID = 3;
 const unsigned char REAR_LEFT_DRIVE_MOTOR_ID = 4;
 const unsigned char REAR_RIGHT_DRIVE_MOTOR_ID = 5;
+// Articulation motors
+const unsigned char FRONT_LEFT_ARTICULATION_MOTOR_ID = 6;
+const unsigned char FRONT_RIGHT_ARTICULATION_MOTOR_ID = 7;
+const unsigned char MIDDLE_LEFT_ARTICULATION_MOTOR_ID = 8;
+const unsigned char MIDDLE_RIGHT_ARTICULATION_MOTOR_ID = 9;
+const unsigned char REAR_LEFT_ARTICULATION_MOTOR_ID = 10;
+const unsigned char REAR_RIGHT_ARTICULATION_MOTOR_ID = 11;

 // Motor addressing (used to link the computer-constants to
 // commands sent to the saberteeth).
@@ -36,6 +43,14 @@
 const unsigned char MIDDLE_RIGHT_DRIVE_MOTOR_ADDRESS = 129;
 const unsigned char REAR_LEFT_DRIVE_MOTOR_ADDRESS = 128;
 const unsigned char REAR_RIGHT_DRIVE_MOTOR_ADDRESS = 128;
+// Articulation motor addressing
+const unsigned char FRONT_LEFT_ARTICULATION_MOTOR_ADDRESS = 000;
+const unsigned char FRONT_RIGHT_ARTICULATION_MOTOR_ADDRESS = 000;
+const unsigned char MIDDLE_LEFT_ARTICULATION_MOTOR_ADDRESS = 000;
+const unsigned char MIDDLE_RIGHT_ARTICULATION_MOTOR_ADDRESS = 000;
+const unsigned char REAR_LEFT_ARTICULATION_MOTOR_ADDRESS = 000;
+const unsigned char REAR_RIGHT_ARTICULATION_MOTOR_ADDRESS = 000;
+

 // Motor addressing offset: If a motor is connected to M1,
 // This will be 0. If the motor is connected to M2, this should
@@ -48,23 +63,43 @@
 const unsigned char MIDDLE_RIGHT_DRIVE_MOTOR_COMMAND = 0;
 const unsigned char REAR_LEFT_DRIVE_MOTOR_COMMAND = 0;
 const unsigned char REAR_RIGHT_DRIVE_MOTOR_COMMAND = 4;
+// Articulation motor offsets. 0 or 4 corresponds to "counterclockwise".
+// a value of 1 or 5 corresponds to "clockwise".
+const unsigned char FRONT_LEFT_ARTICULATION_MOTOR_COMMAND = 0;
+const unsigned char FRONT_RIGHT_ARTICULATION_MOTOR_COMMAND = 0;
+const unsigned char MIDDLE_LEFT_ARTICULATION_MOTOR_COMMAND = 0;
+const unsigned char MIDDLE_RIGHT_ARTICULATION_MOTOR_COMMAND = 0;
+const unsigned char REAR_LEFT_ARTICULATION_MOTOR_COMMAND = 0;
+const unsigned char REAR_RIGHT_ARTICULATION_MOTOR_COMMAND = 0;

 // shorthand that will allow us to use the motor ID as an array index to access
 // the relevant constants.
-const unsigned char DRIVE_MOTOR_ADDRESS[6] = {
+const unsigned char MOTOR_ADDRESS[12] = {
   FRONT_LEFT_DRIVE_MOTOR_ADDRESS,
   FRONT_RIGHT_DRIVE_MOTOR_ADDRESS,
   MIDDLE_LEFT_DRIVE_MOTOR_ADDRESS,
   MIDDLE_RIGHT_DRIVE_MOTOR_ADDRESS,
   REAR_LEFT_DRIVE_MOTOR_ADDRESS,
-  REAR_RIGHT_DRIVE_MOTOR_ADDRESS};
-const unsigned char DRIVE_MOTOR_COMMAND[6] = {
+  REAR_RIGHT_DRIVE_MOTOR_ADDRESS,
+  FRONT_LEFT_ARTICULATION_MOTOR_ADDRESS,
+  FRONT_RIGHT_ARTICULATION_MOTOR_ADDRESS,
+  MIDDLE_LEFT_ARTICULATION_MOTOR_ADDRESS,
+  MIDDLE_RIGHT_ARTICULATION_MOTOR_ADDRESS,
+  REAR_LEFT_ARTICULATION_MOTOR_ADDRESS,
+  REAR_RIGHT_ARTICULATION_MOTOR_ADDRESS};
+const unsigned char MOTOR_COMMAND[12] = {
   FRONT_LEFT_DRIVE_MOTOR_COMMAND,
   FRONT_RIGHT_DRIVE_MOTOR_COMMAND,
   MIDDLE_LEFT_DRIVE_MOTOR_COMMAND,
   MIDDLE_RIGHT_DRIVE_MOTOR_COMMAND,
   REAR_LEFT_DRIVE_MOTOR_COMMAND,
-  REAR_RIGHT_DRIVE_MOTOR_COMMAND};
+  REAR_RIGHT_DRIVE_MOTOR_COMMAND,
+  FRONT_LEFT_ARTICULATION_MOTOR_COMMAND,
+  FRONT_RIGHT_ARTICULATION_MOTOR_COMMAND,
+  MIDDLE_LEFT_ARTICULATION_MOTOR_COMMAND,
+  MIDDLE_RIGHT_ARTICULATION_MOTOR_COMMAND,
+  REAR_LEFT_ARTICULATION_MOTOR_COMMAND,
+  REAR_RIGHT_ARTICULATION_MOTOR_COMMAND};

 // Track current motor status so we don't overload our serial lines
@@ -128,8 +163,8 @@
 void driveForwards(char speed, char motor){
   // Build the data packet:
   // Get the address and motor command ID from a predefined array.
-  unsigned char address = DRIVE_MOTOR_ADDRESS[motor];
-  unsigned char command = DRIVE_MOTOR_COMMAND[motor];
+  unsigned char address = MOTOR_ADDRESS[motor];
+  unsigned char command = MOTOR_COMMAND[motor];
   unsigned char checksum = (address + command + speed) & 0b01111111;
   // Write the packet.
   Serial3.write(address);
@@ -141,8 +176,8 @@
 // Function to drive a specific motor backwards.
 // Packet format: Address Byte, Command Byte, Value Byte, Checksum.
 void driveBackwards(char speed, char motor){
-  unsigned char address = DRIVE_MOTOR_ADDRESS[motor];
-  unsigned char command = DRIVE_MOTOR_COMMAND[motor] + 1;
+  unsigned char address = MOTOR_ADDRESS[motor];
+  unsigned char command = MOTOR_COMMAND[motor] + 1;
   unsigned char checksum = (address + command + speed) & 0b01111111;
   Serial3.write(address);
   Serial3.write(command);


Delete rov.ino

Delete rov.ino

--- arduino/rov.ino
+++ arduino/rov.ino
@@ -1,22 +0,0 @@
-#include "rov.h" // Main header file
-#include "mpu01.h" // MPU6050 header file
-#include <Servo.h>
-#include <Wire.h> //Gyroscope
-Servo panServo;
-Servo tiltServo;
-
-// Create structures that hold sensor values and actuator positions
-SENS sens;
-ACT act;
-
-void setup() {
-  Serial.begin (115200); //9600 115200
-  startPins();
-  initialize();
-}
-
-void loop() {
-  sens = readSensors(); // Read sensors values
-  act = communicate(sens, act); // Send sensor values and receive actuator values if new
-  moveActuator(act); // Update position of actuators
-}


Change &PBSAVE at &W, expand phone book to 9, add AT&DEBUG=0/1

--- MicroView/WiFiModem-Menu/WiFiModem-Menu.ino
+++ MicroView/WiFiModem-Menu/WiFiModem-Menu.ino
@@ -68,14 +68,16 @@
 char autoConnectHost = 0;
 boolean autoConnectedAtBootAlready = 0;           // We only want to auto-connect once..
 #define ADDR_HOST_SIZE     40
+#define ADDR_HOST_ENTRIES  9

 // EEPROM Addresses
 #define ADDR_PETSCII       0
 #define ADDR_AUTOSTART     1
 #define ADDR_BAUD_LO       2
 #define ADDR_BAUD_HI       3
+#define ADDR_DEBUG         4
 #define ADDR_HOST_AUTO    99     // Autostart host number
-#define ADDR_HOSTS         100    // to 299 with ADDR_HOST_SIZE = 40
+#define ADDR_HOSTS         100    // to 299 with ADDR_HOST_SIZE = 40 and ADDR_HOST_ENTRIES = 5
 //#define ADDR_xxxxx         300

 // PETSCII state
@@ -176,7 +178,11 @@

         DisplayBoth(F("Wi-Fi Init..."));

-        boolean ok = wifly.begin(&WifiSerial, &C64Serial);
+        boolean ok;
+        if(EEPROM.read(ADDR_DEBUG) == 1)
+           ok = wifly.begin(&WifiSerial, &C64Serial);
+        else
+           ok = wifly.begin(&WifiSerial);

         if (ok)
         {
@@ -1393,9 +1399,10 @@
     }
     else if (strcmp(Modem_CommandBuffer, ("AT&F")) == 0)
     {
-            Modem_LoadDefaults();
-            Modem_PrintOK();
-        }
+        Modem_LoadDefaults();
+        updateEEPROMByte(ADDR_DEBUG,0);
+        Modem_PrintOK();
+    }
     else if (strcmp(Modem_CommandBuffer, ("ATA")) == 0)
     {
         Modem_Answer();
@@ -1420,7 +1427,7 @@
         char address[ADDR_HOST_SIZE];

         int phoneBookNumber = atoi(numString);
-        if (phoneBookNumber >= 1 && phoneBookNumber <= 5)
+        if (phoneBookNumber >= 1 && phoneBookNumber <= ADDR_HOST_ENTRIES)
         {
             strncpy(address,readEEPROMPhoneBook(ADDR_HOSTS + ((phoneBookNumber-1) * ADDR_HOST_SIZE)).c_str(),ADDR_HOST_SIZE);
             Modem_Dialout(address);
@@ -1479,13 +1486,6 @@

         Modem_PrintOK();
     }
-    else if (strncmp(Modem_CommandBuffer, ("AT&SAVE"), 7) == 0)
-    {
-        if (wifly.save())
-            Modem_PrintOK();
-        else
-            Modem_PrintERROR();
-    }
     // AT&PB1=bbs.jammingsignal.com:23
     else if (strncmp(Modem_CommandBuffer, ("AT&PBAUTO="), 10) == 0)
     {
@@ -1494,7 +1494,7 @@
         numString[1] = '\0';

         int phoneBookNumber = atoi(numString);
-        if (phoneBookNumber >= 0 && phoneBookNumber <= 5)
+        if (phoneBookNumber >= 0 && phoneBookNumber <= ADDR_HOST_ENTRIES)
         {
             updateEEPROMByte(ADDR_HOST_AUTO, phoneBookNumber);

@@ -1502,9 +1502,10 @@
         }
         else
             Modem_PrintERROR();
-    }    else if (strncmp(Modem_CommandBuffer, ("AT&PB?"), 6) == 0)
-    {
-        for (int i = 0; i < 5; i++)
+    }
+    else if (strstr(Modem_CommandBuffer, ("AT&PB?")) != NULL)
+    {
+        for (int i = 0; i < ADDR_HOST_ENTRIES; i++)
         {
             C64Serial.print(i+1);
             C64Print(F(":"));
@@ -1516,9 +1517,9 @@
         C64Println();
         Modem_PrintOK();
     }
-    else if (strncmp(Modem_CommandBuffer, ("AT&PBCLEAR"), 6) == 0)
-    {
-        for (int i = 0; i < 5; i++)
+    else if (strstr(Modem_CommandBuffer, ("AT&PBCLEAR")) != NULL)
+    {
+        for (int i = 0; i < ADDR_HOST_ENTRIES; i++)
         {
             updateEEPROMPhoneBook(ADDR_HOSTS + (i * ADDR_HOST_SIZE), "\0");
         }
@@ -1532,7 +1533,7 @@
         numString[1] = '\0';

         int phoneBookNumber = atoi(numString);
-        if (phoneBookNumber >= 1 && phoneBookNumber <= 5)
+        if (phoneBookNumber >= 1 && phoneBookNumber <= ADDR_HOST_ENTRIES)
         {
             updateEEPROMPhoneBook(ADDR_HOSTS + ((phoneBookNumber-1) * ADDR_HOST_SIZE), Modem_CommandBuffer + 7);
             Modem_PrintOK();
@@ -1592,7 +1593,22 @@
         {
             Modem_flowControl = true;
         }
-
+        if (strstr(Modem_CommandBuffer, ("&W")) != NULL)
+        {
+            if (wifly.save())
+                Modem_PrintOK();
+            else
+                Modem_PrintERROR();
+        }
+        if (strstr(Modem_CommandBuffer, ("&DEBUG=1")) != NULL)
+        {
+            updateEEPROMByte(ADDR_DEBUG,1);
+        }
+        if (strstr(Modem_CommandBuffer, ("&DEBUG=0")) != NULL)
+        {
+            updateEEPROMByte(ADDR_DEBUG,0);
+        }
+
         char *currentS;
         char temp[100];

@@ -1897,7 +1913,7 @@
     //	digitalWrite(DTE_RTS, LOW);
     //}

-    if (autoConnectHost >=1 && autoConnectHost <= 5 && !autoConnectedAtBootAlready)
+    if (autoConnectHost >=1 && autoConnectHost <= ADDR_HOST_ENTRIES && !autoConnectedAtBootAlready)
     {
         // Phonebook dial
         autoConnectedAtBootAlready = 1;
@@ -2088,14 +2104,14 @@
     return baud;
 }

-void updateEEPROMByte(byte address, byte value)
+void updateEEPROMByte(int address, byte value)
 {
     if (EEPROM.read(address) != value)
         EEPROM.write(address, value);
 }

 //void updateEEPROMPhoneBook(byte address, String host, int port)
-void updateEEPROMPhoneBook(byte address, String host)
+void updateEEPROMPhoneBook(int address, String host)
 {
     int i=0;
     for (; i < 38; i++)
@@ -2110,7 +2126,7 @@
     updateEEPROMByte(address+i,b);*/
 }

-String readEEPROMPhoneBook(byte address)
+String readEEPROMPhoneBook(int address)
 {
     char host[38];
     int i=0;


Adding some more dynamic data to generated web page; digital pin values.

--- examples/Ethernet/CosaWebServer/CosaWebServer.ino
+++ examples/Ethernet/CosaWebServer/CosaWebServer.ino
@@ -89,15 +89,16 @@
   while ((res = sock->available()) == 0);
   if (res < 0) goto error;
   TRACE(sock->available());
-  trace << PSTR("Request#") << nr << endl;

   // Read request and print in debug mode. Ignore contents
+#ifndef NDEBUG
+  trace << PSTR("Request#") << nr << endl;
   while ((res = sock->recv(buf, sizeof(buf) - 1)) > 0) {
-#ifndef NDEBUG
     buf[res] = 0;
     trace << buf;
+  }
+  trace << endl;
 #endif
-  }

   // Reply page; header and footer are static, contents dynamic
   static const char header[] PROGMEM =
@@ -117,13 +118,15 @@

   // Construct the page; header-contents-footer
   page << header;
-  page << PSTR("Requests: ") << nr++ << BR;
+  for (uint8_t i = 0; i < 14; i++)
+    page << PSTR("D") << i << PSTR(": ") << InputPin::read(i) << BR;
   for (uint8_t i = 0; i < 4; i++)
     page << PSTR("A") << i << PSTR(": ") << AnalogPin::sample(i) << BR;
   page << PSTR("Vcc (mV): ") << AnalogPin::bandgap() << BR;
   page << PSTR("Memory (byte): ") << free_memory();
   page << PSTR("(") << setup_free_memory << PSTR(")") << BR;
   page << PSTR("Uptime (s): ") << Watchdog::millis() / 1000 << BR;
+  page << PSTR("Requests: ") << nr++ << BR;
   page << footer;
   page << flush;


Count down every 4 instead of 1 seconds in the Parkinglot sketch

--- examples/04.FSM/Parkinglot/Parkinglot.ino
+++ examples/04.FSM/Parkinglot/Parkinglot.ino
@@ -16,7 +16,7 @@
 void setup(void)
 {
   shield.setRepeatInterval(250);
-  scheduler.addTask(&parkinglot, 1000, true);
+  scheduler.addTask(&parkinglot, 4000, true);
 }

 void loop(void)


Teensy MIDI fix

Teensy MIDI fix

This fixes issues with the reuse of OPL2 channels in the TeensyMidi
sketch. Issues in the function to get a free OPL2 channel would return
the wrong channel causing clicks and pops. This fix eliminates this
issue mostly, though not fully as it also depends on the instrument
being used.

--- examples/Teensy/TeensyMidi/TeensyMidi.ino
+++ examples/Teensy/TeensyMidi/TeensyMidi.ino
@@ -126,6 +126,8 @@
  * Handle a note on MIDI event to play a note.
  */
 void onNoteOn(byte channel, byte note, byte velocity) {
+	channel = channel % 16;
+
 	// Treat notes with a velocity of 0 as note off.
 	if (velocity == 0) {
 		onNoteOff(channel, note, velocity);


Added Libraries and started on initialization

--- Arduino/sensors/sensors.ino
+++ Arduino/sensors/sensors.ino
@@ -29,16 +29,27 @@
      A3  ADXL193 Output
 */

+//// Includes ////
 #include "libraries/SparkFun_LSM9DS1/SparkFunLSM9DS1.h"   // 9DOF Sensor
-#include "libraries/Adafruit_ADS1X15/Adafruit_ADS1015.h"  // ADC
+#include "libraries/Adafruit_ADS1X15/Adafruit_ADS1015.h"  // 16 Bit ADC
 #include "libraries/ITG3701/ITG3701.h"                    // ITG3701
+#include <Wire.h>                                         // I2C
+#include <SPI.h>                                          // SPI
+
+//// Object declarations ////
+LSM9DS1           LSM;    // Declare 9DOF object  (addr 0x1E, 0x6B)
+Adafruit_ADS1115  ADS;    // Declare ADC object   (addr 0x48)

 void setup() {
-  // put your setup code here, to run once:
-
+  LSM.settings.device.commInterface = IMU_MODE_I2C;
+  LSM.settings.device.mAddress      = 0x1E;
+  LSM.settings.device.agAddress     = 0x6B;
+  LSM.begin();          // Initialize the 9DOF
+  ADS.begin();          // Initialzie the ADC
+  Serial.begin(115200); // Intialize serial line
+  Serial.println("Setup successfully completed"); // Announce the completion of setup
 }

 void loop() {
-  // put your main code here, to run repeatedly:

 }


player push button interrupt is removed from WWW mode

--- code/PABS/PABS.ino
+++ code/PABS/PABS.ino
@@ -38,6 +38,7 @@
 		SystemMethodsObject.SetDisplayNumber(11);
 		gameMode = new TestMode();
 		Serial.write("TestMode");
+		attachInterrupt(1,UserInterrupt,RISING);
 	}
 	else
 	{
@@ -46,6 +47,7 @@
 			SystemMethodsObject.SetDisplayNumber(22);
 			gameMode = new BrainRingMode();
 			Serial.write("BrainMode");
+			attachInterrupt(1,UserInterrupt,RISING);
 		}
 		else
 		{
@@ -54,6 +56,7 @@
 				SystemMethodsObject.SetDisplayNumber(33);
 				gameMode = new OwnGameMode();
 				Serial.write("OwnGameMode");
+				attachInterrupt(1,UserInterrupt,RISING);
 			}
 			else
 			{
@@ -61,9 +64,9 @@
 				{
 					SystemMethodsObject.SetDisplayNumber(44);
 					gameMode = new WwwMode();
-					  Timer1.initialize(1000000);
-				      Timer1.attachInterrupt(TimerInterrupt);
-					  Serial.write("WwwMode!");
+					Timer1.initialize(1000000);
+					Timer1.attachInterrupt(TimerInterrupt);
+					Serial.write("WwwMode!");

 				}
 			}
@@ -74,7 +77,6 @@
 	SystemMethodsObject.PlaySound(1000,1000);

 	attachInterrupt(0,AdminInterrupt,RISING);
-	attachInterrupt(1,UserInterrupt,RISING);
 }

 void loop()
@@ -96,7 +98,7 @@
 			gameMode ->AdminButtonPush(Constants.adminSet);
 		}
 	}
-	 interrupts();
+	interrupts();
 }

 void UserInterrupt()
@@ -134,11 +136,11 @@
 			}
 		}
 	}
-	 interrupts();
+	interrupts();
 }

 void TimerInterrupt()
 {
-   gameMode ->PlayerButtonPush(Constants.player5);
+	gameMode ->PlayerButtonPush(Constants.player5);
 }


Updated to use new disk sensors; ring of IR steps rather than a single hall effect sensor

--- arduino/DiskInterface/DiskInterface.ino
+++ arduino/DiskInterface/DiskInterface.ino
@@ -5,18 +5,17 @@

   Example commands:

+HELLO
 DISK-RESET
-DISK-STATE success
-DISK 0 POS 10 DIR 1 USER 1
-DISK 1 POS 50 DIR 1 USER 1
-DISK 2 POS 60 DIR 1 USER 2
+DISK 0 POS 10 DIR 1
+DISK 1 POS 50 DIR 1
+DISK 2 POS 60 DIR 1
 DISK 0 DIR 0 USER 1
 DISK 0 DIR 1 USER 1
 DISK 0 DIR -1 USER 1
 DISK 0 DIR 1 USER 1
 DISK 1 DIR -1 USER 1
 DISK 2 DIR 1 USER 1
-DISK-EXIT

 */

@@ -24,37 +23,38 @@
 #error Oops!  Make sure you have 'Teensy 3.1' selected from the 'Tools -> Board' menu.
 #endif

-#include "./Timer.h"
-#include "./Bounce2.h"
 #include "DiskInterface.h"
 #include "anyware_serial.h"

 // Set to 1 to start in debug mode
 #define DEBUG_MODE 0

+// All disks
+const int STEPS_PER_REVOLUTION = 180;
+
 // Bottom disk
-const int DISK0_HOME_SENSOR = A0;
-const int DISK0_ENC_A = 5;
-const int DISK0_ENC_B = 6;
-const int DISK0_MOTOR_A = 4;
-const int DISK0_MOTOR_B = 3;
-const int DISK0_TICKS_PER_REVOLUTION = 30089;
+const int DISK0_STEP_SENSOR = 2;
+const int DISK0_ENC_A = 17;
+const int DISK0_ENC_B = 16;
+const int DISK0_MOTOR_A = 21;
+const int DISK0_MOTOR_B = 20;
+const int DISK0_TICKS_PER_STEP = 36;

 // Middle disk
-const int DISK1_HOME_SENSOR = A1;
-const int DISK1_ENC_A = 9;
-const int DISK1_ENC_B = 10;
-const int DISK1_MOTOR_A = 8;
-const int DISK1_MOTOR_B = 7;
-const int DISK1_TICKS_PER_REVOLUTION = 31348;
+const int DISK1_STEP_SENSOR = 1;
+const int DISK1_ENC_A = 11;
+const int DISK1_ENC_B = 12;
+const int DISK1_MOTOR_A = 3;
+const int DISK1_MOTOR_B = 5;
+const int DISK1_TICKS_PER_STEP = 56;

 // Top disk
-const int DISK2_HOME_SENSOR = A2;
-const int DISK2_ENC_A = 20;
-const int DISK2_ENC_B = 19;
-const int DISK2_MOTOR_A = 17;
-const int DISK2_MOTOR_B = 18;
-const int DISK2_TICKS_PER_REVOLUTION = 31385;
+const int DISK2_STEP_SENSOR = 0;
+const int DISK2_ENC_A = 19;
+const int DISK2_ENC_B = 18;
+const int DISK2_MOTOR_A = 22;
+const int DISK2_MOTOR_B = 23;
+const int DISK2_TICKS_PER_STEP = 36;

 // Globals

@@ -64,48 +64,43 @@
 #define USER1_STR "1"
 #define USER2_STR "2"

-Timer timer;
-int8_t homingIdx = -1;
-
 struct Disk {
   int id;
-  int homeSensor;
+  int stepSensor;
   int enca, encb;
   int motorA,motorB;
-  uint32_t ticksPerRevolution;
+  uint16_t ticksPerStep;

   void (*enca_isr)();
   void (*encb_isr)();
+  void (*step_isr)();

   bool enca_val;
   bool encb_val;
-
-  int magnetValue;
-  int lastMagnetValue;
-
-  uint16_t targetPosition;
+  bool step_val;
+
+  int16_t targetPosition;
   uint16_t actualPosition;
-  int32_t tickCount;
-  bool posChanged;
+  int16_t tickCount;
+  int16_t lastTickCount;
+  int16_t tickDir;
+  int16_t stepCount;

   Direction direction;

   static const int DISK_READY = 0;
   static const int DISK_HOMING = 1;
   int state;
-
-  int32_t lastExitTicks;
-  int32_t lastHitTicks;
-
-  Disk(int diskid, int hs, int enca, int encb, int ma, int mb, uint32_t ticks, void (*enca_isr)(), void (*encb_isr)()) :
-    id(diskid), homeSensor(hs), enca(enca), encb(encb), motorA(ma), motorB(mb),
-    ticksPerRevolution(ticks),
-    enca_isr(enca_isr), encb_isr(encb_isr),
+  uint8_t home;
+
+  Disk(int diskid, int stepsensor, int enca, int encb, int ma, int mb, uint16_t ticks,
+       void (*enca_isr)(), void (*encb_isr)(), void (*step_isr)()) :
+    id(diskid), stepSensor(stepsensor), enca(enca), encb(encb), motorA(ma), motorB(mb),
+    ticksPerStep(ticks),
+    enca_isr(enca_isr), encb_isr(encb_isr), step_isr(step_isr),
     enca_val(false), encb_val(false),
-    magnetValue(0), lastMagnetValue(0),
-    actualPosition(0), tickCount(0), posChanged(false),
-    direction(DIR_OFF), state(DISK_READY),
-    lastExitTicks(0), lastHitTicks(0)
+    actualPosition(0), tickCount(0), tickDir(DIR_OFF), lastTickCount(0), stepCount(0),
+    direction(DIR_OFF), state(DISK_READY), home(0)
   {
   }

@@ -114,33 +109,62 @@
     pinMode(motorB, OUTPUT);
     pinMode(enca, INPUT_PULLUP);
     pinMode(encb, INPUT_PULLUP);
+    pinMode(stepSensor, INPUT_PULLUP);
     enca_val = digitalRead(enca);
     encb_val = digitalRead(encb);
     reset();
     attachInterrupt(enca, enca_isr, CHANGE);
     attachInterrupt(encb, encb_isr, CHANGE);
+    attachInterrupt(stepSensor, step_isr, CHANGE);
   }

   void reset() {
     targetPosition = -1;
+    Serial.println("Reset");
     direction = DIR_OFF;
   }

-  inline uint16_t ticksToPos(int32_t ticks) {
-    if (ticks < 0) ticks += ticksPerRevolution;
-    return (ticks * 360 / ticksPerRevolution) % 360;
+  inline uint16_t calcPos() {
+    return (stepCount * 360 / STEPS_PER_REVOLUTION + tickCount * (360 / STEPS_PER_REVOLUTION) / ticksPerStep + 360)%360;
   }

   inline void handleEncA() {
     enca_val = digitalRead(enca);
-    if (enca_val != encb_val) tickCount = (tickCount-1+ticksPerRevolution)%ticksPerRevolution;
-    else tickCount = (tickCount+1)%ticksPerRevolution;
+    if (enca_val != encb_val) {
+      tickCount++;
+      tickDir = DIR_CCW;
+    }
+    else {
+      tickCount--;
+      tickDir = DIR_CW;
+    }
   }

   inline void handleEncB() {
     encb_val = digitalRead(encb);
-    if (enca_val == encb_val) tickCount = (tickCount-1+ticksPerRevolution)%ticksPerRevolution;
-    else tickCount = (tickCount+1)%ticksPerRevolution;
+    if (enca_val == encb_val) {
+      tickCount++;
+      tickDir = DIR_CCW;
+    }
+    else {
+      tickCount--;
+      tickDir = DIR_CW;
+    }
+  }
+
+  inline void handleStep() {
+    if (abs(tickCount) > ticksPerStep * 2) {
+      if (tickCount > 0) stepCount = 0;
+      else stepCount = STEPS_PER_REVOLUTION-3;
+      tickCount = 0;
+      if (state == DISK_HOMING) home++;
+    }
+    else {
+      if (tickDir == DIR_CCW) stepCount++;
+      else if (tickDir == DIR_CW) stepCount--;
+      lastTickCount = tickCount;
+      tickCount = 0;
+    }
   }

   void setState(int s) {
@@ -153,7 +177,8 @@
       break;
     case DISK_HOMING:
       Serial.println(" homing");
-      direction = DIR_CW;
+      setTargetPosition(-1, DIR_CW);
+      home = 0;
       break;
     }
   }
@@ -174,14 +199,6 @@
     return actualPosition;
   }

-  void readSensors() {
-    magnetValue = analogRead(homeSensor);
-    // if (magnetValue < 300 && magnetValue > 20) {
-    //   Serial.print(id);Serial.print(" ");
-    //   Serial.print(magnetValue);Serial.println();
-    // }
-  }
-
   void motorMove() {
     switch (direction) {
     case DIR_CW:
@@ -199,22 +216,15 @@
     }
   }

-  bool magnetActive(int magnetValue) {
-    return magnetValue < MAGNET_SENSITIVITY;
-  }
-
-  bool isHome() {
-    return (magnetActive(magnetValue) && !magnetActive(lastMagnetValue));
-  }
-
   void handleCount() {
-    uint16_t pos = ticksToPos(tickCount);
+    uint16_t pos = calcPos();
     if (pos != actualPosition) {
       actualPosition = pos;
       if (global_state == STATE_READY) {
         Serial.print("DISK ");Serial.print(id);
         Serial.print(" POS ");Serial.print(actualPosition);
         Serial.print(" DIR ");Serial.print(direction);
+        Serial.print(" STEPS ");Serial.print(stepCount);
         Serial.print(" TICKS ");Serial.print(tickCount);
         Serial.println();
       }
@@ -222,13 +232,11 @@
   }

   void manage() {
-
-    // Read local sensors
-    readSensors();
-
     if (state == DISK_HOMING) {
-      if (isHome()) {
-        tickCount = 0;
+      if (home == 1) {
+        direction = DIR_CCW;
+      }
+      else if (home == 2) {
         actualPosition = 0;
         setState(DISK_READY);
       }
@@ -237,33 +245,12 @@
       handleCount();

       if (targetPosition >= 0 && actualPosition == targetPosition) {
+        Serial.println("at wanted position");
         direction = DIR_OFF;
         targetPosition = -1;
       }
-
-      if (magnetActive(magnetValue) && !magnetActive(lastMagnetValue)) {
-        // Hit left side of magnet
-        int32_t tmpticks = tickCount;
-        if (global_state == STATE_READY && this->direction != DIR_OFF) {
-          Serial.print("DEBUG DISK ");
-          Serial.print(id);
-          Serial.print(" HIT TICKS " );
-          Serial.println(tmpticks);
-        }
-        lastHitTicks = tmpticks;
-      }
-      else if (!magnetActive(magnetValue) && magnetActive(lastMagnetValue)) {
-        // Exited left side of magnet
-        // Serial.print(id);
-        // Serial.print(" EXIT TICKS " );
-        // Serial.println(tickCount);
-        lastExitTicks = tickCount;
-      }
-
     }
     motorMove();
-
-    lastMagnetValue = magnetValue;
   }
 };

@@ -279,6 +266,11 @@
   disk[0].handleEncB();
   sei();
 }
+void disk0step_isr() {
+  cli();
+  disk[0].handleStep();
+  sei();
+}
 void disk1a_isr() {
   cli();
   disk[1].handleEncA();
@@ -289,6 +281,11 @@
   disk[1].handleEncB();
   sei();
 }
+void disk1step_isr() {
+  cli();
+  disk[1].handleStep();
+  sei();
+}
 void disk2a_isr() {
   cli();
   disk[2].handleEncA();
@@ -299,29 +296,31 @@
   disk[2].handleEncB();
   sei();
 }
+void disk2step_isr() {
+  cli();
+  disk[2].handleStep();
+  sei();
+}

 Disk disk[3] = {
-  Disk(0, DISK0_HOME_SENSOR, DISK0_ENC_A, DISK0_ENC_B, DISK0_MOTOR_A, DISK0_MOTOR_B, DISK0_TICKS_PER_REVOLUTION, &disk0a_isr, &disk0b_isr),
-  Disk(1, DISK1_HOME_SENSOR, DISK1_ENC_A, DISK1_ENC_B, DISK1_MOTOR_A, DISK1_MOTOR_B, DISK1_TICKS_PER_REVOLUTION, &disk1a_isr, &disk1b_isr),
-  Disk(2, DISK2_HOME_SENSOR, DISK2_ENC_A, DISK2_ENC_B, DISK2_MOTOR_A, DISK2_MOTOR_B, DISK2_TICKS_PER_REVOLUTION, &disk2a_isr, &disk2b_isr)
+  Disk(0, DISK0_STEP_SENSOR, DISK0_ENC_A, DISK0_ENC_B, DISK0_MOTOR_A, DISK0_MOTOR_B, DISK0_TICKS_PER_STEP, &disk0a_isr, &disk0b_isr, &disk0step_isr),
+  Disk(1, DISK1_STEP_SENSOR, DISK1_ENC_A, DISK1_ENC_B, DISK1_MOTOR_A, DISK1_MOTOR_B, DISK1_TICKS_PER_STEP, &disk1a_isr, &disk1b_isr, &disk1step_isr),
+  Disk(2, DISK2_STEP_SENSOR, DISK2_ENC_A, DISK2_ENC_B, DISK2_MOTOR_A, DISK2_MOTOR_B, DISK2_TICKS_PER_STEP, &disk2a_isr, &disk2b_isr, &disk2step_isr)
 };

 void setGlobalState(int state) {
   if (state == STATE_HOMING) {
     global_state = STATE_BLOCKED; // Don't output anything before we start homing
-    // Move out of home zone for a bit to make sure we re-trigger the sensors
-    for (int i=0;i<3;i++) disk[i].setTargetPosition(-1, DIR_CCW);
-    homingIdx = timer.after(2000, startHoming, NULL);
+    startHoming();
   }
   else {
     global_state = state;
   }
 }

-void startHoming(void *context) {
+void startHoming() {
   global_state = STATE_HOMING;
   for (int i=0;i<3;i++) disk[i].setState(Disk::DISK_HOMING);
-  homingIdx = -1;
 }

 void manageDiskGame() {
@@ -331,11 +330,6 @@
       if (disk[i].getState() == Disk::DISK_HOMING) homed = false;
     }
     if (homed) {
-      // for (int i=0;i<3;i++) {
-      //   Serial.print(disk[i].id);
-      //   Serial.print(" HOME TICKS ");
-      //   Serial.println(disk[i].tickCount);
-      // }
       setGlobalState(STATE_READY);
     }
   }
@@ -391,7 +385,6 @@
 {
   handleSerial();

-  timer.update();
   manageDiskGame();
 }


merging

merging

--- deploy-dist/rootfolder/sketches/ArdulinkProtocol/ArdulinkProtocol.ino
+++ deploy-dist/rootfolder/sketches/ArdulinkProtocol/ArdulinkProtocol.ino
@@ -1,5 +1,5 @@
 /*
-Copyright 2013 Luciano Zu project Ardulink http://www.ardulink.org/
+Copyright 2013 project Ardulink http://www.ardulink.org/

 Licensed under the Apache License, Version 2.0 (the "License");
 you may not use this file except in compliance with the License.
@@ -227,236 +227,3 @@
     }
   }
 }
-
-
-/*
-Copyright 2013 Luciano Zu project Ardulink http://www.ardulink.org/
-
-Licensed under the Apache License, Version 2.0 (the "License");
-you may not use this file except in compliance with the License.
-You may obtain a copy of the License at
-
-    http://www.apache.org/licenses/LICENSE-2.0
-
-Unless required by applicable law or agreed to in writing, software
-distributed under the License is distributed on an "AS IS" BASIS,
-WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
-See the License for the specific language governing permissions and
-limitations under the License.
-
-This sketch is an example to understand how Arduino can recognize ALProtocol.
-However, it can easily be reused for their own purposes or as a base for a library.
-Read carefully the comments. When you find "this is general code you can reuse"
-then it means that it is generic code that you can use to manage the ALProtocol.
-When you find "this is needed just as example for this sketch" then it means that
-you code useful for a specific purpose. In this case you have to modify it to suit
-your needs.
-*/
-
-// int intensity = 0;               // led intensity this is needed just as example for this sketch
-String inputString = "";         // a string to hold incoming data (this is general code you can reuse)
-boolean stringComplete = false;  // whether the string is complete (this is general code you can reuse)
-
-#define digitalPinListeningNum 14 // Change 14 if you have a different number of pins.
-#define analogPinListeningNum 6 // Change 6 if you have a different number of pins.
-boolean digitalPinListening[digitalPinListeningNum]; // Array used to know which pins on the Arduino must be listening.
-boolean analogPinListening[analogPinListeningNum]; // Array used to know which pins on the Arduino must be listening.
-int digitalPinListenedValue[digitalPinListeningNum]; // Array used to know which value is read last time.
-int analogPinListenedValue[analogPinListeningNum]; // Array used to know which value is read last time.
-
-void setup() {
-  // initialize serial: (this is general code you can reuse)
-  Serial.begin(115200);
-
-  Serial.print("alp://rply/");
-  Serial.print("ok?id=0");
-  Serial.print('\n'); // End of Message
-  Serial.flush();
-
-  //set to false all listen variable
-  int index = 0;
-  for (index = 0; index < digitalPinListeningNum; index++) {
-    digitalPinListening[index] = false;
-    digitalPinListenedValue[index] = -1;
-  }
-  for (index = 0; index < analogPinListeningNum; index++) {
-    analogPinListening[index] = false;
-    analogPinListenedValue[index] = -1;
-  }
-
-  // Turn off everything (not on RXTX)
-  for (index = 2; index < digitalPinListeningNum; index++) {
-    pinMode(index, OUTPUT);
-    digitalWrite(index, LOW);
-  }
-
-  // Turn off LED this is needed just as example for this sketch
-//  analogWrite(11, intensity);
-
-  // Read from 4 this is needed just as example for this sketch
-//  pinMode(4, INPUT);
-
-  // In order to work with analog input signal you have to set pinMode to INPUT please add Ax pinMode statement if you need for it
-  //pinMode(A0, INPUT);
-
-}
-
-void loop() {
-  // when a newline arrives:
-  if (stringComplete) {
-
-    if(inputString.startsWith("alp://")) { // OK is a message I know (this is general code you can reuse)
-
-      boolean msgRecognized = true;
-
-      if(inputString.substring(6,10) == "kprs") { // KeyPressed
-        // here you can write your own code. For instance the commented code change pin intensity if you press 'a' or 's'
-        // take the command and change intensity on pin 11 this is needed just as example for this sketch
-        //char commandChar = inputString.charAt(14);
-        //if(commandChar == 'a' and intensity > 0) { // If press 'a' less intensity
-        //  intensity--;
-        //  analogWrite(11,intensity);
-        //} else if(commandChar == 's' and intensity < 125) { // If press 's' more intensity
-        //  intensity++;
-        //  analogWrite(11,intensity);
-        //}
-      } else if(inputString.substring(6,10) == "ppin") { // Power Pin Intensity (this is general code you can reuse)
-          int separatorPosition = inputString.indexOf('/', 11 );
-          String pin = inputString.substring(11,separatorPosition);
-          String intens = inputString.substring(separatorPosition + 1);
-          pinMode(pin.toInt(), OUTPUT);
-          analogWrite(pin.toInt(),intens.toInt());
-      } else if(inputString.substring(6,10) == "ppsw") { // Power Pin Switch (this is general code you can reuse)
-          int separatorPosition = inputString.indexOf('/', 11 );
-          String pin = inputString.substring(11,separatorPosition);
-          String power = inputString.substring(separatorPosition + 1);
-          pinMode(pin.toInt(), OUTPUT);
-          if(power.toInt() == 1) {
-            digitalWrite(pin.toInt(), HIGH);
-          } else if(power.toInt() == 0) {
-            digitalWrite(pin.toInt(), LOW);
-          }
-      } else if(inputString.substring(6,10) == "tone") { // tone request (this is general code you can reuse)
-          int firstSlashPosition = inputString.indexOf('/', 11 );
-          int secondSlashPosition = inputString.indexOf('/', firstSlashPosition + 1 );
-          int pin = inputString.substring(11,firstSlashPosition).toInt();
-          int frequency = inputString.substring(firstSlashPosition + 1, secondSlashPosition).toInt();
-          int duration = inputString.substring(secondSlashPosition + 1).toInt();
-          if(duration == -1) {
-          	tone(pin, frequency);
-          } else {
-          	tone(pin, frequency, duration);
-          }
-      } else if(inputString.substring(6,10) == "notn") { // no tone request (this is general code you can reuse)
-          int firstSlashPosition = inputString.indexOf('/', 11 );
-          int pin = inputString.substring(11,firstSlashPosition).toInt();
-          noTone(pin);
-      } else if(inputString.substring(6,10) == "srld") { // Start Listen Digital Pin (this is general code you can reuse)
-          String pin = inputString.substring(11);
-          digitalPinListening[pin.toInt()] = true;
-          digitalPinListenedValue[pin.toInt()] = -1; // Ensure a message back when start listen happens.
-          pinMode(pin.toInt(), INPUT);
-      } else if(inputString.substring(6,10) == "spld") { // Stop Listen Digital Pin (this is general code you can reuse)
-          String pin = inputString.substring(11);
-          digitalPinListening[pin.toInt()] = false;
-          digitalPinListenedValue[pin.toInt()] = -1; // Ensure a message back when start listen happens.
-      } else if(inputString.substring(6,10) == "srla") { // Start Listen Analog Pin (this is general code you can reuse)
-          String pin = inputString.substring(11);
-          analogPinListening[pin.toInt()] = true;
-          analogPinListenedValue[pin.toInt()] = -1; // Ensure a message back when start listen happens.
-      } else if(inputString.substring(6,10) == "spla") { // Stop Listen Analog Pin (this is general code you can reuse)
-          String pin = inputString.substring(11);
-          analogPinListening[pin.toInt()] = false;
-          analogPinListenedValue[pin.toInt()] = -1; // Ensure a message back when start listen happens.
-      } else {
-        msgRecognized = false; // this sketch doesn't know other messages in this case command is ko (not ok)
-      }
-
-      // Prepare reply message if caller supply a message id (this is general code you can reuse)
-      int idPosition = inputString.indexOf("?id=");
-      if(idPosition != -1) {
-        String id = inputString.substring(idPosition + 4);
-        // print the reply
-        Serial.print("alp://rply/");
-        if(msgRecognized) { // this sketch doesn't know other messages in this case command is ko (not ok)
-          Serial.print("ok?id=");
-        } else {
-          Serial.print("ko?id=");
-        }
-        Serial.print(id);
-        Serial.print('\n'); // End of Message
-        Serial.flush();
-      }
-    }
-
-    // clear the string:
-    inputString = "";
-    stringComplete = false;
-  }
-
-  // Send listen messages
-  int index = 0;
-  for (index = 0; index < digitalPinListeningNum; index++) {
-    if(digitalPinListening[index] == true) {
-      int value = digitalRead(index);
-      if(value != digitalPinListenedValue[index]) {
-        digitalPinListenedValue[index] = value;
-        Serial.print("alp://dred/");
-        Serial.print(index);
-        Serial.print("/");
-        Serial.print(value);
-        Serial.print('\n'); // End of Message
-        Serial.flush();
-      }
-    }
-  }
-  for (index = 0; index < analogPinListeningNum; index++) {
-    if(analogPinListening[index] == true) {
-      int value = highPrecisionAnalogRead(index);
-      if(value != analogPinListenedValue[index]) {
-        analogPinListenedValue[index] = value;
-        Serial.print("alp://ared/");
-        Serial.print(index);
-        Serial.print("/");
-        Serial.print(value);
-        Serial.print('\n'); // End of Message
-        Serial.flush();
-      }
-    }
-  }
-}
-
-// Reads 4 times and computes the average value
-int highPrecisionAnalogRead(int pin) {
-  int value1 = analogRead(pin);
-  int value2 = analogRead(pin);
-  int value3 = analogRead(pin);
-  int value4 = analogRead(pin);
-
-  int retvalue = (value1 + value2 + value3 + value4) / 4;
-  return retvalue;
-}
-
-/*
-  SerialEvent occurs whenever a new data comes in the
- hardware serial RX.  This routine is run between each
- time loop() runs, so using delay inside loop can delay
- response.  Multiple bytes of data may be available.
- This is general code you can reuse.
- */
-void serialEvent() {
-
-  while (Serial.available() && !stringComplete) {
-    // get the new byte:
-    char inChar = (char)Serial.read();
-    // add it to the inputString:
-    inputString += inChar;
-    // if the incoming character is a newline, set a flag
-    // so the main loop can do something about it:
-    if (inChar == '\n') {
-      stringComplete = true;
-    }
-  }
-}
-
-


fixed fatal syntax error

fixed fatal syntax error

--- exhaust_sensor_array.ino
+++ exhaust_sensor_array.ino
@@ -22,11 +22,11 @@
 // code!
 //#define DEBUG
 #ifdef DEBUG
-#define print   Serial.print
-#define println Serial.println
+#define fprint   Serial.print
+#define fprintln Serial.println
 #else
-#define print   log_file.print
-#define println log_file.println
+#define fprint   log_file.print
+#define fprintln log_file.println
 #endif

 int sensor_array[6];
@@ -35,36 +35,36 @@

   File log_file = SD.open("log.csv", FILE_WRITE);

-  print(gps.location.lat(), 6);
-  print(',');
-  print(gps.location.lng(), 6);
-  print(',');
-  print(gps.time.hour());
-  print(',');
-  print(gps.time.minute());
-  print(',');
-  print(gps.time.second());
-  print(',');
-  print(gps.date.day());
-  print(',');
-  print(gps.date.month());
-  print(',');
-  print(gps.date.year());
-  print(',');
-  print(gps.speed.mph());
-  print(',');
-  print(map(CO,  0, 1023, 20,  2000)); //ppm
-  print(',');
-  print(map(CO2, 0, 1023,  0, 10000)); //ppm
-  print(',');
-  print(map(O3,  0, 1023, 10,  2000)); //ppb
-  print(',');
-  print(map(NO,  0, 1023, 50, 10000)); //ppb
-  print(',');
-  print(map(TEMP, 0, 1023 , -40, 125)); // celsius
-  print(',');
-  print(map(WIND, 0, 1023 , 0, 100)); // meter per second
-  println();
+  fprint(gps.location.lat(), 6);
+  fprint(',');
+  fprint(gps.location.lng(), 6);
+  fprint(',');
+  fprint(gps.time.hour());
+  fprint(',');
+  fprint(gps.time.minute());
+  fprint(',');
+  fprint(gps.time.second());
+  fprint(',');
+  fprint(gps.date.day());
+  fprint(',');
+  fprint(gps.date.month());
+  fprint(',');
+  fprint(gps.date.year());
+  fprint(',');
+  fprint(gps.speed.mph());
+  fprint(',');
+  fprint(map(CO,  0, 1023, 20,  2000)); //ppm
+  fprint(',');
+  fprint(map(CO2, 0, 1023,  0, 10000)); //ppm
+  fprint(',');
+  fprint(map(O3,  0, 1023, 10,  2000)); //ppb
+  fprint(',');
+  fprint(map(NO,  0, 1023, 50, 10000)); //ppb
+  fprint(',');
+  fprint(map(TEMP, 0, 1023 , -40, 125)); // celsius
+  fprint(',');
+  fprint(map(WIND, 0, 1023 , 0, 100)); // meter per second
+  fprintln();

   log_file.close();
 }
@@ -74,18 +74,19 @@
   Serial.begin(9600);
   gps_port.begin(GPS_BAUD_RATE); //GPS Setup

+  #ifndef DEBUG
   //SD card start
   pinMode(SD_PIN, OUTPUT);
   digitalWrite(SD_PIN, HIGH);
   SD.begin(SD_PIN);
-//  if( !SD.begin(SD_PIN) ) Serial.println("ERROR: SD failure");
-
+
   //print header
-  if(!SD.exsists("log.csv")) {
+  if(!SD.exists("log.csv")) {
     File log_file = SD.open("log.csv", FILE_WRITE);
     log_file.println("latitude,longitude,hour,minute,second,day,month,year,speed (in mph),CO (in ppm),CO2 (in ppm),O3 (in ppb),NO (in ppb),tempurature (in celsius),wind speed (in meters per second)");
     log_file.close();
   }
+  #endif
 }

 void loop() {


removed set CLK code from main sketch

removed set CLK code from main sketch

--- code/arduino/main/aws_sketch/aws_sketch.ino
+++ code/arduino/main/aws_sketch/aws_sketch.ino
@@ -20,7 +20,6 @@
 #include <Time.h>
 #include <TimeAlarms.h>
 #include <DS1307RTC.h>
-#include <AWS.h>

 // @change pins and output modes
 #define DHT22_PIN 6
@@ -57,52 +56,46 @@
 float humidity ;
 int32_t pressure ;

-const char *month_names[12] = {
-  "Jan", "Feb", "Mar", "Apr", "May", "Jun",
-  "Jul", "Aug", "Sep", "Oct", "Nov", "Dec"
-};
-
-tmElements_t tm;
-
 // return codes
 DHT22_ERROR_t dht22_code ;
-aws_error_t rtc_code ;

 void setup() {
+
+#if !defined(AWS_NO_SERIAL)
+    Serial.begin(9600);
+#endif

     // watchdog enabled
     wdt_enable(WDTO_8S);

-    // DS1307 RTC
+    // synchronize time library with DS1307 RTC
     // DS1307RTC instance created in DS1307 lib
     // DS1307RTC RTC = DS1307RTC();
     // DS1307RTC constructor calls Wire.begin()
     // sync interval is default 5 minutes

-    rtc_code = init_rtc(__TIME__,__DATE__);
-    micro_delay(20);
-
-    if(rtc_code == AWS_RTC_ERROR_NONE) {
-        setSyncProvider(RTC.get);
-        if(timeStatus()!= timeSet) {
-            // wait a bit
-            micro_delay(400);
-        }
-
-        // try again
-        if(timeStatus()!= timeSet) {
-          rtc_code = AWS_RTC_SYNC_ERROR ;
-        }
-    }
+    setSyncProvider(RTC.get);
+    micro_delay(20);
+
+    if(timeStatus()!= timeSet) {
+        // wait a bit
+        micro_delay(100);
+    }
+
+    // try again
+    if(timeStatus()!= timeSet) {
+        // CLK error
+#if !defined(AWS_NO_SERIAL)
+        Serial.println("clock error");
+#endif
+        for(;;);
+    }

     bmp.begin();
     // INT0 interrupt
     attachInterrupt(0,isr_pin2,RISING);
     last_irq_time = 0 ;

-#if !defined(AWS_NO_SERIAL)
-    Serial.begin(9600);
-#endif

 #if !defined(AWS_NO_GSM)
     gsmSerial.begin(9600);
@@ -215,38 +208,6 @@
         rain_counter_reset = false ;
     }

-
-}
-
-aws_error_t init_rtc(const char* str_time, const char* str_date) {
-
-    int hour, min, sec;
-    char month[12]; int day, year;
-    uint8_t month_index;
-
-    if (sscanf(str_time, "%d:%d:%d", &hour, &min, &sec) != 3) return AWS_RTC_COMPILER_ERROR;
-    if (sscanf(str_date, "%s %d %d", month, &day, &year) != 3) return AWS_RTC_COMPILER_ERROR;
-
-    tm.Hour = hour;
-    tm.Minute = min;
-    tm.Second = sec;
-
-
-    for (month_index = 0; month_index < 12; month_index++) {
-        if (strcmp(month, month_names[month_index]) == 0) break;
-    }
-
-    if (month_index >= 12) return AWS_RTC_COMPILER_ERROR;
-
-    tm.Day = day;
-    tm.Month = month_index + 1;
-    tm.Year = CalendarYrToTm(year);
-
-    // set this date time to DS1307 chip
-    bool flag = RTC.write(tm);
-    if(!flag) return AWS_RTC_WRITE_ERROR ;
-
-    return AWS_RTC_ERROR_NONE;

 }


Adjust motor via serial if there are no buttons, and a lot of formatting (sorry)

--- laserharp.ino
+++ laserharp.ino
@@ -27,7 +27,7 @@
 // Create the motor shield object with the default I2C address
 Adafruit_MotorShield AFMS = Adafruit_MotorShield();
 // Or, create it with a different I2C address (say for stacking)
-// Adafruit_MotorShield AFMS = Adafruit_MotorShield(0x61);
+// Adafruit_MotorShield AFMS = Adafruit_MotorShield(0x61);

 // Connect a stepper motor with 200 steps per revolution (1.8 degree)
 // to motor port #2 (M3 and M4)
@@ -40,8 +40,8 @@
 #define ovfPin  2  // this is the pin used for overflow control ( can be either 2 or 10 )
 GinSingPoly * poly;

-#define GINSING0 0
-#define GINSING1 1
+#define GINSING0 0
+#define GINSING1 1
 #endif

 const int lightSensorPin = 0;
@@ -68,29 +68,29 @@

 void setup()
 {
-    harpNoteDetector.setNumNotes(numberNotes);
-    Serial.begin(9600);
-
-    //For the light sensor
-    analogReference(EXTERNAL);
+  harpNoteDetector.setNumNotes(numberNotes);
+  Serial.begin(9600);
+
+  //For the light sensor
+  analogReference(EXTERNAL);

 #ifdef ADJUSTER_BUTTONS
-    pinMode(buttonApin, INPUT_PULLUP);
-    pinMode(buttonBpin, INPUT_PULLUP);
-#endif
-
-    AFMS.begin();  // create with the default frequency 1.6KHz
-    myMotor->setSpeed(250);
-
-    //Get some initial values for each light string
-    for (int i = 0; i < numberNotes; i++)
-    {
-        reflectedLightValues[i] = analogRead(lightSensorPin);
-        pluckedNotes[i] = false;
-    }
-
-#ifdef GINSING
-    setupGinSing();
+  pinMode(buttonApin, INPUT_PULLUP);
+  pinMode(buttonBpin, INPUT_PULLUP);
+#endif
+
+  AFMS.begin();  // create with the default frequency 1.6KHz
+  myMotor->setSpeed(250);
+
+  //Get some initial values for each light string
+  for (int i = 0; i < numberNotes; i++)
+  {
+    reflectedLightValues[i] = analogRead(lightSensorPin);
+    pluckedNotes[i] = false;
+  }
+
+#ifdef GINSING
+  setupGinSing();
 #endif
 }

@@ -98,27 +98,27 @@
 //This is the code required to get GinSing ready to go.
 void setupGinSing()
 {
-    GS.begin(rcvPin, sndPin, ovfPin);               // start the device (required) and enter preset mode
-    //For preset mode - change this when going to poly mode
-    poly = GS.getPoly();
-    poly->begin();                                    // enter presetmode
-
-    poly->setWaveform(GINSING0, SAWTOOTH);
-    poly->setWaveform(GINSING1, SAWTOOTH);
-
-    setupGinsingNotes();
+  GS.begin(rcvPin, sndPin, ovfPin);               // start the device (required) and enter preset mode
+  //For preset mode - change this when going to poly mode
+  poly = GS.getPoly();
+  poly->begin();                                    // enter presetmode
+
+  poly->setWaveform(GINSING0, SAWTOOTH);
+  poly->setWaveform(GINSING1, SAWTOOTH);
+
+  setupGinsingNotes();
 }

 //These are the notes I want to play with GinSing.
 void setupGinsingNotes()
 {
-    ginsingNotes[0] = C_4;
-    ginsingNotes[1] = D_4;
-    ginsingNotes[2] = E_4;
-    ginsingNotes[3] = F_4;
-    ginsingNotes[4] = G_4;
-    ginsingNotes[5] = A_4;
-    ginsingNotes[6] = B_4;
+  ginsingNotes[0] = C_4;
+  ginsingNotes[1] = D_4;
+  ginsingNotes[2] = E_4;
+  ginsingNotes[3] = F_4;
+  ginsingNotes[4] = G_4;
+  ginsingNotes[5] = A_4;
+  ginsingNotes[6] = B_4;
 }
 #endif

@@ -126,7 +126,7 @@
 //that into something to change the GinSing note being played.
 int findMultiplier(int height)
 {
-    /*
+  /*
     Over 170 = nothing
     140 = high           80 - 5
     125 = normal  64 - 4
@@ -134,42 +134,42 @@
     92 = very low       32 - 2
     74 = lower          16 - 1
     62 bottom out
-    */
-    if (height > 135) return 5;
-    if (height > 119) return 4;
-    if (height > 100) return 3;
-    if (height > 80) return 2;
-    //My speaker gets weird at the low values. So I commented that one out.
-//	if (height > 65) return 1;
-    return 0;
+  */
+  if (height > 135) return 5;
+  if (height > 119) return 4;
+  if (height > 100) return 3;
+  if (height > 80) return 2;
+  //My speaker gets weird at the low values. So I commented that one out.
+  //	if (height > 65) return 1;
+  return 0;
 }

 //Read the sonar unit and figure out if the
-//notes should move up or down
+//notes should move up or down
 void checkSonar()
 {
-    int height = analogRead(sonarPin);
-
-    if (debug)
-    {
-        Serial.print("Height:");
-        Serial.println(height);
-    }
-
-    if (height > 170)
-    {
-        return;
-    }
-    int multiplier = findMultiplier(height);
-    int baseValue = 16 * multiplier;
-#ifdef GINSING
-    ginsingNotes[0] = (GSNote)baseValue;
-    ginsingNotes[1] = (GSNote)(baseValue + 1);
-    ginsingNotes[2] = (GSNote)(baseValue + 2);
-    ginsingNotes[3] = (GSNote)(baseValue + 3);
-    ginsingNotes[4] = (GSNote)(baseValue + 4);
-    ginsingNotes[5] = (GSNote)(baseValue + 5);
-    ginsingNotes[6] = (GSNote)(baseValue + 6);
+  int height = analogRead(sonarPin);
+
+  if (debug)
+  {
+    Serial.print("Height:");
+    Serial.println(height);
+  }
+
+  if (height > 170)
+  {
+    return;
+  }
+  int multiplier = findMultiplier(height);
+  int baseValue = 16 * multiplier;
+#ifdef GINSING
+  ginsingNotes[0] = (GSNote)baseValue;
+  ginsingNotes[1] = (GSNote)(baseValue + 1);
+  ginsingNotes[2] = (GSNote)(baseValue + 2);
+  ginsingNotes[3] = (GSNote)(baseValue + 3);
+  ginsingNotes[4] = (GSNote)(baseValue + 4);
+  ginsingNotes[5] = (GSNote)(baseValue + 5);
+  ginsingNotes[6] = (GSNote)(baseValue + 6);
 #endif
 }

@@ -177,171 +177,166 @@
 //These two are the notes that Ginsing is currently playing.
 int ginsingNote0 = -1;
 int ginsingNote1 = -1;
-#endif
+#endif

 //FirstNote and SecondNote are the notes we want to be playing.
 void playNote(int firstNote, int secondNote)
 {

+  if (debug)
+  {
+    Serial.print("Playing notes ");
+    Serial.print(firstNote);
+    Serial.print(" and ");
+    Serial.println(secondNote);
+  }
+
+  //Pick the notes to be played and which channel to play them on
+#if GINSING
+  harpNoteChoice.pickNotes(ginsingNote0, ginsingNote1, firstNote, secondNote);
+  if (ginsingNote0 == -1)
+  {
+    poly->release(GINSING0);
+  }
+  else
+  {
+    poly->setNote(GINSING0, ginsingNotes[ginsingNote0]);
+    poly->trigger(GINSING0);
+  }
+
+  if (ginsingNote1 == -1)
+  {
+    poly->release(GINSING1);
+  }
+  else
+  {
+    poly->setNote(GINSING1, ginsingNotes[ginsingNote1]);
+    poly->trigger(GINSING1);
+  }
+#endif
+}
+
+//Move the motor one step. Sleep, then take a light reading. The sleep
+//gives the sensor time to actually report the new reading.
+int stepTheMotorAndGetLightReading(int directionToStep)
+{
+  myMotor->step(stepSize, directionToStep, DOUBLE);
+  delay(delayBetweenSteps);
+  int currentLightReading = analogRead(lightSensorPin);
+  return currentLightReading;
+}
+
+//Is debug on? If so print some data.
+void checkNotes(int reflectedLightValues[], boolean pluckedNotes[])
+{
+  if (debug)
+  {
+    for (int i = 0; i < numberNotes; i++)
+    {
+      Serial.print(i);
+      Serial.print("=");
+      Serial.print(reflectedLightValues[i]);
+      Serial.print(" - ");
+    }
+    Serial.println("");
+  }
+
+  //So ... are any light readings different from any others?
+  //To find the anomaly, see how different each string is to every other string.
+  //One or two strings should stand out. Those are the plucked strings.
+  harpNoteDetector.checkNotes(reflectedLightValues, pluckedNotes);
+
+  //So what strings are plucked? Note that if more than two are plucked,
+  //that counts as an error ... if that's the case, just keep playing the current notes
+  //and hope the player gets his act straight.
+  int firstNote = -1;
+  int secondNote = -1;
+  if (harpNoteDetector.getNotes(firstNote, secondNote, pluckedNotes))
+  {
     if (debug)
     {
-        Serial.print("Playing notes ");
-        Serial.print(firstNote);
-        Serial.print(" and ");
+      if (firstNote >= 0)
+      {
+        Serial.print("==============PLUCKED 1: ");
+        Serial.println(firstNote);
+      }
+      if (secondNote >= 0)
+      {
+        Serial.print("==============PLUCKED 2: ");
         Serial.println(secondNote);
+      }
     }
-
-    //Pick the notes to be played and which channel to play them on
-#if GINSING
-    harpNoteChoice.pickNotes(ginsingNote0, ginsingNote1, firstNote, secondNote);
-    if (ginsingNote0 == -1)
+    playNote(firstNote, secondNote);
+  }
+  else if (debug)
+  {
+    Serial.println("getNotes returned false - more than three notes were counted as plucked.");
+  }
+  return;
+}
+
+//Is a button pressed? If so move the motor a bit. This lets the user adjust the laser fan so it's pointing upwards properly.
+void checkButtons()
+{
+  Serial.println("in checkButtons");
+#ifdef ADJUSTER_BUTTONS
+  if (digitalRead(buttonApin) == LOW)
+  {
+    myMotor->step(stepSize, BACKWARD, DOUBLE);
+  }
+
+  if (digitalRead(buttonBpin) == LOW)
+  {
+    myMotor->step(stepSize, FORWARD, DOUBLE);
+  }
+#else
+  while (Serial.available() > 0)
+  {
+    char c = Serial.peek();
+    if (c != 'f' && c != 'b')
     {
-        poly->release(GINSING0);
+      break;
     }
     else
     {
-        poly->setNote(GINSING0, ginsingNotes[ginsingNote0]);
-        poly->trigger(GINSING0);
+      myMotor->step(stepSize, c == 'b' ? BACKWARD : FORWARD, DOUBLE);
+      Serial.read();
     }
-
-    if (ginsingNote1 == -1)
-    {
-        poly->release(GINSING1);
-    }
-    else
-    {
-        poly->setNote(GINSING1, ginsingNotes[ginsingNote1]);
-        poly->trigger(GINSING1);
-    }
-#endif
-}
-
-//Move the motor one step. Sleep, then take a light reading. The sleep
-//gives the sensor time to actually report the new reading.
-int stepTheMotorAndGetLightReading(int directionToStep)
-{
-    myMotor->step(stepSize, directionToStep, DOUBLE);
-    delay(delayBetweenSteps);
-    int currentLightReading = analogRead(lightSensorPin);
-    return currentLightReading;
-}
-
-//Is debug on? If so print some data.
-void checkNotes(int reflectedLightValues[], boolean pluckedNotes[])
-{
-    if (debug)
-    {
-        for (int i = 0; i < numberNotes; i++)
-        {
-            Serial.print(i);
-            Serial.print("=");
-            Serial.print(reflectedLightValues[i]);
-            Serial.print(" - ");
-        }
-        Serial.println("");
-    }
-
-    //So ... are any light readings different from any others?
-    //To find the anomaly, see how different each string is to every other string.
-    //One or two strings should stand out. Those are the plucked strings.
-    harpNoteDetector.checkNotes(reflectedLightValues, pluckedNotes);
-
-    //So what strings are plucked? Note that if more than two are plucked,
-    //that counts as an error ... if that's the case, just keep playing the current notes
-    //and hope the player gets his act straight.
-    int firstNote = -1;
-    int secondNote = -1;
-    if (harpNoteDetector.getNotes(firstNote, secondNote, pluckedNotes))
-    {
-        if (debug)
-        {
-            if (firstNote >= 0)
-            {
-                Serial.print("==============PLUCKED 1: ");
-                Serial.println(firstNote);
-            }
-            if (secondNote >= 0)
-            {
-                Serial.print("==============PLUCKED 2: ");
-                Serial.println(secondNote);
-            }
-        }
-        playNote(firstNote, secondNote);
-    }
-    else if (debug)
-    {
-        Serial.println("getNotes returned false - more than three notes were counted as plucked.");
-    }
+  }
+#endif
+}
+
+void loop()
+{
+
+  //There must be at least a handful notes for the code below to work right.
+  if (numberNotes < 5)
+  {
     return;
-}
-
-//Is a button pressed? If so move the motor a bit. This lets the user adjust the laser fan so it's pointing upwards properly.
-void checkButtons()
-{
-#ifdef ADJUSTER_BUTTONS
-    if (digitalRead(buttonApin) == LOW)
-    {
-        myMotor->step(stepSize, BACKWARD, DOUBLE);
-    }
-
-    if (digitalRead(buttonBpin) == LOW)
-    {
-        myMotor->step(stepSize, FORWARD, DOUBLE);
-    }
-#endif
-}
-
-void loop()
-{
-
-    //There must be at least a handful notes for the code below to work right.
-    if (numberNotes < 5)
-    {
-        return;
-    }
-
-    //Run the laser forward, read all values, and see what is there. Note that this pretty much uses one
-    //less note than requested - but the START position counts as a spot. So moving it numberNotes makes that many
-    //strings plus the start string.
-
-    //It's already read the zero item. So read array items 1 through 7.
-    for (int i = 1; i < numberNotes; i++)
-    {
-        reflectedLightValues[i] = stepTheMotorAndGetLightReading(FORWARD);
-        checkNotes(reflectedLightValues, pluckedNotes);
-    }
-
-    checkButtons();
-    checkSonar();
-
-    //It just read item 7. So going backwards, read items 6 through zero.
-    for (int i = numberNotes - 2; i >= 0; i--)
-    {
-        reflectedLightValues[i] = stepTheMotorAndGetLightReading(BACKWARD);
-        checkNotes(reflectedLightValues, pluckedNotes);
-    }
-
-    checkButtons();
-    checkSonar();
-
-}
-
-/*
-TODO
-#) encapsulate ginsing/midi
-
-#) improve (?) initialization of reflected light values
-    a) spinning mirror during initialization
-    b) by taking averaging several values over time?
-    c) update it while looping?
-
-#) classes may not need to exist
-
-
-*/
-
-
-
-
-
-
+  }
+
+  //Run the laser forward, read all values, and see what is there. Note that this pretty much uses one
+  //less note than requested - but the START position counts as a spot. So moving it numberNotes makes that many
+  //strings plus the start string.
+
+  //It's already read the zero item. So read array items 1 through 7.
+  for (int i = 1; i < numberNotes; i++)
+  {
+    reflectedLightValues[i] = stepTheMotorAndGetLightReading(FORWARD);
+    checkNotes(reflectedLightValues, pluckedNotes);
+  }
+
+  checkButtons();
+  checkSonar();
+
+  //It just read item 7. So going backwards, read items 6 through zero.
+  for (int i = numberNotes - 2; i >= 0; i--)
+  {
+    reflectedLightValues[i] = stepTheMotorAndGetLightReading(BACKWARD);
+    checkNotes(reflectedLightValues, pluckedNotes);
+  }
+
+  checkButtons();
+  checkSonar();
+
+}


Update ArincShieldAutoTest.ino

Update ArincShieldAutoTest.ino

--- SRC/ArincShieldAutoTest.ino
+++ SRC/ArincShieldAutoTest.ino
@@ -1,223 +1,233 @@
-//
-// Arinc Shield Test.ino
-//   V1.01 (15/03/2017) : ACLK divider is a parameter, to cope with both units:
-//   - 12MHz (prototypes) or
-//   - 16MHz (serial production)
-//
-
-#include <SPI.h>
-
-// pin numbers
-#define SS     10  // SPI Slave Select
-#define OE      9  // Output Enable of voltage translator (TXB0104)
-#define MR      8  // HI-3593 Master Reset
-#define TxEmpty 7  // HI-3593 Transmitter Empty
-#define DIn0    5  // Discrete input #0 (0V / open)
-#define DIn1    6  // Discrete input #1 (0V / open)
-#define DOut    4  // Discrete output (0V / Open)
-#define AIn0    A5 // Analog input #0 (0V .. 5V)
-#define AIn1    A4 // Analog input #1 (0V .. 5V)
-#define AIn2    A3 // Analog input #2 (0V .. 5V)
-#define AIn3    A2 // Analog input #3 (0V .. 5V)
-#define R1Int   3  // HI-3593 Receiver #1 interrupt
-#define R2Int   2  // HI-3593 Receiver #2 interrupt
-#define RTOut   1  // RS422 Tx Out
-#define RRIn    0  // RS422 Rx In
-
-// clock divider (page 9, table 2)
-   // for prototypes (Arduino USB 12MHz oscillator is used)
-//#define ClkDiv 0x0C
-   // for serial production (dedicated 16MHz oscillator on the shield)
-#define ClkDiv 0x10
-
-SPISettings HI3593SpiSettings(
-  // for arduino, SPI clock will be @16MHz/2 = 8MHz (the nearest from 10MHz)
-  10000000, // page 1, features: "10MHz SPI"
-  MSBFIRST, // page 14, fig 5
-  SPI_MODE0 // page 14, fig 5
-);
-
-// interrupt service routine for digital input #3 (RINT1)
-bool RINT1Trigd;
-void isr1() {
-  RINT1Trigd = true;
-}
-
-// interrupt service routine for digital input #2 (RINT2)
-bool RINT2Trigd;
-void isr2() {
-  RINT2Trigd = true;
-}
-
-void setup() {
-  // open serial port for debug
-  Serial.begin(9600);
-  Serial.println(F("\t>> Arinc 429 shield test program V1.01 <<\n"));
-
-  // in/out pins configuration
-  pinMode(SS,     OUTPUT);
-  pinMode(OE,     OUTPUT);
-  pinMode(MR,     OUTPUT);
-  pinMode(TxEmpty, INPUT);
-  pinMode(DIn1,    INPUT);
-  pinMode(DIn0,    INPUT);
-  pinMode(DOut,   OUTPUT);
-  pinMode(R1Int,   INPUT);
-  pinMode(R2Int,   INPUT);
-  pinMode(RTOut,  OUTPUT);
-  pinMode(RRIn,    INPUT);
-
-  // default states on outputs
-  digitalWrite(SS,    HIGH);
-  digitalWrite(OE,    HIGH);
-  digitalWrite(RTOut, HIGH);
-
-  // reset HI-3593
-  digitalWrite(MR, HIGH); delay(1); digitalWrite(MR,  LOW);
-
-  // initialize SPI
-  SPI.begin();
-  SPI.beginTransaction(HI3593SpiSettings);
-
-  // -------------------------------------------------------------------------
-  // Test MR (master reset) signal to HI-3593
-  // -------------------------------------------------------------------------
-  // write a register (the ACLK division register)
-  digitalWrite(SS, LOW); SPI.transfer(0x38); SPI.transfer(ClkDiv); digitalWrite(SS, HIGH);
-  // read back the register
-  digitalWrite(SS, LOW); SPI.transfer(0xd4); unsigned char readback = SPI.transfer(0); digitalWrite(SS, HIGH);
-  bool shieldPres = readback==ClkDiv;
-  // reset HI-3593
-  digitalWrite(MR, HIGH); delay(1); digitalWrite(MR,  LOW);
-  // read back again the register (default value of ACLK division register after reset is 0x00)
-  digitalWrite(SS, LOW); SPI.transfer(0xd4); readback = SPI.transfer(0); digitalWrite(SS, HIGH);
-  if (readback != ClkDiv && shieldPres) Serial.println(F("Test of Master Reset is:\t\tPASSED"));
-  else Serial.println(F("Master Reset didn't have the expected effect :("));
-  Serial.println();
-
-  // -------------------------------------------------------------------------
-  // Proper initialization after master reset
-  // -------------------------------------------------------------------------
-  // set the HI-3593 ACLK division register to accomodate the right clock frequency
-  digitalWrite(SS, LOW);
-  SPI.transfer(0x38); // Set ACLK division register (HI-3593 data sheet, page 6)
-  SPI.transfer(ClkDiv); // page 9, table 2
-  digitalWrite(SS, HIGH);
-
-  // set the HI-3593 TX control register
-  digitalWrite(SS, LOW);
-  SPI.transfer(0x08); // write transmit control register, page 4)
-  SPI.transfer(0x20); // bit 5 (TMODE): send ARINC words without enable command (page 5)
-  digitalWrite(SS, HIGH);
-
-  // -------------------------------------------------------------------------
-  // Test SPI communication with HI-3593 (reads back the TX control register)
-  // -------------------------------------------------------------------------
-  // read transmit control register
-  digitalWrite(SS, LOW); SPI.transfer(0x84); unsigned char tcr = SPI.transfer(0); digitalWrite(SS, HIGH);
-  if (tcr==0x20) Serial.println(F("Test of SPI from/to HI-3593 is:\t\tPASSED"));
-  else {
-    Serial.print(F("Incorrect read back of a HI-3593 register. Should read 0x20, obtained: 0x"));
-    Serial.println(tcr, HEX);
-  }
-  Serial.println();
-
-  // -------------------------------------------------------------------------
-  // Test ARINC transmit and receive (requires to loopback TX to both RX)
-  // -------------------------------------------------------------------------
-  // emission of an ARINC word
-  union {long int w; unsigned char b[4];} ArincWord;
-  ArincWord.w = 0x40302010;
-  digitalWrite(SS, LOW); SPI.transfer(0x0C); for (int i=0; i<4; i++) SPI.transfer(ArincWord.b[i]); digitalWrite(SS, HIGH);
-  // waits fot complete transmission
-  delay(1);
-  // reads RX channel #1
-  digitalWrite(SS, LOW); SPI.transfer(0xA0); for (int i=0; i<4; i++) ArincWord.b[i] = SPI.transfer(0); digitalWrite(SS, HIGH);
-  if (ArincWord.w == 0x40302010) Serial.println(F("Test of ARINC TX loop back to RX1 is:\tPASSED"));
-  else {
-    Serial.print(F("Incorrect loop back of A429 TX on RX1. Should read 0x40302010, obtained: 0x"));
-    Serial.println(ArincWord.w, HEX);
-  }
-  // reads RX channel #2
-  ArincWord.w = 0;
-  digitalWrite(SS, LOW); SPI.transfer(0xC0); for (int i=0; i<4; i++) ArincWord.b[i] = SPI.transfer(0); digitalWrite(SS, HIGH);
-  if (ArincWord.w == 0x40302010) Serial.println(F("Test of ARINC TX loop back to RX2 is:\tPASSED"));
-  else {
-    Serial.print(F("Incorrect loop back of A429 TX on RX2. Should read 0x40302010, obtained: 0x"));
-    Serial.println(ArincWord.w, HEX);
-  }
-  Serial.println();
-
-  // -------------------------------------------------------------------------
-  // Test ARINC receive interrupts RINT1 & RINT2 (loopback TX to both RX)
-  // -------------------------------------------------------------------------
-  // configure interrupts
-  attachInterrupt(digitalPinToInterrupt(3), isr1, RISING);
-  attachInterrupt(digitalPinToInterrupt(2), isr2, RISING);
-  RINT1Trigd = false; RINT2Trigd = false;
-  // emission of an ARINC word
-  ArincWord.w = 0x40302010;
-  digitalWrite(SS, LOW); SPI.transfer(0x0C); for (int i=0; i<4; i++) SPI.transfer(ArincWord.b[i]); digitalWrite(SS, HIGH);
-  // waits for complete transmission
-  delay(1);
-  if (RINT1Trigd) Serial.println(F("Test of RINT1 interrupt is:\t\tPASSED"));
-  else Serial.println(F("RINT1 didn't trigger :("));
-  if (RINT2Trigd) Serial.println(F("Test of RINT2 interrupt is:\t\tPASSED"));
-  else Serial.println(F("RINT2 didn't trigger :("));
-  detachInterrupt(digitalPinToInterrupt(3));
-  detachInterrupt(digitalPinToInterrupt(2));
-  Serial.println();
-
-  // -------------------------------------------------------------------------
-  // Test ARINC "transmit empty" (TEMPTY) signal
-  // -------------------------------------------------------------------------
-  // emission of several ARINC words
-  ArincWord.w = 0x40302010;
-  for (int j=0; j<12; j++)
-    {digitalWrite(SS, LOW); SPI.transfer(0x0C); for (int i=0; i<4; i++) SPI.transfer(ArincWord.b[i]); digitalWrite(SS, HIGH);}
-  int c=0;
-  int InitialTxEmpty = digitalRead(TxEmpty);
-  while (!digitalRead(TxEmpty) && c<1000) c++;
-  int FinalTxEmpty = digitalRead(TxEmpty);
-  if (InitialTxEmpty==0 && FinalTxEmpty==1) Serial.println(F("Test of TEMPTY is:\t\t\tPASSED"));
-  else Serial.println(F("TEMPTY didn't evolve as exptected (check ACLK devider) :("));
-  Serial.println();
-
-  // ---------------------------------------------------------------------------
-  // Test DOUT, DIN1 & DIN2 0v/open discrete ; and AIN0 .. AIN3 analog signals
-  // DOUT is to be looped back to DIN1, DIN2 and AIN0 .. AIN3
-  // ---------------------------------------------------------------------------
-  digitalWrite(DOut, LOW);
-  char id0 = digitalRead(DIn0); char id1 = digitalRead(DIn1);
-  int  ia0 = analogRead(AIn0);  int  ia1 = analogRead(AIn1);
-  int  ia2 = analogRead(AIn2);  int  ia3 = analogRead(AIn3);
-  digitalWrite(DOut, HIGH);
-  char fd0 = digitalRead(DIn0); char fd1 = digitalRead(DIn1);
-  int  fa0 = analogRead(AIn0);  int  fa1 = analogRead(AIn1);
-  int  fa2 = analogRead(AIn2);  int  fa3 = analogRead(AIn3);
-  if (id0==1 && fd0==0)   Serial.println(F("Test of loop back of DOUT to DIN0 is:\tPASSED"));
-  else                    Serial.println(F("Incorrect loop back of DOUT to DIN0 :("));
-  if (id1==1 && fd1==0)   Serial.println(F("Test of loop back of DOUT to DIN1 is:\tPASSED"));
-  else                    Serial.println(F("Incorrect loop back of DOUT to DIN1 :("));
-  if (ia0>923 && fa0<100) Serial.println(F("Test of loop back of DOUT to AIN0 is:\tPASSED"));
-  else                    Serial.println(F("Incorrect loop back of DOUT to AIN0 :("));
-  if (ia1>923 && fa1<100) Serial.println(F("Test of loop back of DOUT to AIN1 is:\tPASSED"));
-  else                    Serial.println(F("Incorrect loop back of DOUT to AIN1 :("));
-  if (ia2>923 && fa2<100) Serial.println(F("Test of loop back of DOUT to AIN2 is:\tPASSED"));
-  else                    Serial.println(F("Incorrect loop back of DOUT to AIN2 :("));
-  if (ia3>923 && fa3<100) Serial.println(F("Test of loop back of DOUT to AIN3 is:\tPASSED"));
-  else                    Serial.println(F("Incorrect loop back of DOUT to AIN3 :("));
-  Serial.println();
-
-  Serial.println(F("\t\tThat's all folks !"));
-
-}
-
-void loop() {
-  // repeatedly emit an ARINC word (this permits to analyze the signal with an oscilloscope)
-  union {long int w; unsigned char b[4];} ArincWord;
-  ArincWord.w = 0x40302010;
-  digitalWrite(SS, LOW); SPI.transfer(0x0C); for (int i=0; i<4; i++) SPI.transfer(ArincWord.b[i]); digitalWrite(SS, HIGH);
-  // waits 1ms to ensure FIFO is flushed
-  delay(1);
-}
+//
+// Arinc Shield Test.ino
+//
+// author: JPP
+//
+// Version V1.01 (15/03/2017) : ACLK divider is a parameter, to cope with both units:
+//   - 12MHz (prototypes) or
+//   - 16MHz (serial production)
+//
+// This program is distributed in the hope that it will be useful, but without any
+// warranty; without even the implied warranty of merchantability or fitness for a
+// particular purpose. See the GNU General Public License for more details.
+//
+// You should have received a copy of the GNU General Public License along with this
+// program. If not, see <http://www.gnu.org/licenses/>.
+//
+
+#include <SPI.h>
+
+// pin numbers
+#define SS     10  // SPI Slave Select
+#define OE      9  // Output Enable of voltage translator (TXB0104)
+#define MR      8  // HI-3593 Master Reset
+#define TxEmpty 7  // HI-3593 Transmitter Empty
+#define DIn0    5  // Discrete input #0 (0V / open)
+#define DIn1    6  // Discrete input #1 (0V / open)
+#define DOut    4  // Discrete output (0V / Open)
+#define AIn0    A5 // Analog input #0 (0V .. 5V)
+#define AIn1    A4 // Analog input #1 (0V .. 5V)
+#define AIn2    A3 // Analog input #2 (0V .. 5V)
+#define AIn3    A2 // Analog input #3 (0V .. 5V)
+#define R1Int   3  // HI-3593 Receiver #1 interrupt
+#define R2Int   2  // HI-3593 Receiver #2 interrupt
+#define RTOut   1  // RS422 Tx Out
+#define RRIn    0  // RS422 Rx In
+
+// clock divider (page 9, table 2)
+   // for prototypes (Arduino USB 12MHz oscillator is used)
+//#define ClkDiv 0x0C
+   // for serial production (dedicated 16MHz oscillator on the shield)
+#define ClkDiv 0x10
+
+SPISettings HI3593SpiSettings(
+  // for arduino, SPI clock will be @16MHz/2 = 8MHz (the nearest from 10MHz)
+  10000000, // page 1, features: "10MHz SPI"
+  MSBFIRST, // page 14, fig 5
+  SPI_MODE0 // page 14, fig 5
+);
+
+// interrupt service routine for digital input #3 (RINT1)
+bool RINT1Trigd;
+void isr1() {
+  RINT1Trigd = true;
+}
+
+// interrupt service routine for digital input #2 (RINT2)
+bool RINT2Trigd;
+void isr2() {
+  RINT2Trigd = true;
+}
+
+void setup() {
+  // open serial port for debug
+  Serial.begin(9600);
+  Serial.println(F("\t>> Arinc 429 shield test program V1.01 <<\n"));
+
+  // in/out pins configuration
+  pinMode(SS,     OUTPUT);
+  pinMode(OE,     OUTPUT);
+  pinMode(MR,     OUTPUT);
+  pinMode(TxEmpty, INPUT);
+  pinMode(DIn1,    INPUT);
+  pinMode(DIn0,    INPUT);
+  pinMode(DOut,   OUTPUT);
+  pinMode(R1Int,   INPUT);
+  pinMode(R2Int,   INPUT);
+  pinMode(RTOut,  OUTPUT);
+  pinMode(RRIn,    INPUT);
+
+  // default states on outputs
+  digitalWrite(SS,    HIGH);
+  digitalWrite(OE,    HIGH);
+  digitalWrite(RTOut, HIGH);
+
+  // reset HI-3593
+  digitalWrite(MR, HIGH); delay(1); digitalWrite(MR,  LOW);
+
+  // initialize SPI
+  SPI.begin();
+  SPI.beginTransaction(HI3593SpiSettings);
+
+  // -------------------------------------------------------------------------
+  // Test MR (master reset) signal to HI-3593
+  // -------------------------------------------------------------------------
+  // write a register (the ACLK division register)
+  digitalWrite(SS, LOW); SPI.transfer(0x38); SPI.transfer(ClkDiv); digitalWrite(SS, HIGH);
+  // read back the register
+  digitalWrite(SS, LOW); SPI.transfer(0xd4); unsigned char readback = SPI.transfer(0); digitalWrite(SS, HIGH);
+  bool shieldPres = readback==ClkDiv;
+  // reset HI-3593
+  digitalWrite(MR, HIGH); delay(1); digitalWrite(MR,  LOW);
+  // read back again the register (default value of ACLK division register after reset is 0x00)
+  digitalWrite(SS, LOW); SPI.transfer(0xd4); readback = SPI.transfer(0); digitalWrite(SS, HIGH);
+  if (readback != ClkDiv && shieldPres) Serial.println(F("Test of Master Reset is:\t\tPASSED"));
+  else Serial.println(F("Master Reset didn't have the expected effect :("));
+  Serial.println();
+
+  // -------------------------------------------------------------------------
+  // Proper initialization after master reset
+  // -------------------------------------------------------------------------
+  // set the HI-3593 ACLK division register to accomodate the right clock frequency
+  digitalWrite(SS, LOW);
+  SPI.transfer(0x38); // Set ACLK division register (HI-3593 data sheet, page 6)
+  SPI.transfer(ClkDiv); // page 9, table 2
+  digitalWrite(SS, HIGH);
+
+  // set the HI-3593 TX control register
+  digitalWrite(SS, LOW);
+  SPI.transfer(0x08); // write transmit control register, page 4)
+  SPI.transfer(0x20); // bit 5 (TMODE): send ARINC words without enable command (page 5)
+  digitalWrite(SS, HIGH);
+
+  // -------------------------------------------------------------------------
+  // Test SPI communication with HI-3593 (reads back the TX control register)
+  // -------------------------------------------------------------------------
+  // read transmit control register
+  digitalWrite(SS, LOW); SPI.transfer(0x84); unsigned char tcr = SPI.transfer(0); digitalWrite(SS, HIGH);
+  if (tcr==0x20) Serial.println(F("Test of SPI from/to HI-3593 is:\t\tPASSED"));
+  else {
+    Serial.print(F("Incorrect read back of a HI-3593 register. Should read 0x20, obtained: 0x"));
+    Serial.println(tcr, HEX);
+  }
+  Serial.println();
+
+  // -------------------------------------------------------------------------
+  // Test ARINC transmit and receive (requires to loopback TX to both RX)
+  // -------------------------------------------------------------------------
+  // emission of an ARINC word
+  union {long int w; unsigned char b[4];} ArincWord;
+  ArincWord.w = 0x40302010;
+  digitalWrite(SS, LOW); SPI.transfer(0x0C); for (int i=0; i<4; i++) SPI.transfer(ArincWord.b[i]); digitalWrite(SS, HIGH);
+  // waits fot complete transmission
+  delay(1);
+  // reads RX channel #1
+  digitalWrite(SS, LOW); SPI.transfer(0xA0); for (int i=0; i<4; i++) ArincWord.b[i] = SPI.transfer(0); digitalWrite(SS, HIGH);
+  if (ArincWord.w == 0x40302010) Serial.println(F("Test of ARINC TX loop back to RX1 is:\tPASSED"));
+  else {
+    Serial.print(F("Incorrect loop back of A429 TX on RX1. Should read 0x40302010, obtained: 0x"));
+    Serial.println(ArincWord.w, HEX);
+  }
+  // reads RX channel #2
+  ArincWord.w = 0;
+  digitalWrite(SS, LOW); SPI.transfer(0xC0); for (int i=0; i<4; i++) ArincWord.b[i] = SPI.transfer(0); digitalWrite(SS, HIGH);
+  if (ArincWord.w == 0x40302010) Serial.println(F("Test of ARINC TX loop back to RX2 is:\tPASSED"));
+  else {
+    Serial.print(F("Incorrect loop back of A429 TX on RX2. Should read 0x40302010, obtained: 0x"));
+    Serial.println(ArincWord.w, HEX);
+  }
+  Serial.println();
+
+  // -------------------------------------------------------------------------
+  // Test ARINC receive interrupts RINT1 & RINT2 (loopback TX to both RX)
+  // -------------------------------------------------------------------------
+  // configure interrupts
+  attachInterrupt(digitalPinToInterrupt(3), isr1, RISING);
+  attachInterrupt(digitalPinToInterrupt(2), isr2, RISING);
+  RINT1Trigd = false; RINT2Trigd = false;
+  // emission of an ARINC word
+  ArincWord.w = 0x40302010;
+  digitalWrite(SS, LOW); SPI.transfer(0x0C); for (int i=0; i<4; i++) SPI.transfer(ArincWord.b[i]); digitalWrite(SS, HIGH);
+  // waits for complete transmission
+  delay(1);
+  if (RINT1Trigd) Serial.println(F("Test of RINT1 interrupt is:\t\tPASSED"));
+  else Serial.println(F("RINT1 didn't trigger :("));
+  if (RINT2Trigd) Serial.println(F("Test of RINT2 interrupt is:\t\tPASSED"));
+  else Serial.println(F("RINT2 didn't trigger :("));
+  detachInterrupt(digitalPinToInterrupt(3));
+  detachInterrupt(digitalPinToInterrupt(2));
+  Serial.println();
+
+  // -------------------------------------------------------------------------
+  // Test ARINC "transmit empty" (TEMPTY) signal
+  // -------------------------------------------------------------------------
+  // emission of several ARINC words
+  ArincWord.w = 0x40302010;
+  for (int j=0; j<12; j++)
+    {digitalWrite(SS, LOW); SPI.transfer(0x0C); for (int i=0; i<4; i++) SPI.transfer(ArincWord.b[i]); digitalWrite(SS, HIGH);}
+  int c=0;
+  int InitialTxEmpty = digitalRead(TxEmpty);
+  while (!digitalRead(TxEmpty) && c<1000) c++;
+  int FinalTxEmpty = digitalRead(TxEmpty);
+  if (InitialTxEmpty==0 && FinalTxEmpty==1) Serial.println(F("Test of TEMPTY is:\t\t\tPASSED"));
+  else Serial.println(F("TEMPTY didn't evolve as exptected (check ACLK devider) :("));
+  Serial.println();
+
+  // ---------------------------------------------------------------------------
+  // Test DOUT, DIN1 & DIN2 0v/open discrete ; and AIN0 .. AIN3 analog signals
+  // DOUT is to be looped back to DIN1, DIN2 and AIN0 .. AIN3
+  // ---------------------------------------------------------------------------
+  digitalWrite(DOut, LOW);
+  char id0 = digitalRead(DIn0); char id1 = digitalRead(DIn1);
+  int  ia0 = analogRead(AIn0);  int  ia1 = analogRead(AIn1);
+  int  ia2 = analogRead(AIn2);  int  ia3 = analogRead(AIn3);
+  digitalWrite(DOut, HIGH);
+  char fd0 = digitalRead(DIn0); char fd1 = digitalRead(DIn1);
+  int  fa0 = analogRead(AIn0);  int  fa1 = analogRead(AIn1);
+  int  fa2 = analogRead(AIn2);  int  fa3 = analogRead(AIn3);
+  if (id0==1 && fd0==0)   Serial.println(F("Test of loop back of DOUT to DIN0 is:\tPASSED"));
+  else                    Serial.println(F("Incorrect loop back of DOUT to DIN0 :("));
+  if (id1==1 && fd1==0)   Serial.println(F("Test of loop back of DOUT to DIN1 is:\tPASSED"));
+  else                    Serial.println(F("Incorrect loop back of DOUT to DIN1 :("));
+  if (ia0>923 && fa0<100) Serial.println(F("Test of loop back of DOUT to AIN0 is:\tPASSED"));
+  else                    Serial.println(F("Incorrect loop back of DOUT to AIN0 :("));
+  if (ia1>923 && fa1<100) Serial.println(F("Test of loop back of DOUT to AIN1 is:\tPASSED"));
+  else                    Serial.println(F("Incorrect loop back of DOUT to AIN1 :("));
+  if (ia2>923 && fa2<100) Serial.println(F("Test of loop back of DOUT to AIN2 is:\tPASSED"));
+  else                    Serial.println(F("Incorrect loop back of DOUT to AIN2 :("));
+  if (ia3>923 && fa3<100) Serial.println(F("Test of loop back of DOUT to AIN3 is:\tPASSED"));
+  else                    Serial.println(F("Incorrect loop back of DOUT to AIN3 :("));
+  Serial.println();
+
+  Serial.println(F("\t\tThat's all folks !"));
+
+}
+
+void loop() {
+  // repeatedly emit an ARINC word (this permits to analyze the signal with an oscilloscope)
+  union {long int w; unsigned char b[4];} ArincWord;
+  ArincWord.w = 0x40302010;
+  digitalWrite(SS, LOW); SPI.transfer(0x0C); for (int i=0; i<4; i++) SPI.transfer(ArincWord.b[i]); digitalWrite(SS, HIGH);
+  // waits 1ms to ensure FIFO is flushed
+  delay(1);
+}