Moved big chunks of code into subroutines; tweaked ramp settings.

--- Runt_Rover/Runt_Rover.ino
+++ Runt_Rover/Runt_Rover.ino
@@ -54,7 +54,9 @@
 #define MOTOR_FORWARD_TURN          33
 #define MOTOR_REVERSE_FULL          44
 #define MOTOR_REVERSE_TURN          55
-#define MOTOR_RAMP_STEP             25
+
+#define MOTOR_RAMP_STEP             5
+#define LOOP_DELAY_MS				50
 #define MOTOR_RAMP_THHRESHOLD       50

 #define BUTTON_MASK                 0x10
@@ -87,8 +89,11 @@
 unsigned int rear_motor_en[2] = {9, 6};

 unsigned int motor_state[2];
-int motor_drive_target[2];
-int motor_drive_present[2];
+unsigned int motor_drive_target[2];
+unsigned int motor_drive_present[2];
+
+void set_motor_states (unsigned int command);
+unsigned int set_motor_outputs (unsigned int mode);

 void setup() {
   // put your setup code here, to run once:
@@ -119,7 +124,7 @@
     unsigned int i;
     char xbee_command;

-    delay(50);    // TODO: Replace this with something more deterministic, perhaps based on a timer.
+    delay(LOOP_DELAY);

     // read xbee data and update motor states
     xbee_command = xbee.read();
@@ -148,85 +153,16 @@
       digitalWrite(13, LOW);
     }

-    switch(xbee_command & JOYSTICK_MASK)
-    {
-      case XBEE_COMMAND_STOP:
-        // stop position: all off
-        motor_state[LEFT_MOTORS] = MOTOR_OFF;
-        motor_state[RIGHT_MOTORS] = MOTOR_OFF;
-        Serial.println("xbee command stop");
-      break;
-
-      case XBEE_COMMAND_FORWARD:
-        // forward position: all forward full speed
-        motor_state[LEFT_MOTORS] = MOTOR_FORWARD_FULL;
-        motor_state[RIGHT_MOTORS] = MOTOR_FORWARD_FULL;
-        Serial.println("xbee command forward");
-      break;
-
-      case XBEE_COMMAND_FORWARD_LEFT:
-        // forward left: left motors forward turn speed, right motors forward full speed
-        motor_state[LEFT_MOTORS] = MOTOR_FORWARD_TURN;
-        motor_state[RIGHT_MOTORS] = MOTOR_FORWARD_FULL;
-        Serial.println("xbee command forward left");
-      break;
-
-      case XBEE_COMMAND_FORWARD_RIGHT:
-        // forward right: left motors forward full speed, right motors forward turn speed
-        motor_state[LEFT_MOTORS] = MOTOR_FORWARD_FULL;
-        motor_state[RIGHT_MOTORS] = MOTOR_FORWARD_TURN;
-        Serial.println("xbee command forward right");
-      break;
-
-      case XBEE_COMMAND_REVERSE:
-        // reverse position: all reverse full speed
-        motor_state[LEFT_MOTORS] = MOTOR_REVERSE_FULL;
-        motor_state[RIGHT_MOTORS] = MOTOR_REVERSE_FULL;
-        Serial.println("xbee command reverse");
-      break;
-
-      case XBEE_COMMAND_REVERSE_LEFT:
-        // reverse left: left motors reverse turn speed, right motors reverse full speed
-        motor_state[LEFT_MOTORS] = MOTOR_REVERSE_TURN;
-        motor_state[RIGHT_MOTORS] = MOTOR_REVERSE_FULL;
-        Serial.println("xbee command reverse left");
-      break;
-
-      case XBEE_COMMAND_REVERSE_RIGHT:
-        // reverse right: left motors reverse full speed, right motors reverse turn speed
-        motor_state[LEFT_MOTORS] = MOTOR_REVERSE_FULL;
-        motor_state[RIGHT_MOTORS] = MOTOR_REVERSE_TURN;
-        Serial.println("xbee command reverse right");
-      break;
-
-      case XBEE_COMMAND_TURN_LEFT:
-        // turn left position: left motors reverse full speed, right motors forward full speed
-        motor_state[LEFT_MOTORS] = MOTOR_REVERSE_FULL;
-        motor_state[RIGHT_MOTORS] = MOTOR_FORWARD_FULL;
-        Serial.println("xbee command turn left");
-      break;
-
-      case XBEE_COMMAND_TURN_RIGHT:
-        // turn right position: left motors forward full speed, right motors reverse full speed
-        motor_state[LEFT_MOTORS] = MOTOR_FORWARD_FULL;
-        motor_state[RIGHT_MOTORS] = MOTOR_REVERSE_FULL;
-        Serial.println("xbee command turn right");
-      break;
-
-      default:
-        // default is stop: all off
-        motor_state[LEFT_MOTORS] = MOTOR_OFF;
-        motor_state[RIGHT_MOTORS] = MOTOR_OFF;
-        Serial.println("Xbee command error");
-      break;
-    }
-
+	set_motor_states(xbee_command & JOYSTICK_MASK);
+
     // read motor states and drive motors
     for(i = 0; i < 2; i++)
-    {
-      if (abs(motor_drive_present[i] - motor_drive_target[i]) < MOTOR_RAMP_THHRESHOLD)
+    {
+	  motor_drive_target[i] = set_motor_outputs(motor_state[i]);
+
+	  if (abs(motor_drive_present[i] - motor_drive_target[i]) < MOTOR_RAMP_THHRESHOLD)
       {
-        // if close to target, set to target
+        // if close to target, set to target, to reduce jitter
         motor_drive_present[i] = motor_drive_target[i];
       }
       else
@@ -243,73 +179,162 @@
           motor_drive_present[i] += MOTOR_RAMP_STEP;
         }
       }
-
-      switch(motor_state[i])
-      {
-        // drive motors: forward: a = high, b = low; reverse: a = low, b = high; off: both low
-        case MOTOR_OFF:
-          digitalWrite(front_motor_a[i], LOW);
-          digitalWrite(front_motor_b[i], LOW);
-          digitalWrite(rear_motor_a[i], LOW);
-          digitalWrite(rear_motor_b[i], LOW);
-          analogWrite(front_motor_en[i], 0);
-          analogWrite(rear_motor_en[i], 0);
-          motor_drive_present[i] = 0;
-        break;
-
-        case MOTOR_FORWARD_FULL:
-          digitalWrite(front_motor_a[i], HIGH);
-          digitalWrite(front_motor_b[i], LOW);
-          digitalWrite(rear_motor_a[i], HIGH);
-          digitalWrite(rear_motor_b[i], LOW);
-          //analogWrite(front_motor_en[i], FULL_SPEED);
-          //analogWrite(rear_motor_en[i], FULL_SPEED);
-          analogWrite(front_motor_en[i], motor_drive_present[i]);
-          analogWrite(rear_motor_en[i], motor_drive_present[i]);
-          motor_drive_target[i] = FULL_SPEED;
-        break;
-
-        case MOTOR_FORWARD_TURN:
-          digitalWrite(front_motor_a[i], HIGH);
-          digitalWrite(front_motor_b[i], LOW);
-          digitalWrite(rear_motor_a[i], HIGH);
-          digitalWrite(rear_motor_b[i], LOW);
-          analogWrite(front_motor_en[i], TURN_SPEED);
-          analogWrite(rear_motor_en[i], TURN_SPEED);
-          motor_drive_target[i] = TURN_SPEED;
-        break;
-
-        case MOTOR_REVERSE_FULL:
-          digitalWrite(front_motor_a[i], LOW);
-          digitalWrite(front_motor_b[i], HIGH);
-          digitalWrite(rear_motor_a[i], LOW);
-          digitalWrite(rear_motor_b[i], HIGH);
-          //analogWrite(front_motor_en[i], FULL_SPEED);
-          //analogWrite(rear_motor_en[i], FULL_SPEED);
-          analogWrite(front_motor_en[i], motor_drive_present[i]);
-          analogWrite(rear_motor_en[i], motor_drive_present[i]);
-          motor_drive_target[i] = FULL_SPEED;
-        break;
-
-        case MOTOR_REVERSE_TURN:
-          digitalWrite(front_motor_a[i], LOW);
-          digitalWrite(front_motor_b[i], HIGH);
-          digitalWrite(rear_motor_a[i], LOW);
-          digitalWrite(rear_motor_b[i], HIGH);
-          analogWrite(front_motor_en[i], TURN_SPEED);
-          analogWrite(rear_motor_en[i], TURN_SPEED);
-          motor_drive_target[i] = TURN_SPEED;
-        break;
-
-        default:
-          digitalWrite(front_motor_a[i], LOW);
-          digitalWrite(front_motor_b[i], LOW);
-          digitalWrite(rear_motor_a[i], LOW);
-          digitalWrite(rear_motor_b[i], LOW);
-          analogWrite(front_motor_en[i], 0);
-          analogWrite(rear_motor_en[i], 0);
-          motor_drive_target[i] = 0;
-        break;
-      }
+
+	  analogWrite(front_motor_en[i], motor_drive_present[i]);
+	  analogWrite(rear_motor_en[i], motor_drive_present[i]);
     }
 }
+
+void set_motor_states (unsigned int command)
+{
+    switch(command)
+    {
+      case XBEE_COMMAND_STOP:
+        // stop position: all off
+        motor_state[LEFT_MOTORS] = MOTOR_OFF;
+        motor_state[RIGHT_MOTORS] = MOTOR_OFF;
+        Serial.println("xbee command stop");
+      break;
+
+      case XBEE_COMMAND_FORWARD:
+        // forward position: all forward full speed
+        motor_state[LEFT_MOTORS] = MOTOR_FORWARD_FULL;
+        motor_state[RIGHT_MOTORS] = MOTOR_FORWARD_FULL;
+        Serial.println("xbee command forward");
+      break;
+
+      case XBEE_COMMAND_FORWARD_LEFT:
+        // forward left: left motors forward turn speed, right motors forward full speed
+        motor_state[LEFT_MOTORS] = MOTOR_FORWARD_TURN;
+        motor_state[RIGHT_MOTORS] = MOTOR_FORWARD_FULL;
+        Serial.println("xbee command forward left");
+      break;
+
+      case XBEE_COMMAND_FORWARD_RIGHT:
+        // forward right: left motors forward full speed, right motors forward turn speed
+        motor_state[LEFT_MOTORS] = MOTOR_FORWARD_FULL;
+        motor_state[RIGHT_MOTORS] = MOTOR_FORWARD_TURN;
+        Serial.println("xbee command forward right");
+      break;
+
+      case XBEE_COMMAND_REVERSE:
+        // reverse position: all reverse full speed
+        motor_state[LEFT_MOTORS] = MOTOR_REVERSE_FULL;
+        motor_state[RIGHT_MOTORS] = MOTOR_REVERSE_FULL;
+        Serial.println("xbee command reverse");
+      break;
+
+      case XBEE_COMMAND_REVERSE_LEFT:
+        // reverse left: left motors reverse turn speed, right motors reverse full speed
+        motor_state[LEFT_MOTORS] = MOTOR_REVERSE_TURN;
+        motor_state[RIGHT_MOTORS] = MOTOR_REVERSE_FULL;
+        Serial.println("xbee command reverse left");
+      break;
+
+      case XBEE_COMMAND_REVERSE_RIGHT:
+        // reverse right: left motors reverse full speed, right motors reverse turn speed
+        motor_state[LEFT_MOTORS] = MOTOR_REVERSE_FULL;
+        motor_state[RIGHT_MOTORS] = MOTOR_REVERSE_TURN;
+        Serial.println("xbee command reverse right");
+      break;
+
+      case XBEE_COMMAND_TURN_LEFT:
+        // turn left position: left motors reverse full speed, right motors forward full speed
+        motor_state[LEFT_MOTORS] = MOTOR_REVERSE_FULL;
+        motor_state[RIGHT_MOTORS] = MOTOR_FORWARD_FULL;
+        Serial.println("xbee command turn left");
+      break;
+
+      case XBEE_COMMAND_TURN_RIGHT:
+        // turn right position: left motors forward full speed, right motors reverse full speed
+        motor_state[LEFT_MOTORS] = MOTOR_FORWARD_FULL;
+        motor_state[RIGHT_MOTORS] = MOTOR_REVERSE_FULL;
+        Serial.println("xbee command turn right");
+      break;
+
+      default:
+        // default is stop: all off
+        motor_state[LEFT_MOTORS] = MOTOR_OFF;
+        motor_state[RIGHT_MOTORS] = MOTOR_OFF;
+        Serial.println("Xbee command error");
+      break;
+    }
+}
+
+unsigned int set_motor_outputs (unsigned int mode)
+{
+  unsigned int target_out;
+
+  switch(mode)
+  {
+	// drive motors: forward: a = high, b = low; reverse: a = low, b = high; off: both low
+	case MOTOR_OFF:
+	  digitalWrite(front_motor_a[i], LOW);
+	  digitalWrite(front_motor_b[i], LOW);
+	  digitalWrite(rear_motor_a[i], LOW);
+	  digitalWrite(rear_motor_b[i], LOW);
+	  //analogWrite(front_motor_en[i], 0);
+	  //analogWrite(rear_motor_en[i], 0);
+	  //motor_drive_present[i] = 0;
+	  target_out = 0;
+	break;
+
+	case MOTOR_FORWARD_FULL:
+	  digitalWrite(front_motor_a[i], HIGH);
+	  digitalWrite(front_motor_b[i], LOW);
+	  digitalWrite(rear_motor_a[i], HIGH);
+	  digitalWrite(rear_motor_b[i], LOW);
+	  //analogWrite(front_motor_en[i], FULL_SPEED);
+	  //analogWrite(rear_motor_en[i], FULL_SPEED);
+	  //analogWrite(front_motor_en[i], motor_drive_present[i]);
+	  //analogWrite(rear_motor_en[i], motor_drive_present[i]);
+	  target_out = FULL_SPEED;
+	break;
+
+	case MOTOR_FORWARD_TURN:
+	  digitalWrite(front_motor_a[i], HIGH);
+	  digitalWrite(front_motor_b[i], LOW);
+	  digitalWrite(rear_motor_a[i], HIGH);
+	  digitalWrite(rear_motor_b[i], LOW);
+	  //analogWrite(front_motor_en[i], TURN_SPEED);
+	  //analogWrite(rear_motor_en[i], TURN_SPEED);
+	  target_out = TURN_SPEED;
+	break;
+
+	case MOTOR_REVERSE_FULL:
+	  digitalWrite(front_motor_a[i], LOW);
+	  digitalWrite(front_motor_b[i], HIGH);
+	  digitalWrite(rear_motor_a[i], LOW);
+	  digitalWrite(rear_motor_b[i], HIGH);
+	  //analogWrite(front_motor_en[i], FULL_SPEED);
+	  //analogWrite(rear_motor_en[i], FULL_SPEED);
+	  //analogWrite(front_motor_en[i], motor_drive_present[i]);
+	  //analogWrite(rear_motor_en[i], motor_drive_present[i]);
+	  target_out = FULL_SPEED;
+	break;
+
+	case MOTOR_REVERSE_TURN:
+	  digitalWrite(front_motor_a[i], LOW);
+	  digitalWrite(front_motor_b[i], HIGH);
+	  digitalWrite(rear_motor_a[i], LOW);
+	  digitalWrite(rear_motor_b[i], HIGH);
+	  //analogWrite(front_motor_en[i], TURN_SPEED);
+	  //analogWrite(rear_motor_en[i], TURN_SPEED);
+	  target_out = TURN_SPEED;
+	break;
+
+	default:
+	  digitalWrite(front_motor_a[i], LOW);
+	  digitalWrite(front_motor_b[i], LOW);
+	  digitalWrite(rear_motor_a[i], LOW);
+	  digitalWrite(rear_motor_b[i], LOW);
+	  //analogWrite(front_motor_en[i], 0);
+	  //analogWrite(rear_motor_en[i], 0);
+	  target_out = 0;
+	break;
+  }
+
+  return target_out;
+}
+
+//


from defiene to const

from defiene to const

--- BlackLED.ino
+++ BlackLED.ino
@@ -15,14 +15,18 @@
 // definitions calculated from user settings
 //
 //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
-#define num_channel_per_output MAX_NUM_LED_PER_OUTPUT*NUM_CHANNEL_PER_LED
+
+const int num_channel_per_output = MAX_NUM_LED_PER_OUTPUT*NUM_CHANNEL_PER_LED;
 #if num_channel_per_output%512 > 0
-#define num_universes_per_output (num_channel_per_output/512)+1
+const int num_universes_per_output = (num_channel_per_output/512)+1;
 #else
-#define num_universes_per_output num_channel_per_output/512
-#endif
-
-#define num_led_per_output num_channel_per_output/NUM_CHANNEL_PER_LED
+const int num_universes_per_output = num_channel_per_output/512;
+#endif
+
+const int num_led_per_output = num_channel_per_output/NUM_CHANNEL_PER_LED;
+
+const int num_artnet_ports num_universes_per_output*NUM_OF_OUTPUTS;
+

 #define num_artnet_ports num_universes_per_output*NUM_OF_OUTPUTS


initial esp32 port (requires patched TLS2591 library)


Adding simple counter; adding commas to fix some readout; turning off green led flash inside camera

--- camera_box/camera_box.ino
+++ camera_box/camera_box.ino
@@ -13,12 +13,18 @@
 int led_pin = 13;
 int led_value = LOW;

+int counter = 0; // Simple counter
+
 Adafruit_MMA8451 mma = Adafruit_MMA8451();

 DHT dht(DHTPIN, DHTTYPE);

 void setup(void) {
   Serial.begin(9600);
+
+  // Turn off LED inside camera box
+  pinMode(led_pin, OUTPUT);
+  digitalWrite(led_pin, LOW);

   // Setup Camera relays
   pinMode(CAM_01_PIN, OUTPUT);
@@ -50,12 +56,17 @@
 void loop() {

   Serial.print("{");
-  read_accelerometer();
-  Serial.print(',');
-  read_dht_temp();
+
+  read_accelerometer(); Serial.print(',');
+
+  read_dht_temp(); Serial.print(",");
+
+  Serial.print("\"count\":"); Serial.print(++counter);
+  if(counter > 65000){
+    counter = 0;
+  }
+
   Serial.println("}");
-
-  toggle_led();

   delay(1000);
 }
@@ -81,14 +92,8 @@
   float h = dht.readHumidity();
   float c = dht.readTemperature(); // Celsius

-  // Check if any reads failed and exit early (to try again).
-  // if (isnan(h) || isnan(t)) {
-  //   Serial.println("Failed to read from DHT sensor!");
-  //   return;
-  // }
-
   Serial.print("\"humidity\":"); Serial.print(h); Serial.print(',');
-  Serial.print("\"temp_01\":"); Serial.print(c);
+  Serial.print("\"temp_01\":"); Serial.print(c);
 }

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


bumped the rev to 3.5

bumped the rev to 3.5

git-svn-id: d8bfcd070c2c81762cca1b3912331324182919ba@17905 0d6f1817-ed0e-0410-87c9-987e46238f29

--- zimodem/zimodem.ino
+++ zimodem/zimodem.ino
@@ -14,7 +14,7 @@
    limitations under the License.
 */
 //#define TCP_SND_BUF                     4 * TCP_MSS
-#define ZIMODEM_VERSION "3.4.5"
+#define ZIMODEM_VERSION "3.5"
 const char compile_date[] = __DATE__ " " __TIME__;
 #define DEFAULT_NO_DELAY true
 #define null 0


wat aanpassingen

wat aanpassingen

--- programmaNano/programmaNano.ino
+++ programmaNano/programmaNano.ino
@@ -5,7 +5,7 @@
 unsigned long previousMillis = 0;
 unsigned long previousMillisStappenmotor = 0;

-const long interval = 50;
+const long interval = 20;
 const long intervalStappenmotor = 10;

 #define echoPin 5          // Echo Pin
@@ -36,11 +36,11 @@
       delay(2);
   }

-  if (reader == 0) { myservo.write(80);  delay(250); reader = -1; }
-  else if (reader == 1) { myservo.write(60); delay(250); reader = -1;}
-  else if (reader == 2) { myservo.write(100); delay(250); reader = -1; }
-  else if (reader == 3) { myservo.write(0); delay(550); reader = -1; }
-  else if (reader == 4) { myservo.write(180); delay(550); reader = -1; }
+  if (reader == 0) { myservo.write(80);  delay(500); reader = -1; }
+  else if (reader == 1) { myservo.write(60); delay(500); reader = -1;}
+  else if (reader == 2) { myservo.write(100); delay(500); reader = -1; }
+  else if (reader == 3) { myservo.write(0); delay(1000); reader = -1; }
+  else if (reader == 4) { myservo.write(180); delay(1000); reader = -1; }
   else{

      if (currentMillis - previousMillis >= interval) {


Improving code

Improving code

--- Arduino/Arduino.ino
+++ Arduino/Arduino.ino
@@ -88,8 +88,8 @@
 const char FLIGHT_REC_OFF_CONFIRM   = 'o';

 //   MPU constants
-const char MPU_POSITIVE_THRESHOLD   = 5;
-const char MPU_NEGATIVE_THRESHOLD   = -5;
+const char MPU_POSITIVE_THRESHOLD   = 3;
+const char MPU_NEGATIVE_THRESHOLD   = -3;

 // INITIALIZE
@@ -126,21 +126,6 @@
   // Get information from the sensors
   recordGyroData();

-  //Serial.write("processed");
-  if( prevX - rotX > MPU_POSITIVE_THRESHOLD || prevX - rotX < MPU_NEGATIVE_THRESHOLD ||
-      prevY - rotY > MPU_POSITIVE_THRESHOLD || prevY - rotY < MPU_NEGATIVE_THRESHOLD ||
-      prevZ - rotZ > MPU_POSITIVE_THRESHOLD || prevZ - rotZ < MPU_NEGATIVE_THRESHOLD )
-  {
-    prevX = rotX;
-    prevY = rotY;
-    prevZ = rotZ;
-    Serial.write(MPU_X_PREFIX);
-    Serial.write(int(rotX));
-    Serial.write(MPU_Y_PREFIX);
-    Serial.write(int(rotY));
-    Serial.write(MPU_Z_PREFIX);
-    Serial.write(int(rotZ));
-  }
   // Process information from the sensors
   // Nothing here yet

@@ -216,13 +201,6 @@
       }
     }
   }
-
-  // Update Servo positions
-  throttle.write(pos1);
-  rotatingFront.write(pos2);
-  rotatingBack.write(pos3);
-  leftRight.write(pos4);
-  upDown.write(pos5);

   // Send status to Serial
   Serial.write(statusReport);
@@ -230,7 +208,20 @@
   // Send sensor data to serial
   if ( sensorReportingOn )
   {
-    // Nothing here yet
+    if( prevX - rotX > MPU_POSITIVE_THRESHOLD || prevX - rotX < MPU_NEGATIVE_THRESHOLD ||
+        prevY - rotY > MPU_POSITIVE_THRESHOLD || prevY - rotY < MPU_NEGATIVE_THRESHOLD ||
+        prevZ - rotZ > MPU_POSITIVE_THRESHOLD || prevZ - rotZ < MPU_NEGATIVE_THRESHOLD )
+    {
+      prevX = rotX;
+      prevY = rotY;
+      prevZ = rotZ;
+      Serial.write(MPU_X_PREFIX);
+      Serial.write(int(rotX));
+      Serial.write(MPU_Y_PREFIX);
+      Serial.write(int(rotY));
+      Serial.write(MPU_Z_PREFIX);
+      Serial.write(int(rotZ));
+    }
   }

   // Record flight data


Removed redundant setscale and changed to 3 readings instead of 5

--- Geek-FLL-Project.ino
+++ Geek-FLL-Project.ino
@@ -15,13 +15,12 @@
 float calibration_factor = 2000; // needs to come from calibration sketch

 void setupScale() {
-  scale.set_scale();
   scale.tare();  //Reset the scale to 0
   scale.set_scale(calibration_factor); //Adjust to this calibration factor
 }

 float getScaleWeight(){
-  return scale.get_units(5);  // average of 5 readings
+  return scale.get_units(3);  // average of 3 readings
 }

 const char pageFirstPart[]="<html>\


Adição dos comentários

Adição dos comentários

--- LineFollow/Vespa.ino
+++ LineFollow/Vespa.ino
@@ -14,42 +14,48 @@

 /******* CONFIGURAÇÃO PARA OS SENSORES *********/

+	//Valores que representam os sensores em ordem nas portas do arduino
 	int sensor[NUMSENSORS] = {22, 24, 26, 28, 30, 32, 34, 36, 38, 40, 42};
+	//Valores atribuídos para cara sensor em ordem (o peso de cada um)
 	//Para esquema 1, -9, -7, -5, -3, -1, 1, 3, 5, 7, 9;
 	//Para esquema 2, 0, 10, 20, 30, 40, 50, 60, 70, 80, 90;
 	int error[NUMSENSORS] = {-9, -7, -5, -3, -1, 0, 1, 3, 5, 7, 9};

 /******** CONFIGURAÇÃO PARA OS MOTORES **********/
-
+
+	//Portas do motor
 	int leftMotor[2] = {2, 3};
 	int rightMotor[2] = {4, 5};

 /******** CONFIGURAÇÃO PARA O CONTROLE **********/
-	int currentPoint = 0;
+
+	int currentPoint = 0;  //Variável que vai armazenar o valor de posição atual do robô
 	int setPoint = 0; //Para esquema 1, setPoint = 0; Para esquema 2, setPoint = 45;
-	int err = 0;
-	int iErr = 0, prevErr = 0;
-	int p = 0, i = 0, d = 0;
+	int err = 0; //Variável para armazenar o valor do erro
+	int iErr = 0, prevErr = 0; //Respectivamente, erro integral e erro anterior
+	int p = 0, i = 0, d = 0; //Valores p, i e d
 	//Valores a serem testados
-	int baseSpeed = 0;
-	int maxSpeed = 0;
-	unsigned long timeFlag = 0;
+	int baseSpeed = 0;    //Velocidade base do robô
+	int maxSpeed = 0;	  //Velocidade máxima atingível pelos motores
+	unsigned long timeFlag = 0; //Sinal de tempo para aceleração

 void setup() {
 	//Definição das portas dos sensores como input e dos motores como output
 	int i = 0;
 	for(i = 0; i < NUMSENSORS; i++) {
-		pinMode(sensor[i], INPUT);
+		pinMode(sensor[i], INPUT); //Definição dos sensores como entrada
 	}

 	for(i = 0; i < 2; i++) {
-		pinMode(leftMotor[i], OUTPUT);
+		pinMode(leftMotor[i], OUTPUT); //Definição dos motores como saída
 		pinMode(rightMotor[i], OUTPUT);
 	}
 }

 void loop() {
+	//Cálculo do erro: ponto atual subtraído do ponto de desejo
 	err = getCurrentPoint() - setPoint;
+	//Cálculo do P,I e D
 	p = KP * err;
 	i = KI * (iErr);
 	d = KD * (err - prevErr);
@@ -58,14 +64,18 @@
 	rightMotor(baseSpeed - CORRECTION(p,i,d));
 	leftMotor(baseSpeed + CORRECTION(p,i,d));

+	//Aceleração ou desaceleração dependendo do erro
 	accel(5, 50);

+	//Atualiza o erro anterior e soma o erro no erro integral
 	prevErr = err;
 	iErr += err;

+	//Previne windup (soma excessiva potencialmente perigosa do erro integral)
 	preventWindup();
 }

+//Previne windup (soma excessiva potencialmente perigosa do erro integral)
 void preventWindup() {
 	if(iErr >= maxSpeed)
 	{
@@ -76,10 +86,14 @@
 	}
 }

+//Cálculo do ponto atual do robô.
+//Pela média dos pesos dos sensores na linha pela quantidade de sensores na linha
 int getCurrentPoint() {
 	int i = 0;
-	int numerador = 0, denominador = 0;
+	int numerador = 0; //numerador: somatório dos pesos de cada sensor
+	int denominador = 0; //denominador: quantidade de sensores na linha
 	for(i = 0; i < NUMSENSORS; i++) {
+		//Vê se o sensor está na linha branca
 		if(!digitalRead(sensor[i]); {
 			denominador++;
 			numerador += error[i];
@@ -89,9 +103,11 @@
 		denominador = 1;
 	}

+	//Cálculo da média
 	return numerador/denominador;
 }

+//Ativa o motor direito com intensidade 'speed'
 void rightMotor(int speed) {
 	int newSpeedRightMotor = speed;
 	if(speed > maxSpeed) {
@@ -108,6 +124,7 @@
 	}
 }

+//Ativa o motor esquerdo com intensidade 'speed'
 void leftMotor(int speed) {
 	int newSpeedLeftMotor = speed;
 	if(speed > maxSpeed) {
@@ -124,6 +141,7 @@
 	}
 }

+//(Des)aceleração com em unidade v/ms²
 void accel(int accelFactor, int timeInterval) {
 	if(millis() - timeFlag >= timeInterval) {
 		if(err == 0 && baseSpeed < maxSpeed)


Update am2315test.ino

Update am2315test.ino

--- firmware/examples/am2315test.ino
+++ firmware/examples/am2315test.ino
@@ -1,5 +1,7 @@
+// This #include statement was automatically added by the Spark IDE.
+#include "Adafruit_AM2315.h"
+
 #include <spark_wiring.h>
-#include <Adafruit_AM2315.h>

 /***************************************************
   This is an example for the AM2315 Humidity + Temp sensor
@@ -25,7 +27,7 @@
 Adafruit_AM2315 am2315;

 void setup() {
-  Serial.begin(9600);
+    Serial.begin(9600);
   Serial.println("AM2315 Test!");

   if (! am2315.begin()) {


updated serial reading code to work in chunks.

--- arduino-json-api.ino
+++ arduino-json-api.ino
@@ -42,6 +42,59 @@
   proto.msgSend();
 }

+int protoState = 0;
+int protoPos = 0;
+static char protoBuf[500];
+void loop() {
+  while (Serial.available()) {
+    char c = (char)Serial.read();
+    if(protoState == 0) {
+      //scanning for a new message...
+      if(c == '{') {
+        //json message
+        protoState = 1;
+        protoBuf[0] = c;
+        protoPos=1;
+      } else if(c=='/') {
+        //rest call
+        protoState = 2;
+      }
+    } else if (protoState == 1) {
+        protoBuf[protoPos++] = c;
+        if (c=='}') {
+          protoBuf[protoPos++] = '\0';
+          //end of message, process it..
+          StaticJsonBuffer<500> jsonBuffer;
+          JsonObject& root = jsonBuffer.parseObject(protoBuf);
+          if (!root.success()) {
+             proto.msgOpen("Error","Error");
+             proto.msgAttr("ErrId",1);
+             proto.msgAttr("ErrName","json_parse_fail");
+             proto.msgSend("Error");
+           } else {
+             //json
+             boolean handled = false;
+             const String lib = root["lib"].asString();
+             if (lib == "servo") {handled = jservo.cmd(root);}
+             if (lib == "core") {handled = jcore.cmd(root);}
+             if (!handled) {
+               proto.msgOpen("Error","Error");
+               proto.msgAttr("ErrId",2);
+               proto.msgAttr("ErrName","unrecognised command");
+               proto.msgAttr("inpute",root["cmd"].asString());
+
+               proto.msgSend("Error");
+             }
+          }
+          protoState = 0;
+          protoPos = 0;
+        }
+    } else if (protoState == 2) {
+
+    }
+  }
+}
+/*
 void loop() {
   //declare input buffer and json buffer sizes.
   StaticJsonBuffer<500> jsonBuffer;
@@ -99,5 +152,5 @@

    delay(50); // give the Arduino some breathing room.
 }
-
+*/


D21FM: moving stuff down to lib

D21FM: moving stuff down to lib

--- Arduino/V0p2_Main/V0p2_Main.ino
+++ Arduino/V0p2_Main/V0p2_Main.ino
@@ -94,7 +94,7 @@
   {
   OTV0P2BASE::serialPrintlnAndFlush(); // Start new line to highlight error.  // May fail.
   OTV0P2BASE::serialPrintAndFlush('!'); // Indicate error with leading '!' // May fail.
-  OTV0P2BASE::serialPrintlnAndFlush(s); // May fail.
+  OTV0P2BASE::serialPrintlnAndFlush(s); // Print supplied detail text. // May fail.
   panic();
   }

@@ -508,79 +508,8 @@
   DEBUG_SERIAL_PRINT(intTempC16);
   DEBUG_SERIAL_PRINTLN();
 #endif
-
 #if !defined(ENABLE_MIN_ENERGY_BOOT)
-  // Seed PRNG(s) with available environmental values and clock time/jitter for some entropy.
-  // Also sweeps over SRAM and EEPROM (see RAMEND and E2END), especially for non-volatile state and uninitialised areas of SRAM.
-  // TODO: add better PRNG with entropy pool (eg for crypto).
-  // TODO: add RFM22B WUT clock jitter, RSSI, temperature and battery voltage measures.
-  const uint16_t srseed = OTV0P2BASE::sramCRC();
-  const uint16_t eeseed = OTV0P2BASE::eeCRC();
-  // DHD20130430: maybe as much as 16 bits of entropy on each reset in seed1, concentrated in the least-significant bits.
-  const uint16_t s16 = (__DATE__[5]) ^
-                       Vcc ^
-                       (intTempC16 << 1) ^
-#if !defined(ALT_MAIN_LOOP)
-                       (heat << 2) ^
-#if defined(TEMP_POT_AVAILABLE)
-                       ((((uint16_t)tempPot) << 3) + tempPot) ^
-#endif
-                       (AmbLight.get() << 4) ^
-#if defined(HUMIDITY_SENSOR_SUPPORT)
-                       ((((uint16_t)rh) << 8) - rh) ^
-#endif
-#endif
-                       (OTV0P2BASE::getMinutesSinceMidnightLT() << 5) ^
-                       (((uint16_t)OTV0P2BASE::getSubCycleTime()) << 6);
-  //const long seed1 = ((((long) clockJitterRTC()) << 13) ^ (((long)clockJitterWDT()) << 21) ^ (((long)(srseed^eeseed)) << 16)) + s16;
-  // Seed simple/fast/small built-in PRNG.  (Smaller and faster than srandom()/random().)
-  const uint8_t nar1 = OTV0P2BASE::noisyADCRead();
-  OTV0P2BASE::seedRNG8(nar1 ^ (uint8_t) s16, oldResetCount - (uint8_t)((s16+eeseed) >> 8), ::OTV0P2BASE::clockJitterWDT() ^ (uint8_t)srseed);
-#if 0 && defined(DEBUG)
-  DEBUG_SERIAL_PRINT_FLASHSTRING("nar ");
-  DEBUG_SERIAL_PRINTFMT(nar1, BIN);
-  DEBUG_SERIAL_PRINTLN();
-#endif
-  // TODO: seed other/better PRNGs.
-  // Feed in mainly persistent/nonvolatile state explicitly.
-  OTV0P2BASE::addEntropyToPool((uint8_t)(eeseed >> 8) + nar1, 0);
-  OTV0P2BASE::addEntropyToPool((uint8_t)s16 ^ (uint8_t)(s16 >> 8), 0);
-  for(uint8_t i = 0; i < V0P2BASE_EE_LEN_SEED; ++i)
-    { OTV0P2BASE::addEntropyToPool(eeprom_read_byte((uint8_t *)(V0P2BASE_EE_START_SEED + i)), 0); }
-  OTV0P2BASE::addEntropyToPool(OTV0P2BASE::noisyADCRead(), 1); // Conservative first push of noise into pool.
-  // Carry a few bits of entropy over a reset by picking one of the four designated EEPROM bytes at random;
-  // if zero, erase to 0xff, else AND in part of the seed including some of the previous EEPROM hash (and write).
-  // This amounts to about a quarter of an erase/write cycle per reset/restart per byte, or 400k restarts endurance!
-  // These 4 bytes should be picked up as part of the hash/CRC of EEPROM above, next time,
-  // essentially forming a longish-cycle (poor) PRNG even with little new real entropy each time.
-  OTV0P2BASE::seedRNG8(nar1 ^ (uint8_t) s16, oldResetCount - (uint8_t)((s16+eeseed) >> 8), ::OTV0P2BASE::clockJitterWDT() ^ (uint8_t)srseed);
-  uint8_t *const erp = (uint8_t *)(V0P2BASE_EE_START_SEED + (3&((s16)^((eeseed>>8)+(__TIME__[7]))))); // Use some new and some eeseed bits to choose which byte to updated.
-  const uint8_t erv = eeprom_read_byte(erp);
-  if(0 == erv) { OTV0P2BASE::eeprom_smart_erase_byte(erp); }
-  else
-    {
-    OTV0P2BASE::eeprom_smart_clear_bits(erp,
-#if !defined(NO_clockJitterEntropyByte)
-      ::OTV0P2BASE::clockJitterEntropyByte()
-#else
-      (::OTV0P2BASE::clockJitterWDT() ^ nar1) // Less good fall-back when clockJitterEntropyByte() not available with more actual entropy.
-#endif
-      + ((uint8_t)eeseed)); // Nominally include disjoint set of eeseed bits in choice of which to clear.
-    }
-#if 0 && defined(DEBUG)
-  DEBUG_SERIAL_PRINT_FLASHSTRING("srseed ");
-  DEBUG_SERIAL_PRINTFMT(srseed, BIN);
-  DEBUG_SERIAL_PRINTLN();
-  DEBUG_SERIAL_PRINT_FLASHSTRING("eeseed ");
-  DEBUG_SERIAL_PRINTFMT(eeseed, BIN);
-  DEBUG_SERIAL_PRINTLN();
-  DEBUG_SERIAL_PRINT_FLASHSTRING("RNG8 ");
-  DEBUG_SERIAL_PRINTFMT(randRNG8(), BIN);
-  DEBUG_SERIAL_PRINTLN();
-  DEBUG_SERIAL_PRINT_FLASHSTRING("erv ");
-  DEBUG_SERIAL_PRINTFMT(erv, BIN);
-  DEBUG_SERIAL_PRINTLN();
-#endif
+  OTV0P2BASE::seedPRNGs();
 #endif
 #endif


Delete ESP_01_mqtt_002_FIN.ino

Delete ESP_01_mqtt_002_FIN.ino


Debouncing pin reads

Debouncing pin reads

--- ESP32/ble_button/ble_button.ino
+++ ESP32/ble_button/ble_button.ino
@@ -7,11 +7,13 @@
 #define CHARACTERISTIC_UUID "beb5483e-36e1-4688-b7f5-ea07361b26a8"

 #define INPUT_PIN 33
+#define DEBOUNCE_TIME_MICROS 35000

 BLEServer* pServer = NULL;
 BLECharacteristic* pCharacteristic = NULL;

 bool connected = false;
+unsigned long lastValidReadTime = 0;

 class BLECallback: public BLEServerCallbacks {
@@ -58,23 +60,40 @@
 }

-void notify(){
-  Serial.println("On interrupt");
-
-  if(connected == true){
-    // Read input and store
-    uint8_t value =  0;
-    if(digitalRead(INPUT_PIN) == HIGH){
-      value = 1;
-    }
-
-    // Send 1 byte of data with value
-    pCharacteristic->setValue((uint8_t*)&value, 1);
-    pCharacteristic->notify();
-    Serial.println("Notification sent");
+/** Debounce
+ *
+ *  Returns true if input value is valid.
+ */
+bool debounce(){
+  unsigned long readTime = micros();
+  if(readTime - lastValidReadTime > DEBOUNCE_TIME_MICROS){
+    lastValidReadTime = readTime;
+    return true;
   }
   else{
-    Serial.println("Interrupted but not connected");
+    return false;
+  }
+}
+
+
+void onPinChanged(){
+  Serial.println("On pin changed");
+  if(debounce() == true){
+    if(connected == true){
+      // Read input and store
+      uint8_t value =  0;
+      if(digitalRead(INPUT_PIN) == HIGH){
+        value = 1;
+      }
+
+      // Send 1 byte of data with value
+      pCharacteristic->setValue((uint8_t*)&value, 1);
+      pCharacteristic->notify();
+      Serial.println("Notification sent");
+    }
+    else{
+      Serial.println("Interrupted but not connected");
+    }
   }
 }

@@ -89,7 +108,7 @@
   pinMode(INPUT_PIN, INPUT);

   // Attach interrupt to input pin
-  attachInterrupt(INPUT_PIN, notify, CHANGE);
+  attachInterrupt(INPUT_PIN, onPinChanged, CHANGE);
 }


fix bug > proc_get() > mistake in secret message display on LCD


Cleaning up OLED/Potentiometer test.

Cleaning up OLED/Potentiometer test.

--- arduino/oled_pot/oled_pot.ino
+++ arduino/oled_pot/oled_pot.ino
@@ -9,12 +9,13 @@
  #error("Height incorrect, please fix Adafruit_SSD1306.h!");
 #endif

+// This is where the Potentiometer pin is hooked up.
 #define POT_PIN 5

 void setup() {
   Serial.begin(9600);

-  Serial.println("OLED FeatherWing test");
+  Serial.println("OLED FeatherWing init");
   // by default, we'll generate the high voltage from the 3.3v line internally! (neat!)
   display.begin(SSD1306_SWITCHCAPVCC, 0x3C);  // initialize with the I2C addr 0x3C (for the 128x32)
   // init done
@@ -25,23 +26,18 @@
   // internally, this will display the splashscreen.
   display.display();
   delay(1000);
+
+  Serial.println("Clearing OLED");

-  // Clear the buffer.
+  // Clear the OLED display
   display.clearDisplay();
   display.display();
-
-  Serial.println("IO test");
-
-  // text display tests
   display.setTextSize(3);
   display.setTextColor(WHITE);
-  display.setCursor(0,0);
-  display.println("Pos: ");
-  display.setCursor(0,0);
-  display.display(); // actually display all of the above
 }

-int last = 0;
+// Set to -1 so that it displays the first time
+int last = -1;
 void loop() {
   // Divide by 10 puts number between 1-10X
   int pot = analogRead(POT_PIN) / 10;


[Minor] Removing moving average for moisture

--- arduino/sen_node/sen_node.ino
+++ arduino/sen_node/sen_node.ino
@@ -39,7 +39,7 @@
 #define PIN_HUM_AIR_TEMP  9
 #define PIN_PH            A0
 #define PIN_LIGHT         A3
-#define PIN_MOISTURE      A5
+#define PIN_MOISTURE      A2

 // Sensor value offsets
 #define OFFSET_PH         1.00 // To be calibrated
@@ -363,7 +363,8 @@
     _tDataPayload.uTempAir       = _humAirTemp.readTemperature();
     _tDataPayload.uTempSoil      = digitalRead(PIN_SOIL_TEMP);
     _tDataPayload.uHumidity      = _humAirTemp.readHumidity();
-    _tDataPayload.uMoisture      = _ma.get();
+//    _tDataPayload.uMoisture      = _ma.get();
+    _tDataPayload.uMoisture      = analogRead(PIN_MOISTURE);
     _tDataPayload.uReserved      = 0x03FF;

     /* Write data payload to the packet */


fix an additional bug recently introduced

--- d_BacpacCommands.ino
+++ d_BacpacCommands.ino
@@ -210,7 +210,7 @@
       Serial.println("");
     }
     buf[0] = 0x83; buf[1] = 'S'; buf[2] = 'R'; buf[3] = RECV(3);
-    if (buf[3] == 1) {
+    if (buf[3] == 1 && td[TD_MODE] != MODE_TIMELAPSE) {
       delay(1000); // start of a capture requres additional delay
     }
     delay(140);


added communication methods

added communication methods


Updated some docs

Updated some docs

--- Arduino/BLuB/BLuB.ino
+++ Arduino/BLuB/BLuB.ino
@@ -11,6 +11,7 @@

 // v0.07  2013-June-25  PEek, POke, for RAM and EEPROM implemented
 //			auto-pinMode()
+//			4800 baud
 //
 // v0.06  2013-June-24  Fixes for Arduino-builds
 //			PROGMEM for low memory usage (ATMega 168)


adjust battery max volt

adjust battery max volt


:art: [R] Send percentage as number

:art: [R] Send percentage as number

--- arduino/appliance/appliance.ino
+++ arduino/appliance/appliance.ino
@@ -36,51 +36,18 @@
   wifiManager.autoConnect(configSSID.c_str());
 }

-void loop()
+void loop()
 {
-
+  // Potentiometer 0...1024
   potentioMeter = analogRead(POTENTIO_METER);

-  if (potentioMeter < 89) {
-    printDebugMessage("0 procent");
-    sendExpressRotate("0");
-  } else if(potentioMeter < 178) {
-    printDebugMessage("10 procent");
-    sendExpressRotate("10");
-  } else if(potentioMeter < 267) {
-    printDebugMessage("20 procent");
-    sendExpressRotate("20");
-  } else if(potentioMeter < 356) {
-    printDebugMessage("30 procent");
-    sendExpressRotate("30");
-  } else if(potentioMeter < 445) {
-    printDebugMessage("40 procent");
-    sendExpressRotate("40");
-  } else if(potentioMeter < 534) {
-    printDebugMessage("50 procent");
-    sendExpressRotate("50");
-  } else if(potentioMeter < 623) {
-    printDebugMessage("60 procent");
-    sendExpressRotate("60");
-  } else if(potentioMeter < 712) {
-    printDebugMessage("70 procent");
-    sendExpressRotate("70");
-  } else if(potentioMeter < 801) {
-    printDebugMessage("80 procent");
-    sendExpressRotate("80");
-  } else if(potentioMeter < 890) {
-    printDebugMessage("90 procent");
-    sendExpressRotate("90");
-  } else if(potentioMeter > 979) {
-    printDebugMessage("100 procent");
-    sendExpressRotate("100");
-  }
+  // Convert 0...1024 to 0...100
+  sendExpressRotate(potentioMeter / 977.0 * 100);

   delay(1000);
-
 }

-void sendExpressRotate(String energyLevel)
+void sendExpressRotate(float energyLevel)
 {
   //Express server api call
   printDebugMessage("Sending rotation to node server");
@@ -97,7 +64,7 @@
   } else {
     printDebugMessage("Connection failed. Return " + String(httpCode));
   }
-
+
   http.end();
 }

@@ -111,5 +78,3 @@

   return chipIDString;
 }
-
-


[Minor] Update on arduino sketch for bl_batt

--- arduino/ble_ph_sensor/ble_ph_sensor.ino
+++ arduino/ble_ph_sensor/ble_ph_sensor.ino
@@ -127,7 +127,7 @@
 }

 int dat_respSensor() {
-  char aBaseStr[32];
+  char aBaseStr[64];
   char aValStrPH[10];
   char aValStrBatt[10];

@@ -148,16 +148,19 @@
   int iAdcValBatt = analogRead(BATT_LEVEL_PIN);
   float dValBatt = (iAdcValBatt * dMaxBatt / 2) / 1024;

-  dtostrf(dValPH, 5, 2, aValStrPH);
-  dtostrf(dValBatt, 5, 2, aValStrBatt);
-
-  strcpy(aBaseStr, " RDATA:pH=");
+  dtostrf(dValPH, 6, 2, aValStrPH);
+  dtostrf(dValBatt, 6, 2, aValStrBatt);
+
+  strcpy(aBaseStr, " RDATA: pH=");
   strcat(aBaseStr, aValStrPH);
-  strcat(aBaseStr, ",batt=");
+  strcat(aBaseStr, ";");
+  Serial.println(aBaseStr);
+
+  strcpy(aBaseStr, " RDATA: bt=");
   strcat(aBaseStr, aValStrBatt);
   strcat(aBaseStr, ";");
-
   Serial.println(aBaseStr);
+
 }

 int dat_liveNotif() {


Update gslc_ex19_ard for compatibility with ESP8266

--- arduino/gslc_ex19_ard/gslc_ex19_ard.ino
+++ arduino/gslc_ex19_ard/gslc_ex19_ard.ino
@@ -8,7 +8,19 @@
 //   - Antialiased Fonts
 //   - NOTE: This is Example demonstrates text antialiasing with the TFT_eSPI library.
 //     The font which can be found in the TFT_eSPI source in the libraries
-//     examples/Smooth Fonts/Print_Smooth_Font/data folder has to be uploaded to SPIFFS first
+//     examples/Smooth Fonts/Print_Smooth_Font/data folder has to be uploaded to SPIFFS first.
+//     Instructions from Bodmer/TFT_eSPI:
+//       ---
+//       The fonts used are in the sketch data folder, press Ctrl+K to view.
+//       Upload the fonts and icons to SPIFFS (must set at least 1M for SPIFFS) using the
+//       "Tools"  "ESP8266 (or ESP32) Sketch Data Upload" menu option in the IDE.
+//       To add this option follow instructions here for the ESP8266:
+//       https://github.com/esp8266/arduino-esp8266fs-plugin
+//       or for the ESP32:
+//       https://github.com/me-no-dev/arduino-esp32fs-plugin
+//       Close the IDE and open again to see the new menu option.
+//       ---
+//

 // Font file is stored in SPIFFS

@@ -17,8 +29,14 @@
 #endif

+// Define FS_NO_GLOBALS ahead of FS include to enable
+// both SPIFFS and SD access.
 #define FS_NO_GLOBALS
-#include <SPIFFS.h>
+#include <FS.h>
+
+#if defined(ESP32)
+  #include <SPIFFS.h>
+#endif

 #include <stdint.h>
 #include "GUIslice.h"
@@ -65,18 +83,15 @@
   gslc_tsElemRef* pElemRef = NULL;

   // Initialize debug output
-  analogReadResolution(10);
   Serial.begin(9600);
   gslc_InitDebug(&DebugOut);
   //delay(1000);  // NOTE: Some devices require a delay after Serial.begin() before serial port can be used
-

   // Init SPIFFS for Font Loading
   if (!SPIFFS.begin()) {
     Serial.println("SPIFFS initialisation failed!");
     while (1) yield(); // Stay here twiddling thumbs waiting
   }
-

   // Initialize
   if (!gslc_Init(&m_gui,&m_drv,m_asPage,MAX_PAGE,m_asFont,MAX_FONT)) { return; }


Added support for safey sensor trigger

Added support for safey sensor trigger

--- Code/CounterCat/CounterCat.ino
+++ Code/CounterCat/CounterCat.ino
@@ -45,6 +45,9 @@
 #define ACTIVE_FLICKER 100
 #define COOLDOWN_FLICKER  200
 #define BUTTON_DEBOUNCE 500
+
+#define USE_PIR2 true
+
 //These are the states for our state machine.
 enum State
 {
@@ -75,6 +78,7 @@

 int buttonThen;
 int sensorThen;
+int safetyThen;
 boolean wasHigh = false;

 ///SETUP//////////////////////////////////////////////////////////////////
@@ -98,7 +102,7 @@
   digitalWrite(RED_LED_PIN, LOW);

   Serial.begin(9600);
-  Serial.println("Starting CounterCat...");
+  Serial.println("Starting CounterCat2...");

   Serial.println("Warming up...");
   timerStart = millis();
@@ -106,6 +110,7 @@
   currentState = S_WARMING_UP;
   buttonThen = 0;
   sensorThen = 0;
+  safetyThen =0;
 }

@@ -138,6 +143,19 @@
     sensorRising = true;
   }
   sensorThen = sensorNow;
+
+   /*
+   * Check for a rising edge on the safety sensor.
+   */
+  boolean safetyRising = false;
+  int safetyNow = digitalRead(SENSOR_2_PIN);
+  if (safetyNow != safetyThen && safetyNow)
+  {
+    //Sensor rising edge!
+    Serial.println("Safety rising edge.");
+    safetyRising = true;
+  }
+  safetyThen = safetyNow;

   /*
@@ -188,7 +206,7 @@
       digitalWrite(BLENDER_PIN, HIGH);
       timerStart = now;
     }
-    else if (buttonPushed)
+    else if (buttonPushed || (safetyRising && USE_PIR2))
     {
       Serial.println("Pausing...");
       currentState = S_PAUSED;


frequency change

frequency change

--- crossbow.ino
+++ crossbow.ino
@@ -1,5 +1,5 @@
-#define DEVICE_MODE_TX
-// #define DEVICE_MODE_RX
+// #define DEVICE_MODE_TX
+#define DEVICE_MODE_RX

 #define FEATURE_TX_OLED

@@ -123,7 +123,7 @@
         LORA32U4_DI0_PIN
     );

-    if (!LoRa.begin(868E6))
+    if (!LoRa.begin(870E6))
     {
     #ifdef DEBUG_SERIAL
         Serial.println("LoRa init failed. Check your connections.");
@@ -311,7 +311,7 @@
         int8_t frameToSend = getFrameToTransmit(&qsp);

         if (frameToSend == QSP_FRAME_RC_DATA && !ppmReader.isReceiving()) {
-            // frameToSend = -1;
+            frameToSend = -1;
             //FIXME uncomment to enable full Failsafe
         }


Adjust for ATtiny (first step).

Adjust for ATtiny (first step).

--- examples/Sandbox/CosaRotaryEncoder/CosaRotaryEncoder.ino
+++ examples/Sandbox/CosaRotaryEncoder/CosaRotaryEncoder.ino
@@ -30,10 +30,6 @@
 #include "Cosa/Trace.hh"
 #include "Cosa/IOStream/Driver/UART.hh"

-// Rotary Dail is connected to D6 and D7 (as interrupt pins)
-// Min: -100, Max: 10, Initial: -100
-Rotary::Dail dail(Board::PCI6, Board::PCI7, -100, 10, -100);
-
 void setup()
 {
   // Use the UART as output stream
@@ -43,6 +39,14 @@
   // Start the interrupt pin handler
   InterruptPin::begin();
 }
+
+// Rotary Dail is connected to D6/D1 and D7/D2 (as interrupt pins)
+// Min: -100, Max: 10, Initial: -100
+#if defined(__ARDUINO_TINY__)
+Rotary::Dail dail(Board::PCI1, Board::PCI2, -100, 10, -100);
+#else
+Rotary::Dail dail(Board::PCI6, Board::PCI7, -100, 10, -100);
+#endif

 void loop()
 {


Lamp Test

Lamp Test

--- PinballDriver/PinballDriver.ino
+++ PinballDriver/PinballDriver.ino
@@ -144,6 +144,20 @@
     }
   }

+  static long lt = 0;
+  static long li = 0;
+
+  lt += dt;
+  while(lt > 50)
+  {
+    lt -= 50;
+
+    pinball.lampValues[li] = !pinball.lampValues[li];
+
+    li += 1;
+    li %= 56;
+  }
+
   pinball.update(dt);

   pinball.handleSolenoids();


Adjusting time for testing.

Adjusting time for testing.

--- examples/Time/CosaDS1307/CosaDS1307.ino
+++ examples/Time/CosaDS1307/CosaDS1307.ino
@@ -81,12 +81,12 @@
   // Set the time. Adjust below to your current time
   time_t now;
 #if defined(SET_TIME)
-  now.year = 0x13;
-  now.month = 0x12;
-  now.date = 0x31;
-  now.day = 0x02;
-  now.hours = 0x23;
-  now.minutes = 0x55;
+  now.year = 0x14;
+  now.month = 0x05;
+  now.date = 0x05;
+  now.day = 0x00;
+  now.hours = 0x00;
+  now.minutes = 0x01;
   now.seconds = 0x00;
   rtc.set_time(now);
   latest.set = now;


D2 pin is reserved for IRQ

D2 pin is reserved for IRQ

--- src/livingRoomNode1/livingRoomNode1.ino
+++ src/livingRoomNode1/livingRoomNode1.ino
@@ -13,7 +13,7 @@
 RFM69 radio;

 const PROGMEM char outdoorLight1Topic[] = "jaidan/home/outdoors/light1";
-SwitchedToggleControl outdoorLight1 = SwitchedToggleControl(1, 2, NODEID, OUTDOOR_LIGHT1_ID);  // Front house light
+SwitchedToggleControl outdoorLight1 = SwitchedToggleControl(1, 3, NODEID, OUTDOOR_LIGHT1_ID);  // Front house light

 void setup()
 {


change frequency to EDF signal

change frequency to EDF signal

--- arduino_ssr/arduino_ssr.ino
+++ arduino_ssr/arduino_ssr.ino
@@ -160,7 +160,7 @@
   digitalWrite( A1, 0 );
   digitalWrite( A2, 0 );

-  Timer1.initialize(200000); // set a timer of length 20000 microseconds (or 0.02 sec - or 50Hz => frequency of electricity in europe)
+  Timer1.initialize(20000); // set a timer of length 20000 microseconds (or 0.02 sec - or 50Hz => frequency of electricity in europe)
   Timer1.attachInterrupt( timerIsr ); // attach the service routine here

   /* initialize the Ethernet adapter */
@@ -168,7 +168,7 @@

   /* setup our default command that will be run when the user accesses
    * the root page on the server */
-  webserver.setDefaultCommand(&parsedCmd);
+  // webserver.setDefaultCommand(&parsedCmd);
   //webserver.setFailureCommand(&my_failCmd);

   webserver.addCommand("index.html", &parsedCmd);


Minor formatting fix.

Minor formatting fix.

--- src/_ota.ino
+++ src/_ota.ino
@@ -29,7 +29,7 @@
     events.send("start", "ota");

     ws.enable(false); // Disable WebSocket client connections
-    ws.closeAll(); // Close WebSocket client connections
+    ws.closeAll();    // Close WebSocket client connections
   });

   ArduinoOTA.onEnd([]() {


Add parameter value struct and conversions.

--- examples/seq/seq.ino
+++ examples/seq/seq.ino
@@ -58,6 +58,21 @@
 static const unsigned char semitone_lt[12] = {'C', 'C', 'D', 'E', 'E', 'F', 'F', 'G', 'G', 'A', 'B', 'B'};
 static const Intonation semitone_in[12] = {IN, IS, IN, IF, IN, IN, IS, IN, IS, IN, IF, IN};

+struct DU_SEQ_Values {
+  float stage_cv[8];
+  uint8_t stage_steps[8];
+  GateMode stage_gate[8];
+  bool stage_slew[8];
+  uint8_t stage_count;
+  bool diradd_mode;
+  float slew_rate;
+  float gate_time;
+  float clock_period;
+  bool clock_ext;
+};
+
+DU_SEQ_Values seq_values;
+
 void clock_isr();
 void reset_isr();
 void timer_isr();
@@ -99,7 +114,8 @@
       {
         stage_pitch[i] = 119;
       }
-    }
+      seq_values.stage_cv[i] = note_to_cv(stage_pitch[i]);
+    }
     load_params(8, stage_steps, 8);
     for(uint8_t i = 0; i < 8; ++i)
     {
@@ -107,6 +123,7 @@
       {
         stage_steps[i] = 8;
       }
+      seq_values.stage_steps[i] = stage_steps[i];
     }
     load_params(16, stage_gate, 8);
     for(uint8_t i = 0; i < 8; ++i)
@@ -115,6 +132,7 @@
       {
         stage_gate[i] = 5;
       }
+      seq_values.stage_gate[i] = (GateMode)stage_gate[i];
     }
     load_params(24, stage_slew, 1);
     load_params(25, stage_count, 1);
@@ -122,14 +140,20 @@
     {
       stage_count = 8;
     }
+    seq_values.stage_count = stage_count;
     load_params(26, diradd_mode, 1);
+    seq_values.diradd_mode = (bool)diradd_mode;
     load_params(27, slew_rate, 1);
+    seq_values.slew_rate = (float)slew_rate / 255.0;
     load_params(28, gate_time, 1);
+    seq_values.gate_time = (float)gate_time / 255.0;
     load_params(29, clock_bpm, 1);
     if(clock_bpm > 30)
     {
       clock_bpm = 30;
     }
+    seq_values.clock_period = bpm_to_ms(clock_bpm);
+    seq_values.clock_ext = !(bool)clock_bpm;

     // draw global elements
     display->draw_char(38, 2, '0' + stage_count, DUINO_SSD1306::White);
@@ -175,6 +199,16 @@
   }

  private:
+  float note_to_cv(uint8_t note)
+  {
+    return ((float)note - 36.0) / 12.0;
+  }
+
+  float bpm_to_ms(uint8_t bpm)
+  {
+    return 600000.0 / (float)bpm;
+  }
+
   void display_clock(int16_t x, int16_t y, uint8_t bpm, DUINO_SSD1306::SSD1306Color color)
   {
     if(bpm == 0)


lint )

lint )

--- f-preform-02/f-preform-02.ino
+++ f-preform-02/f-preform-02.ino
@@ -1,17 +1,14 @@
 #include <Wire.h> //include  i2c library
 #include <LiquidCrystal_I2C.h> //include library for work with lcd display via i2c
 #include <MsTimer2.h>
-
 #define GAME_START 0
 #define GAME_PERFORMED 1
 #define GAME_SIDE_OUT 2
 #define GAME_END_OUT 3
 #define GAME_OFFSIDE 4
 #define GAME_GOAL 9
-
 #define GREENS 1
-#define REDS -1
-
+#define REDS - 1
 #define POT_PIN A15
 #define RANDOMSEED_PIN A14
 #define MODE_PIN 49
@@ -22,7 +19,6 @@
 #define SD_SS_PIN 53
 #define LCD_SDA_PIN 20
 #define LCD_SCL_PIN 21
-
 #define B11_PIN A0
 #define B12_PIN A1
 #define B13_PIN A2
@@ -33,7 +29,6 @@
 #define B23_PIN A7
 #define B24_PIN A8
 #define B25_PIN A9
-
 #define L101_PIN 24
 #define L102_PIN 23
 #define L103_PIN 26
@@ -70,308 +65,371 @@
 #define L4R_PIN 11
 #define L4G_PIN 12
 #define L4B_PIN 13
-
-class Button {
-  public:
-    Button(byte pin, byte timeButton);  // конструктор
-    boolean flagPress;    // признак кнопка в нажатом состоянии
-    boolean flagClick;    // признак нажатия кнопки (клик)
-    boolean scanState();    // метод проверки состояние сигнала
-    void filterAvarage(); // метод фильтрации сигнала по среднему значению
-    void setPinTime(byte pin, byte timeButton); // метод установки номера вывода и времени (числа) подтверждения
-  private:
-    byte _buttonCount;    // счетчик подтверждений состояния кнопки
-    byte _timeButton;      // время подтверждения состояния кнопки
-    byte _pin;             // номер вывода кнопки
-};
+class Button
+{
+public:
+        Button(byte pin, byte timeButton); // конструктор
+        boolean flagPress; // признак кнопка в нажатом состоянии
+        boolean flagClick; // признак нажатия кнопки (клик)
+        boolean scanState(); // метод проверки состояние сигнала
+        void filterAvarage(); // метод фильтрации сигнала по среднему значению
+        void setPinTime(byte pin, byte timeButton); // метод установки номера вывода и времени (числа) подтверждения
+      private:
+        byte _buttonCount; // счетчик подтверждений состояния кнопки
+        byte _timeButton; // время подтверждения состояния кнопки
+        byte _pin; // номер вывода кнопки
+      };

 // метод фильтрации сигнала по среднему значению
 // при сигнале низкого уровня flagPress= true
 // при сигнале высокого уровня flagPress= false
 // при изменении состояния с высокого на низкий flagClick= true
-void Button::filterAvarage() {
-
-  if ( flagPress != digitalRead(_pin) ) {
-    //  состояние кнопки осталось прежним
-    if ( _buttonCount != 0 ) _buttonCount--; // счетчик подтверждений - 1 с ограничением на 0
-  }
-  else {
-    // состояние кнопки изменилось
-    _buttonCount++;   // +1 к счетчику подтверждений
-
-    if ( _buttonCount >= _timeButton ) {
-      // состояние сигнала достигло порога _timeButton
-      flagPress = ! flagPress; // инверсия признака состояния
-      _buttonCount = 0; // сброс счетчика подтверждений
-
-      if ( flagPress == true ) flagClick = true; // признак клика кнопки
-    }
-  }
-}
+      void Button::filterAvarage()
+      {
+        if (flagPress != digitalRead(_pin))
+        {
+        // состояние кнопки осталось прежним
+          if (_buttonCount != 0)
+            _buttonCount--; // счетчик подтверждений - 1 с ограничением на 0
+        }
+        else
+        {
+        // состояние кнопки изменилось
+        _buttonCount++; // +1 к счетчику подтверждений
+        if (_buttonCount >= _timeButton)
+        {
+            // состояние сигнала достигло порога _timeButton
+            flagPress = !flagPress; // инверсия признака состояния
+            _buttonCount = 0; // сброс счетчика подтверждений
+            if (flagPress == true)
+                flagClick = true; // признак клика кнопки
+            }
+          }
+        }

 // метод проверки состояния кнопки
 // при нажатой кнопке flagPress= true
 // при отжатой кнопке flagPress= false
 // при нажатии на кнопку flagClick= true
-boolean Button::scanState() {
-  boolean _stateChanged = false;
-  if ( flagPress != digitalRead(_pin) ) {
-    //  состояние кнопки осталось прежним
-    _buttonCount = 0; // сброс счетчика подтверждений
-  }
-  else {
-    // состояние кнопки изменилось
-    _buttonCount++;   // +1 к счетчику подтверждений
-
-    if ( _buttonCount >= _timeButton ) {
-      // состояние кнопки не мянялось в течение времени _timeButton
-      // состояние кнопки стало устойчивым
-      flagPress = ! flagPress; // инверсия признака состояния
-      _buttonCount = 0; // сброс счетчика подтверждений
-      _stateChanged = true;
-
-      if ( flagPress == true ) flagClick = true; // признак клика кнопки
-    }
-  }
-  return (_stateChanged);
-}
+        boolean Button::scanState()
+        {
+          boolean _stateChanged = false;
+          if (flagPress != digitalRead(_pin))
+          {
+        // состояние кнопки осталось прежним
+        _buttonCount = 0; // сброс счетчика подтверждений
+      }
+      else
+      {
+        // состояние кнопки изменилось
+        _buttonCount++; // +1 к счетчику подтверждений
+        if (_buttonCount >= _timeButton)
+        {
+            // состояние кнопки не мянялось в течение времени _timeButton
+            // состояние кнопки стало устойчивым
+            flagPress = !flagPress; // инверсия признака состояния
+            _buttonCount = 0; // сброс счетчика подтверждений
+            _stateChanged = true;
+            if (flagPress == true)
+                flagClick = true; // признак клика кнопки
+            }
+          }
+          return(_stateChanged);
+        }
+
 // метод установки номера вывода и времени подтверждения
-void Button::setPinTime(byte pin, byte timeButton)  {
-
-  _pin = pin;
-  _timeButton = timeButton;
-  pinMode(_pin, INPUT_PULLUP);  // определяем вывод кнопки как вход
-}
+        void Button::setPinTime(byte pin, byte timeButton)
+        {
+          _pin = pin;
+          _timeButton = timeButton;
+    pinMode(_pin, INPUT_PULLUP); // определяем вывод кнопки как вход
+  }

 // конструктор класса Button
-Button::Button(byte pin, byte timeButton) {
-
-  _pin = pin;
-  _timeButton = timeButton;
-  pinMode(_pin, INPUT_PULLUP);  // определяем вывод кнопки как вход
-}
-
-volatile Button button11(B11_PIN, 15);
-volatile Button button12(B12_PIN, 15);
-volatile Button button13(B13_PIN, 15);
-volatile Button button14(B14_PIN, 15);
-volatile Button button15(B15_PIN, 15);
-volatile Button button21(B21_PIN, 15);
-volatile Button button22(B22_PIN, 15);
-volatile Button button23(B23_PIN, 15);
-volatile Button button24(B24_PIN, 15);
-volatile Button button25(B25_PIN, 15);
-
-void  timerInterupt() {
-  button11.scanState();  // вызов метода ожидания стабильного состояния для кнопки
-  button12.scanState();
-  button13.scanState();
-  button14.scanState();
-  button15.scanState();
-  button21.scanState();
-  button22.scanState();
-  button23.scanState();
-  button24.scanState();
-  button25.scanState();
-}
+  Button::Button(byte pin, byte timeButton)
+  {
+    _pin = pin;
+    _timeButton = timeButton;
+    pinMode(_pin, INPUT_PULLUP); // определяем вывод кнопки как вход
+  }
+
+  volatile Button button11(B11_PIN, 15);
+  volatile Button button12(B12_PIN, 15);
+  volatile Button button13(B13_PIN, 15);
+  volatile Button button14(B14_PIN, 15);
+  volatile Button button15(B15_PIN, 15);
+  volatile Button button21(B21_PIN, 15);
+  volatile Button button22(B22_PIN, 15);
+  volatile Button button23(B23_PIN, 15);
+  volatile Button button24(B24_PIN, 15);
+  volatile Button button25(B25_PIN, 15);
+  void timerInterupt()
+  {
+    button11.scanState(); // вызов метода ожидания стабильного состояния для кнопки
+    button12.scanState();
+    button13.scanState();
+    button14.scanState();
+    button15.scanState();
+    button21.scanState();
+    button22.scanState();
+    button23.scanState();
+    button24.scanState();
+    button25.scanState();
+  }

 LiquidCrystal_I2C lcd(0x3f, 16, 2); // set the LCD address to 0x27 for a 16 chars and 2 line display
-
-const int b11 = B11_PIN, b12 = B12_PIN, b13 = B13_PIN, b14 = B14_PIN, b15 = B15_PIN, b21 = B21_PIN, b22 = B22_PIN, b23 = B23_PIN, //buttons
-          b24 = B24_PIN, b25 = B25_PIN,
-          l101 = L101_PIN, l102 = L102_PIN, l103 = L103_PIN, l104 = L104_PIN, l105 = L105_PIN, l106 = L106_PIN, l107 = L107_PIN, //leds
-          l108 = L108_PIN, l109 = L109_PIN, l110 = L110_PIN, l111 = L111_PIN, l112 = L112_PIN, l201 = L201_PIN, l202 = L202_PIN,
-          l203 = L203_PIN, l204 = L204_PIN, l205 = L205_PIN, l206 = L206_PIN, l207 = L207_PIN, l208 = L208_PIN, l209 = L209_PIN,
-          l210 = L210_PIN, l211 = L211_PIN, l212 = L212_PIN,
-          l1r = L1R_PIN, l1g = L1G_PIN, l1b = L1B_PIN, l2r = L2R_PIN, l2g = L2G_PIN, l2b = L2B_PIN, l3r = L3R_PIN, l3g = L3G_PIN, //rgb leds
-          l3b = L3B_PIN, l4r = L4R_PIN, l4g = L4G_PIN, l4b = L4B_PIN;
-const int field[12][5] = {
-  { -1, -1,   -1,   -1,   -1},
-  { -1, 1,    l108, 3,    -1},
-  { -1, l210, l204, l201, -1},
-  { -1, l103, l107, l112, -1},
-  { -1, l211, l205, l202, -1},
-  { -1, -1,   l106, -1,   -1},
-  { -1, -1,   l206, -1,   -1},
-  { -1, l102, l105, l111, -1},
-  { -1, l212, l207, l203, -1},
-  { -1, l101, l104, l110, -1},
-  { -1, 2,    l208, 4,    -1},
-  { -1, -1,   -1,   -1,   -1}
+const int b11 = B11_PIN, b12 = B12_PIN, b13 = B13_PIN, b14 = B14_PIN, b15 = B15_PIN, b21 = B21_PIN, b22 = B22_PIN, b23 = B23_PIN, // buttons
+b24 = B24_PIN, b25 = B25_PIN,
+l101 = L101_PIN, l102 = L102_PIN, l103 = L103_PIN, l104 = L104_PIN, l105 = L105_PIN, l106 = L106_PIN, l107 = L107_PIN, // leds
+l108 = L108_PIN, l109 = L109_PIN, l110 = L110_PIN, l111 = L111_PIN, l112 = L112_PIN, l201 = L201_PIN, l202 = L202_PIN,
+l203 = L203_PIN, l204 = L204_PIN, l205 = L205_PIN, l206 = L206_PIN, l207 = L207_PIN, l208 = L208_PIN, l209 = L209_PIN,
+l210 = L210_PIN, l211 = L211_PIN, l212 = L212_PIN,
+l1r = L1R_PIN, l1g = L1G_PIN, l1b = L1B_PIN, l2r = L2R_PIN, l2g = L2G_PIN, l2b = L2B_PIN, l3r = L3R_PIN, l3g = L3G_PIN, // rgb leds
+l3b = L3B_PIN, l4r = L4R_PIN, l4g = L4G_PIN, l4b = L4B_PIN;
+const int field[12][5] =
+{
+  {
+    - 1, -1, -1, -1, -1
+  },
+  {
+    - 1, 1, l108, 3, -1
+  },
+  {
+    - 1, l210, l204, l201, -1
+  },
+  {
+    - 1, l103, l107, l112, -1
+  },
+  {
+    - 1, l211, l205, l202, -1
+  },
+  {
+    - 1, -1, l106, -1, -1
+  },
+  {
+    - 1, -1, l206, -1, -1
+  },
+  {
+    - 1, l102, l105, l111, -1
+  },
+  {
+    - 1, l212, l207, l203, -1
+  },
+  {
+    - 1, l101, l104, l110, -1
+  },
+  {
+    - 1, 2, l208, 4, -1
+  },
+  {
+    - 1, -1, -1, -1, -1
+  }
 };
+
 int game = GAME_START,
-    x = -1, y = -1, vector = 0, xPrev = -1, yPrev = -1, vectorPrev = 0;
+x = -1, y = -1, vector = 0, xPrev = -1, yPrev = -1, vectorPrev = 0;
 unsigned long currentMillis = 0, previousMillis = 0;
 boolean ballkick = false;
-
-void setup() {
-  // put your setup code here, to run once:
-  MsTimer2::set(2, timerInterupt); // задаем период прерывания по таймеру 2 мс
-  MsTimer2::start();              // разрешаем прерывание по таймеру
-
-  currentMillis = millis();
-  previousMillis = currentMillis;
-
-  randomSeed(analogRead(RANDOMSEED_PIN));
-  pinMode(SPEAKER_PIN, OUTPUT);
-
-  lcd.init();
-  // Print a message to the LCD.
-  lcd.backlight();
-  //lcd.setCursor(0, 1); lcd.print(field[8][2]);
-
-  for (int i = 22; i <= 45; i++) { //init common leds
-    pinMode(i, OUTPUT);
-  }
-  for (int i = 2; i <= 13; i++) { //init rgb leds
-    pinMode(i, OUTPUT);
-  }
-}
-
-void reset_buttons_flagClick() {
-  button11.flagClick = 0;
-  button12.flagClick = 0;
-  button13.flagClick = 0;
-  button14.flagClick = 0;
-  button15.flagClick = 0;
-  button21.flagClick = 0;
-  button22.flagClick = 0;
-  button23.flagClick = 0;
-  button24.flagClick = 0;
-  button25.flagClick = 0;
-}
-
-void newxy (int _x, int _y, int _vector) {
-  xPrev = x;
-  yPrev = y;
-  vectorPrev = vector;
-  x = _x;
-  y = _y;
-  vector = _vector;
-  currentMillis = millis();
-  previousMillis = currentMillis;
-  reset_buttons_flagClick();
-  digitalWrite(field[x][y], HIGH);
-  digitalWrite(field[xPrev][yPrev], LOW);
-}
-
-void start_game() {
-  game = 999;
-  lcd.init();
-  reset_buttons_flagClick;
-  for (int j = random(100, 1000); j > 0; j = j - 100 ) {
-    for (int i = 2; i <= 13; i++) { //init rgb leds
-      digitalWrite(i, HIGH);
+void setup()
+{
+    // put your setup code here, to run once:
+    MsTimer2::set(2, timerInterupt); // задаем период прерывания по таймеру 2 мс
+    MsTimer2::start(); // разрешаем прерывание по таймеру
+    currentMillis = millis();
+    previousMillis = currentMillis;
+    randomSeed(analogRead(RANDOMSEED_PIN));
+    pinMode(SPEAKER_PIN, OUTPUT);
+    lcd.init();
+    // Print a message to the LCD.
+    lcd.backlight();
+    // lcd.setCursor(0, 1); lcd.print(field[8][2]);
+    for (int i = 22; i <= 45; i++)
+    {
+        // init common leds
+      pinMode(i, OUTPUT);
     }
-    delay(j);
-    for (int i = 2; i <= 13; i++) { //init rgb leds
-      //lcd.setCursor(12, 1); lcd.print(analogRead(b11));
-      //lcd.setCursor(15, 1); lcd.print(analogRead(b21));
-      digitalWrite(i, LOW);
+    for (int i = 2; i <= 13; i++)
+    {
+        // init rgb leds
+      pinMode(i, OUTPUT);
     }
-    delay(j);
-
-    if (button11.flagClick == 1 && button21.flagClick == 1) {
-      lcd.setCursor(0, 0); lcd.print("Both plrs false start!");
-      return;
-    }
-    else if (button21.flagClick == 1) {
-      lcd.setCursor(0, 0); lcd.print("Red plr false start! Green plr wins!");
-      game = GAME_PERFORMED;
-      newxy(5, 2, GREENS);
-      return;
-    }
-    else if (button11.flagClick == 1) {
-      lcd.setCursor(0, 0); lcd.print("Green plr false start! Red plr wins!");
-      game = GAME_PERFORMED;
-      newxy(6, 2, REDS);
-      return;
-    }
-  }
-  tone(SPEAKER_PIN, 3000, 250);
-  reset_buttons_flagClick;
-  while (1) {
-    if (button11.flagClick == 1) {
-      lcd.setCursor(0, 0); lcd.print("Green plr wins!");
-      game = GAME_PERFORMED;
-      newxy(5, 2, GREENS);
-      return;
-    }
-    else if (button21.flagClick == 1) {
-      lcd.setCursor(0, 0); lcd.print("Red plr wins!");
-      game = GAME_PERFORMED;
-      newxy(6, 2, REDS);
-      return;
-    }
-  }
-}
-
-void in_game() {
-  currentMillis = millis();
-  if (!ballkick && ((currentMillis - previousMillis) >= 3000)) {
-    game = GAME_OFFSIDE;
-    return;
-  }
-  else if (ballkick && ((currentMillis - previousMillis) >= 300)) {
-    newxy(x + x - xPrev, y + y - yPrev, vector);
-    return;
-  }
-  if ((button14.flagClick == 1) || (button24.flagClick == 1)) {
-    newxy(x + vector, y, vector);
-    ballkick = true;
-  }
-  if ((button13.flagClick == 1) || (button23.flagClick == 1)) {
-    newxy(x - vector, y, vector);
-    ballkick = true;
-  }
-  if ((button12.flagClick == 1) || (button22.flagClick == 1)) {
-    newxy(x, y + vector, vector);
-    ballkick = true;
-  }
-  if ((button15.flagClick == 1) || (button25.flagClick == 1)) {
-    newxy(x, y - vector, vector);
-    ballkick = true;
-  }
-}
-
-void loop() {
-  // put your main code here, to run repeatedly:
-  switch (game) {
-    case GAME_START:
-      start_game();
-
-      /*#define GAME_SIDE_OUT 2
-        #define GAME_END_OUT 3
-        #define GAME_OFFSIDE 4
-        #define GAME_GOAL 9
-      */
-      break;
-    case GAME_PERFORMED:
-      in_game();
-      //выполняется когда  var равно 2
-      break;
-    default:
-      // выполняется, если не выбрана ни одна альтернатива
-      // default необязателен
-      for (int i = 2; i <= 13; i++) {
-        lcd.setCursor(2, 1);
-        lcd.print(millis() / 1000);
-        digitalWrite(i, HIGH);   // turn the LED on (HIGH is the voltage level)
-        delay(1000);                       // wait for a second
-        digitalWrite(i, LOW);    // turn the LED off by making the voltage LOW
-        delay(1000); // wait for a second
+  }
+
+  void reset_buttons_flagClick()
+  {
+    button11.flagClick = 0;
+    button12.flagClick = 0;
+    button13.flagClick = 0;
+    button14.flagClick = 0;
+    button15.flagClick = 0;
+    button21.flagClick = 0;
+    button22.flagClick = 0;
+    button23.flagClick = 0;
+    button24.flagClick = 0;
+    button25.flagClick = 0;
+  }
+
+  void newxy(int _x, int _y, int _vector)
+  {
+    xPrev = x;
+    yPrev = y;
+    vectorPrev = vector;
+    x = _x;
+    y = _y;
+    vector = _vector;
+    currentMillis = millis();
+    previousMillis = currentMillis;
+    reset_buttons_flagClick();
+    digitalWrite(field[x][y], HIGH);
+    digitalWrite(field[xPrev][yPrev], LOW);
+  }
+
+  void start_game()
+  {
+    game = 999;
+    lcd.init();
+    reset_buttons_flagClick;
+    for (int j = random(100, 1000); j > 0; j = j - 100)
+    {
+      for (int i = 2; i <= 13; i++)
+      {
+            // init rgb leds
+        digitalWrite(i, HIGH);
       }
-      for (int i = 22; i <= 45; i++) {
-        lcd.setCursor(2, 1);
-        lcd.print(millis() / 1000);
-        digitalWrite(i, HIGH);   // turn the LED on (HIGH is the voltage level)
-        delay(1000);                       // wait for a second
-        digitalWrite(i, LOW);    // turn the LED off by making the voltage LOW
-        delay(1000); // wait for a second
-        //        if (i == 45) {
-        //          i = 22;
-        //        }
+      delay(j);
+      for (int i = 2; i <= 13; i++)
+      {
+            // init rgb leds
+            // lcd.setCursor(12, 1); lcd.print(analogRead(b11));
+            // lcd.setCursor(15, 1); lcd.print(analogRead(b21));
+        digitalWrite(i, LOW);
       }
-  }
-}
-
+      delay(j);
+      if (button11.flagClick == 1 && button21.flagClick == 1)
+      {
+        lcd.setCursor(0, 0);
+        lcd.print("Both plrs false start!");
+        return;
+      }
+      else
+        if (button21.flagClick == 1)
+        {
+          lcd.setCursor(0, 0);
+          lcd.print("Red plr false start! Green plr wins!");
+          game = GAME_PERFORMED;
+          newxy(5, 2, GREENS);
+          return;
+        }
+        else
+          if (button11.flagClick == 1)
+          {
+            lcd.setCursor(0, 0);
+            lcd.print("Green plr false start! Red plr wins!");
+            game = GAME_PERFORMED;
+            newxy(6, 2, REDS);
+            return;
+          }
+        }
+        tone(SPEAKER_PIN, 3000, 250);
+        reset_buttons_flagClick;
+        while (1)
+        {
+          if (button11.flagClick == 1)
+          {
+            lcd.setCursor(0, 0);
+            lcd.print("Green plr wins!");
+            game = GAME_PERFORMED;
+            newxy(5, 2, GREENS);
+            return;
+          }
+          else
+            if (button21.flagClick == 1)
+            {
+              lcd.setCursor(0, 0);
+              lcd.print("Red plr wins!");
+              game = GAME_PERFORMED;
+              newxy(6, 2, REDS);
+              return;
+            }
+          }
+        }
+
+        void in_game()
+        {
+          currentMillis = millis();
+          if (!ballkick && ((currentMillis - previousMillis) >= 3000))
+          {
+            game = GAME_OFFSIDE;
+            return;
+          }
+          else
+            if (ballkick && ((currentMillis - previousMillis) >= 300))
+            {
+              newxy(x + x - xPrev, y + y - yPrev, vector);
+              return;
+            }
+            if ((button14.flagClick == 1) || (button24.flagClick == 1))
+            {
+              newxy(x + vector, y, vector);
+              ballkick = true;
+            }
+            if ((button13.flagClick == 1) || (button23.flagClick == 1))
+            {
+              newxy(x - vector, y, vector);
+              ballkick = true;
+            }
+            if ((button12.flagClick == 1) || (button22.flagClick == 1))
+            {
+              newxy(x, y + vector, vector);
+              ballkick = true;
+            }
+            if ((button15.flagClick == 1) || (button25.flagClick == 1))
+            {
+              newxy(x, y - vector, vector);
+              ballkick = true;
+            }
+          }
+
+          void loop()
+          {
+    // put your main code here, to run repeatedly:
+            switch (game)
+            {
+              case GAME_START:
+              start_game();
+            /*#define GAME_SIDE_OUT 2
+            #define GAME_END_OUT 3
+            #define GAME_OFFSIDE 4
+            #define GAME_GOAL 9
+            */
+              break;
+              case GAME_PERFORMED:
+              in_game();
+            // выполняется когда  var равно 2
+              break;
+              default:
+        // выполняется, если не выбрана ни одна альтернатива
+        // default необязателен
+              for (int i = 2; i <= 13; i++)
+              {
+                lcd.setCursor(2, 1);
+                lcd.print(millis() / 1000);
+            digitalWrite(i, HIGH); // turn the LED on (HIGH is the voltage level)
+            delay(1000); // wait for a second
+            digitalWrite(i, LOW); // turn the LED off by making the voltage LOW
+            delay(1000); // wait for a second
+          }
+          for (int i = 22; i <= 45; i++)
+          {
+            lcd.setCursor(2, 1);
+            lcd.print(millis() / 1000);
+            digitalWrite(i, HIGH); // turn the LED on (HIGH is the voltage level)
+            delay(1000); // wait for a second
+            digitalWrite(i, LOW); // turn the LED off by making the voltage LOW
+            delay(1000); // wait for a second
+            // if (i == 45) {
+            // i = 22;
+            // }
+          }
+        }
+      }


Removed unnecessary code, and split up functions into blocks that make more sense for when the watch is implemented.

--- TrinketWatch.ino
+++ TrinketWatch.ino
@@ -23,41 +23,16 @@

 #define OLED_RESET 4
 Adafruit_SSD1306 display(OLED_RESET);
-
-#define NUMFLAKES 10
-#define XPOS 0
-#define YPOS 1
-#define DELTAY 2
-
-
-#define LOGO16_GLCD_HEIGHT 16
-#define LOGO16_GLCD_WIDTH  16
-static const unsigned char PROGMEM logo16_glcd_bmp[] =
-{ B00000000, B11000000,
-  B00000001, B11000000,
-  B00000001, B11000000,
-  B00000011, B11100000,
-  B11110011, B11100000,
-  B11111110, B11111000,
-  B01111110, B11111111,
-  B00110011, B10011111,
-  B00011111, B11111100,
-  B00001101, B01110000,
-  B00011011, B10100000,
-  B00111111, B11100000,
-  B00111111, B11110000,
-  B01111100, B11110000,
-  B01110000, B01110000,
-  B00000000, B00110000 };

 #if (SSD1306_LCDHEIGHT != 64)
 #error("Height incorrect, please fix Adafruit_SSD1306.h!");
 #endif

+
+
+unsigned long stopWatchStart = -1;
 int hours = 9;
 int minutes = 50;
-
-unsigned long stopWatchStart = -1;

 void setup() {
  Serial.begin(9600);
@@ -72,18 +47,28 @@
 }

 void loop() {
-  demo();
+  demo(); // update the time, now it's the demo but eventually it'll be a function calling the RTC
+  digitalTime(); // display the time in a digital format.
 }

 void demo() {
-  display.clearDisplay();
-  display.setTextSize(4);
   if (minutes >= 60) {
     hours++;
     minutes = 0;
   }
   if (hours > 23)
     hours = 1;
+  minutes++;
+}
+
+void updateButtonStates() {
+
+}
+
+void digitalTime() {
+  display.clearDisplay();
+  display.setTextSize(4);
+
   if (hours < 10)
     display.setCursor(17,10);
   else
@@ -97,7 +82,6 @@
   display.display();
   delay(200);

-  minutes++;
 }

 void stopwatch() {
@@ -111,7 +95,7 @@
     unsigned long inttime;

     /*
-      davekw7x from Arduino forms wrote the code to get mins, secs, etc.
+      davekw7x from Arduino forms wrote the code to get mins, secs, etc. from milliseconds.
       http://forum.arduino.cc/index.php?topic=18588.0
     */


updates

updates

--- TrinketWatch.ino
+++ TrinketWatch.ino
@@ -110,6 +110,11 @@
     int fractime;
     unsigned long inttime;

+    /*
+      davekw7x from Arduino forms wrote the code to get mins, secs, etc.
+      http://forum.arduino.cc/index.php?topic=18588.0
+    */
+
     inttime  = stopTime / 1000;
     fractime = stopTime % 1000;
     // inttime is the total number of number of seconds


Bump version date code for blynk fix

Bump version date code for blynk fix

--- wled00/wled00.ino
+++ wled00/wled00.ino
@@ -39,7 +39,7 @@
 #include "src/dependencies/e131/E131.h"

 //version in format yymmddb (b = daily build)
-#define VERSION 1808111
+#define VERSION 1808311
 char versionString[] = "0.7.1";

 //AP and OTA default passwords (change them!)


Disable mDNS broadcasting for the ESP32IOBoard by default. (#218)

* Disable mDNS broadcasting for the ESP32IOBoard by default.

By default the ESP32IOBoard should not broadcast over mDNS as this
should only be done for nodes which are acting as a hub. The
ESP32IOBoard can be a hub for other nodes to connect to via the
advertised mDNS service details.

--- arduino/examples/ESP32IOBoard/ESP32IOBoard.ino
+++ arduino/examples/ESP32IOBoard/ESP32IOBoard.ino
@@ -52,6 +52,12 @@

 #define USE_WIFI
 // #define USE_CAN
+
+// Uncomment the line below to have this node advertise itself via mDNS as a
+// hub. When this is enabled, other devices can find and connect to this node
+// via mDNS, treating it as a hub. Note this requires USE_WIFI to be enabled
+// above and should only be enabled on one node which is acting as a hub.
+// #define BROADCAST_MDNS

 // uncomment the line below to have all packets printed to the Serial
 // output. This is not recommended for production deployment.
@@ -344,7 +350,7 @@
         new Esp32HardwareCan("esp32can", CAN_RX_PIN, CAN_TX_PIN));
 #endif // USE_CAN

-#if defined(USE_WIFI)
+#if defined(USE_WIFI) && defined(BROADCAST_MDNS)
     // Broadcast this node's hostname with the mDNS service name
     // for a TCP GridConnect endpoint.
     MDNS.addService(openlcb::TcpDefs::MDNS_SERVICE_NAME_GRIDCONNECT_CAN,


Working on duino says game

Working on duino says game

--- arduino/duinosays/duinosays.ino
+++ arduino/duinosays/duinosays.ino
@@ -22,7 +22,7 @@
         return buttonState >> btn & 1 ? true : false;
     }
     static bool wasButtonOn(ScreenButtonId btn) {
-        return buttonState >> (4 + btn) ? true : false;
+        return buttonState >> (4 + btn) & 1? true : false;
     }
     static bool isButtonActivated(ScreenButtonId btn) {
         return isButtonOn(btn) && !wasButtonOn(btn);
@@ -43,59 +43,15 @@
         return !isAnyButtonOn() && wasAnyButtonOn();
     }

-    static bool isBottomLeftPressed() {
-        return buttonState & 1 ? true : false;
-    }
-    static bool isTopLeftPressed() {
-        return buttonState & 2 ? true : false;
-    }
-    static bool isTopRightPressed() {
-        return buttonState & 4 ? true : false;
-    }
-    static bool isBottomRightPressed() {
-        return buttonState & 8 ? true : false;
-    }
-    static bool wasBottomLeftPressed() {
-        return buttonState & 16 ? true : false;
-    }
-    static bool wasTopLeftPressed () {
-        return buttonState & 32 ? true : false;
-    }
-    static bool wasTopRightPressed() {
-        return buttonState & 64 ? true : false;
-    }
-    static bool wasBottomRightPressed() {
-        return buttonState & 128 ? true : false;
-    }
-
-    static bool wasBottomLeftActivated() {
-        return !wasBottomLeftPressed() && isBottomLeftPressed();
-    }
-    static bool wasTopLeftActivated() {
-        return !wasTopLeftPressed() && isTopLeftPressed();
-    }
-    static bool wasBottomRightActivated() {
-        return !wasBottomRightPressed() && isBottomRightPressed();
-    }
-    static bool wasTopRightActivated() {
-        return !wasTopRightPressed() && isTopRightPressed();
-    }
-
-    static bool wasBottomLeftReleased() {
-        return wasBottomLeftPressed() && !isBottomLeftPressed();
-    }
-    static bool wasTopLeftReleased() {
-        return wasTopLeftPressed() && !isTopLeftPressed();
-    }
-    static bool wasBottomRightReleased() {
-        return wasBottomRightPressed() && !isBottomRightPressed();
-    }
-    static bool wasTopRightReleased() {
-        return wasTopRightPressed() && !isTopRightPressed();
-    }
-
 };
 uint8_t ScreenButtonState::buttonState;
+
+namespace ParticleType {
+    const uint8_t bottomLeftButton = 0;
+    const uint8_t topLeftButton = 1;
+    const uint8_t topRightButton = 2;
+    const uint8_t bottomRightButton = 3;
+}

 enum DuinoSaysGameMode {
     DSMODE_MAINMENU,
@@ -103,6 +59,43 @@
     DSMODE_GAMEOVER
 };
 class DuinoSays;
+
+class Particle {
+private:
+    int16_t x, y, vx, vy;
+    uint8_t type, frameAge, maxAge;
+
+public:
+    void init(uint8_t type, int16_t x, int16_t y, int16_t vx, int16_t vy, int8_t maxAge) {
+        this->type = type;
+        this->x = x;
+        this->y = y;
+        this->vx = vx;
+        this->vy = vy;
+        this->maxAge = maxAge;
+        this->frameAge = 0;
+    }
+
+    bool isAlive() {
+        return frameAge < maxAge;
+    }
+
+    void draw(DuinoSays *duinoSays);
+};
+
+template<uint8_t maxParticles>
+class ParticleSystem {
+private:
+    uint8_t particleCount;
+    Particle particles[maxParticles];
+public:
+    ParticleSystem(): particleCount(0) {};
+    void draw(DuinoSays *duinoSays);
+    void spawn(uint8_t type, int16_t x, int16_t y, int16_t vx, int16_t vy, uint16_t maxAge) {
+        if (particleCount >= maxParticles) return;
+        particles[particleCount++].init(type,x<<8,y<<8,vx,vy, maxAge);
+    }
+};

 class Button {
 private:
@@ -122,6 +115,7 @@
 private:
     uint16_t seed;
     uint16_t currentLevel;
+    uint16_t currentStep;
     DuinoSaysGameMode mode;
     TinyScreen display;
     Button btnTopLeft;
@@ -129,7 +123,8 @@
     Button btnBottomLeft;
     Button btnBottomRight;
 public:
-    RenderBuffer<uint16_t,8> buffer;
+    RenderBuffer<uint16_t,40> buffer;
+    ParticleSystem<28> particleSystem;

 public:
     DuinoSays():
@@ -149,6 +144,10 @@
         display.setFlip(0);
         display.setBrightness(8);
         display.setBitDepth(buffer.is16bit()? 1:0);
+    }
+
+    void init() {
+        mode = DSMODE_MAINMENU;
     }

     void drawButton(bool on, uint16_t normalColor, uint16_t pressedColor, uint8_t x, uint8_t y) {
@@ -188,7 +187,7 @@
     void loop() {
         ScreenButtonState::updateButtonState(display.getButtons());

-
+        static unsigned long throttle = millis();
         static unsigned long t = millis();
         unsigned long t2 = millis();

@@ -198,17 +197,59 @@
         case DSMODE_PLAYING: loopPlaying(); break;
         }

+        particleSystem.draw(this);
+
         t = t2;
         buffer.flush(display);
         stringBuffer.reset();
-    }
-};
+
+        while (millis() - throttle < 50) continue;
+        throttle = millis();
+    }
+};
+
+void Particle::draw(DuinoSays* duinoSays) {
+    const int height = 24;
+    frameAge+=1;
+
+    const uint8_t rel = 255 - frameAge * 255 / maxAge;
+    const int width = 16 * rel >> 8;
+
+    uint8_t r = 255, g = 0, b = 255;
+    switch (type) {
+        case ParticleType::topLeftButton: r = 255, g = 64, b = 32; break;
+        case ParticleType::bottomLeftButton: r = 255, g = 255, b = 64; break;
+        case ParticleType::topRightButton: r = 32, g = 255, b = 32; break;
+        case ParticleType::bottomRightButton: r = 64, g = 64, b = 255; break;
+    }
+
+    duinoSays->buffer.drawRect((x>>8) - width / 2,(y>>8) - height / 2,width,height)->filledRect(duinoSays->buffer.rgb(rel * r >> 8,rel * g >> 8,rel * b >> 8));
+    x+=vx;
+    y+=vy;
+    vx -= vx>>3;
+    vy -= vy>>3;
+}
+
+template<uint8_t maxParticles>
+void ParticleSystem<maxParticles>::draw(DuinoSays* duinoSays) {
+    int n = 0;
+    for (int i=0; i < particleCount; i += 1) {
+        particles[i].draw(duinoSays);
+        if (particles[i].isAlive()) {
+            particles[n++] = particles[i];
+        }
+    }
+    particleCount = n;
+}

 void Button::draw(DuinoSays* duinoSays) {
     const bool on = ScreenButtonState::isButtonOn(btn);
     const int width = on ? 7 : 5;
     const int height = on ? 23 : 25;
     duinoSays->buffer.drawRect(x - width / 2,y - height / 2,width,height)->filledRect(on ? pressedColor : normalColor);
+    if (on && ScreenButtonState::isButtonActivated(btn)) {
+        duinoSays->particleSystem.spawn(btn, x,y,x<48?2000:-2000,0, 16);
+    }
 }

 DuinoSays duinoSays;


Don't manually initialize the button pins -- the new lib does that for us.

--- WirelessTrigger.ino
+++ WirelessTrigger.ino
@@ -62,10 +62,7 @@
     radio.startListening();
     radio.writeAckPayload(1, &ackVal, 1);

-#if ROLE == ROLE_SENDER
-    pinMode(triggerButtonPin, INPUT_PULLUP);
-    pinMode(resetButtonPin, INPUT_PULLUP);
-#else
+#if ROLE == ROLE_RECEIVER
     actuationServo.attach(servoPin);
     actuationServo.write(RESET_SERVO_ANGLE);
 #endif


Add flash support

Add flash support

--- Arilux_AL-LC0X.ino
+++ Arilux_AL-LC0X.ino
@@ -101,6 +101,15 @@
 int stepR, stepG, stepB;
 int redVal, grnVal, bluVal;

+// Globals for flash
+bool flash = false;
+bool startFlash = false;
+int flashLength = 0;
+unsigned long flashStartTime = 0;
+byte flashRed = 0;
+byte flashGreen = 0;
+byte flashBlue = 0;
+byte flashBrightness = 0;

 ///////////////////////////////////////////////////////////////////////////
 //  SSL/TLS
@@ -177,25 +186,53 @@
     startFade = true;
     inFade = false; // Kill the current fade

-    if (arilux.getState() != boolState) {
-      arilux.setState(boolState);
-      publishStateChange();
-    }
-
-    if(boolState) {
-      if (arilux.getBrightness() != brightness) {
-        arilux.setBrightness(brightness);
-        publishBrightnessChange();
+    if (root.containsKey("flash")) {
+      flashLength = (int)root["flash"] * 1000;
+
+      if (root.containsKey("brightness")) {
+        flashBrightness = root["brightness"];
+      } else {
+        flashBrightness = arilux.getBrightness();
       }

-      if (arilux.getWhite1Value() != white_value || arilux.getWhite2Value() != white_value) {
-        arilux.setWhite(white_value, white_value);
-        publishWhiteChange();
+      if (root.containsKey("color")) {
+        flashRed = root["color"]["r"];
+        flashGreen = root["color"]["g"];
+        flashBlue = root["color"]["b"];
+      } else {
+        flashRed = arilux.getRedValue();
+        flashGreen = arilux.getGreenValue();
+        flashBlue = arilux.getBlueValue();
       }

-      if (arilux.getRedValue() != red_color || arilux.getGreenValue() != green_color || arilux.getBlueValue() != blue_color) {
-        arilux.setColor(red_color, green_color, blue_color);
-        publishColorChange();
+      flashRed = map(flashRed, 0, 255, 0, flashBrightness);
+      flashGreen = map(flashGreen, 0, 255, 0, flashBrightness);
+      flashBlue = map(flashBlue, 0, 255, 0, flashBrightness);
+
+      flash = true;
+      startFlash = true;
+    } else { // Not flashing
+      flash = false;
+      if (arilux.getState() != boolState) {
+        arilux.setState(boolState);
+        publishStateChange();
+      }
+
+      if(boolState) {
+        if (arilux.getBrightness() != brightness) {
+          arilux.setBrightness(brightness);
+          publishBrightnessChange();
+        }
+
+        if (arilux.getWhite1Value() != white_value || arilux.getWhite2Value() != white_value) {
+          arilux.setWhite(white_value, white_value);
+          publishWhiteChange();
+        }
+
+        if (arilux.getRedValue() != red_color || arilux.getGreenValue() != green_color || arilux.getBlueValue() != blue_color) {
+          arilux.setColor(red_color, green_color, blue_color);
+          publishColorChange();
+        }
       }
     }
   } else if (String(ARILUX_MQTT_STATE_COMMAND_TOPIC).equals(p_topic)) {
@@ -271,6 +308,7 @@
           root.printTo(configBuf, sizeof(configBuf));
           publishToMQTT(HOME_ASSISTANT_MQTT_DISCOVERY_TOPIC, configBuf);
         #endif
+        flashSuccess(true);
       } else {
         DEBUG_PRINTLN(F("ERROR: The connection to the MQTT broker failed"));
         DEBUG_PRINT(F("Username: "));
@@ -279,6 +317,7 @@
         DEBUG_PRINTLN(MQTT_PASS);
         DEBUG_PRINT(F("Broker: "));
         DEBUG_PRINTLN(MQTT_SERVER);
+        flashSuccess(false);
       }

       subscribeToMQTTTopic(ARILUX_MQTT_STATE_COMMAND_TOPIC);
@@ -735,6 +774,7 @@
   ArduinoOTA.setHostname(MQTT_CLIENT_ID);
   ArduinoOTA.onStart([]() {
     DEBUG_PRINTLN("OTA Beginning!");
+    flashSuccess(true);
   });
   ArduinoOTA.onError([](ota_error_t error) {
     DEBUG_PRINT("ArduinoOTA Error[");
@@ -770,7 +810,7 @@
   // Handle commands
   handleCMD();
   yield();
-  handleFade();
+  handleEffects();
   connectMQTT();
   mqttClient.loop();
   yield();
@@ -782,50 +822,93 @@
 //  Utilities
 ///////////////////////////////////////////////////////////////////////////

-void handleFade(void) {
+void flashSuccess(bool success) {
+  flashLength = 5000;
+
+  flashBrightness = 255;
+
+  if(success) {
+    flashRed = 0;
+    flashGreen = 255;
+  } else {
+    flashRed = 255;
+    flashGreen = 0;
+  }
+  flashBlue = 0;
+
+  flashRed = map(flashRed, 0, 255, 0, flashBrightness);
+  flashGreen = map(flashGreen, 0, 255, 0, flashBrightness);
+  flashBlue = map(flashBlue, 0, 255, 0, flashBrightness);
+
+  flash = true;
+  startFlash = true;
+}
+
+void handleEffects(void) {
+  if (flash) {
+    if (startFlash) {
+      startFlash = false;
+      flashStartTime = millis();
+      arilux.setWhite(0, 0);
+    }
+    if ((millis() - flashStartTime) <= flashLength) {
+      if ((millis() - flashStartTime) % 1000 <= 500) {
+        arilux.setColor(flashRed, flashGreen, flashBlue);
+      } else {
+        arilux.setColor(0, 0, 0);
+        // If you'd prefer the flashing to happen "on top of"
+        // the current color, uncomment the next line.
+        // arilux.setColor(realRed, realGreen, realBlue);
+      }
+    } else {
+      flash = false;
+      arilux.setColor(realRed, realGreen, realBlue);
+    }
+  }
+
   if (startFade) {
-      // If we don't want to fade, skip it.
-      if (transitionTime == 0) {
-        arilux.setColor(realRed, realGreen, realBlue);
-
-        redVal = realRed;
-        grnVal = realGreen;
-        bluVal = realBlue;
-
-        startFade = false;
+    // If we don't want to fade, skip it.
+    if (transitionTime == 0) {
+      arilux.setColor(realRed, realGreen, realBlue);
+
+      redVal = realRed;
+      grnVal = realGreen;
+      bluVal = realBlue;
+
+      startFade = false;
+      publishColorChange();
+    } else {
+      loopCount = 0;
+      stepR = calculateStep(redVal, realRed);
+      stepG = calculateStep(grnVal, realGreen);
+      stepB = calculateStep(bluVal, realBlue);
+
+      inFade = true;
+    }
+  }
+
+  if (inFade) {
+    startFade = false;
+    unsigned long now = millis();
+    if (now - lastLoop > transitionTime) {
+      if (loopCount <= 1020) {
+        lastLoop = now;
+
+        redVal = calculateVal(stepR, redVal, loopCount);
+        grnVal = calculateVal(stepG, grnVal, loopCount);
+        bluVal = calculateVal(stepB, bluVal, loopCount);
+
+        arilux.setColor(redVal, grnVal, bluVal); // Write current values to LED pins
+
+        DEBUG_PRINT("Fade Loop count: ");
+        DEBUG_PRINTLN(loopCount);
+        loopCount++;
+      } else {
+        inFade = false;
         publishColorChange();
-      } else {
-        loopCount = 0;
-        stepR = calculateStep(redVal, realRed);
-        stepG = calculateStep(grnVal, realGreen);
-        stepB = calculateStep(bluVal, realBlue);
-
-        inFade = true;
       }
     }
-
-    if (inFade) {
-      startFade = false;
-      unsigned long now = millis();
-      if (now - lastLoop > transitionTime) {
-        if (loopCount <= 1020) {
-          lastLoop = now;
-
-          redVal = calculateVal(stepR, redVal, loopCount);
-          grnVal = calculateVal(stepG, grnVal, loopCount);
-          bluVal = calculateVal(stepB, bluVal, loopCount);
-
-          arilux.setColor(redVal, grnVal, bluVal); // Write current values to LED pins
-
-          DEBUG_PRINT("Fade Loop count: ");
-          DEBUG_PRINTLN(loopCount);
-          loopCount++;
-        } else {
-          inFade = false;
-          publishColorChange();
-        }
-      }
-    }
+  }
 }

 // From https://www.arduino.cc/en/Tutorial/ColorCrossfader


Delete HC-SR04.ino

Delete HC-SR04.ino

--- Device/HC-SR04.ino
+++ Device/HC-SR04.ino
@@ -1,201 +0,0 @@
-/*********************************************************************************
-SMART PARKING LOT SYSTEM
-*********************************************************************************/
-//Reference Value to Get The Status of Parking
-#define g_distanceMinimum 100
-#define g_faultValue 4500
-
-//Pin Setting for the 3 Ultrasonic Sensors
-#define g_trigPin 13
-#define g_echoPin 12
-#define g_trigPin2 4
-#define g_echoPin2 5
-#define g_trigPin3 8
-#define g_echoPin3 9
-
-/**************************************************************************************
-Function Name 		:	setup
-Description		:	Initialize the Sensor Trigger Pin as Output and
-                                echo pin as Input and begin the serial communication
-                                with 9600 BAUD
-Parameters 		:	void
-Return 			:	void
-**************************************************************************************/
-//Initialize the Pins and BAUD rate
-void setup(void) {
-        Serial.begin (9600);
-        pinMode(g_trigPin, OUTPUT);
-        pinMode(g_echoPin, INPUT);
-        pinMode(g_trigPin2, OUTPUT);
-        pinMode(g_echoPin2, INPUT);
-        pinMode(g_trigPin3, OUTPUT);
-        pinMode(g_echoPin3, INPUT);
-}
-
-/**************************************************************************************
-Function Name 		:	loop
-Description		:	Generate a Trigger signal and wait for the echo on
-                                HC-SR04 Ultrasonic Sensor and calculate the distance.
-Parameters 		:	void
-Return 			:	void
-**************************************************************************************/
-void loop(void) {
-  //Variables to calculate the distance using the duration taken for 1 cycle of trigger and echo
-  long l_duration,l_distance,l_duration2,l_distance2,l_duration3,l_distance3;
-  //Distance form the Ultrasonic Sensor 1
-  //Generate a high pulse on Trigger Pin with 10 micro seconds delay and wait for the echo
-  digitalWrite(g_trigPin, LOW);
-  delayMicroseconds(2);
-  digitalWrite(g_trigPin, HIGH);
-  delayMicroseconds(10);
-  digitalWrite(g_trigPin, LOW);
-  //Once received the Echo calculate the distance from the duration
-  l_duration = pulseIn(g_echoPin, HIGH);
-  l_distance = (l_duration/2) / 29.1;
-  delay(300);
-
-  //Distance form the Ultrasonic Sensor 2
-  digitalWrite(g_trigPin2, LOW);
-  delayMicroseconds(2);
-  digitalWrite(g_trigPin2, HIGH);
-  delayMicroseconds(10);
-  digitalWrite(g_trigPin2, LOW);
-  l_duration2 = pulseIn(g_echoPin2, HIGH);
-  l_distance2 = (l_duration2/2) / 29.1;
-  delay(300);
-
-  //Distance form the Ultrasonic Sensor 3
-  digitalWrite(g_trigPin3, LOW);
-  delayMicroseconds(2);
-  digitalWrite(g_trigPin3, HIGH);
-  delayMicroseconds(10);
-  digitalWrite(g_trigPin3, LOW);
-  l_duration3 = pulseIn(g_echoPin3, HIGH);
-  l_distance3 = (l_duration3/2) / 29.1;
-  delay(300);
-
-  //Check if the Sensor has any fault
-  /*DATA SENT by UART to RPi is  1,2,3
-		1	-	Parking LOT is Free
-		2	-	Parking LOT is Filled
-		3	-	Fault in the Sensor	*/
-  if(l_distance < g_fault && l_distance2 < g_fault && l_distance3 < g_fault)
-  {
-        if(l_distance <= g_parked && l_distance2 <= g_parked && l_distance3 <= g_parked)
-        {
-                Serial.write("222");
-        }
-        else if(l_distance <= g_parked && l_distance2 <= g_parked && l_distance3 > g_parked)
-        {
-                Serial.write("221");
-        }
-        else if(l_distance <= g_parked && l_distance2 > g_parked && l_distance3 <= g_parked)
-        {
-                Serial.write("212");
-        }
-        else if(l_distance <= g_parked && l_distance2 > g_parked && l_distance3 > g_parked)
-        {
-                Serial.write("211");
-        }
-        else if(l_distance > g_parked && l_distance2 <= g_parked && l_distance3 <= g_parked)
-        {
-                Serial.write("122");
-        }
-        else if(l_distance > g_parked && l_distance2 <= g_parked && l_distance3 > g_parked)
-        {
-                Serial.write("121");
-        }
-        else if(l_distance > g_parked && l_distance2 > g_parked && l_distance3 <= g_parked)
-        {
-                Serial.write("112");
-        }
-        else if(l_distance > g_parked && l_distance2 > g_parked && l_distance3 > g_parked)
-        {
-                Serial.write("111");
-        }
-  }
-  else
-  {
-        if(l_distance > g_fault && l_distance2 <= g_parked && l_distance3 <= g_parked)
-        {
-                Serial.write("322");
-        }
-        else if(l_distance > g_fault && l_distance2 <= g_parked && l_distance3 > g_parked)
-        {
-                Serial.write("321");
-        }
-        else if(l_distance > g_fault && l_distance2 > g_parked && l_distance3 <= g_parked)
-        {
-                Serial.write("312");
-        }
-        else if(distance > g_fault && distance2 > g_parked && distance3 > g_parked)
-        {
-                Serial.write("311");
-        }
-        else if(l_distance <= g_parked && l_distance2 > g_fault && l_distance3 <= g_parked)
-        {
-                Serial.write("232");
-        }
-        else if(l_distance <= g_parked && l_distance2 > g_fault && l_distance3 > g_parked)
-        {
-                Serial.write("231");
-        }
-        else if(l_distance > g_parked && l_distance2 > g_fault && l_distance3 <= g_parked)
-        {
-                Serial.write("132");
-        }
-        else if(l_distance > g_parked && l_distance2 > g_fault && l_distance3 > g_parked)
-        {
-                Serial.write("131");
-        }
-        else if(l_distance <= g_parked && l_distance2 <= g_parked && l_distance3 > g_fault)
-        {
-                Serial.write("223");
-        }
-        else if(l_distance <= g_parked && l_distance2 > g_parked && l_distance3 > g_fault)
-        {
-                Serial.write("213");
-        }
-        else if(l_distance > g_parked && l_distance2 <= g_parked && l_distance3 > g_fault)
-        {
-                Serial.write("123");
-        }
-        else if(l_distance > g_parked && l_distance2 > g_parked && l_distance3 > g_fault)
-        {
-                Serial.write("113");
-        }
-        else if(l_distance > g_fault && l_distance2 > g_fault && l_distance3 <= g_parked)
-        {
-                Serial.write("332");
-        }
-        else if(l_distance > g_fault && l_distance2 > g_fault && l_distance3 > g_parked)
-        {
-                Serial.write("331");
-        }
-        else if(l_distance <= g_parked && l_distance2 > g_fault && l_distance3 > g_fault)
-        {
-                Serial.write("233");
-        }
-        else if(l_distance > g_parked && l_distance2 > g_fault && l_distance3 > g_fault)
-        {
-                Serial.write("133");
-        }
-        else if(l_distance > g_fault && l_distance2 <= g_parked && l_distance3 > g_fault)
-        {
-                Serial.write("323");
-        }
-        else if(l_distance > g_fault && l_distance2 > g_parked && l_distance3 > g_fault)
-        {
-                Serial.write("313");
-        }
-        else if(l_distance > g_fault && l_distance2 > g_fault && l_distance3 > g_fault)
-        {
-                Serial.write("333");
-        }
-  }
-  //Provide a Delay for every 5 Seconds once data sent to the RPi
-  delay(5000);
-}
-
-//End of the Program
-/***************************************************************************************************/


reset demo_stopWithDelay to match description

--- Firmware/Demo.ino
+++ Firmware/Demo.ino
@@ -65,8 +65,8 @@
     CurveResult result;
     result.finished = false;
     result.omega = 0;
-    result.vx = 1;
-    result.vy = 0;
+    result.vx = 0;
+    result.vy = 1;

     if (t > 10.0)
     {


Update YunSmartMeasuringCupSketch.ino

Update YunSmartMeasuringCupSketch.ino

--- YunSmartMeasuringCupSketch/YunSmartMeasuringCupSketch.ino
+++ YunSmartMeasuringCupSketch/YunSmartMeasuringCupSketch.ino
@@ -14,9 +14,9 @@
 #define SENSOR_PIN          0      // Analog pin which is connected to the sensor.

 // Calibration values measured from the LiquidSensor sketch.
-#define ZERO_VOLUME_RESISTANCE    1963.70    // Resistance value (in ohms) when no liquid is present.
-#define CALIBRATION_RESISTANCE    512.81    // Resistance value (in ohms) when liquid is at max line.
-#define CALIBRATION_VOLUME        500.0    // Volume (in any units) when liquid is at max line.
+#define ZERO_VOLUME_RESISTANCE    0.00    // Resistance value (in ohms) when no liquid is present.
+#define CALIBRATION_RESISTANCE    0.00    // Resistance value (in ohms) when liquid is at max line.
+#define CALIBRATION_VOLUME        0.00    // Volume (in any units) when liquid is at max line.

 #define YUN_SERVER_PORT  5678  // Internal port the YunServer instance will use for communication with Flask.
                                  // Don't change this unless you know what you're doing!