Comment stuff

Comment stuff

--- Firmware/R2-Quadcopter/R2-Quadcopter.ino
+++ Firmware/R2-Quadcopter/R2-Quadcopter.ino
@@ -7,21 +7,21 @@
 #include <utility/imumaths.h>

 // Mise en place des variables
-Servo esc_1; //FRONT RIGHT (avant droit)
-Servo esc_2; //BACK LEFT (arrière gauche)e
-Servo esc_3; //FRONT LEFT (avant gauche)
-Servo esc_4; //BACK RIGHT (arrière droit)
+Servo esc_1; //FRONT RIGHT (Moteur avant droit)
+Servo esc_2; //BACK LEFT (Moteur arrière gauche)e
+Servo esc_3; //FRONT LEFT (Moteur avant gauche)
+Servo esc_4; //BACK RIGHT (Moteur arrière droit)

 // PID
-byte dt = 20;//c'est le temps que doit attendre le PID avant de calculer
-unsigned long dernierTemps;//est utile aussi pour le dt du PID
+byte dt = 20; // C'est le temps que doit attendre le PID avant de calculer
+unsigned long dernierTemps; // Est utile aussi pour le dt du PID
 unsigned long maintenant, deltaTemps;
 bool auto_stabilisation_mode = false; // Activer ou pas le mode auto-stabilisé
 float pid_roll_out,   pid_roll_setpoint,  roll_error, Proportional_roll,  Integral_roll,  Derivative_roll,  last_roll_error, roll_angle_adjust = 0;
 float pid_pitch_out,  pid_pitch_setpoint, pitch_error, Proportional_pitch, Integral_pitch, Derivative_pitch, last_pitch_error, pitch_angle_adjust = 0;
 float pid_yaw_out,    pid_yaw_setpoint,   yaw_error,  Proportional_yaw,   Integral_yaw,   Derivative_yaw,   last_yaw_error = 0;

-// MOTORS
+// MOTEURS
 int motorFR, motorBL, motorFL, motorBR;

 // RX
@@ -36,7 +36,7 @@
 float pitch_speed, pitch_angle;
 float yaw_speed, yaw_angle;
 const float pi = 3.14159265359;
-Adafruit_BNO055 bno = Adafruit_BNO055();
+Adafruit_BNO055 bno = Adafruit_BNO055(); // Initialisation de l'objet BNO

 ////////////////////////////////////////////////////////////////////////
 //INTERRUPTS
@@ -49,9 +49,6 @@
     if (chrono_start0 != 0) {
       inputARMprev = inputARM;
       inputARM = ((volatile int)micros() - chrono_start0);
-      if (inputARM >= inputARMprev + 300){
-        inputARM = inputARMprev + 300;
-      }
       chrono_start0 = 0;
     }
   }
@@ -68,6 +65,9 @@
       if (inputROLL >= inputROLLprev + 300){
         inputROLL = inputROLLprev + 300;
       }
+      if (inputROLL <= inputROLLprev - 300){
+        inputROLL = inputROLLprev - 300;
+      }
       chrono_start1 = 0;
     }
   }
@@ -84,6 +84,9 @@
       if (inputPITCH >= inputPITCHprev + 300){
         inputPITCH = inputPITCHprev + 300;
       }
+      if (inputPITCH <= inputPITCHprev - 300){
+        inputPITCH = inputPITCHprev - 300;
+      }
       chrono_start2 = 0;
     }
   }
@@ -100,6 +103,9 @@
       if (inputTHROTTLE >= inputTHROTTLEprev + 300){
         inputTHROTTLE = inputTHROTTLEprev + 300;
       }
+      if (inputTHROTTLE <= inputTHROTTLEprev - 300){
+        inputTHROTTLE = inputTHROTTLEprev - 300;
+      }
       chrono_start3 = 0;
     }
   }
@@ -116,102 +122,97 @@
       if (inputYAW >= inputYAWprev + 300){
         inputYAW = inputYAWprev + 300;
       }
+      if (inputYAW <= inputYAWprev - 300){
+        inputYAW = inputYAWprev - 300;
+      }
       chrono_start4 = 0;
     }
   }
 }

-//////////////////////////////////////////////////////////////////////////////////////////////////////////////////
-
-
-
-
-
-
-
 ////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
-//PID controller
+//Controleur PID
 ////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
 void pid_compute() {
   unsigned long maintenant = millis();
   int deltaTemps = (maintenant - dernierTemps);
   //if(deltaTemps >= dt){
-
+
     //ROLL calculations
     //definition du setpoint
     pid_roll_setpoint = 0;
     if (inputROLL > THROTTLE_RMID + 10)pid_roll_setpoint = (inputROLL - THROTTLE_RMID + 10)/3.0;
     else if (inputROLL < THROTTLE_RMID - 10)pid_roll_setpoint = (inputROLL - THROTTLE_RMID - 10)/3.0;
-
+
     roll_error = roll_speed - pid_roll_setpoint;
-
+
     Proportional_roll = ROLL_PID_KP * roll_error;
     Integral_roll += (ROLL_PID_KI ) * roll_error;
     if (Integral_roll > ROLL_PID_MAX)Integral_roll = ROLL_PID_MAX;
     else if (Integral_roll < ROLL_PID_MIN)Integral_roll = ROLL_PID_MIN;
     Derivative_roll = ROLL_PID_KD * (roll_error - last_roll_error);
-
+
     pid_roll_out = Proportional_roll + Integral_roll + Derivative_roll;
     if (pid_roll_out > ROLL_PID_MAX)pid_roll_out = ROLL_PID_MAX;
     else if (pid_roll_out < ROLL_PID_MIN)pid_roll_out = ROLL_PID_MIN;
-
+
     last_roll_error = roll_error;
-
-
+
+
     //PITCH calculations
     //definition du setpoint
     pid_pitch_setpoint = 0;
     if (inputPITCH > THROTTLE_RMID + 10)pid_pitch_setpoint = (inputPITCH - THROTTLE_RMID + 10)/3.0;
     else if (inputPITCH< THROTTLE_RMID - 10)pid_pitch_setpoint = (inputPITCH - THROTTLE_RMID - 10)/3.0;
-
+
     pitch_error = pitch_speed - pid_pitch_setpoint;
-
+
     Proportional_pitch = PITCH_PID_KP * pitch_error;
     Integral_pitch += PITCH_PID_KI * pitch_error;
     if (Integral_pitch > PITCH_PID_MAX)Integral_pitch = PITCH_PID_MAX;
     else if (Integral_pitch < PITCH_PID_MIN)Integral_pitch = PITCH_PID_MIN;
     Derivative_pitch = PITCH_PID_KD * (pitch_error - last_pitch_error);
-
+
     pid_pitch_out = Proportional_pitch + Integral_pitch + Derivative_pitch;
     if (pid_pitch_out > PITCH_PID_MAX)pid_pitch_out = PITCH_PID_MAX;
     else if (pid_pitch_out < PITCH_PID_MIN)pid_pitch_out = PITCH_PID_MIN;
-
+
     last_pitch_error = pitch_error;
-
+
     //YAW calculations
     //On calcule le setpoint du yaw ici car il est le meme en stabilise ou en acro
     pid_yaw_setpoint = 0;
     if (inputYAW > THROTTLE_RMID + 10)pid_yaw_setpoint = (inputYAW - THROTTLE_RMID + 10) / 3.0;
     else if (inputYAW < THROTTLE_RMID - 10)pid_yaw_setpoint = (inputYAW - THROTTLE_RMID - 10) / 3.0;
-
+
     yaw_error = yaw_speed - pid_yaw_setpoint;
-
+
     Proportional_yaw = YAW_PID_KP * yaw_error;
     Integral_yaw += YAW_PID_KI * yaw_error;
     if (Integral_yaw > YAW_PID_MAX)Integral_yaw = YAW_PID_MAX;
     else if (Integral_yaw < YAW_PID_MIN)Integral_yaw = YAW_PID_MIN;
     Derivative_yaw = YAW_PID_KD * (yaw_error - last_yaw_error);
-
+
     pid_yaw_out = Proportional_yaw + Integral_yaw + Derivative_yaw;
     if (pid_yaw_out > YAW_PID_MAX)pid_yaw_out = YAW_PID_MAX;
     else if (pid_yaw_out < YAW_PID_MIN)pid_yaw_out = YAW_PID_MIN;
-
+
     last_yaw_error = yaw_error;

     //dernierTemps = maintenant;
   //}
-
+
 }
 void pid_LEVEL_compute() {

-  //ROLL calculations
+  //ROLL calculs
   //definition du setpoint angle
   pid_roll_setpoint = 0;
   if (inputROLL > THROTTLE_RMID + 10)pid_roll_setpoint = inputROLL - THROTTLE_RMID + 10;
   else if (inputROLL < THROTTLE_RMID - 10)pid_roll_setpoint = inputROLL - THROTTLE_RMID - 10;
-  pid_roll_setpoint -= roll_angle_adjust;            //On soustrait roll adjust pour que le setpoint soit change avec langle
+  pid_roll_setpoint -= roll_angle_adjust;            //On soustrait roll adjust pour que le setpoint soit change avec langle
   pid_roll_setpoint /= 2;
-
+
   roll_error = roll_speed - pid_roll_setpoint;

   Proportional_roll = ROLL_PID_LEVEL_KP * roll_error;
@@ -227,14 +228,14 @@
   last_roll_error = roll_error;

-  //PITCH calculations
+  //PITCH calculs
   //definition du setpoint
   pid_pitch_setpoint = 0;
   if (inputPITCH > THROTTLE_RMID + 10)pid_pitch_setpoint = inputPITCH - THROTTLE_RMID + 10;
   else if (inputPITCH < THROTTLE_RMID - 10)pid_pitch_setpoint = inputPITCH - THROTTLE_RMID - 10;
   pid_pitch_setpoint -= pitch_angle_adjust;
   pid_pitch_setpoint /= 2;
-
+
   pitch_error = pitch_speed - pid_pitch_setpoint;

   Proportional_pitch = PITCH_PID_LEVEL_KP * pitch_error;
@@ -249,7 +250,7 @@

   last_pitch_error = pitch_error;

-  //YAW calculations
+  //YAW calculs
   //On calcule le setpoint du yaw ici car il est le meme en stabilise ou en acro
   pid_yaw_setpoint = 0;
   if (inputYAW > THROTTLE_RMID + 10)pid_yaw_setpoint = (inputYAW - THROTTLE_RMID + 10) / 2.0;
@@ -351,7 +352,7 @@
   Serial.print(roll_speed);
   Serial.print(",");
   Serial.println(pid_roll_setpoint);
-
+
 }

@@ -383,15 +384,13 @@
   Proportional_roll, Integral_roll, Derivative_roll = 0;
   Proportional_pitch, Integral_pitch, Derivative_pitch = 0;
   Proportional_yaw, Integral_yaw, Derivative_yaw = 0;
-
-  delay(5000);
 }

 // Fonction qui s'execute a chaque cycle
 void loop() {

-  //IMU calculations
+  //IMU calculs
   //vitesse angulaire

   imu::Vector<3> gyroscope = bno.getVector(Adafruit_BNO055::VECTOR_GYROSCOPE);
@@ -403,9 +402,9 @@
   roll_angle = -1 * euler.z();
   pitch_angle = -1 * euler.y();
   yaw_angle = euler.x();
-
+
   //maintenant = 0;
-  roll_angle_adjust = roll_angle * -15;  //la constante multipliee est a ajuster
+  roll_angle_adjust = roll_angle * -15;  //la constante multipliee est a ajuster
   pitch_angle_adjust = pitch_angle * -15;//selon l'angle maximal que l'on veut

   //PID
@@ -423,12 +422,12 @@
     motorFL = throttle + pid_pitch_out - pid_roll_out + pid_yaw_out;
     motorBL = throttle - pid_pitch_out - pid_roll_out - pid_yaw_out;
     motorBR = throttle - pid_pitch_out + pid_roll_out + pid_yaw_out;
-
+
     if (motorFR > MOTOR_MAX_LEVEL) motorFR = MOTOR_MAX_LEVEL;
     if (motorFL > MOTOR_MAX_LEVEL) motorFL = MOTOR_MAX_LEVEL; //on ne veut pas ecrire aux esc une valeur
     if (motorBL > MOTOR_MAX_LEVEL) motorBL = MOTOR_MAX_LEVEL; //plus grande que 2000
     if (motorBR > MOTOR_MAX_LEVEL) motorBR = MOTOR_MAX_LEVEL;
-
+
     if (motorFR < MOTOR_ZERO_LEVEL + 100) motorFR = MOTOR_ZERO_LEVEL + 100;
     if (motorFL < MOTOR_ZERO_LEVEL + 100) motorFL = MOTOR_ZERO_LEVEL + 100; //histoire que les moteurs tournent
     if (motorBL < MOTOR_ZERO_LEVEL + 100) motorBL = MOTOR_ZERO_LEVEL + 100; //quand meme quand on arme


small update

small update

--- proj/parallel_out_test/parallel_out_test.ino
+++ proj/parallel_out_test/parallel_out_test.ino
@@ -14,10 +14,10 @@
 // WS2811_PORTD: 25,26,27,28,14,15,29,11
 //

-const CRGBPalette16 test = {CRGB::Red, CRGB::Blue, CRGB::Orange, CRGB::Purple, CRGB::Yellow,
+const CRGBPalette16 test(CRGB::Red, CRGB::Blue, CRGB::Orange, CRGB::Purple, CRGB::Yellow,
                             CRGB::Green, CRGB::White, CRGB::Pink, CRGB::Black, CRGB::Black,
                             CRGB::Black, CRGB::Black, CRGB::Black, CRGB::Black, CRGB::Black, CRGB::Black
-                           };
+                           );

 void setup() {
   // LEDS.addLeds<WS2811_PORTA,NUM_STRIPS>(leds, NUM_LEDS_PER_STRIP);


Добавлен функционал, исправлены ошибки с кнопками

--- main.ino
+++ main.ino
@@ -36,9 +36,9 @@
 /*bits system_byte*/
 #define RED_SPEED			(1 << 0)	// Включать ли красный свет при уменьшении скорости
 #define AUTO_BACKLIGHT		(1 << 1)	// Включать подсветку экрана по датчику света или нет
-#define AUTO_HEADLIGHTS		(1 << 2)	// Включать фару по датчику света или нет
+#define AUTO_HEADLIGHT		(1 << 2)	// Включать фару по датчику света или нет
 #define AlARM_STATE			(1 << 3)	// Для того, чтобы даже после сброса сигнализация не выключилась
-#define NENON_ON_DOWNTIME	(1 << 4)	// Плавное свечение нижней подсветки в простое
+#define NEON_ON_DOWNTIME	(1 << 4)	// Плавное свечение нижней подсветки в простое

 struct sys_conf {
 	byte	password[6],		// Пароль, для отключения сигнала
@@ -51,7 +51,7 @@
 			system_byte,		// Байт взявший в себя функцию нескольких болевкских переменных
 			lux_light_on,		// При какой яркости включать фару
 			lux_backlight_on,	// При какой яркости включать подсветку экрана
-			lux_headlight;		// Яркость фары
+			bright_headlight;		// Яркость фары

 	float	distance,
 			max_speed,
@@ -89,6 +89,14 @@
 #define	BUT_DOWN			3
 #define	BUT_SIGNAL			4

+/*Для определения заряда батарей*/
+#define TYPVBG				1.1
+#define R1_P0				0
+#define R2_P0				0
+#define R1_P1				0
+#define R2_P1				0
+
+
 /*bits turn_signals*/
 #define TURN_SIGNAL_ON		(1 << 0)
 #define TURN_SIGNAL_LEFT	(1 << 1)
@@ -111,8 +119,9 @@
 #define SPEED_MODE			0
 #define ALARM_MODE			1
 #define MENU_MODE			2
-#define SLEEP_MODE			3
-#define ENGINEERING_MODE	4
+#define SETTING_MODE		3
+#define SLEEP_MODE			4
+#define ENGINEERING_MODE	5

 sys_conf		btc_config; // Конфигурация системы

@@ -152,6 +161,8 @@
 	attachInterrupt(0, alarm, CHANGE);
 	attachInterrupt(1, speed, CHANGE);

+	analogReference(DEFAULT);	// DEFAULT INTERNAL использовать Vcc как AREF
+
 	lcd.createChar(0, bat_icon);	// Загрузка иконки батареи

 	#ifdef DEBUG
@@ -165,7 +176,7 @@
 	#ifdef FIRST_LOADING
 	btc_config	= {};
 	btc_config.time_to_slpeep	= 5;
-	set_bit(btc_config.system_byte, AUTO_BACKLIGHT);
+	btc_config.bright_headlight	= 254;
 	calibration();
 	input_password();
 	WriteSysConfEEPROM(btc_config, 0);
@@ -221,7 +232,7 @@
 	Serial.println(btc_config.lux_backlight_on);

 	Serial.print("btc_config.lux_headlight: ");
-	Serial.println(btc_config.lux_headlight);
+	Serial.println(btc_config.bright_headlight);

 	Serial.print("btc_config.distance: ");
 	Serial.println(btc_config.distance);
@@ -233,9 +244,12 @@
 	Serial.println(btc_config.wheel_length);
 	#endif

-	if ((analogRead(ACTION_BUTTON) > (btc_config.button_ok_signal - 5)) && (analogRead(ACTION_BUTTON) > (btc_config.button_ok_signal - 5))) {
+	if ((analog_to_byte(analogRead(ACTION_BUTTON)) > (btc_config.button_ok_signal - 5)) && (analog_to_byte(analogRead(ACTION_BUTTON)) > (btc_config.button_ok_signal - 5))) {
+		system_mode	= ENGINEERING_MODE;
 		engineering_menu();
 	}
+
+	registerWrite(0);

 	system_mode	= SPEED_MODE;
 }
@@ -248,6 +262,9 @@
 		case ALARM_MODE:	break;

 		case MENU_MODE:		menu();
+							break;
+
+		case SETTING_MODE:	settings();
 							break;

 		case SLEEP_MODE:	break;
@@ -269,21 +286,23 @@
 	}
 }

-void(* resetFunc) (void) = 0; // Функция сброса arduino
-
 bool sys_watch() {
-	if ((bit_seted(btc_config.system_byte, AUTO_HEADLIGHTS)) && (analogRead(LIGHT_SENSOR) > btc_config.lux_light_on)) {	// Следилка за фарой
+	if ((bit_seted(btc_config.system_byte, AUTO_HEADLIGHT)) && (analog_to_byte(analogRead(LIGHT_SENSOR)) > btc_config.lux_light_on)) {	// Следилка за фарой
 		digitalWrite(HEADLIGHT, LOW);
 	} else {
-		analogWrite(HEADLIGHT, btc_config.lux_headlight);
-	}
-
-	if ((bit_seted(btc_config.system_byte, AUTO_BACKLIGHT)) && (analogRead(LIGHT_SENSOR) > btc_config.lux_backlight_on)) {	// Следилка за фарой
+		analogWrite(HEADLIGHT, btc_config.bright_headlight);
+	}
+
+	if ((bit_seted(btc_config.system_byte, AUTO_BACKLIGHT)) && (analog_to_byte(analogRead(LIGHT_SENSOR)) > btc_config.lux_backlight_on)) {	// Следилка за подсветкой экрана
 		digitalWrite(DISPLAY_LIGHT, LOW);
 	} else {
 		digitalWrite(DISPLAY_LIGHT, LOW);
 	}

+	if ((bit_seted(btc_config.system_byte, AUTO_BACKLIGHT) == false) && (digitalRead(DISPLAY_LIGHT) == LOW)) {	// Чтобы при выключенной автоподсветке включилась посветка экрана
+		digitalWrite(DISPLAY_LIGHT, HIGH);
+	}
+
 	return true;
 }

@@ -297,7 +316,7 @@

 		key_now	= analogRead(ACTION_BUTTON);

-		#ifdef DEBUG
+		#ifdef DEBUG_1
 		Serial.println("****");
 		Serial.print("Key pressed: ");
 		Serial.println(key_now);
@@ -313,7 +332,7 @@

 		key_now	= analog_to_byte(key_now);

-		#ifdef DEBUG
+		#ifdef DEBUG_1
 		Serial.println(key_now);
 		#endif

@@ -352,7 +371,7 @@
 		delay_time++;
 	}

-	#ifdef DEBUG
+	#ifdef DEBUG_1
 	Serial.println("****");
 	#endif

@@ -363,9 +382,22 @@
 	lcd.clear();
 	lcd.print("BlueSparkProject");
 	lcd.setCursor(0, 1);
+	lcd.print("Version: ");
+	lcd.print(VERSION);
+	key_pressed(true);
+
+	lcd.clear();
+	lcd.print("Build time:");
+	lcd.print(__TIME__);
+	lcd.setCursor(0, 1);
+	lcd.print("Date:");
 	lcd.print(__DATE__);
-	lcd.print(" ");
-	lcd.print(__TIME__);
+	key_pressed(true);
+
+	lcd.clear();
+	lcd.print(":DV company 2016");
+	lcd.setCursor(0, 1);
+	lcd.print("dima201246");
 	key_pressed(true);
 }

@@ -375,11 +407,12 @@
 		"Speedometr",
 		"Stopwatch",
 		"System state",
-		"Settings"
+		"Settings",
+		"Back"
 	};

-	while (system_mode == MENU_MODE) {
-		switch(display_list(menu_array, 5)) {
+	while ((system_mode == MENU_MODE) && (sys_watch())) {
+		switch(display_list(menu_array, 6)) {
 			case 0:	break;

 			case 1:	system_mode	= SPEED_MODE;
@@ -389,15 +422,18 @@

 			case 3:	break;

-			case 4:	settings();
-					break;
+			case 4:	system_mode	= SETTING_MODE;
+					break;
+
+			default:	system_mode	= SPEED_MODE;
+						break;
 		}
 	}
 }

 void settings() {
-	byte changes	= false,	// Для отслеживания изменений и последующей записи в EEPROM
-		 count = 0;
+	bool	changes	= false;	// Для отслеживания изменений и последующей записи в EEPROM
+	byte	count = 0;

 	char setting_array[][15]	= {
 		"Blue light",
@@ -408,13 +444,16 @@
 		"Back"
 	};

-	while (true) {
+	while ((system_mode	== SETTING_MODE) && (sys_watch())) {
 		switch (display_list(setting_array, 6)) {
 			case 0: if (digitalRead(LOWER_LIGHT) == HIGH) {
 						digitalWrite(LOWER_LIGHT, LOW);
 					} else {
 						digitalWrite(LOWER_LIGHT, HIGH);
 					}
+					lcd.clear();
+					lcd.print("       OK");
+					delay_w(1000);
 					break;

 			case 1:	while ((read_password() == false) && (count < 3)) {	// Счётчик количества неправильных вводов
@@ -429,26 +468,19 @@
 					}
 					break;

-			case 2: break;
-
-			case 3:	TimeElements	t_n;
-					time_t			timeVal;
-					t_n.Second	= 0;
-					t_n.Hour	= input_int_number("Input hour", 0, 23);
-					t_n.Minute	= input_int_number("Input minutes", 0, 59);
-					t_n.Day		= input_int_number("Input day", 1, 31);
-					t_n.Month	= input_int_number("Input month", 1, 12);
-					t_n.Year	= input_int_number("Input year", 15, 20) + 30;
-					timeVal		= makeTime(t_n);
-					RTC.set(timeVal);
-					setTime(timeVal);
+			case 2: if (!changes) changes	= light_settings();
+					else light_settings();
+					break;
+
+			case 3:	if (!changes) changes	= time_settings();
+					else time_settings();
 					break;

 			case 4: about();
 					break;

-			case 5: return;
-					break;
+			default:	system_mode	= MENU_MODE;
+						break;
 		}
 	}

@@ -519,11 +551,11 @@
 	}
 }

-byte input_int_number(const char *text, byte min_num, byte max_num) {	// Ввод целочисленного числа
+byte input_int_number(const char *text, byte min_num, byte max_num, byte stnd) {	// Ввод целочисленного числа
 	lcd.clear();
 	lcd.print(text);

-	byte	same_num = min_num;
+	byte	same_num = stnd;

 	while (true) {
 		lcd.setCursor(0, 1);
@@ -586,9 +618,7 @@
 	}
 }

-byte input_int_number(byte min_num, byte max_num) {	// Ввод целочисленного числа
-	byte	same_num = min_num;
-
+bool input_int_number(byte min_num, byte max_num, byte &same_num) {	// Ввод целочисленного числа
 	lcd.setCursor(0, 1);
 	lcd.print("   ");

@@ -601,6 +631,7 @@
 						} else {
 							same_num++;
 						}
+						return true;
 						break;

 		case BUT_DOWN:	if (same_num == min_num) {
@@ -608,11 +639,14 @@
 						} else {
 							same_num--;
 						}
+						return true;
 						break;

-		case BUT_OK:	return same_num;
+		case BUT_OK:	return false;
 						break;
 	}
+
+	return true;
 }

 void registerWrite(int whichPin, int whichState) {
@@ -784,7 +818,7 @@
 void calibration() {
 	byte	key_num = 0;

-	while (key_num != 3) {
+	while (key_num != 5) {
 		while (analogRead(ACTION_BUTTON) > 5);
 		lcd.clear();

@@ -829,6 +863,7 @@

 			lcd.print(btc_config.button_signal);
 			key_num++;
+			continue;
 		}

 		if (key_num == 4) {
@@ -836,19 +871,20 @@
 			lcd.setCursor(0, 1);

 			btc_config.button_ok_signal	= 0;
-
+
 			while ((analog_to_byte(analogRead(ACTION_BUTTON)) > 2) || (btc_config.button_ok_signal == 0)) {
 				btc_config.button_ok_signal	= analog_to_byte(analogRead(ACTION_BUTTON));
 			}

-
 			lcd.print(btc_config.button_ok_signal);
 			key_num++;
 		}
 	}

 	while (analogRead(ACTION_BUTTON) > 5);
-	lcd.print("Key OK!");
+
+	lcd.clear();
+	lcd.print("Calibration end!");
 	delay(2000);
 }

@@ -882,7 +918,7 @@
 		lcd.setCursor(0, 1);
 		lcd.print(analogRead(ACTION_BUTTON));
 		delay(500);
-		if ((analogRead(ACTION_BUTTON) > (btc_config.button_ok - 5)) && (analogRead(ACTION_BUTTON) < (btc_config.button_ok + 5))) break;
+		if ((analog_to_byte(analogRead(ACTION_BUTTON)) > (btc_config.button_ok - 2)) && (analog_to_byte(analogRead(ACTION_BUTTON)) < (btc_config.button_ok + 2))) break;
 	}

 	lcd.clear();
@@ -935,6 +971,266 @@
 	char en_menu[][15] = {
 		"Calibration",
 		"Self test",
-		"Continue work"
+		"Continue"
 	};
+
+	lcd.clear();
+	lcd.print("ENGINEERING MODE");
+
+	while (analogRead(ACTION_BUTTON) > 5);
+
+	while ((sys_watch()) && (system_mode == ENGINEERING_MODE)) {
+		switch (display_list(en_menu, 3)) {
+			case 0:	calibration();
+					WriteSysConfEEPROM(btc_config, 0);
+					break;
+
+			case 1:	self_test();
+					break;
+
+			default:	system_mode	= SPEED_MODE;
+						break;
+		}
+	}
+}
+
+byte bat_state(byte pin) {
+	float	vcc			= 0.0,
+			curVoltage	= 0.0;
+
+	for (byte	i	= 0; i < 5; i++) {	// Получение точного значения опорного напряжения
+		// Read 1.1V reference against AVcc
+		// set the reference to Vcc and the measurement to the internal 1.1V reference
+		#if defined(__AVR_ATmega32U4__) || defined(__AVR_ATmega1280__) || defined(__AVR_ATmega2560__)
+			ADMUX = _BV(REFS0) | _BV(MUX4) | _BV(MUX3) | _BV(MUX2) | _BV(MUX1);
+		#elif defined (__AVR_ATtiny24__) || defined(__AVR_ATtiny44__) || defined(__AVR_ATtiny84__)
+			ADMUX = _BV(MUX5) | _BV(MUX0);
+		#elif defined (__AVR_ATtiny25__) || defined(__AVR_ATtiny45__) || defined(__AVR_ATtiny85__)
+			ADMUX = _BV(MUX3) | _BV(MUX2);
+		#else	// works on an Arduino 168 or 328
+			ADMUX = _BV(REFS0) | _BV(MUX3) | _BV(MUX2) | _BV(MUX1);
+		#endif
+
+		delay(3); // Wait for Vref to settle
+		ADCSRA |= _BV(ADSC); // Start conversion
+		while (bit_is_set(ADCSRA,ADSC)); // measuring
+
+		uint8_t low  = ADCL; // must read ADCL first - it then locks ADCH
+		uint8_t high = ADCH; // unlocks both
+
+		vcc = vcc + (TYPVBG * 1023.0) / ((high<<8) | low);
+
+		sys_watch();
+		delay(5);
+	}
+
+	vcc	= vcc / 5;
+
+	for (byte	i	= 0; i < 5; i++) {
+		curVoltage = curVoltage + analogRead(pin);
+		sys_watch();
+		delay(10);
+	}
+
+	curVoltage = curVoltage / 5;
+
+	#ifdef DEBUG
+	Serial.print("Current voltage: ");
+	Serial.println(curVoltage);
+	#endif
+
+	if (pin == 0) {
+		return (byte)(((((curVoltage * vcc) / 1024.0) / (R2_P0 / (R1_P0 + R2_P0))) - 2.4) / 1.8 * 100);
+	} else {
+		return (byte)(((((curVoltage * vcc) / 1024.0) / (R2_P1 / (R1_P1 + R2_P1))) - 2.4) / 1.8 * 100);
+	}
+
+	return 0;
+}
+
+bool time_settings() {
+	char time_set_array[][15] = {
+		"Clock setting",
+		"Sleep time",
+		"Back"
+	};
+
+	bool	changes	= false;
+
+	while (sys_watch()) {
+		switch (display_list(time_set_array, 3)) {
+			case 0:	TimeElements	t_n;
+					time_t			timeVal;
+					t_n.Second	= 0;
+					t_n.Hour	= input_int_number("Input hour", 0, 23, hour());
+					t_n.Minute	= input_int_number("Input minutes", 0, 59, minute());
+					t_n.Day		= input_int_number("Input day", 1, 31, day());
+					t_n.Month	= input_int_number("Input month", 1, 12, month());
+					t_n.Year	= input_int_number("Input year", 16, 20, year()) + 30;
+					timeVal		= makeTime(t_n);
+					RTC.set(timeVal);
+					setTime(timeVal);
+					break;
+
+			case 1:	input_int_number("Input sleep time", 1, 254, btc_config.time_to_slpeep);
+					changes	= true;
+					break;
+
+			default:	if (changes) return true;
+						else return false;
+						break;
+		}
+	}
+
+	if (changes)
+		return true;
+
+	return false;
+}
+
+bool light_settings() {
+	char light_set_array[][15] {
+		"Red signal",
+		"Auto backlight",
+		"Auto headlight",
+		"Blue on sleep",
+		"Bright hdlight",
+		"Lux for screen",
+		"Lux for light",
+		"Back"
+	};
+
+	bool changes	= false;
+
+	byte value		= 0;
+
+	while (sys_watch()) {
+		switch (display_list(light_set_array, 8)) {
+			case 0:	value	= input_int_number("Red on stop", 0, 1, bit_seted(btc_config.system_byte, RED_BACK_LIGHT));
+					if (value != bit_seted(btc_config.system_byte, RED_BACK_LIGHT)) {
+						if (value) {
+							set_bit(btc_config.system_byte, RED_BACK_LIGHT);
+						} else {
+							unset_bit(btc_config.system_byte, RED_BACK_LIGHT);
+						}
+
+						changes	= true;
+					}
+					break;
+
+			case 1:	value	= input_int_number("Auto backlight", 0, 1, bit_seted(btc_config.system_byte, AUTO_BACKLIGHT));
+					if (value != bit_seted(btc_config.system_byte, AUTO_BACKLIGHT)) {
+						if (value) {
+							set_bit(btc_config.system_byte, AUTO_BACKLIGHT);
+						} else {
+							unset_bit(btc_config.system_byte, AUTO_BACKLIGHT);
+						}
+
+						changes	= true;
+					}
+					break;
+
+			case 2:	value	= input_int_number("Auto headlight", 0, 1, bit_seted(btc_config.system_byte, AUTO_HEADLIGHT));
+					if (value != bit_seted(btc_config.system_byte, AUTO_HEADLIGHT)) {
+						if (value) {
+							set_bit(btc_config.system_byte, AUTO_HEADLIGHT);
+						} else {
+							unset_bit(btc_config.system_byte, AUTO_HEADLIGHT);
+						}
+
+						changes	= true;
+					}
+					break;
+
+			case 3:	value	= input_int_number("Blue on downtime", 0, 1, bit_seted(btc_config.system_byte, NEON_ON_DOWNTIME));
+					if (value != bit_seted(btc_config.system_byte, NEON_ON_DOWNTIME)) {
+						if (value) {
+							set_bit(btc_config.system_byte, NEON_ON_DOWNTIME);
+						} else {
+							unset_bit(btc_config.system_byte, NEON_ON_DOWNTIME);
+						}
+
+						changes	= true;
+					}
+					break;
+
+			case 4:	value	= btc_config.bright_headlight;
+					lcd.clear();
+					lcd.print("Bright headlight");
+					lcd.setCursor(9, 1);
+					lcd.print("Now:");
+
+					while (sys_watch()) {
+						lcd.setCursor(13, 1);
+						lcd.print("   ");
+						lcd.setCursor(13, 1);
+						lcd.print(btc_config.bright_headlight);
+						analogWrite(HEADLIGHT, btc_config.bright_headlight);
+						if (!input_int_number(1, 254, btc_config.bright_headlight))
+							break;
+					}
+
+					digitalWrite(HEADLIGHT, LOW);
+
+					if (value != btc_config.bright_headlight) {
+						changes	= true;
+					}
+
+					break;
+
+			case 5:	value	= btc_config.lux_backlight_on;
+					lcd.clear();
+					lcd.print("Lux for screen");
+					lcd.setCursor(9, 1);
+					lcd.print("Now:");
+
+					while (sys_watch()) {
+						lcd.setCursor(13, 1);
+						lcd.print("   ");
+						lcd.setCursor(13, 1);
+						lcd.print(analog_to_byte(analogRead(LIGHT_SENSOR)));
+						if (!input_int_number(0, 254, btc_config.lux_backlight_on))
+							break;
+					}
+
+					if (value != btc_config.lux_backlight_on) {
+						changes	= true;
+					}
+
+					break;
+
+			case 6:	value	= btc_config.lux_light_on;
+					lcd.clear();
+					lcd.print("Lux for hdlight");
+					lcd.setCursor(9, 1);
+					lcd.print("Now:");
+
+					while (sys_watch()) {
+						lcd.setCursor(13, 1);
+						lcd.print("   ");
+						lcd.setCursor(13, 1);
+						lcd.print(analog_to_byte(analogRead(LIGHT_SENSOR)));
+						if (!input_int_number(0, 254, btc_config.lux_light_on))
+							break;
+					}
+
+					if (value != btc_config.lux_light_on) {
+						changes	= true;
+					}
+
+					break;
+
+			default:	if (changes) return true;
+						else return false;
+						break;
+		}
+	}
+
+	if (changes) return true;
+
+	return false;
+}
+
+void delay_w(int delay_num) {
+	for (int	delay_count	= 0; ((delay_count < delay_num) && (sys_watch())); delay_count++, delay(1));
 }


Program bottom servo to move to desired place

--- skittle-color-sorter.ino
+++ skittle-color-sorter.ino
@@ -129,20 +129,12 @@
 }

 void updateBtmServo() {
-
   // Calculate the angle of the bottom servo arm
-  static int btmAngle = 0;
-  static bool btmReversed = false;
-  btmAngle += btmReversed ? -10 : 10;
-
-  // The bottom arm angle range from 30 to 150 degrees
-  if (btmAngle >= 150)
-    btmReversed = true;
-  if (btmAngle <= 30)
-    btmReversed = false;
-
-  // Set the angle of the shaft (in degrees), ranging from 0 to 180
-  //servoBtm.write(90);
+#define MAX_BTM_ANGLE 150 // Maximum bottom servo angle
+#define MIN_BTM_ANGLE 30 // Minimum bottom servo angle
+#define NUM_OF_CUPS 5 // The number of cups at the bottom
+#define EACH_CUP_ANGLE_INTERVAL ((MAX_BTM_ANGLE - MIN_BTM_ANGLE) / NUM_OF_CUPS)
+  int btmAngle = MIN_BTM_ANGLE + EACH_CUP_ANGLE_INTERVAL * sortingResult;
   servoBtm.write(btmAngle);
 }

@@ -301,7 +293,7 @@
   updateTopServo();

   // Update the bottom servo (arm)
-  //updateBtmServo();
+  updateBtmServo();

   // Update the color sensor
   updateColorSensor();


Phone: sleep fix

Phone: sleep fix

--- examples/Phone/PhoneSleep.ino
+++ examples/Phone/PhoneSleep.ino
@@ -26,6 +26,7 @@
     display.update();
     if (display.isTouched() || isSelectPressed()) {
       display.setBacklight(256);
+      resetSleep();
       return;
     }
   }


Version 1.3 24th July 2016

Version 1.3 24th July 2016

* Adds setf, allowing you to modify lists in place. The other in-place operations push, pop, incf, and decf have also been extended in the same way.
* Fixed two bugs that affected append with null arguments, and with-spi.

--- ulisp.ino
+++ ulisp.ino
@@ -1,4 +1,4 @@
-/* uLisp Version 1.2a - www.ulisp.com
+/* uLisp Version 1.3 - www.ulisp.com
    Copyright (c) 2016 David Johnson-Davies

    Licensed under the MIT license: https://opensource.org/licenses/MIT
@@ -29,7 +29,7 @@

 #define numberp(x)         ((x)->type == NUMBER)
 #define streamp(x)         ((x)->type == STREAM)
-#define listp(x)           ((x)->type >= PAIR || (x)->type == ZERO)
+#define listp(x)           ((x) == NULL || (x)->type >= PAIR || (x)->type == ZERO)
 #define consp(x)           (((x)->type >= PAIR || (x)->type == ZERO) && (x) != NULL)

 #define mark(x)            (car(x) = (object *)(((unsigned int)(car(x))) | 0x8000))
@@ -52,15 +52,16 @@
 enum token { UNUSED, BRA, KET, QUO, DOT };
 enum stream { SERIALSTREAM, I2CSTREAM, SPISTREAM };

-enum function { SYMBOLS, NIL, TEE, LAMBDA, LET, LETSTAR, CLOSURE, SPECIAL_FORMS, QUOTE, DEFUN, DEFVAR,
-SETQ, LOOP, PUSH, POP, INCF, DECF, DOLIST, DOTIMES, FORMILLIS, WITHI2C, WITHSPI, TAIL_FORMS, PROGN, RETURN,
-IF, COND, WHEN, UNLESS, AND, OR, FUNCTIONS, NOT, NULLFN, CONS, ATOM, LISTP, CONSP, NUMBERP, STREAMP, EQ,
-CAR, FIRST, CDR, REST, CAAR, CADR, SECOND, CDAR, CDDR, CAAAR, CAADR, CADAR, CADDR, THIRD, CDAAR, CDADR,
-CDDAR, CDDDR, LENGTH, LIST, REVERSE, NTH, ASSOC, MEMBER, APPLY, FUNCALL, APPEND, MAPC, MAPCAR, ADD, SUBTRACT,
-MULTIPLY, DIVIDE, MOD, ONEPLUS, ONEMINUS, ABS, RANDOM, MAX, MIN, NUMEQ, LESS, LESSEQ, GREATER, GREATEREQ,
-NOTEQ, PLUSP, MINUSP, ZEROP, ODDP, EVENP, LOGAND, LOGIOR, LOGXOR, LOGNOT, ASH, LOGBITP, READ, EVAL, GLOBALS,
-MAKUNBOUND, BREAK, PRINT, PRINC, WRITEBYTE, READBYTE, RESTARTI2C, GC, SAVEIMAGE, LOADIMAGE, PINMODE, DIGITALREAD,
-DIGITALWRITE, ANALOGREAD, ANALOGWRITE, DELAY, MILLIS, NOTE, ENDFUNCTIONS };
+enum function { SYMBOLS, NIL, TEE, LAMBDA, LET, LETSTAR, CLOSURE, SPECIAL_FORMS, QUOTE, DEFUN, DEFVAR,
+SETQ, LOOP, PUSH, POP, INCF, DECF, SETF, DOLIST, DOTIMES, FORMILLIS, WITHI2C, WITHSPI, TAIL_FORMS, PROGN,
+RETURN, IF, COND, WHEN, UNLESS, AND, OR, FUNCTIONS, NOT, NULLFN, CONS, ATOM, LISTP, CONSP, NUMBERP,
+STREAMP, EQ, CAR, FIRST, CDR, REST, CAAR, CADR, SECOND, CDAR, CDDR, CAAAR, CAADR, CADAR, CADDR, THIRD,
+CDAAR, CDADR, CDDAR, CDDDR, LENGTH, LIST, REVERSE, NTH, ASSOC, MEMBER, APPLY, FUNCALL, APPEND, MAPC,
+MAPCAR, ADD, SUBTRACT, MULTIPLY, DIVIDE, MOD, ONEPLUS, ONEMINUS, ABS, RANDOM, MAX, MIN, NUMEQ, LESS,
+LESSEQ, GREATER, GREATEREQ, NOTEQ, PLUSP, MINUSP, ZEROP, ODDP, EVENP, LOGAND, LOGIOR, LOGXOR, LOGNOT,
+ASH, LOGBITP, READ, EVAL, GLOBALS, LOCALS, MAKUNBOUND, BREAK, PRINT, PRINC, WRITEBYTE, READBYTE,
+RESTARTI2C, GC, SAVEIMAGE, LOADIMAGE, PINMODE, DIGITALREAD, DIGITALWRITE, ANALOGREAD, ANALOGWRITE,
+DELAY, MILLIS, NOTE, ENDFUNCTIONS };

 // Typedefs

@@ -466,6 +467,36 @@
   return NULL;
 }

+// In-place operations
+
+object **place (object *args, object *env) {
+  if (!consp(args)) return &cdr(findvalue(args, env));
+  object* function = first(args);
+  if (issymbol(function, CAR) || issymbol(function, FIRST)) {
+    object *value = eval(second(args), env);
+    if (!listp(value)) error(F("Can't take car"));
+    return &car(value);
+  }
+  if (issymbol(function, CDR) || issymbol(function, REST)) {
+    object *value = eval(second(args), env);
+    if (!listp(value)) error(F("Can't take cdr"));
+    return &cdr(value);
+  }
+  if (issymbol(function, NTH)) {
+    int index = integer(eval(second(args), env));
+    object *list = eval(third(args), env);
+    if (!consp(list)) error(F("'nth' second argument is not a list"));
+    while (index > 0) {
+      list = cdr(list);
+      if (list == NULL) error(F("'nth' index out of range"));
+      index--;
+    }
+    return &car(list);
+  }
+  error(F("Illegal place"));
+  return nil;
+}
+
 // Checked car and cdr

 inline object *carx (object *arg) {
@@ -601,61 +632,66 @@

 object *sp_push (object *args, object *env) {
   object *item = eval(first(args), env);
-  object *pair = findvalue(second(args), env);
-  push(item,cdr(pair));
-  return cdr(pair);
+  object **loc = place(second(args), env);
+  push(item, *loc);
+  return *loc;
 }

 object *sp_pop (object *args, object *env) {
-  object *pair = findvalue(first(args), env);
-  object *result = car(cdr(pair));
-  pop(cdr(pair));
+  object **loc = place(first(args), env);
+  object *result = car(*loc);
+  pop(*loc);
   return result;
 }

 object *sp_incf (object *args, object *env) {
-  object *var = first(args);
-  object *pair = findvalue(var, env);
-  int result = integer(eval(var, env));
-  int temp = 1;
+  object **loc = place(first(args), env);
+  int increment = 1;
+  int result = integer(*loc);
   args = cdr(args);
-  if (args != NULL) temp = integer(eval(first(args), env));
+  if (args != NULL) increment = integer(eval(first(args), env));
   #if defined(checkoverflow)
-  if (temp < 1) { if (-32768 - temp > result) error(F("'incf' arithmetic overflow")); }
-  else { if (32767 - temp < result) error(F("'incf' arithmetic overflow")); }
+  if (increment < 1) { if (-32768 - increment > result) error(F("'incf' arithmetic overflow")); }
+  else { if (32767 - increment < result) error(F("'incf' arithmetic overflow")); }
   #endif
-  result = result + temp;
-  var = number(result);
-  cdr(pair) = var;
-  return var;
+  result = result + increment;
+  *loc = number(result);
+  return *loc;
 }

 object *sp_decf (object *args, object *env) {
-  object *var = first(args);
-  object *pair = findvalue(var, env);
-  int result = integer(eval(var, env));
-  int temp = 1;
+  object **loc = place(first(args), env);
+  int decrement = 1;
+  int result = integer(*loc);
   args = cdr(args);
-  if (args != NULL) temp = integer(eval(first(args), env));
+  if (args != NULL) decrement = integer(eval(first(args), env));
   #if defined(checkoverflow)
-  if (temp < 1) { if (32767 + temp < result) error(F("'decf' arithmetic overflow")); }
-  else { if (-32768 + temp > result) error(F("'decf' arithmetic overflow")); }
+  if (decrement < 1) { if (32767 + decrement < result) error(F("'decf' arithmetic overflow")); }
+  else { if (-32768 + decrement > result) error(F("'decf' arithmetic overflow")); }
   #endif
-  result = result - temp;
-  var = number(result);
-  cdr(pair) = var;
-  return var;
+  result = result - decrement;
+  *loc = number(result);
+  return *loc;
+}
+
+object *sp_setf (object *args, object *env) {
+  object **loc = place(first(args), env);
+  object *result = eval(second(args), env);
+  *loc = result;
+  return result;
 }

 object *sp_dolist (object *args, object *env) {
   object *params = first(args);
   object *var = first(params);
+  object *result = nil;
   object *list = eval(second(params), env);
   if (!listp(list)) error(F("'dolist' argument is not a list"));
   push(list, GCStack); // Don't GC the list
   object *pair = cons(var,nil);
   push(pair,env);
-  object *result = third(params);
+  params = cdr(cdr(params));
+  if (params != NULL) result = car(params);
   object *forms = cdr(args);
   while (list != NULL) {
     cdr(pair) = first(list);
@@ -670,9 +706,11 @@
 object *sp_dotimes (object *args, object *env) {
   object *params = first(args);
   object *var = first(params);
+  object *result = nil;
   int count = integer(eval(second(params), env));
   int index = 0;
-  object *result = third(params);
+  params = cdr(cdr(params));
+  if (params != NULL) result = car(params);
   object *pair = cons(var,number(0));
   push(pair,env);
   object *forms = cdr(args);
@@ -721,6 +759,7 @@
   object *params = first(args);
   object *var = first(params);
   int pin = integer(eval(second(params), env));
+  int divider = 0, mode = 0, bitorder = 1;
   object *pair = cons(var, stream(SPISTREAM, pin));
   push(pair,env);
   SPI.begin();
@@ -728,18 +767,21 @@
   if (params != NULL) {
     int d = integer(eval(first(params), env));
     if (d<1 || d>7) error(F("'with-spi' invalid divider"));
-    if (d == 7) SPI.setClockDivider(3);
-    else if (d & 1) SPI.setClockDivider((d>>1) + 4);
-    else SPI.setClockDivider((d>>1) - 1);
+    if (d == 7) divider = 3;
+    else if (d & 1) divider = (d>>1) + 4;
+    else divider = (d>>1) - 1;
     params = cdr(params);
     if (params != NULL) {
-      SPI.setBitOrder(eval(first(params), env) == NULL);
+      bitorder = (eval(first(params), env) == NULL);
       params = cdr(params);
-      if (params != NULL) SPI.setDataMode(integer(eval(first(params), env)));
+      if (params != NULL) mode = integer(eval(first(params), env));
     }
   }
   pinMode(pin, OUTPUT);
   digitalWrite(pin, LOW);
+  SPI.setBitOrder(bitorder);
+  SPI.setClockDivider(divider);
+  SPI.setDataMode(mode);
   object *forms = cdr(args);
   object *result = eval(tf_progn(forms,env), env);
   digitalWrite(pin, HIGH);
@@ -1432,6 +1474,11 @@
     list = cdr(list);
   }
   return nil;
+}
+
+object *fn_locals (object *args, object *env) {
+  (void) args;
+  return env;
 }

 object *fn_makunbound (object *args, object *env) {
@@ -1684,6 +1731,7 @@

 // Insert your own function definitions here

+
 // Built-in procedure names - stored in PROGMEM

 const char string0[] PROGMEM = "symbols";
@@ -1703,108 +1751,110 @@
 const char string14[] PROGMEM = "pop";
 const char string15[] PROGMEM = "incf";
 const char string16[] PROGMEM = "decf";
-const char string17[] PROGMEM = "dolist";
-const char string18[] PROGMEM = "dotimes";
-const char string19[] PROGMEM = "for-millis";
-const char string20[] PROGMEM = "with-i2c";
-const char string21[] PROGMEM = "with-spi";
-const char string22[] PROGMEM = "tail_forms";
-const char string23[] PROGMEM = "progn";
-const char string24[] PROGMEM = "return";
-const char string25[] PROGMEM = "if";
-const char string26[] PROGMEM = "cond";
-const char string27[] PROGMEM = "when";
-const char string28[] PROGMEM = "unless";
-const char string29[] PROGMEM = "and";
-const char string30[] PROGMEM = "or";
-const char string31[] PROGMEM = "functions";
-const char string32[] PROGMEM = "not";
-const char string33[] PROGMEM = "null";
-const char string34[] PROGMEM = "cons";
-const char string35[] PROGMEM = "atom";
-const char string36[] PROGMEM = "listp";
-const char string37[] PROGMEM = "consp";
-const char string38[] PROGMEM = "numberp";
-const char string39[] PROGMEM = "streamp";
-const char string40[] PROGMEM = "eq";
-const char string41[] PROGMEM = "car";
-const char string42[] PROGMEM = "first";
-const char string43[] PROGMEM = "cdr";
-const char string44[] PROGMEM = "rest";
-const char string45[] PROGMEM = "caar";
-const char string46[] PROGMEM = "cadr";
-const char string47[] PROGMEM = "second";
-const char string48[] PROGMEM = "cdar";
-const char string49[] PROGMEM = "cddr";
-const char string50[] PROGMEM = "caaar";
-const char string51[] PROGMEM = "caadr";
-const char string52[] PROGMEM = "cadar";
-const char string53[] PROGMEM = "caddr";
-const char string54[] PROGMEM = "third";
-const char string55[] PROGMEM = "cdaar";
-const char string56[] PROGMEM = "cdadr";
-const char string57[] PROGMEM = "cddar";
-const char string58[] PROGMEM = "cdddr";
-const char string59[] PROGMEM = "length";
-const char string60[] PROGMEM = "list";
-const char string61[] PROGMEM = "reverse";
-const char string62[] PROGMEM = "nth";
-const char string63[] PROGMEM = "assoc";
-const char string64[] PROGMEM = "member";
-const char string65[] PROGMEM = "apply";
-const char string66[] PROGMEM = "funcall";
-const char string67[] PROGMEM = "append";
-const char string68[] PROGMEM = "mapc";
-const char string69[] PROGMEM = "mapcar";
-const char string70[] PROGMEM = "+";
-const char string71[] PROGMEM = "-";
-const char string72[] PROGMEM = "*";
-const char string73[] PROGMEM = "/";
-const char string74[] PROGMEM = "mod";
-const char string75[] PROGMEM = "1+";
-const char string76[] PROGMEM = "1-";
-const char string77[] PROGMEM = "abs";
-const char string78[] PROGMEM = "random";
-const char string79[] PROGMEM = "max";
-const char string80[] PROGMEM = "min";
-const char string81[] PROGMEM = "=";
-const char string82[] PROGMEM = "<";
-const char string83[] PROGMEM = "<=";
-const char string84[] PROGMEM = ">";
-const char string85[] PROGMEM = ">=";
-const char string86[] PROGMEM = "/=";
-const char string87[] PROGMEM = "plusp";
-const char string88[] PROGMEM = "minusp";
-const char string89[] PROGMEM = "zerop";
-const char string90[] PROGMEM = "oddp";
-const char string91[] PROGMEM = "evenp";
-const char string92[] PROGMEM = "logand";
-const char string93[] PROGMEM = "logior";
-const char string94[] PROGMEM = "logxor";
-const char string95[] PROGMEM = "lognot";
-const char string96[] PROGMEM = "ash";
-const char string97[] PROGMEM = "logbitp";
-const char string98[] PROGMEM = "read";
-const char string99[] PROGMEM = "eval";
-const char string100[] PROGMEM = "globals";
-const char string101[] PROGMEM = "makunbound";
-const char string102[] PROGMEM = "break";
-const char string103[] PROGMEM = "print";
-const char string104[] PROGMEM = "princ";
-const char string105[] PROGMEM = "write-byte";
-const char string106[] PROGMEM = "read-byte";
-const char string107[] PROGMEM = "restart-i2c";
-const char string108[] PROGMEM = "gc";
-const char string109[] PROGMEM = "save-image";
-const char string110[] PROGMEM = "load-image";
-const char string111[] PROGMEM = "pinmode";
-const char string112[] PROGMEM = "digitalread";
-const char string113[] PROGMEM = "digitalwrite";
-const char string114[] PROGMEM = "analogread";
-const char string115[] PROGMEM = "analogwrite";
-const char string116[] PROGMEM = "delay";
-const char string117[] PROGMEM = "millis";
-const char string118[] PROGMEM = "note";
+const char string17[] PROGMEM = "setf";
+const char string18[] PROGMEM = "dolist";
+const char string19[] PROGMEM = "dotimes";
+const char string20[] PROGMEM = "for-millis";
+const char string21[] PROGMEM = "with-i2c";
+const char string22[] PROGMEM = "with-spi";
+const char string23[] PROGMEM = "tail_forms";
+const char string24[] PROGMEM = "progn";
+const char string25[] PROGMEM = "return";
+const char string26[] PROGMEM = "if";
+const char string27[] PROGMEM = "cond";
+const char string28[] PROGMEM = "when";
+const char string29[] PROGMEM = "unless";
+const char string30[] PROGMEM = "and";
+const char string31[] PROGMEM = "or";
+const char string32[] PROGMEM = "functions";
+const char string33[] PROGMEM = "not";
+const char string34[] PROGMEM = "null";
+const char string35[] PROGMEM = "cons";
+const char string36[] PROGMEM = "atom";
+const char string37[] PROGMEM = "listp";
+const char string38[] PROGMEM = "consp";
+const char string39[] PROGMEM = "numberp";
+const char string40[] PROGMEM = "streamp";
+const char string41[] PROGMEM = "eq";
+const char string42[] PROGMEM = "car";
+const char string43[] PROGMEM = "first";
+const char string44[] PROGMEM = "cdr";
+const char string45[] PROGMEM = "rest";
+const char string46[] PROGMEM = "caar";
+const char string47[] PROGMEM = "cadr";
+const char string48[] PROGMEM = "second";
+const char string49[] PROGMEM = "cdar";
+const char string50[] PROGMEM = "cddr";
+const char string51[] PROGMEM = "caaar";
+const char string52[] PROGMEM = "caadr";
+const char string53[] PROGMEM = "cadar";
+const char string54[] PROGMEM = "caddr";
+const char string55[] PROGMEM = "third";
+const char string56[] PROGMEM = "cdaar";
+const char string57[] PROGMEM = "cdadr";
+const char string58[] PROGMEM = "cddar";
+const char string59[] PROGMEM = "cdddr";
+const char string60[] PROGMEM = "length";
+const char string61[] PROGMEM = "list";
+const char string62[] PROGMEM = "reverse";
+const char string63[] PROGMEM = "nth";
+const char string64[] PROGMEM = "assoc";
+const char string65[] PROGMEM = "member";
+const char string66[] PROGMEM = "apply";
+const char string67[] PROGMEM = "funcall";
+const char string68[] PROGMEM = "append";
+const char string69[] PROGMEM = "mapc";
+const char string70[] PROGMEM = "mapcar";
+const char string71[] PROGMEM = "+";
+const char string72[] PROGMEM = "-";
+const char string73[] PROGMEM = "*";
+const char string74[] PROGMEM = "/";
+const char string75[] PROGMEM = "mod";
+const char string76[] PROGMEM = "1+";
+const char string77[] PROGMEM = "1-";
+const char string78[] PROGMEM = "abs";
+const char string79[] PROGMEM = "random";
+const char string80[] PROGMEM = "max";
+const char string81[] PROGMEM = "min";
+const char string82[] PROGMEM = "=";
+const char string83[] PROGMEM = "<";
+const char string84[] PROGMEM = "<=";
+const char string85[] PROGMEM = ">";
+const char string86[] PROGMEM = ">=";
+const char string87[] PROGMEM = "/=";
+const char string88[] PROGMEM = "plusp";
+const char string89[] PROGMEM = "minusp";
+const char string90[] PROGMEM = "zerop";
+const char string91[] PROGMEM = "oddp";
+const char string92[] PROGMEM = "evenp";
+const char string93[] PROGMEM = "logand";
+const char string94[] PROGMEM = "logior";
+const char string95[] PROGMEM = "logxor";
+const char string96[] PROGMEM = "lognot";
+const char string97[] PROGMEM = "ash";
+const char string98[] PROGMEM = "logbitp";
+const char string99[] PROGMEM = "read";
+const char string100[] PROGMEM = "eval";
+const char string101[] PROGMEM = "globals";
+const char string102[] PROGMEM = "locals";
+const char string103[] PROGMEM = "makunbound";
+const char string104[] PROGMEM = "break";
+const char string105[] PROGMEM = "print";
+const char string106[] PROGMEM = "princ";
+const char string107[] PROGMEM = "write-byte";
+const char string108[] PROGMEM = "read-byte";
+const char string109[] PROGMEM = "restart-i2c";
+const char string110[] PROGMEM = "gc";
+const char string111[] PROGMEM = "save-image";
+const char string112[] PROGMEM = "load-image";
+const char string113[] PROGMEM = "pinmode";
+const char string114[] PROGMEM = "digitalread";
+const char string115[] PROGMEM = "digitalwrite";
+const char string116[] PROGMEM = "analogread";
+const char string117[] PROGMEM = "analogwrite";
+const char string118[] PROGMEM = "delay";
+const char string119[] PROGMEM = "millis";
+const char string120[] PROGMEM = "note";

 const tbl_entry_t lookup_table[] PROGMEM = {
   { string0, NULL, NIL, NIL },
@@ -1824,108 +1874,110 @@
   { string14, sp_pop, 1, 1 },
   { string15, sp_incf, 1, 2 },
   { string16, sp_decf, 1, 2 },
-  { string17, sp_dolist, 1, 127 },
-  { string18, sp_dotimes, 1, 127 },
-  { string19, sp_formillis, 1, 127 },
-  { string20, sp_withi2c, 1, 127 },
-  { string21, sp_withspi, 1, 127 },
-  { string22, NULL, NIL, NIL },
-  { string23, tf_progn, 0, 127 },
-  { string24, tf_return, 0, 127 },
-  { string25, tf_if, 2, 3 },
-  { string26, tf_cond, 0, 127 },
-  { string27, tf_when, 1, 127 },
-  { string28, tf_unless, 1, 127 },
-  { string29, tf_and, 0, 127 },
-  { string30, tf_or, 0, 127 },
-  { string31, NULL, NIL, NIL },
-  { string32, fn_not, 1, 1 },
+  { string17, sp_setf, 2, 2 },
+  { string18, sp_dolist, 1, 127 },
+  { string19, sp_dotimes, 1, 127 },
+  { string20, sp_formillis, 1, 127 },
+  { string21, sp_withi2c, 1, 127 },
+  { string22, sp_withspi, 1, 127 },
+  { string23, NULL, NIL, NIL },
+  { string24, tf_progn, 0, 127 },
+  { string25, tf_return, 0, 127 },
+  { string26, tf_if, 2, 3 },
+  { string27, tf_cond, 0, 127 },
+  { string28, tf_when, 1, 127 },
+  { string29, tf_unless, 1, 127 },
+  { string30, tf_and, 0, 127 },
+  { string31, tf_or, 0, 127 },
+  { string32, NULL, NIL, NIL },
   { string33, fn_not, 1, 1 },
-  { string34, fn_cons, 2, 2 },
-  { string35, fn_atom, 1, 1 },
-  { string36, fn_listp, 1, 1 },
-  { string37, fn_consp, 1, 1 },
-  { string38, fn_numberp, 1, 1 },
-  { string39, fn_streamp, 1, 1 },
-  { string40, fn_eq, 2, 2 },
-  { string41, fn_car, 1, 1 },
+  { string34, fn_not, 1, 1 },
+  { string35, fn_cons, 2, 2 },
+  { string36, fn_atom, 1, 1 },
+  { string37, fn_listp, 1, 1 },
+  { string38, fn_consp, 1, 1 },
+  { string39, fn_numberp, 1, 1 },
+  { string40, fn_streamp, 1, 1 },
+  { string41, fn_eq, 2, 2 },
   { string42, fn_car, 1, 1 },
-  { string43, fn_cdr, 1, 1 },
+  { string43, fn_car, 1, 1 },
   { string44, fn_cdr, 1, 1 },
-  { string45, fn_caar, 1, 1 },
-  { string46, fn_cadr, 1, 1 },
+  { string45, fn_cdr, 1, 1 },
+  { string46, fn_caar, 1, 1 },
   { string47, fn_cadr, 1, 1 },
-  { string48, fn_cdar, 1, 1 },
-  { string49, fn_cddr, 1, 1 },
-  { string50, fn_caaar, 1, 1 },
-  { string51, fn_caadr, 1, 1 },
-  { string52, fn_cadar, 1, 1 },
-  { string53, fn_caddr, 1, 1 },
+  { string48, fn_cadr, 1, 1 },
+  { string49, fn_cdar, 1, 1 },
+  { string50, fn_cddr, 1, 1 },
+  { string51, fn_caaar, 1, 1 },
+  { string52, fn_caadr, 1, 1 },
+  { string53, fn_cadar, 1, 1 },
   { string54, fn_caddr, 1, 1 },
-  { string55, fn_cdaar, 1, 1 },
-  { string56, fn_cdadr, 1, 1 },
-  { string57, fn_cddar, 1, 1 },
-  { string58, fn_cdddr, 1, 1 },
-  { string59, fn_length, 1, 1 },
-  { string60, fn_list, 0, 127 },
-  { string61, fn_reverse, 1, 1 },
-  { string62, fn_nth, 2, 2 },
-  { string63, fn_assoc, 2, 2 },
-  { string64, fn_member, 2, 2 },
-  { string65, fn_apply, 2, 127 },
-  { string66, fn_funcall, 1, 127 },
-  { string67, fn_append, 0, 127 },
-  { string68, fn_mapc, 2, 3 },
-  { string69, fn_mapcar, 2, 3 },
-  { string70, fn_add, 0, 127 },
-  { string71, fn_subtract, 1, 127 },
-  { string72, fn_multiply, 0, 127 },
-  { string73, fn_divide, 2, 127 },
-  { string74, fn_mod, 2, 2 },
-  { string75, fn_oneplus, 1, 1 },
-  { string76, fn_oneminus, 1, 1 },
-  { string77, fn_abs, 1, 1 },
-  { string78, fn_random, 1, 1 },
-  { string79, fn_max, 1, 127 },
-  { string80, fn_min, 1, 127 },
-  { string81, fn_numeq, 1, 127 },
-  { string82, fn_less, 1, 127 },
-  { string83, fn_lesseq, 1, 127 },
-  { string84, fn_greater, 1, 127 },
-  { string85, fn_greatereq, 1, 127 },
-  { string86, fn_noteq, 1, 127 },
-  { string87, fn_plusp, 1, 1 },
-  { string88, fn_minusp, 1, 1 },
-  { string89, fn_zerop, 1, 1 },
-  { string90, fn_oddp, 1, 1 },
-  { string91, fn_evenp, 1, 1 },
-  { string92, fn_logand, 0, 127 },
-  { string93, fn_logior, 0, 127 },
-  { string94, fn_logxor, 0, 127 },
-  { string95, fn_lognot, 1, 1 },
-  { string96, fn_ash, 2, 2 },
-  { string97, fn_logbitp, 2, 2 },
-  { string98, fn_read, 0, 0 },
-  { string99, fn_eval, 1, 1 },
-  { string100, fn_globals, 0, 0 },
-  { string101, fn_makunbound, 1, 1 },
-  { string102, fn_break, 0, 0 },
-  { string103, fn_print, 1, 1 },
-  { string104, fn_princ, 1, 1 },
-  { string105, fn_writebyte, 1, 2 },
-  { string106, fn_readbyte, 0, 2 },
-  { string107, fn_restarti2c, 1, 2 },
-  { string108, fn_gc, 0, 0 },
-  { string109, fn_saveimage, 0, 1 },
-  { string110, fn_loadimage, 0, 0 },
-  { string111, fn_pinmode, 2, 2 },
-  { string112, fn_digitalread, 1, 1 },
-  { string113, fn_digitalwrite, 2, 2 },
-  { string114, fn_analogread, 1, 1 },
-  { string115, fn_analogwrite, 2, 2 },
-  { string116, fn_delay, 1, 1 },
-  { string117, fn_millis, 0, 0 },
-  { string118, fn_note, 0, 3 },
+  { string55, fn_caddr, 1, 1 },
+  { string56, fn_cdaar, 1, 1 },
+  { string57, fn_cdadr, 1, 1 },
+  { string58, fn_cddar, 1, 1 },
+  { string59, fn_cdddr, 1, 1 },
+  { string60, fn_length, 1, 1 },
+  { string61, fn_list, 0, 127 },
+  { string62, fn_reverse, 1, 1 },
+  { string63, fn_nth, 2, 2 },
+  { string64, fn_assoc, 2, 2 },
+  { string65, fn_member, 2, 2 },
+  { string66, fn_apply, 2, 127 },
+  { string67, fn_funcall, 1, 127 },
+  { string68, fn_append, 0, 127 },
+  { string69, fn_mapc, 2, 3 },
+  { string70, fn_mapcar, 2, 3 },
+  { string71, fn_add, 0, 127 },
+  { string72, fn_subtract, 1, 127 },
+  { string73, fn_multiply, 0, 127 },
+  { string74, fn_divide, 2, 127 },
+  { string75, fn_mod, 2, 2 },
+  { string76, fn_oneplus, 1, 1 },
+  { string77, fn_oneminus, 1, 1 },
+  { string78, fn_abs, 1, 1 },
+  { string79, fn_random, 1, 1 },
+  { string80, fn_max, 1, 127 },
+  { string81, fn_min, 1, 127 },
+  { string82, fn_numeq, 1, 127 },
+  { string83, fn_less, 1, 127 },
+  { string84, fn_lesseq, 1, 127 },
+  { string85, fn_greater, 1, 127 },
+  { string86, fn_greatereq, 1, 127 },
+  { string87, fn_noteq, 1, 127 },
+  { string88, fn_plusp, 1, 1 },
+  { string89, fn_minusp, 1, 1 },
+  { string90, fn_zerop, 1, 1 },
+  { string91, fn_oddp, 1, 1 },
+  { string92, fn_evenp, 1, 1 },
+  { string93, fn_logand, 0, 127 },
+  { string94, fn_logior, 0, 127 },
+  { string95, fn_logxor, 0, 127 },
+  { string96, fn_lognot, 1, 1 },
+  { string97, fn_ash, 2, 2 },
+  { string98, fn_logbitp, 2, 2 },
+  { string99, fn_read, 0, 0 },
+  { string100, fn_eval, 1, 1 },
+  { string101, fn_globals, 0, 0 },
+  { string102, fn_locals, 0, 0 },
+  { string103, fn_makunbound, 1, 1 },
+  { string104, fn_break, 0, 0 },
+  { string105, fn_print, 1, 1 },
+  { string106, fn_princ, 1, 1 },
+  { string107, fn_writebyte, 1, 2 },
+  { string108, fn_readbyte, 0, 2 },
+  { string109, fn_restarti2c, 1, 2 },
+  { string110, fn_gc, 0, 0 },
+  { string111, fn_saveimage, 0, 1 },
+  { string112, fn_loadimage, 0, 0 },
+  { string113, fn_pinmode, 2, 2 },
+  { string114, fn_digitalread, 1, 1 },
+  { string115, fn_digitalwrite, 2, 2 },
+  { string116, fn_analogread, 1, 1 },
+  { string117, fn_analogwrite, 2, 2 },
+  { string118, fn_delay, 1, 1 },
+  { string119, fn_millis, 0, 0 },
+  { string120, fn_note, 0, 3 },
 };

 // Table lookup functions
@@ -1963,8 +2015,8 @@
   int TC=0;
   EVAL:
   // Enough space?
-  if (freespace < 10) gc(form, env);
-  if (_end != 0xA5) error(F("Error: Stack overflow"));
+  if (freespace < 20) gc(form, env);
+  if (_end != 0xA5) error(F("Stack overflow"));
   // Break
   if (Serial.read() == '~') error(F("Break!"));

@@ -2235,7 +2287,7 @@
   initworkspace();
   initenv();
   _end = 0xA5;
-  Serial.println(F("uLisp 1.2a"));
+  Serial.println(F("uLisp 1.3"));
 }

 // Read/Evaluate/Print loop
@@ -2251,8 +2303,9 @@
     }
     Serial.print(F("> "));
     object *line = read();
-    if (line == nil) { Serial.println(); return; }
+    if (BreakLevel && line == nil) { Serial.println(); return; }
     Serial.println();
+    if (line == (object *)KET) error(F("Unmatched right bracket"));
     push(line, GCStack);
     printobject(eval(line,env));
     pop(GCStack);


Updated RM6 with new PID api

Updated RM6 with new PID api

--- examples/RoboMagellan6x6/RoboMagellan6x6.ino
+++ examples/RoboMagellan6x6/RoboMagellan6x6.ino
@@ -38,7 +38,8 @@
 HLA 			pitch( 100, 0);
 HLA 			roll ( 100, 0);
 Servo			servo[3]; //drive, steer, backSteer
-PIDcontroller   cruise;
+PIDparameters   cruisePID(0,0,0,-90,90);
+PIDcontroller   cruise(&cruisePID);
 		//scheduler, navigation, obstacle, stop times
 uint32_t uTime = 0, nTime = 0, oTime = 0, sTime = 0;
 uint32_t gpsHalfTime = 0, gpsTime = 0;
@@ -75,10 +76,9 @@
 void dangerTimeCallback(float in){ dangerTime = coastTime+in; }
 void newPIDparam(float x){
 	using namespace groundSettings;
-	PIDparameters newPID = PIDparameters(settings.get(CRUISE_P),
-										 settings.get(CRUISE_I),
-										 settings.get(CRUISE_D) );
-	cruise.tune(newPID);
+	cruisePID = PIDparameters(settings.get(CRUISE_P),
+                              settings.get(CRUISE_I),
+                              settings.get(CRUISE_D) );
 }

 void setupSettings(){


v19.8 Clean up

v19.8 Clean up

--- GPSLCD.ino
+++ GPSLCD.ino
@@ -285,12 +285,11 @@
       // Compute fraction.  UTC is the best I can do. "sun_rise_set" dose not return minutes and seconds.
       double riseF = rise - (double)riseI;
       double setF = set - (double)setI;
-      // Put it into a String type for printing on the LCD to remove the leading 0.
-      String riseS(abs(riseF));
-      String setS(abs(setF));
-      riseS = riseS.substring(1, 6);
-      setS = setS.substring(1, 6);
-
+      String riseFS(abs(riseF));
+      String setFS(abs(setF));
+      riseFS = riseFS.substring(1, 6);
+      setFS = setFS.substring(1, 6);
+
       // Convert UTC "sunrise" time to local "sunset" time
       (void) convertToLocal(&riseI, &year, &month,
                             &day, GPSData.lon, false); // false means no date and DST conversion
@@ -327,13 +326,13 @@
       lcd.print("Sunrise: ");
       if (riseI > 12)  riseI -= 12;
       lcd.print(riseI);
-      lcd.print(riseS);
+      lcd.print(riseFS);
       lcd.print("am");
       lcd.setCursor(0, 2);
       lcd.print("Sunset:  ");
       if (setI > 12) setI -= 12;
       lcd.print(setI);
-      lcd.print(setS);
+      lcd.print(setFS);
       lcd.print("pm");
       lcd.setCursor(0, 3);
       lcd.print("Day len: ");


Got the powerOn() method working. Working on powerOff().

--- Helios.ino
+++ Helios.ino
@@ -23,11 +23,13 @@
   if (F_CPU == 16000000) clock_prescale_set(clock_div_1);
 #endif
   // End of trinket special code
-
+  Serial.begin(9600);
   strip.begin();
   strip.show(); // Initialize all pixels to 'off'
   //powerOn(strip.Color(255, 150, 110), 750);
-  //powerOn(245,0,245, 500, 25);
+  powerOn(0,100,0, 50);
+  delay(1000);
+  powerOff();
 }

 void loop() {
@@ -41,8 +43,8 @@
  // theaterChase(strip.Color(  0,   0, 127), 50); // Blue
  // 255 152 96

- powerOn(245,0,245, 500, 25);
- delay(10);
+ //powerOn(0,100,0, 100);
+ //delay(10);
  /*
  powerOn(strip.Color(255, 0, 0), 100);
  powerOn(strip.Color(0, 255, 0), 100);
@@ -55,19 +57,55 @@
  // theaterChaseRainbow(50);
 }

-void powerOn(uint16_t r, uint16_t g, uint16_t b, uint16_t wait, uint16_t fadeTime) {
+uint8_t splitColor ( uint32_t c, char value )
+{
+  switch ( value ) {
+    case 'r': return (uint8_t)(c >> 16);
+    case 'g': return (uint8_t)(c >>  8);
+    case 'b': return (uint8_t)(c >>  0);
+    default:  return 0;
+  }
+}
+
+void powerOn(int r, int g, int b, int wait) {
  // uint8_t a = 0;
-  for(uint8_t a = 0; a < strip.numPixels()/2; a++) {
-    strip.setPixelColor(a, strip.Color(r,g,b));
-    strip.setPixelColor(((strip.numPixels() - 1) - a), strip.Color(r,g,b));
-    strip.show();
+  for(int a = 0; a < strip.numPixels()/2; a++) {
+    for(int i = 1; i <= 100; i++) {
+      double percentage = (double)i/100;
+      int red = percentage * r;
+      int green = percentage * g;
+      int blue = percentage * b;
+    //  Serial.println(red);
+    //  Serial.println(green);
+    //  Serial.println(blue);
+      Serial.println(percentage);
+      strip.setPixelColor(a, strip.Color(red,green,blue));
+      strip.setPixelColor(((strip.numPixels() - 1) - a), strip.Color(red,green,blue));
+      strip.show();
+      delay(5);
+    }
     delay(wait);
   }
-  for(uint8_t a = strip.numPixels()/2 - 1; a >= 0; a--) {
-    strip.setPixelColor(a, strip.Color(0,0,0));
-    strip.setPixelColor(((strip.numPixels() - 1) - a), strip.Color(0,0,0));
-    strip.show();
-    delay(wait);
+}
+
+void powerOff() {
+  for(int a = 0; a < strip.numPixels(); a++) {
+    for(double k = 100; k >= 0; k--) {
+      double percentage = k/100.0;
+      uint32_t colorVal = strip.getPixelColor(a);
+      Serial.println(colorVal);
+      double r = splitColor(colorVal, 'r');
+      double g = splitColor(colorVal, 'g');
+      double b = splitColor(colorVal, 'b');
+      r = (double)r * percentage;
+      g = (double)g * percentage;
+      b = (double)b * percentage;
+     // Serial.println(r);
+      strip.setPixelColor(a, strip.Color((int)r,(int)g,(int)b));
+      delay(3);
+      strip.show();
+    }
+    delay(10);
   }
 }

@@ -94,7 +132,7 @@
 }
 */

-/*
+
 // Slightly different, this makes the rainbow equally distributed throughout
 void rainbowCycle(uint8_t wait) {
   uint16_t i, j;
@@ -107,7 +145,6 @@
     delay(wait);
   }
 }
-*/

 /*
 //Theatre-style crawling lights.


fixed trailing comma and coefficients names

--- src/analog_sensors_board.ino
+++ src/analog_sensors_board.ino
@@ -70,8 +70,8 @@
 //  [8]: http://forum.arduino.cc/index.php?topic=128717.0
 //  [9]: http://www.nongnu.org/avr-libc/user-manual/group__avr__watchdog.html

-const int ACS_ZERO = (int) 2500 / ADC_INTERNAL_MV;	// ADC reading for 2.5V (~ 1007)
-const float ACS_CONV = ADC_INTERNAL_MV / ACS714_MVA	// Amps per ADC level
+const int ACS_ZERO = (int) 2500 / ADC_INTERNAL_MV;		// ADC reading for 2.5V (~ 1007)
+const float ACS714_CONV = ADC_INTERNAL_MV / ACS714_MVA;	// Amps per ADC level
 const float BAT_RK = (BAT_R1 + BAT_R2) / BAT_R2;

 unsigned long time_iq;


Further rewriting

Further rewriting

--- all/all.ino
+++ all/all.ino
@@ -23,7 +23,7 @@
 #define SINGLE_COLOR_SPARKLES 3
 #define DISCO_BARBER_1 4
 #define DISCO_BARBER_2 5
-#define JUGGLE 6
+#define WORMS 6
 #define NEW 7

 int maxPatternId = 6;
@@ -48,7 +48,7 @@
 }

 int numberOfSparkles = 1;
-int increasing = true;
+bool increasing = true;

 int upAndDownBy(int value, int difference) {
   if (value < 80 && increasing) {
@@ -95,50 +95,41 @@
   }
 }

-uint8_t    numdots = 3;    // Number of dots in use.
-uint8_t   faderate = 64;  // How long should the trails be. Very low value = longer trails.
-uint8_t     hueinc = 1;   // Incremental change in hue between each dot.
-uint8_t     curhue = 0;    // The current hue
-uint8_t   basebeat = 2;   // Higher = faster movement.
+uint8_t numberOfWorms = 3;
+uint8_t wormsFadeRate = 64; // Very low value = longer trails.
+uint8_t wormsHueIncrement = 1; // Incremental change in hue between each dot.
+uint8_t wormsStartingHue = 0; // The current hue
+uint8_t wormsBaseBeat = 2; // Higher = faster movement.

-void juggle() {
-  hueinc = 1;
-  faderate = 64;
-  if (faderate == 100 || faderate == 200) {
-    numdots += 1;
-  }
-
-  fadeToBlackBy(leds, NUM_LEDS, faderate);
-
-  for ( int i = 0; i < numdots; i++) {
+void worms() {
+  fadeToBlackBy(leds, NUM_LEDS, wormsFadeRate);
+  for ( int i = 0; i < numberOfWorms; i++) {
     for ( int j = 0; j < 20; j++) {
-      leds[beatsin16(basebeat + i + numdots, 0, NUM_LEDS - 20) + j] += CHSV(curhue, 240, 255); //beat16 is a FastLED 3.1 function
+      leds[beatsin16(wormsBaseBeat + i + numberOfWorms, 0, NUM_LEDS - 20) + j] += CHSV(wormsStartingHue, 240, 255);
     }
-    // leds[beatsin16(basebeat + i + numdots, 0, NUM_LEDS)] += CHSV(curhue, 240, 255); //beat16 is a FastLED 3.1 function
-    curhue += hueinc;
+    wormsStartingHue += wormsHueIncrement;
   }
 }

-uint8_t allfreq = 3;
-int     thisphase = 0;
-uint8_t thiscutoff = 120;
-uint8_t thisrot = 1;
-int8_t  thisspeed = 48;
-uint8_t allsat = 240;
+uint8_t discoBarberFrequency = 3;
+int     discoBarberPhase = 0;
+uint8_t discoBarberCutoff = 120;
+uint8_t discoBarberSaturation = 240;

 void discoBarber() {
   if (patternId == DISCO_BARBER_1) {
-    allfreq = 5;
-    thisphase += 24;
+    discoBarberFrequency = 5;
+    discoBarberPhase += 24;
   } else {
-    allfreq = 3;
-    thisphase += 48;
+    discoBarberFrequency = 3;
+    discoBarberPhase += 48;
   }

-  hue = hue + 1;                                                // Hue rotation is fun for thiswave.
+  hue = hue + 1;

-  for (int k = 0; k < NUM_LEDS - 1; k++) {                                    // For each of the LED's in the strand, set a brightness based on a wave as follows:
-    int _brightness = qsubd(cubicwave8((k * allfreq) + thisphase), thiscutoff); // qsub sets a minimum value called thiscutoff. If < thiscutoff, then bright = 0. Otherwise, bright = 128 (as defined in qsub)..
+  for (int k = 0; k < NUM_LEDS - 1; k++) {
+    // qsub sets a minimum value called discoBarberCutoff. If < discoBarberCutoff, then bright = 0. Otherwise, bright = 128 (as defined in qsub)..
+    int _brightness = qsubd(cubicwave8((k * discoBarberFrequency) + discoBarberPhase), discoBarberCutoff);
     leds[k] = CHSV(0, 0, 0);                                        // First set a background colour, but fully saturated.

     // Sparkles!
@@ -148,10 +139,10 @@

     if (patternId == DISCO_BARBER_1) {
       // original disco barber 1
-      // leds[k] += CHSV(hue+k/5, allsat, _brightness);                             // Then assign a hue to any that are bright enough.
-      leds[k] += CHSV(hue * 10 + k / 2, allsat, _brightness);                             // Then assign a hue to any that are bright enough.
+      // leds[k] += CHSV(hue+k/5, discoBarberSaturation, _brightness);                             // Then assign a hue to any that are bright enough.
+      leds[k] += CHSV(hue * 10 + k / 2, discoBarberSaturation, _brightness);                             // Then assign a hue to any that are bright enough.
     } else {
-      leds[k] += CHSV(hue * -20 + k / 4, allsat, _brightness);                       // Then assign a hue to any that are bright enough.
+      leds[k] += CHSV(hue * -20 + k / 4, discoBarberSaturation, _brightness);                       // Then assign a hue to any that are bright enough.
     }
   }
  }
@@ -173,8 +164,8 @@
     sparkles();
   } else if (patternId == DISCO_BARBER_1 || patternId == DISCO_BARBER_2) {
     discoBarber();
-  } else if (patternId == JUGGLE) {
-    juggle();
+  } else if (patternId == WORMS) {
+    worms();
   }

   firstRun = false;


left and right

left and right

--- dist.ino
+++ dist.ino
@@ -6,12 +6,13 @@

 // motor one - rear wheels forward reverse
 int enA = 10;
-int in1 = 9;
-int in2 = 8;
+int in1 = 9; //high actually goes in reverse
+int in2 = 8; //high makes it go forward, reverse these to go in reverse
 // motor two - left right
+
 int enB = 5;
-int in3 = 7;
-int in4 = 6;
+int in3 = 7; //HIGH left
+int in4 = 6; // HIGH right

 void setup() {
@@ -45,19 +46,32 @@
   digitalWrite(in2, HIGH);
   analogWrite(enA, 200); //when you are using anything other than the digital high voltage, so this goes to the pwm pins

+
+
   if (distance < 4) {  // This is where the LED On/Off happens

-    digitalWrite(in1, HIGH); //digital high voltage - think of this as a constant
-    digitalWrite(in2, LOW);
-    analogWrite(enA, 255); //when you are using anything other than the digital high voltage, so this goes to the pwm pins
+    digitalWrite(in2, HIGH); //digital high voltage - think of this as a constant
+    digitalWrite(in1, LOW);
+    analogWrite(enA, 0); //when you are using anything other than the digital high voltage, so this goes to the pwm pins

     digitalWrite(led,HIGH); // When the Red condition is met, the Green LED should turn off
     digitalWrite(led2,LOW);
+
+    digitalWrite(in3, HIGH);
+    digitalWrite(in4, LOW);
+    analogWrite(enB, 255);
+
   }

  else {
     digitalWrite(led,LOW);
     digitalWrite(led2,HIGH);
+    analogWrite(enA, 0);
+
+    digitalWrite(in4, HIGH);
+    digitalWrite(in3, LOW);
+    analogWrite(enB, 255);
+
   }

   //Printing details to screen


v10.21 Clean up

v10.21 Clean up

--- GPSLCD.ino
+++ GPSLCD.ino
@@ -203,7 +203,6 @@
     gps.hdop.isValid();

   // Check if the GPS data is valid or data valid override is set (for debugging)
-  //  if (dataValid || dataValidOverride) {
   if (dataValid || dataValidOverride) {
 #ifndef DATA_VALID_OVERRIDE
     // Store the real GPS data


Refactor OLED code.

Refactor OLED code.

--- oled.ino
+++ oled.ino
@@ -1,4 +1,7 @@

+
+time_t nextOLEDswitch = now() + 5;                   //switch between showing IP or hostname every 5 seconds
+bool showIP = true;

 void updateOLEDbar() {
   int barWidth = DISPLAY_WIDTH / numberOfChannels;
@@ -15,27 +18,6 @@
     OLED.drawString( 2 + x1 + barWidth / 2, y1 - 11, String( (int) channel[thisChannel].currentPercentage ) );
   }
   OLED.drawString( DISPLAY_WIDTH / 2, 0, formattedTime( localTime() ) );
-  showHostname_IP_OLED();
-}
-
-void updateOLEDstring() {
-  OLED.clear();
-  OLED.setTextAlignment(TEXT_ALIGN_RIGHT);
-  OLED.setFont(ArialMT_Plain_10);
-  for ( byte thisChannel = 0; thisChannel < numberOfChannels; thisChannel++ ) {
-    OLED.drawString(DISPLAY_WIDTH, 10 * thisChannel, String( channel[thisChannel].currentPercentage ) + "%");
-  }
-  OLED.setTextAlignment(TEXT_ALIGN_CENTER);
-  OLED.setFont(ArialMT_Plain_16);
-  OLED.drawString( 45, 10 , formattedTime( localTime() ) );
-  showHostname_IP_OLED();
-}
-
-time_t nextOLEDswitch = now() + 5;                   //switch between showing IP or hostname every 5 seconds
-bool showIP = true;
-
-void showHostname_IP_OLED() {
-  OLED.setTextAlignment(TEXT_ALIGN_CENTER);
   OLED.setFont(ArialMT_Plain_10);
   if ( now() >= nextOLEDswitch ) {
     showIP = !showIP;


Delete game_simon_says.ino

Delete game_simon_says.ino

--- examples/game_simon_says/game_simon_says.ino
+++ examples/game_simon_says/game_simon_says.ino
@@ -1,117 +0,0 @@
-#include <Servo.h>
-#include <InkyBoard.h>
-#include <Display.h>
-
-InkyBoard B; // definieer B als InkyBoard
-
-byte simonList[32];
-int simonLengthToWin;
-int simonListCount;
-
-void setup() {
-  B.init();
-  Serial.begin(9600);
-  simonStart();
-}
-
-void loop() {
-  simonList[0] = simonWaits();
-
-  simonListCount = 1;
-  simonSays();
-  delay(1000);
-}
-
-void simonStart(){
-  randomSeed(analogRead(B.pLight)); // make sure the random function is random
-  random(1000); // start up the random function (weird arduino stuff)
-  simonLengthToWin = 10;
-}
-
-void simonSays(){
-  B.setLED(simonList[0], B.OFF);
-  delay(1000);
-
-  Serial.println("simon says...");
-  for(int i = simonListCount; i < simonLengthToWin; i++){
-    simonDisplaySequence();
-    if(!simonCheckPlayerInput()) return;
-    simonAddToSequence();
-  }
-}
-
-/**
- *
- */
-int simonWaits(){
-  unsigned int refreshRate = 100;
-  unsigned long refreshTimer = millis();
-  int ledCounter = 0;
-  while(1){
-    if( (millis() - refreshTimer) > refreshRate){
-      refreshTimer = millis();
-      B.setLED(ledCounter,B.OFF); // turn off the current led
-      ledCounter ++;
-      if(ledCounter > 3) ledCounter = 0;
-      B.setLED(ledCounter,B.ON); // turn on next led
-    }
-
-    // check if one of the buttons is pressed
-    if(simonCheckButtons() >= 0) return ledCounter;
-
-  }
-}
-
-void simonDisplaySequence(){
-
-  for (int i = 0; i < simonListCount; i++){
-    B.setLED(simonList[i], B.ON);
-    delay(200);
-    B.setLED(simonList[i], B.OFF);
-    delay(200);
-    Serial.print(simonList[i]);
-    Serial.print(" ");
-  }
-  Serial.println("simon is done saying");
-  delay(200);
-}
-
-bool simonCheckPlayerInput(){
-  for (int i = 0; i < simonListCount; i++){
-    unsigned long timer = millis();
-    while(1){
-      if( (millis() - timer) > 3000){
-        Serial.println("timeout");
-        return false; // timeout
-      }
-
-      int button = simonCheckButtons();
-      if(button >= 0){
-        if(simonList[i] != button){
-          Serial.println("wrong button");
-          return false; // wrong button
-        }
-        B.setLED(button, B.ON);
-        delay(200); // debounce
-
-        B.setLED(button, B.OFF);
-        break; // break while loop
-      }
-    }
-  }
-  delay(500);
-  return true;
-}
-
-void simonAddToSequence(){
-  simonList[simonListCount] = random(0,4);
-  simonListCount ++;
-}
-
-int simonCheckButtons(){
-  for(int i = 0; i < 4; i++){
-    if(B.isButton(i)) return i;
-  }
-  return -1;
-}
-


print mob tripped current

print mob tripped current

--- short-circuit-limiter/short-circuit-limiter.ino
+++ short-circuit-limiter/short-circuit-limiter.ino
@@ -2,7 +2,7 @@
 #include "CTSensor.h"

 #define CURRENT_ENABLE_THRESHOLD 0.2
-#define CURRENT_MCB_CUT 20
+#define CURRENT_MCB_CUT 16

 #define PIN_LED 26
 #define PIN_CT A0
@@ -41,7 +41,6 @@
 int samplesTaken = 0;

 unsigned long enableWindowTime = 0;
-

 double mcbTrippedCurrent;

@@ -182,7 +181,8 @@

     currentState = STATE_MCB_TRIPPED;
     mcbTrippedCurrent = currentValue;
-    Serial.println("MCB tripped");
+    Serial.print("MCB tripped at: ");
+    Serial.println(mcbTrippedCurrent);
   }

   int buttonPressed = digitalRead(PIN_BUTTON_ENTER);


Rename key timeout to click timeout

Rename key timeout to click timeout

--- volvo_hid.ino
+++ volvo_hid.ino
@@ -15,7 +15,8 @@
 #define RX_LED 17

 #define HEARTBEAT_TIMEOUT 2000
-#define KEY_TIMEOUT 100
+#define CLICK_TIMEOUT 100
+
 #define MOUSE_BASE_SPEED 8
 #define MOUSE_SPEEDUP 3

@@ -150,17 +151,17 @@
 }

 void release_keys() {
-  if (lastEnterDown && currentMillis - lastEnterDown > KEY_TIMEOUT) {
+  if (lastEnterDown && currentMillis - lastEnterDown > CLICK_TIMEOUT) {
     Mouse.release();
     lastEnterDown = 0;
   }

-  if (lastBackDown && currentMillis - lastBackDown > KEY_TIMEOUT) {
+  if (lastBackDown && currentMillis - lastBackDown > CLICK_TIMEOUT) {
     Keyboard.release(KEY_ESC);
     lastBackDown = 0;
   }

-  if (lastMouseDown && currentMillis - lastMouseDown > KEY_TIMEOUT) {
+  if (lastMouseDown && currentMillis - lastMouseDown > CLICK_TIMEOUT) {
     lastMouseDown = 0;
     mouseSpeed = MOUSE_BASE_SPEED;
   }


analoginoutserial working!

analoginoutserial working!

--- html/examples/03.Analog/AnalogInOutSerial/AnalogInOutSerial.ino
+++ html/examples/03.Analog/AnalogInOutSerial/AnalogInOutSerial.ino
@@ -1,3 +1,4 @@
+//  This example is Chibitronics Love to Code tested!
 /*
   Analog input, analog output, serial output

@@ -6,14 +7,16 @@
  Also prints the results to the serial monitor.

  The circuit:
- * potentiometer connected to analog pin 0.
+ * potentiometer connected to pin A1.
    Center pin of the potentiometer goes to the analog pin.
-   side pins of the potentiometer go to +5V and ground
- * LED connected from digital pin 9 to ground
+   side pins of the potentiometer go to A0 and A3
+ * LED connected from digital pin A2 to ground

  created 29 Dec. 2008
  modified 9 Apr 2012
  by Tom Igoe
+ modified 25 May 2016
+ by bunnie

  This example code is in the public domain.

@@ -21,15 +24,25 @@

 // These constants won't change.  They're used to give names
 // to the pins used:
-const int analogInPin = A0;  // Analog input pin that the potentiometer is attached to
-const int analogOutPin = 9; // Analog output pin that the LED is attached to
+const int analogInPin = A1;  // Analog input pin that the potentiometer is attached to
+const int analogOutPin = A2; // Analog output pin that the LED is attached to

 int sensorValue = 0;        // value read from the pot
 int outputValue = 0;        // value output to the PWM (analog out)

 void setup() {
-  // initialize serial communications at 9600 bps:
-  Serial.begin(9600);
+  Serial.begin(115200);
+
+  pinMode(A0, OUTPUT);
+  digitalWrite(A0, LOW);   // A0 is the - reference
+
+  pinMode(A3, OUTPUT);
+  digitalWrite(A3, HIGH);  // A3 is the + voltage
+
+  pinMode(A1, INPUT);      // A1 is the sensor input
+
+  pinMode(A2, OUTPUT);     // A2 has the LED
+
 }

 void loop() {


This call to update_time() not needed

This call to update_time() not needed

--- time.ino
+++ time.ino
@@ -30,7 +30,6 @@
 }

 void set_time(time_t t) {
-    update_time();
     next_sync_threshold = t + sync_interval;
     if (time_has_been_set) {
         measured_time_drift += current_timestamp - t;


lidar works but arduino cannot keep

lidar works but arduino cannot keep

--- robik_arduino.ino
+++ robik_arduino.ino
@@ -81,7 +81,6 @@
 RTIMU *imu;                                           // the IMU object
 RTIMUSettings settings;                               // the settings object
 void read_IMU();
-void clean_IMU();

 //Lidar
 unsigned int ranges[360];
@@ -89,7 +88,7 @@
 unsigned char Data_status=0;
 unsigned char Data_4deg_index=0;
 unsigned char Data_loop_index=0;
-unsigned char SpeedRPHhighbyte=0; //
+unsigned char SpeedRPHhighbyte=0;
 unsigned char SpeedRPHLowbyte=0;
 int SpeedRPH=0;

@@ -98,7 +97,6 @@

 unsigned long lastDisplay;
 unsigned long lastRate;
-int sampleCount = 0;

 //determine the sign of a value
 template <typename type>
@@ -175,6 +173,7 @@
 	estimated_clamp_pos.corrected = false;

 	status_msg.status_code = (int32_t *) malloc(20 * sizeof(int32_t));
+	status_msg.lidar_data = (byte *) malloc(360 * sizeof(byte));
 }

 void log_string(String str) {
@@ -209,8 +208,8 @@
 	charBuf[0] = '\0';
 	status_msg.log_count = 0;
 	status_msg.status_code_length = 0;
+	status_msg.lidar_data_length = 0;
 	status_msg.status_param_length = 0;
-	clean_IMU();
 }

 void add_status_code (int32_t code) {
@@ -274,11 +273,11 @@

 	//Lidar
 	lidar_complete = false;
-	Serial3.begin(115200);  // XV-11 LDS data
+	Serial2.begin(115200);  // XV-11 LDS data

 	//ROS node
-	nh.getHardware()->setBaud(115200); //57600 115200
+	nh.getHardware()->setBaud(500000); //57600 115200 500000
 	nh.initNode();
 	nh.subscribe(sub_generic_control);
 	nh.subscribe(sub_arm_control);
@@ -371,12 +370,12 @@
 			progress = 1;

 		uint32_t estimatedClampPos = estimated_clamp_pos.orig_pos + (uint32_t)(progress * (estimated_clamp_pos.target_pos - estimated_clamp_pos.orig_pos));
-		sprintf(strtmp, "SSS %lu | TTC %lu | ORG %lu | TRG %lu | PRG %lu | ECP %lu", milliseconds_since_start, estimated_clamp_pos.time_to_complete, estimated_clamp_pos.orig_pos, estimated_clamp_pos.target_pos, (uint32_t)(progress*100), estimatedClampPos); log_chars(strtmp);
+		//sprintf(strtmp, "SSS %lu | TTC %lu | ORG %lu | TRG %lu | PRG %lu | ECP %lu", milliseconds_since_start, estimated_clamp_pos.time_to_complete, estimated_clamp_pos.orig_pos, estimated_clamp_pos.target_pos, (uint32_t)(progress*100), estimatedClampPos); log_chars(strtmp);
 		armSetJointState(estimatedClampPos, 0, 0, 0, 0, 80); //80ms
 		estimated_clamp_pos.corrected = true; //prevent iteration for stopping clamp again
 	}
-	else
-		sprintf(strtmp, "SSS %lu | TTC %lu | ORG %lu | TRG %lu ", milliseconds_since_start, estimated_clamp_pos.time_to_complete, estimated_clamp_pos.orig_pos, estimated_clamp_pos.target_pos); log_chars(strtmp);
+	//else
+		//sprintf(strtmp, "SSS %lu | TTC %lu | ORG %lu | TRG %lu ", milliseconds_since_start, estimated_clamp_pos.time_to_complete, estimated_clamp_pos.orig_pos, estimated_clamp_pos.target_pos); log_chars(strtmp);
 }

 unsigned int menu_lag = 0;
@@ -457,6 +456,8 @@
       break;
     case 17: //data 3:1
       ranges[(Data_4deg_index << 2) + 3] = ((inByte & 0x3F) << 8) + ranges[(Data_4deg_index << 2) + 3];
+	if (Data_4deg_index == 89)
+		lidar_complete = true;
       break;
     case 18: //data 3:2 signal strength
     case 19: //data 3:3 signal strength
@@ -481,7 +482,7 @@
 				if (inByte==0xFA) {
 					Data_status=2;
 					Data_loop_index=1;
-				}
+				}
 				else {// if not FA search again
 					Data_status=0;
 				}
@@ -512,91 +513,82 @@
 /*---------------------- LOOP() ---------------------*/
 void loop() {

-	//sent status message
-	if ( (millis()-range_timer50) > 50){   //[ms] 50ms == 20Hz
-
-		status_msg.header.stamp = nh.now();
-
-		//bumper
-		status_msg.bumper_front = bumperFront;
-		bumperFrontPublished = true;
-
-		//menu controls
-		status_msg.menu_controls = menu_controls();
-
-		//odom
-		status_msg.odom_ticksLeft = motor_left_dir * odom_ticks_left;
-		status_msg.odom_ticksRight = motor_right_dir * odom_ticks_right;
-		odom_ticks_left = 0;
-		odom_ticks_right = 0;
-		unsigned long now = millis();
-		status_msg.odom_millisSinceLastUpdate = now - odomMillisSinceLastUpdate;
-		odomMillisSinceLastUpdate = now;
-
-		//wheels are expected to move but robot is stopped
-		velocity_control_LR();
-//add_status_code(req_motor_left);
-//add_status_code(old_motor_left);
-//add_status_code(odom_ticks_left_since_cmd);
-//add_status_code(millis_since_cmd);
-
-
-		//sonar
-		status_msg.ultrasound_Back = ultrasoundBack;
-
-		//arm
-		status_msg.arm_enabled = getArmPower();
-		status_msg.arm_yaw = servoSenseMedian_yaw.getMedian();
-		status_msg.arm_shoulder = servoSenseMedian_shoulder.getMedian();
-		status_msg.arm_elbow = servoSenseMedian_elbow.getMedian();
-		status_msg.arm_roll = servoSenseMedian_roll.getMedian();
-		status_msg.arm_clamp = servoSenseMedian_clamp.getMedian();
-
-		status_msg.arm_fore_clamp = digitalRead(PIN_ARM_FORE_CLAMP) == LOW ? true : false;
-		status_msg.arm_back_clamp = digitalRead(PIN_ARM_BACK_CLAMP) == LOW ? true : false;
-		if (estimated_clamp_pos.corrected == false && (status_msg.arm_fore_clamp == true || status_msg.arm_back_clamp == true))
-			checkClampAndStop();
-
-		//motion detector
-		status_msg.motion_detector = motionDetector;
-		motionDetectorPublished = true;
-
-
-		//parking photo sensor
-		status_msg.parkSens_inner = analogRead(PIN_PARK_SENS_INNER);
-		status_msg.parkSens_outer = analogRead(PIN_PARK_SENS_OUTER);
-
-
-		//IMU
-		status_msg.imu_sample_count = sampleCount;
-		status_msg.imu_gyro_bias_valid = imu->IMUGyroBiasValid();  //do not move IMU if false
-
-		refreshMotorJoints();
-
-		//Lidar
-		if (Serial3.available() > 0) {
-			decodeData(Serial3.read());
+
+	status_msg.header.stamp = nh.now();
+
+	//bumper
+	status_msg.bumper_front = bumperFront;
+	bumperFrontPublished = true;
+
+	//menu controls
+	status_msg.menu_controls = menu_controls();
+
+	//odom
+	status_msg.odom_ticksLeft = motor_left_dir * odom_ticks_left;
+	status_msg.odom_ticksRight = motor_right_dir * odom_ticks_right;
+	odom_ticks_left = 0;
+	odom_ticks_right = 0;
+	unsigned long now = millis();
+	status_msg.odom_millisSinceLastUpdate = now - odomMillisSinceLastUpdate;
+	odomMillisSinceLastUpdate = now;
+
+	//wheels are expected to move but robot is stopped
+	velocity_control_LR();
+
+	//sonar
+	status_msg.ultrasound_Back = ultrasoundBack;
+
+	//arm
+	status_msg.arm_enabled = getArmPower();
+	status_msg.arm_yaw = servoSenseMedian_yaw.getMedian();
+	status_msg.arm_shoulder = servoSenseMedian_shoulder.getMedian();
+	status_msg.arm_elbow = servoSenseMedian_elbow.getMedian();
+	status_msg.arm_roll = servoSenseMedian_roll.getMedian();
+	status_msg.arm_clamp = servoSenseMedian_clamp.getMedian();
+
+	status_msg.arm_fore_clamp = digitalRead(PIN_ARM_FORE_CLAMP) == LOW ? true : false;
+	status_msg.arm_back_clamp = digitalRead(PIN_ARM_BACK_CLAMP) == LOW ? true : false;
+	if (estimated_clamp_pos.corrected == false && (status_msg.arm_fore_clamp == true || status_msg.arm_back_clamp == true))
+		checkClampAndStop();
+
+	//motion detector
+	status_msg.motion_detector = motionDetector;
+	motionDetectorPublished = true;
+
+
+	//parking photo sensor
+	status_msg.parkSens_inner = analogRead(PIN_PARK_SENS_INNER);
+	status_msg.parkSens_outer = analogRead(PIN_PARK_SENS_OUTER);
+
+
+	//IMU
+	status_msg.imu_gyro_bias_valid = imu->IMUGyroBiasValid();  //do not move IMU if false
+
+	refreshMotorJoints();
+
+	//Lidar
+/*	if (Serial2.available()) {
+		decodeData(Serial2.read());
+	}
+*/	if (lidar_complete == true || true) {
+		for (int i = 0; i < 200; i++) {
+			if (ranges[i] > 5100) ranges[i] = 5100;  //max is 5meters anyway
+			status_msg.lidar_data[i] = (byte)(ranges[i] / 20);  //transfer 2cm steps to safe bandwidth
 		}
-		if (lidar_complete == true) {
-			for (int i = 0; i < 360; i++) {
-				if (ranges[i] > 5100) ranges[i] = 5100;  //max is 5meters anyway
-				status_msg.lidar_data[i] = (byte)(ranges[i] / 20);  //transfer 2cm steps to safe bandwidth
-			}
-			status_msg.lidar_speed = SpeedRPH; //needs to be divided by 64
-			lidar_complete = false;
-		}
-
-		//publish
-		range_timer50 = millis();
-		pub_status.publish(&status_msg);
-		status_msg_clean();
-
-		//check arm power timeout to prevent overheat
-		if ( (getArmPower() == true) && ((arm_enabled_time + ARM_TIME_MAX_ENABLED) < millis()) ) {
-			setArmPower(false);
-		}
-
-	}
+		status_msg.lidar_data_length = 200;
+		status_msg.lidar_speed = SpeedRPH / 64;
+		lidar_complete = false;
+	}
+
+	//publish
+	pub_status.publish(&status_msg);
+	status_msg_clean();
+
+	//check arm power timeout to prevent overheat
+	if ( (getArmPower() == true) && ((arm_enabled_time + ARM_TIME_MAX_ENABLED) < millis()) ) {
+		setArmPower(false);
+	}
+

 	//thigs to be done frequently
 	read_IMU();
@@ -642,42 +634,24 @@
 } //end of loop

-void clean_IMU() {
-	for (int i = 0; i < 3; i++) {
-		status_msg.imu_angular_velocity_v3_x[i] = 0;
-		status_msg.imu_angular_velocity_v3_y[i] = 0;
-		status_msg.imu_angular_velocity_v3_z[i] = 0;
-
-		status_msg.imu_linear_acceleration_v3_x[i] = 0;
-		status_msg.imu_linear_acceleration_v3_y[i] = 0;
-		status_msg.imu_linear_acceleration_v3_z[i] = 0;
-
-		status_msg.imu_compass_v3_x[i] = 0;
-		status_msg.imu_compass_v3_y[i] = 0;
-		status_msg.imu_compass_v3_z[i] = 0;
-	}
-	sampleCount = 0;
-}

 void read_IMU() {

-	if (sampleCount < 3 && imu->IMURead()) { // get the latest data if ready yet
+	if (imu->IMURead()) { // get the latest data if ready yet
 		RTVector3 gyro_v3 = (RTVector3&)imu->getGyro();
-		status_msg.imu_angular_velocity_v3_x[sampleCount] = gyro_v3.x();
-		status_msg.imu_angular_velocity_v3_y[sampleCount] = gyro_v3.y();
-		status_msg.imu_angular_velocity_v3_z[sampleCount] = gyro_v3.z();
+		status_msg.imu_angular_velocity_v3_x = gyro_v3.x();
+		status_msg.imu_angular_velocity_v3_y = gyro_v3.y();
+		status_msg.imu_angular_velocity_v3_z = gyro_v3.z();

 		RTVector3 accel_v3 = (RTVector3&)imu->getAccel();
-		status_msg.imu_linear_acceleration_v3_x[sampleCount] = accel_v3.x();
-		status_msg.imu_linear_acceleration_v3_y[sampleCount] = accel_v3.y();
-		status_msg.imu_linear_acceleration_v3_z[sampleCount] = accel_v3.z();
+		status_msg.imu_linear_acceleration_v3_x = accel_v3.x();
+		status_msg.imu_linear_acceleration_v3_y = accel_v3.y();
+		status_msg.imu_linear_acceleration_v3_z = accel_v3.z();

 		RTVector3 compass_v3 = (RTVector3&)imu->getCompass();
-		status_msg.imu_compass_v3_x[sampleCount] = compass_v3.x();
-		status_msg.imu_compass_v3_y[sampleCount] = compass_v3.y();
-		status_msg.imu_compass_v3_z[sampleCount] = compass_v3.z();
-
-		sampleCount++;
+		status_msg.imu_compass_v3_x = compass_v3.x();
+		status_msg.imu_compass_v3_y = compass_v3.y();
+		status_msg.imu_compass_v3_z = compass_v3.z();
 	}

 }
@@ -871,11 +845,9 @@

     if (val < min) {
 	val = min;
-	log_string("ArmSrvoMinX:" + String(min, DEC));  //nevim jestli funguje
     }
     if (val > max) {
 	val = max;
-	log_string("ArmSrvoMaxX:" + String(max, DEC));
     }

     return val;
@@ -891,7 +863,7 @@
 void setMotorJoint(int pin0, int pin1, int pinsense, int target_ohm) {

 	int current_ohm = analogRead(pinsense);
-	add_status_code(current_ohm);
+	//add_status_code(current_ohm);

 	int a0 = LOW;  //stop implicitly
 	int a1 = LOW;
@@ -969,7 +941,7 @@
 	}

 	String cmd = String(arm_clamp + arm_roll + arm_elbow + arm_shoulder + arm_yaw + "T" + time_to_complete_str + "\r\n");
-	log_string(cmd);
+	//log_string(cmd);
 	Serial3.print(cmd);

 }
@@ -1043,8 +1015,8 @@
 	//include correction <0 - ow; MOTOR_MAX + ow> where ow is an overflow
 	int corrected_motor_left  = motor_vel_to_pwm(abs(req_motor_left))  + constrain(correction_motor_left  * 5, -MOTOR_MAX/5, MOTOR_MAX/5);
 	int corrected_motor_right = motor_vel_to_pwm(abs(req_motor_right)) + constrain(correction_motor_right * 5, -MOTOR_MAX/5, MOTOR_MAX/5);
-	add_status_code(corrected_motor_left);
-	add_status_code(corrected_motor_right);
+	//add_status_code(corrected_motor_left);
+	//add_status_code(corrected_motor_right);

 	//remap if speed of any wheel overflows 0 or MOTOR_MAX
 	if (corrected_motor_left < MOTOR_MIN)
@@ -1080,8 +1052,8 @@
 	digitalWrite(PIN_MOTOR_LEFT_0, a0);
 	digitalWrite(PIN_MOTOR_LEFT_1, a1);
 	analogWrite(PIN_MOTOR_LEFT_ENA, constrain(corrected_motor_left, 0, MOTOR_MAX));
-	add_status_code(correction_motor_left);
-	add_status_code(corrected_motor_left);
+	//add_status_code(correction_motor_left);
+	//add_status_code(corrected_motor_left);

 	//right
 	a0 = LOW;
@@ -1097,8 +1069,8 @@
 	digitalWrite(PIN_MOTOR_RIGHT_0, a0);
 	digitalWrite(PIN_MOTOR_RIGHT_1, a1);
 	analogWrite(PIN_MOTOR_RIGHT_ENA, constrain(corrected_motor_right, 0, MOTOR_MAX));
-	add_status_code(correction_motor_right);
-	add_status_code(corrected_motor_right);
+	//add_status_code(correction_motor_right);
+	//add_status_code(corrected_motor_right);
 }

 //odometry encoders


Plays Happy Birthday, without using pin 11 as tone() messes with pin 11

--- oven.ino
+++ oven.ino
@@ -21,9 +21,9 @@
 int pulses, A_SIG=0, B_SIG=1;

 // Pin numbers for the RGB LEB
-const int ledRedPin = 9;
-const int ledGreenPin = 10;
-const int ledBluePin = 11;
+const int ledRedPin = 8;
+const int ledGreenPin = 9;
+const int ledBluePin = 10;

 // I2C address of our S7S
 const byte s7sAddress = 0x71;
@@ -79,8 +79,7 @@
       adjustTime();
       break;
     case 1:
-      setColor(255, 0, 0);
-      countDown();
+      cooking();
       break;
     case 2:
       setColor(0, 0, 0);
@@ -100,7 +99,9 @@
   updateDisplay();
 }

-void countDown() {
+void cooking() {
+  setColor(255, 0, 0);
+
   displayValue--;
   updateDisplay();

@@ -121,42 +122,42 @@

   // notes in the melody:
   int melody[] = {
-    NOTE_C4, NOTE_G3, NOTE_G3, NOTE_A3, NOTE_G3, 0, NOTE_B3, NOTE_C4 };
+    NOTE_C4, NOTE_C4, NOTE_D4, NOTE_C4, NOTE_F4, NOTE_E4 };

   // note durations: 4 = quarter note, 8 = eighth note, etc.:
   int noteDurations[] = {
-    4, 8, 8, 4, 4, 4, 4, 4 };
+    8, 8, 4, 4, 4, 2 };

   int colors[][3] = {
-    {255, 255, 255},
+    {255, 255, 0},
+    {255, 255, 128},
     {255, 255, 0},
     {255, 128, 0},
-    {255, 0, 128},
-    {255, 0, 255},
-    {255, 0, 255},
-    {0, 255, 255},
-    {255, 255, 255},
+    {255, 0, 0},
+    {255, 0, 255}
   };

   char* display[] = {
     "   0",
-    "  00",
+    "   0",
     "  00",
     " 000",
     "0000",
-    "0000",
-    "0  0",
-    " 00 "
+    "0  0"
   };

+  int numberOfNotes = sizeof(melody) / sizeof(int);
+
   // iterate over the notes of the melody:
-  for (int thisNote = 0; thisNote < 8; thisNote++) {
+  for (int thisNote = 0; thisNote < numberOfNotes; thisNote++) {

     // to calculate the note duration, take one second
     // divided by the note type.
     //e.g. quarter note = 1000 / 4, eighth note = 1000/8, etc.
-    int noteDuration = 1000/noteDurations[thisNote];
-    tone(buzzerPin, melody[thisNote],noteDuration);
+    int noteDuration = 1800/noteDurations[thisNote];
+    Serial.println(melody[thisNote]);
+    Serial.println(noteDuration);
+    tone(buzzerPin, melody[thisNote], noteDuration);

     // Change LED color
     setColor(colors[thisNote][0], colors[thisNote][1], colors[thisNote][2]);


Only show next quarter indicator to reduce clutter

--- Clock.ino
+++ Clock.ino
@@ -78,7 +78,9 @@
         return zeroColor;
     else if (minute > currentDateTime.minute())
     {
-        if ((minute % 15) == 0)
+        int currentQuarter = currentDateTime.minute() / 15;
+        int targetQuarter = minute / 15;
+        if ((minute % 15) == 0 && (targetQuarter - currentQuarter) == 1)
             return zeroColor;
         else
             return 0;
@@ -97,7 +99,9 @@
         return zeroColor;
     else if (hour > currentDateTime.hour())
     {
-        if ((hour % 6) == 0)
+        int currentQuarter = currentDateTime.hour() / 6;
+        int targetQuarter = hour / 6;
+        if ((hour % 6) == 0 && (targetQuarter - currentQuarter) == 1)
             return zeroColor;
         else
             return 0;


Improve sketch.ino: refactoring for better OOP

--- sketch/sketch.ino
+++ sketch/sketch.ino
@@ -15,7 +15,6 @@
   }

   protected:
-
     /* サーボを回転させる関数 */
     /* 値は0~180の間で */
     void rotateServo(const int difference){
@@ -29,7 +28,7 @@
   public:
     /* サーボモータのピンを設定する関数 */
     /* 無くても良いが、あると統一感が生まれる */
-    void servoPin(int pin){
+    void servoPin(const int pin){
       servo.attach(pin);
     }
 }; //}}}
@@ -37,35 +36,44 @@
 /* モータの制御クラス */
 class MotorIO{ //{{{

-  /* モータの状態を表す型 */
-  struct MotorState{
-    bool isMoveFoward; /* 前進するか */
-    bool isStop;       /* 停止するか */
-    bool isBrake;      /* ブレーキするか */
-  };
-
-  /* モータの現在の状態
-     もう少し良い方法があれば書き直す */
-  MotorState motorState = {true, false, false};
+  /* 優先度は Brake > Stop > Otherewise */
+  bool isMoveFoward; /* 前進するか */
+  bool isStop;       /* 停止するか */
+  bool isBrake;      /* ブレーキするか */

-  /* モータの変更後の状態
-     現在と違う状態がセットされていればmotor関数が状態を変更する */
-  MotorState changedMotorState = {true, false, false};
+  void brake(){/* Brake code here... */}
+  void stop(){/* Stop code here... */}
+  void moveFoward(){/* Move Foward code here... */}
+  void moveBackward(){/* Move backward code here... */}

-  void motor(){
-    if(motorState.isMoveFoward != changedMotorState.isMoveFoward ||
-       motorState.isStop       != changedMotorState.isStop       ||
-       motorState.isBrake      != changedMotorState.isBrake      ){
-      motorState = changedMotorState;
-      if(motorState.isBrake){
+  public:
+    void toMoveFoward(){ /* 前進するよう状態を変更 */
+      isMoveFoward = true;
+      isStop = false;
+      isBrake = false;
+    }
+    void toMoveBackward(){ /* 後退するよう状態を変更 */
+      isMoveFoward = false;
+      isStop = false;
+      isBrake = false;
+    }
+    void toMoveStop(){ /* 停止するよう状態を変更 */
+      isStop = true;
+    }
+    void toBrake(){ /* ブレーキするよう状態を変更 */
+      isBrake = true;
+    }
+
+    void updateMotorState(){ /* モータの状態を更新 */
+       if(isBrake){
         brake();
         return;
       }
-      if(motorState.isStop){
+      if(isStop){
         stop();
         return;
       }
-      if(motorState.isMoveFoward){
+      if(isMoveFoward){
         moveFoward();
         return;
       } else {
@@ -73,65 +81,35 @@
         return;
       }
     }
-  }
-
-  void brake(){
-    // Brake code here...
-  }
-  void stop(){
-    // Stop code here...
-  }
-  void moveFoward(){
-    // Move Foward code here...
-  }
-  void moveBackward(){
-    // Move backward code here...
-  }
-
-  public:
-    /* 前進するよう状態を変更 */
-    void toMoveFoward(){
-      changedMotorState = {true,false, false};
-    }
-    /* 後退するよう状態を変更 */
-    void toMoveBackward(){
-      changedMotorState = {false,false, false};
-    }
-    /* 停止するよう状態を変更 */
-    void toMoveStop(){
-      changedMotorState = {true,true, false};
-    }
-    /* モータの状態を更新 */
-    void updateMotorState(){
-      motor();
-    }
 };//}}}

-/* 制御のクラス */
+/* 制御 クラス */
 class Control: public ServoIO, public MotorIO{ //{{{
-  int errorPinNum; /* エラーピンの番号を表す */
-  void error(void){
-    digitalWrite(errorPinNum,HIGH);
+  int errorPinNumber; /* エラーピンの番号を表す */
+
+  void putError(void){
+    digitalWrite(errorPinNumber, HIGH);
   }

   /* moveFooBarの抽象化関数 */
-  void angleMove(const int angle, const bool isFoward){
+  void setAngleAndDirection(const int angle, const bool isFoward){
     rotateServo(angle);
     if(isFoward){toMoveFoward();}else{toMoveBackward();}
   }

   public:
     /* 左前に移動するよう状態を変更 */
-    void toMoveLeftFoward(){angleMove(-30, true);}
+    void setMoveLeftFoward(){setAngleAndDirection(-30, true);}
     /* 右前に移動するよう状態を変更 */
-    void toMoveRightFoward(){angleMove(30, true);}
+    void setMoveRightFoward(){setAngleAndDirection(30, true);}
     /* 左後に移動するよう状態を変更 */
-    void toMoveLeftBackward(){angleMove(-30, false);}
+    void setMoveLeftBackward(){setAngleAndDirection(-30, false);}
     /* 右後に移動するよう状態を変更 */
-    void toMoveRightBackward(){angleMove(30, false);}
+    void setMoveRightBackward(){setAngleAndDirection(30, false);}
+
     /* エラーLEDのピンを設定する関数 */
     void errorPin(const int pin){
-      errorPinNum = pin;
+      errorPinNumber = pin;
       pinMode(pin,OUTPUT);
     }
 };//}}}


refactored by krystiand

refactored by krystiand

--- zamek.ino
+++ zamek.ino
@@ -83,6 +83,9 @@
 	digitalWrite(pinButtonSwitch, HIGH);
 	digitalWrite(pinReedSwitch, HIGH);
 	Ethernet.begin(mac, ip);
+
+        pinMode(8, OUTPUT);
+        digitalWrite(8, LOW);
 }

@@ -97,6 +100,10 @@

 int buttonEvent = 0;
 int doorEvent = 0;
+
+int cyclicBufferPosition = 0;
+int lastSerialEventTime = 0;
+bool eventReceived = false;

 inline bool isStable(const int lastEvent){
 	return (millis() - lastEvent) > debounceDelay;
@@ -111,7 +118,39 @@
 void copyFromBuffer(int cyclicBufferPosition);
 void dumpCardToSerial();

+
+unsigned int toneDisableTime;
+int toneEnabled = 0;
+
+int lastMs = 0;
+
 void loop() {
+
+		if(eventReceived and (millis() - lastSerialEventTime >= 20) ){
+			eventReceived = false;
+			cyclicBufferPosition = 0;
+			if(isDoorLocked)
+{
+				copyFromBuffer(cyclicBufferPosition);
+				dumpCardToSerial();
+				processCardNumber();
+			}
+		}
+
+if (millis() != lastMs)
+{
+  lastMs = millis();
+  if (toneDisableTime)
+  {
+    toneDisableTime--;
+  }
+  else
+  {
+    noTone(pinPiezo);
+  }
+}
+
+
 		bool button = digitalRead(pinButtonSwitch);
 		if(button != previousButtonState){
 			buttonEvent = millis();
@@ -139,7 +178,7 @@
 	}
 #endif

-void skipSerialBuffer(){
+void Buffer(){
 	while(Serial.available()){
 		Serial.read();
 	}
@@ -149,13 +188,17 @@
 		Serial.print("VALID\n");
 	#endif
 	if(isCardAuthorized()){
-		tone(pinPiezo, toneAccepted, toneDuration);
-		unlockDoor();
-		cleanBuffer();
+		tone(pinPiezo, toneAccepted);
+                toneDisableTime = toneDuration;
+toneEnabled = 1;
+unlockDoor();
+		//cleanBuffer();
 		reportOpened();
 		return;
 	}else{
-		tone(pinPiezo, toneRejected, toneDuration);
+		tone(pinPiezo, toneRejected);
+toneDisableTime = toneDuration;
+toneEnabled = 1;
 	}
 }

@@ -163,18 +206,22 @@
 	return index%(BUFSIZE);
 }

-int cyclicBufferPosition = 0;
 //called by Arduino framework when there are available bytes in input buffer
 void serialEvent(){
-	while (Serial.available()) {
-		buffer[cyclicBufferPosition] = Serial.read();
-		cyclicBufferPosition = bufferIndex(cyclicBufferPosition + 1);
-		if(isDoorLocked and isBufferValid(cyclicBufferPosition)){
-			copyFromBuffer(cyclicBufferPosition);
-			dumpCardToSerial();
-			processCardNumber();
-		}
-	}
+        digitalWrite(8, HIGH);
+	while (Serial.available())
+        {
+                char temp = Serial.read();
+                if(cyclicBufferPosition < 10){
+		  buffer[cyclicBufferPosition++] = temp;
+                }else{
+                  Serial.flush();
+                }
+
+	}
+	lastSerialEventTime = millis();
+        eventReceived = true;
+        digitalWrite(8, LOW);
 }

 inline void cleanBuffer(){
@@ -189,7 +236,7 @@
 #endif
 inline void copyFromBuffer(int cyclicBufferPosition){
 	for(int i = 0; i < LENGTH; ++i)
-		card[i] = buffer[bufferIndex(cyclicBufferPosition + i + offset)];
+		card[i] = buffer[i + offset];
 }

 #ifdef STASZEK_MODE
@@ -233,8 +280,6 @@

 int remoteEvent = 0;
 bool checkRemote(){
-        if((millis() - remoteEvent) < remoteDelay)
-          return false;
 	char data[20];
 	sprintf(data, "card=%s", card);
 	int retval = client.post("/api/v1/checkCard", data);


Added Location of Coordinates

Added Location of Coordinates

--- ChickenDoorController/ChickenDoorController.ino
+++ ChickenDoorController/ChickenDoorController.ino
@@ -14,7 +14,7 @@
 const int doorUpPin = 3;
 const int doorDownPin = 5;

-//define the location / timezone for dusk2dawn
+//define the location / timezone for dusk2dawn (this is Colton, SD)
 Dusk2Dawn colton(43.789369, -96.927453, -6);

 //Temporarily define how long to run the motor