Update position variables

Update position variables

--- Arduino/Arduino.ino
+++ Arduino/Arduino.ino
@@ -11,22 +11,42 @@
 Servo upDown;

 // VARIABLES
-int pos = 90;       // variable to store the servo position
+int pos1 = 90;
+int pos2 = 90;
+int pos3 = 90;
+int pos4 = 90;
+int pos5 = 90;
 int ByteReceived;   // store byte recieved via serial

 // INITIALIZE
 void setup() {
-  throttle.attach(9);  // attaches the servo on pin 9 to the servo object
+  // Set up all servos
+  throttle.attach(9);
+  rotatingFront.attach(10);
+  rotatingBack.attach(11);
+  leftRight.attach(12);
+  upDown.attach(13);
+
+  // Begin Serial
   Serial.begin(9600);
-  throttle.write(pos);
+
+  // Write default values to the servos
+  throttle.write(pos1);
+  rotatingFront.write(pos2);
+  rotatingBack.write(pos3);
+  leftRight.write(pos4);
+  upDown.write(pos5);
 }

 // UPDATE
 void loop() {
+  // Read information from Serial
   if (Serial.read() != -1) {
     ByteReceived = Serial.read();
     Serial.print(ByteReceived);
   }
+
+  // Write new positions
   throttle.write(ByteReceived);
   delay(1000);
   ByteReceived = 0;


Removed the Serial.print() commands from the code.

--- BackEnd/BackEnd.ino
+++ BackEnd/BackEnd.ino
@@ -329,7 +329,7 @@
 void *in, size_t len)
 {

-       Serial.println("callback_http()");
+//       Serial.println("callback_http()");
   // WE ARE ALWAYS HITTING THIS POINT

 //  char buf[256];
@@ -342,7 +342,7 @@
   case LWS_CALLBACK_HTTP:
 //    lwsl_notice("LWS_CALLBACK_HTTP");

-    Serial.println("LWS_CALLBACK_HTTP");
+ //   Serial.println("LWS_CALLBACK_HTTP");
     #ifdef DEBUG_CAT
       trace_info("%s(): LWS_CALLBACK_HTTP: IN", __func__);
     #endif
@@ -372,7 +372,7 @@

 //    lwsl_notice("LWS_FILE_COMPLETION");

-    Serial.println("LWS_FILE_COMPLETION");
+ //   Serial.println("LWS_FILE_COMPLETION");
     #ifdef DEBUG_CAT
       trace_info("%s(): LWS_FILE_COMPLETION", __func__);
     #endif
@@ -382,7 +382,7 @@

   default:

-       Serial.println("callback_http() - default");
+   //    Serial.println("callback_http() - default");
     #ifdef DEBUG_CAT
       trace_info("%s(): default", __func__);
     #endif
@@ -405,7 +405,7 @@
 void *in, size_t len)
 {

-  Serial.println("callback_cat_protocol()");
+//  Serial.println("callback_cat_protocol()");
   // WE ARE ALWAYS HITTING THIS POINT

   int iNumBytes = -1;
@@ -415,7 +415,7 @@

   case LWS_CALLBACK_SERVER_WRITEABLE:

-    Serial.println("LWS_CALLBACK_SERVER_WRITEABLE");
+  //  Serial.println("LWS_CALLBACK_SERVER_WRITEABLE");
     #ifdef DEBUG_CAT
       trace_info("%s(): LWS_CALLBACK_SERVER_WRITEABLE: IN", __func__);
     #endif
@@ -439,7 +439,7 @@

   case LWS_CALLBACK_RECEIVE:

-    Serial.println("LWS_CALLBACK_RECEIVE");
+ //   Serial.println("LWS_CALLBACK_RECEIVE");
     #ifdef DEBUG_CAT
       trace_info("%s(): LWS_CALLBACK_RECEIVE: IN", __func__);
     #endif
@@ -460,7 +460,7 @@

   default:

-    Serial.println("callback_cat_protocol() - default()");
+    // Serial.println("callback_cat_protocol() - default()");
     #ifdef DEBUG_CAT
       trace_info("%s(): default", __func__);
     #endif


不要な出力を削除.

不要な出力を削除.

--- GeneralIoSerial.ino
+++ GeneralIoSerial.ino
@@ -42,7 +42,6 @@
       if(read_buf[buf_index] == (char)10){
         String msg = String(read_buf);
         msg.trim();
-        //Serial.println(msg);
         Serial.println(task(msg));
         buf_index = 0;
         memset(read_buf,0,128);


extend servo angle calculation

extend servo angle calculation

--- testing/arduino/self-driving-v4.ino
+++ testing/arduino/self-driving-v4.ino
@@ -34,9 +34,16 @@
 const uint8_t servoPin = 6;
 const uint8_t servoRotationAngel = 10;

+enum direction {
+  left,
+  center,
+  right
+};
+
 uint8_t servoPos = 90;
-bool servoDirectionRight = false;
-bool servoRight = false;
+direction servoMovement = right;
+direction servoLocation = center;
+

 void setup()
 {
@@ -126,18 +133,41 @@

 uint8_t GetNextServoAngle()
 {
+    // 0 - 80
+    // 80 - 100
+    // 100 - 180
+
+    if(servoPos <= 0)
+    {
+        servoLocation = left;
+        servoMovement = right;
+        servoPos = 0;
+    }
+
+    if(servoPos < 80)
+    {
+        servoLocation = left;
+    }
+
+    if(servoPos >= 80 && servoPos <= 100)
+    {
+        servoLocation = center;
+    }
+
+    if(servoPos > 100)
+    {
+        servoLocation = right;
+    }
+
     if(servoPos >= 180)
     {
-        servoDirectionRight = false;
+        servoLocation = right;
+        servoMovement = left;
         servoPos = 180;
     }
-    if(servoPos <= 0)
-    {
-        servoDirectionRight = true;
-        servoPos = 0;
-    }
-
-    if(servoDirectionRight)
+
+
+    if(servoMovement == right)
     {
         servoPos += servoRotationAngel;
     }
@@ -145,9 +175,6 @@
     {
         servoPos -= servoRotationAngel;
     }
-
-    // todo - center would be nice as well
-    if(servoPos >= 90) { servoRight = true; } else { servoRight = false; }

     return servoPos;
 }


Update

Update

--- simple-ambient-sensor/simple-ambient-sensor.ino
+++ simple-ambient-sensor/simple-ambient-sensor.ino
@@ -16,12 +16,12 @@
 // 1: Thingspeak
 // 2: MQTT
 // 3: Only serial output
-int output = 3;
+int output = 2;

 // MQTT settings
 // If you want to use Thingspeak set mqtt_broker to "mqtt.thingspeak.com"
-//const char* mqtt_broker = "";
-const char* mqtt_broker = "mqtt.thingspeak.com";
+const char* mqtt_broker = "";
+//const char* mqtt_broker = "mqtt.thingspeak.com";
 // Not needed for Thingspeak
 const char* mqtt_username = "";
 const char* mqtt_password = "";
@@ -31,7 +31,6 @@
 // Replace <YOUR-CHANNEL-ID> with your channel ID and <YOUR-CHANNEL-WRITEAPIKEY>
 // with your write API key
 const char* thingspeak_topic = "channels/<YOUR-CHANNEL-ID>/publish/<YOUR-CHANNEL-WRITEAPIKEY>/";
-

 // Pin for an additional LED
 int led_pin = 2;
@@ -157,7 +156,7 @@
   pinMode(led_pin, OUTPUT);
   delay(10);

-  chipid = ESP.getEfuseMac();
+//  chipid = ESP.getEfuseMac();

   bme.settings(0, 3, 0, 0, 3, 3, 3);
   while (bme.begin()) {
@@ -201,7 +200,7 @@
   temperature = bme.readTemp();
   pressure = bme.readPressure() / 100.0F;
   humidity = bme.readHumidity();
-  hall = hallRead();
+  //hall = hallRead();

   if (output == 3) {
     Serial.print("Temperature: ");
@@ -210,8 +209,8 @@
     Serial.println(humidity);
     Serial.print("Pressure: ");
     Serial.println(pressure);
-    Serial.print("Hall: ");
-    Serial.println(hall);
+    //Serial.print("Hall: ");
+    //Serial.println(hall);
     delay(2000);
   }

@@ -263,7 +262,7 @@
             client.println(String("
Temperature:	") + temperature + " C
");
             client.println(String("
Humidity:	") + humidity + " % RH
");
             client.println(String("
Pressure:	") + pressure + " hPa
");
-            client.println(String("
Hall:	") + hall + "
");
+            //client.println(String("
Hall:	") + hall + "
");
             //client.println(String("
xxxx	xxx
");
             client.println("
");
             client.println("
");
@@ -392,14 +391,14 @@
             client.println();
             client.stop();
           }
-          else if (method.equals("GET /api/hall HTTP/1.1")) {
-            client.println("HTTP/1.1 200 OK");
-            client.println("Content-Type: application/json");
-            client.println();
-            client.println(String("{\"value\":") + hallRead() + "}");
-            client.println();
-            client.stop();
-          }
+//          else if (method.equals("GET /api/hall HTTP/1.1")) {
+//            client.println("HTTP/1.1 200 OK");
+//            client.println("Content-Type: application/json");
+//            client.println();
+//            client.println(String("{\"value\":") + hallRead() + "}");
+//            client.println();
+//            client.stop();
+//          }
           else if (method.equals("GET /api/temperature HTTP/1.1")) {
             client.println("HTTP/1.1 200 OK");
             client.println("Content-Type: application/json");


distans not translated correctly to height

--- ray-gfx.ino
+++ ray-gfx.ino
@@ -16,26 +16,47 @@
 #define DISP_HEIGHT	64

+
 /*Game*/
+#define ROTSPEED 0.78
+
 const uint8_t level_map[][8] PROGMEM =
 {
   {1,1,1,1,1,1,1,1},
+  {1,0,1,0,0,0,0,1},
+  {1,0,1,0,0,0,0,1},
+  {1,0,1,0,0,0,0,1},
+  {1,0,1,0,0,0,0,1},
+  {1,0,0,0,1,1,1,1},
   {1,0,0,0,0,0,0,1},
-  {1,1,1,1,0,0,0,1},
-  {1,0,0,0,0,0,0,1},
-  {1,0,0,0,0,1,0,1},
-  {1,0,0,0,0,1,0,1},
-  {1,0,0,0,0,1,0,1},
   {1,1,1,1,1,1,1,1}
 };

-struct Player {
+typedef struct Player {
 	float x;
 	float y;
 	float dirX;
 	float dirY;
 	float planeX;
 	float planeY;
+} Player;
+
+void doRayCasting(Player *player);
+void drawWallLine(uint8_t x,uint8_t h);
+
+void printDouble( float val, uint8_t precision){
+// prints val with number of decimal places determine by precision
+// NOTE: precision is 1 followed by the number of zeros for the desired number of decimial places
+// example: printDouble( 3.1415, 100); // prints 3.14 (two decimal places)
+
+   Serial.print (int(val));  //prints the int part
+   Serial.print("."); // print the decimal point
+   unsigned int frac;
+   if(val >= 0)
+       frac = (val - int(val)) * precision;
+   else
+       frac = (int(val)- val ) * precision;
+   Serial.println(frac,DEC) ;
 }

 void setup()  {
@@ -48,59 +69,128 @@

 void loop() {
-	struct Player player;
-	player.x = 1;
-	player.y = 1;
+	Player player;
+	player.x = 7;
+	player.y = 7;
 	player.dirX = -1;
 	player.dirY = 0;
 	player.planeX = 0;
 	player.planeY = 0.66;

-
-	for (uint8_t x = 0; x < DISP_WIDTH; x++) {
-		drawWallLine(x, abs(x - 64));
-	}
-	display.display();
+	int bla = 0;

 	while(1){
-		// statement
+		D(Serial.print("\n\nframe\n"));
+		D(Serial.print(bla));
+		bla = (bla +1) % 8;
+		display.clearDisplay();
+		doRayCasting(&player);
+		display.display();
+		delay(10000);
+
+		float oldXDir = player.dirX;
+		player.dirX = player.dirX*cos(-ROTSPEED) - player.dirY*sin(-ROTSPEED);
+		player.dirY = oldXDir*sin(-ROTSPEED) + player.dirY*cos(-ROTSPEED);
+
+		double oldplaneX = player.planeX;
+		player.planeX = player.planeX*cos(-ROTSPEED) - player.planeY*sin(-ROTSPEED);
+		player.planeY = oldplaneX*sin(-ROTSPEED) + player.planeY*cos(-ROTSPEED);
 	}

 }

 void drawWallLine(uint8_t x,uint8_t h) {
-	display.drawLine(x, CAMERA_HEIGHT + (h >> 1) , x, CAMERA_HEIGHT - (h >> 1), WHITE);
+	uint8_t drawStart = CAMERA_HEIGHT + (h >> 1);
+	uint8_t drawEnd = CAMERA_HEIGHT - (h >> 1);
+	if (drawStart < 0) {
+		drawStart = 0;
+	}
+	if (drawEnd > DISP_HEIGHT) {
+		drawEnd = DISP_HEIGHT;
+	}
+
+	display.drawLine(x, drawStart , x, drawEnd, WHITE);
 }

-void doRayCasting(Player player) {
+void doRayCasting(Player *player) {
 	for (uint8_t x = 0; x < DISP_WIDTH; x++) {
 		//calculate ray position and direction
 		float cameraX = 2 * x / (float)DISP_WIDTH - 1; //x-coordinate in camera space
-		float rayPosX = player.x;
-		float rayPosY = player.y;
-		float rayDirX = player.dirX + player.planeX * cameraX;
-		float rayDirY = player.dirY + player.planeY * cameraX;
+		float rayPosX = player->x;
+		float rayPosY = player->y;
+		float rayDirX = player->dirX + player->planeX * cameraX;
+		float rayDirY = player->dirY + player->planeY * cameraX;

-		int mapX = (int)player.x;
-		int mapY = (int)player.y;
+		int mapX = (int)player->x;
+		int mapY = (int)player->y;

 		//length of ray from current position to next x or y-side
-		double sideDistX;
-		double sideDistY;
+		float sideDistX;
+		float sideDistY;

 		//length of ray from one x or y-side to next x or y-side
-		double deltaDistX = sqrt(1 + (rayDirY * rayDirY) / (rayDirX * rayDirX));
-		double deltaDistY = sqrt(1 + (rayDirX * rayDirX) / (rayDirY * rayDirY));
-		double perpWallDist;
+		float deltaDistX = 0.1; //sqrt(1 + (rayDirY * rayDirY) / (rayDirX * rayDirX));
+		float deltaDistY = 0.1; //sqrt(1 + (rayDirX * rayDirX) / (rayDirY * rayDirY));
+		float perpWallDist;

+		//what direction to step in x or y-direction (either +1 or -1)
+		uint8_t stepX;
+		uint8_t stepY;
+
+		uint8_t hit = 0; //was there a wall hit?
+		uint8_t side; //was a NS or a EW wall hit?
+
+		//calculate step and initial sideDist
+		if (rayDirX < 0) {
+			stepX = -1;
+			sideDistX = (player->x - mapX) * deltaDistX;
+		} else {
+			stepX = 1;
+			sideDistX = (mapX + 1.0 - player->x) * deltaDistX;
+		}
+
+		if(rayDirY < 0) {
+			stepY = -1;
+			sideDistY = (player->y - mapY) * deltaDistY;
+		} else {
+			stepY = 1;
+			sideDistY = (mapY + 1 - player->y) * deltaDistY;
+		}
+
+		//DDA
+		while(!hit) {
+			if(sideDistX < sideDistY) {
+				sideDistX += deltaDistX;
+				mapX += stepX;
+				side = 0;
+			} else {
+				sideDistY += deltaDistY;
+				mapY += stepY;
+				side = 1;
+			}
+
+			// Check if ray has hit a wall
+			level_map[mapY][mapX] != 0 ? hit = 1 : hit = 0;
+		}
+
+		if(side) {
+			perpWallDist = sqrt(((mapY - player->y + (1 - stepY) / 2) / rayDirY) * ((mapY - player->y + (1 - stepY) / 2) / rayDirY));
+		}
+		else {
+			perpWallDist = sqrt(((mapX - player->x + (1 - stepX) / 2) / rayDirX) * ((mapX - player->x + (1 - stepX) / 2) / rayDirX));
+		}
+		Serial.print("dist");
+		printDouble(perpWallDist,3);
+		uint8_t lineHeight;
+		if(perpWallDist > 0) {
+			lineHeight = abs((int)(DISP_HEIGHT / (perpWallDist / 100)));
+		}
+		else {
+			lineHeight = DISP_HEIGHT;
+		}
+		if (lineHeight >= 1) {
+			drawWallLine(x,lineHeight);
+		}
 	}
 }

-
-
-
-
-
-
-
-


updated arduino2.ino to implement rotation_servo_movement function without using attach

--- working_directory/arduino_codes/arduino2/arduino2.ino
+++ working_directory/arduino_codes/arduino2/arduino2.ino
@@ -39,11 +39,15 @@
 Servo gripper_servo;

 int COUNT = 0;
+int val_0_rot = 1248;   //
+int val_90_rot = 2172;  //

 void setup(){
   Serial.begin(57600);
   //attach
-  rotation_servo.attach(rotation_servo_pin);
+  // rotation_servo.attach(rotation_servo_pin);
+  pinMode(rotation_servo_pin,OUTPUT);
+  digitalWrite(rotation_servo_pin,LOW);
   vertical_servo.attach(vertical_servo_pin);
   gripper_servo.attach(gripper_servo_pin);

@@ -164,11 +168,24 @@
   // double_blink();
 }

-void move(int position) {
-  // Serial.write("moving");
-  rotation_servo.write(position);
-  delay(10);
-  // double_blink();
+void move(int angle){
+  int angle_ = angle%90;
+  float f;
+  f = ((val_90_rot-val_0_rot)*1.0*angle_/90) + val_0_rot;
+  angle_ = int(f);
+  _move_3_(angle_);
+}
+
+void _move_3_(int on_time){
+  int off_time = 20000 - on_time;
+  for(int i = 0;i<25;i++){
+    digitalWrite(rotation_servo_pin,HIGH);
+    delay(on_time/1000);
+    delayMicroseconds(on_time%1000);
+    digitalWrite(rotation_servo_pin,LOW);
+    delay(off_time/1000);
+    delayMicroseconds(off_time%1000);
+  }
 }

 void _blink_() {


Referred the includes from library path

Referred the includes from library path

--- ESP8266/TouchSensor/TouchSensor.ino
+++ ESP8266/TouchSensor/TouchSensor.ino
@@ -1,16 +1,16 @@
 #include <ESP8266WiFi.h>
-#include "Transceiver.h"
+#include <Transceiver.h>

 //#define USE_UDP
 #define USE_MQTT
 //#define USE_HTTP

 #if defined(USE_UDP)
-#include "UdpTransceiver.h"
+#include <UdpTransceiver.h>
 #elif defined(USE_MQTT)
-#include "MqttTransceiver.h"
+#include <MqttTransceiver.h>
 #elif defined(USE_HTTP)
-#include "HttpTransceiver.h"
+#include <HttpTransceiver.h>
 #endif

 bool touched = false;


Ooopppsss missed a quote fixed :-)

Ooopppsss missed a quote fixed :-)

--- ThermoStatESP32.ino
+++ ThermoStatESP32.ino
@@ -25,7 +25,7 @@
 #include <Adafruit_GFX.h>    // Core graphics library
 #include <Adafruit_ILI9341.h>
 #include "fonts/VeraSe60pt7b.h"
-#include "fonts/VeraSe42pt7b.h
+#include "fonts/VeraSe42pt7b.h"
 #include "fonts/VeraSe18pt7b.h"
 #include "fonts/VeraSe10pt7b.h"
 #include <dragon.h>


Учет задержки от скорости порта при дебаге

--- RF3Sens/RF3Sens.ino
+++ RF3Sens/RF3Sens.ino
@@ -154,10 +154,10 @@
     SERIAL_OUT.write(0x0a);
     //SERIAL_OUT.write(0x0d);

-#if !defined(software_serial)
+#if SERIAL_SPEED > 115200
       delay(20);
 #else
-      delay(60);  //задержка больше из-за низкой скорости Digispark
+      delay(60);  //задержка больше из-за низкой скорости Serial
     #endif
   }
 //-------------------------------------------------------------------------------------------
@@ -185,10 +185,10 @@
       SERIAL_OUT.write(0x0a);
       //SERIAL_OUT.write(0x0d);

-#if !defined(software_serial)
+#if SERIAL_SPEED > 115200
       delay(20);
 #else
-      delay(60);  //задержка больше из-за низкой скорости Digispark
+      delay(60);  //задержка больше из-за низкой скорости Serial
 #endif
     }
   }


Let's really use this thing

Let's really use this thing

--- Arduino/weather-tree.ino
+++ Arduino/weather-tree.ino
@@ -2,17 +2,19 @@
 #include "PixelControl.h"

-Adafruit_NeoPixel neopixelRingLarge = Adafruit_NeoPixel(24, 4, WS2812);
+Adafruit_NeoPixel neopixelRingLarge = Adafruit_NeoPixel(24, 6, WS2812);
 PixelControl ringLarge = PixelControl();

 Adafruit_NeoPixel neopixelRingMedium = Adafruit_NeoPixel(16, 5, WS2812);
 PixelControl ringMedium = PixelControl();

-Adafruit_NeoPixel neopixelRingSmall = Adafruit_NeoPixel(12, 6, WS2812);
+Adafruit_NeoPixel neopixelRingSmall = Adafruit_NeoPixel(12, 4, WS2812);
 PixelControl ringSmall = PixelControl();

 // This is the pixel on the top...it will be controlled differently: TODO
 Adafruit_NeoPixel neopixelSingle = Adafruit_NeoPixel(1, 7, WS2812);
+
+int currentPercipitation = 0;

 void setup()
@@ -29,6 +31,13 @@
     neopixelSingle.begin();
     neopixelSingle.show();

+    // Default color
+    // ringSmall.ColorWipe(neopixelRingSmall, neopixelRingLarge.Color(0, 255, 0), 100);
+    // ringMedium.ColorWipe(neopixelRingMedium, neopixelRingMedium.Color(0, 255, 0), 100);
+    // ringLarge.ColorWipe(neopixelRingLarge, neopixelRingSmall.Color(0, 255, 0), 100);
+
+    int result = noPercipitation();
+
     randomSeed(analogRead(0));

     Spark.function("rain", rain);
@@ -39,35 +48,53 @@

 void loop()
 {
+    switch (currentPercipitation) {
+        case 1:
+            // Rain
+            ringSmall.AnimateRandom(neopixelRingSmall, neopixelRingLarge.Color(0, 0, 255), 100);
+            ringMedium.AnimateRandom(neopixelRingMedium, neopixelRingMedium.Color(0, 0, 255), 100);
+            ringLarge.AnimateRandom(neopixelRingLarge, neopixelRingSmall.Color(0, 0, 255), 100);
+            break;
+        case 2:
+            // Snow
+            ringSmall.AnimateRandom(neopixelRingSmall, neopixelRingLarge.Color(127, 127, 127), 100);
+            ringMedium.AnimateRandom(neopixelRingMedium, neopixelRingMedium.Color(127, 127, 127), 100);
+            ringLarge.AnimateRandom(neopixelRingLarge, neopixelRingSmall.Color(127, 127, 127), 100);
+            break;
+    }
+}

+
+int noPercipitation(String args)
+{
+    clear();
+    ringSmall.ColorWipe(neopixelRingSmall, neopixelRingLarge.Color(0, 255, 0), 100);
+    ringMedium.ColorWipe(neopixelRingMedium, neopixelRingMedium.Color(0, 255, 0), 100);
+    ringLarge.ColorWipe(neopixelRingLarge, neopixelRingSmall.Color(0, 255, 0), 100);
+    currentPercipitation = 0;
+    return 200;
 }

 int rain(String args)
 {
-    ringSmall.AnimateRandom(neopixelRingSmall, neopixelRingLarge.Color(0, 0, 255), 100);
-    ringMedium.AnimateRandom(neopixelRingMedium, neopixelRingMedium.Color(0, 0, 255), 100);
-    ringLarge.AnimateRandom(neopixelRingLarge, neopixelRingSmall.Color(0, 0, 255), 100);
-
+    clear();
+    currentPercipitation = 1;
     return 200;
 }

 int snow(String args)
 {
-    ringSmall.AnimateRandom(neopixelRingSmall, neopixelRingLarge.Color(127, 127, 127), 100);
-    ringMedium.AnimateRandom(neopixelRingMedium, neopixelRingMedium.Color(127, 127, 127), 100);
-    ringLarge.AnimateRandom(neopixelRingLarge, neopixelRingSmall.Color(127, 127, 127), 100);
-
+    clear();
+    currentPercipitation = 2;
     return 200;
 }

-int noPercipitation(String args)
+void clear()
 {
-    ringSmall.ColorWipe(neopixelRingSmall, neopixelRingLarge.Color(0, 255, 0), 100);
-    ringMedium.ColorWipe(neopixelRingMedium, neopixelRingMedium.Color(0, 255, 0), 100);
-    ringLarge.ColorWipe(neopixelRingLarge, neopixelRingSmall.Color(0, 255, 0), 100);
-
-    return 200;
+    ringSmall.ColorWipe(neopixelRingSmall, 0, 0);
+    ringMedium.ColorWipe(neopixelRingMedium, 0, 0);
+    ringLarge.ColorWipe(neopixelRingLarge, 0, 0);
 }


Config tool osd knob fix

Config tool osd knob fix

--- KISS_OSD_CONFIG/KISS_OSD_CONFIG.ino
+++ KISS_OSD_CONFIG/KISS_OSD_CONFIG.ino
@@ -333,6 +333,8 @@
 static uint16_t fcNotConnectedCount = 0;
 static uint8_t serialBuf[512];
 static bool activeOSDItems[] = { true, true, true, true, true, true, true, true, true, true, true };
+static uint8_t oldPrintCount = 0;
+static uint8_t printCount = 0;

 #ifdef DEBUG
 static int16_t versionProto = 0;
@@ -442,15 +444,16 @@
     vtx_flash_led(1);
 #endif

-    if (triggerCleanScreen ||
-        (abs((DV_PPMs[currentDVItem] + 1000) - (AuxChanVals[settings.m_DVchannel] + 1000)) >= CSettings::DV_PPM_INCREMENT
-         && (AuxChanVals[settings.m_DVchannel] + 1000) < (CSettings::DV_PPM_INCREMENT * (CSettings::DISPLAY_DV_SIZE))
-         && !moveItems))
-    {
-      currentDVItem = CSettings::DISPLAY_DV_SIZE - 1;
-      while (abs((DV_PPMs[currentDVItem] + 1000) - (AuxChanVals[settings.m_DVchannel] + 1000)) >= CSettings::DV_PPM_INCREMENT && currentDVItem > 0) currentDVItem--;
+    if(triggerCleanScreen)
+    {
       triggerCleanScreen = false;
       cleanScreen();
+    }
+
+    if(oldPrintCount != printCount)
+    {
+      cleanScreen();
+      oldPrintCount = printCount;
     }

     if (settings.m_tempUnit == 1)
@@ -804,10 +807,12 @@
       last_Aux_Val = AuxChanVals[settings.m_DVchannel];
     }

+    printCount = 0;
     uint8_t TMPmargin          = 0;
     uint8_t CurrentMargin      = 0;
     if (AuxChanVals[settings.m_DVchannel] > DV_PPMs[DISPLAY_RC_THROTTLE])
     {
+      printCount++;
       activeOSDItems[THROTTLE] = true;
       if (OSD_ITEM_BLINK[THROTTLE]) OSD.blink1sec();
       itemLengthOK[THROTTLE] = OSD.printInt16( settings.m_OSDItems[THROTTLE][0], settings.m_OSDItems[THROTTLE][1], throttle, 0, 1, "%", 2, THROTTLEp);
@@ -817,6 +822,7 @@

     if (AuxChanVals[settings.m_DVchannel] > DV_PPMs[DISPLAY_NICKNAME])
     {
+      printCount++;
       activeOSDItems[NICKNAME] = true;
       uint8_t nickBlanks = 0;
       itemLengthOK[NICKNAME] = OSD.checkPrintLength(settings.m_OSDItems[NICKNAME][0], settings.m_OSDItems[NICKNAME][1], (uint8_t)strlen(settings.m_nickname), nickBlanks, NICKNAMEp);
@@ -833,6 +839,7 @@

     if (AuxChanVals[settings.m_DVchannel] > DV_PPMs[DISPLAY_COMB_CURRENT])
     {
+      printCount++;
       activeOSDItems[AMPS] = true;
       if(settings.m_wattMeter == 0)
       {
@@ -880,6 +887,7 @@

     if (AuxChanVals[settings.m_DVchannel] > DV_PPMs[DISPLAY_LIPO_VOLTAGE])
     {
+      printCount++;
       activeOSDItems[VOLTAGE] = true;
       if (OSD_ITEM_BLINK[VOLTAGE]) OSD.blink1sec();
       itemLengthOK[VOLTAGE] = OSD.printInt16( settings.m_OSDItems[VOLTAGE][0], settings.m_OSDItems[VOLTAGE][1], LipoVoltage / 10, 1, 1, "v", 1, VOLTAGEp);
@@ -888,6 +896,7 @@

     if (AuxChanVals[settings.m_DVchannel] > DV_PPMs[DISPLAY_MA_CONSUMPTION])
     {
+      printCount++;
       activeOSDItems[MAH] = true;
       if (settings.m_displaySymbols == 1 && settings.m_IconSettings[MAH_ICON] == 1)
       {
@@ -937,6 +946,7 @@
     bool displayAnyESCData = false;
     if (AuxChanVals[settings.m_DVchannel] > DV_PPMs[DISPLAY_ESC_KRPM])
     {
+      printCount++;
       displayAnyESCData = true;
       static char KR[4];
       if (settings.m_displaySymbols == 1 && settings.m_IconSettings[PROPS_ICON] == 1)
@@ -1001,6 +1011,7 @@

     if (AuxChanVals[settings.m_DVchannel] > DV_PPMs[DISPLAY_ESC_CURRENT])
     {
+      printCount++;
       displayAnyESCData = true;
       static char ampESC[] = { 'a', 0x7E, 0x00};
       ampESC[1] = ESCSymbol[0];
@@ -1017,6 +1028,7 @@

     if (AuxChanVals[settings.m_DVchannel] > DV_PPMs[DISPLAY_ESC_TEMPERATURE])
     {
+      printCount++;
       displayAnyESCData = true;
       static char tempESC[] = { tempSymbol[0], 0x7E, 0x00};
       tempESC[0] = tempSymbol[0];
@@ -1035,6 +1047,7 @@

     if (AuxChanVals[settings.m_DVchannel] > DV_PPMs[DISPLAY_TIMER])
     {
+      printCount++;
       activeOSDItems[STOPW] = true;
       char stopWatchStr[] = { 0x00, 0x00 };
       if (settings.m_displaySymbols == 1 && settings.m_IconSettings[TIMER_ICON] == 1)
@@ -1061,6 +1074,7 @@

     if((settings.m_RSSIchannel > -1 && AuxChanVals[settings.m_DVchannel] > DV_PPMs[DISPLAY_RSSI]) || (moveItems && settings.m_DVchannel < 4))
     {
+      printCount++;
       activeOSDItems[RSSI_] = true;
       if (settings.m_displaySymbols == 1 && settings.m_IconSettings[RSSI_ICON] == 1)
       {


Add missing sendWhirlpoolAC() to IRMQTTServer.ino (#558)

Fixes #556

--- examples/IRMQTTServer/IRMQTTServer.ino
+++ examples/IRMQTTServer/IRMQTTServer.ino
@@ -731,6 +731,11 @@
       irsend.sendHitachiAC2(reinterpret_cast<uint8_t *>(state));
       break;
 #endif
+#if SEND_WHIRLPOOL_AC
+    case WHIRLPOOL_AC:
+      irsend.sendWhirlpoolAC(reinterpret_cast<uint8_t *>(state));
+      break;
+#endif
 #if SEND_SAMSUNG_AC
     case SAMSUNG_AC:
       irsend.sendSamsungAC(reinterpret_cast<uint8_t *>(state), stateSize);


Stop repeat key...

Stop repeat key...

--- main.ino
+++ main.ino
@@ -4,7 +4,7 @@
 IRrecv irrecv(RECV_PIN);
 decode_results results;
 uint8_t keys[21] = {0x5D, 0x9D, 0x1D, 0xDD, 0xFD, 0x3D, 0x1F, 0x57, 0x6F, 0x97, 0x67, 0x4F, 0xCF, 0xE7, 0x85, 0xEF, 0xC7, 0xA5, 0xBD, 0xB5, 0xAD};
-uint8_t to[21] = {0x1A, 0x14, 0x04, 0x1B, 0x16, 0x1D, 0x06, 0x07, 0x08, 0x19, 0x09, 0x15, 0x05, 0x0A, 0x17, 0x11, 0x0B, 0x1C, 0x36, 0x0D, 0x18};
+uint8_t to[21] = {0x45, 0x14, 0x04, 0x1B, 0x16, 0x1D, 0x06, 0x07, 0x08, 0x19, 0x09, 0x15, 0x05, 0x0A, 0x17, 0x11, 0x0B, 0x1C, 0x36, 0x0D, 0x18};

 void setup()
 {
@@ -17,16 +17,16 @@

 void loop() {
   if (irrecv.decode(&results)) {
-    if (results.value != 0xFFFFFFFF) {
+    int test = results.value & 0xFF000000;
+    if (test == 0) {
       buf[2] = getConvertedKey(results.value);
       Serial.write(buf, 8);
-    } else {
+      delay(20);
       buf[2] = 0;
       Serial.write(buf, 8);
     }
     irrecv.resume(); // Receive the next value
   }
-  delay(200);
 }

 uint8_t getConvertedKey(int val){


Renamed functions to be clearer

Renamed functions to be clearer

--- main.ino
+++ main.ino
@@ -75,16 +75,16 @@
 }
 int getSelectedDice()
 {
-  int dice = checkAndRoll(PINDTWENTY, 20);
-  dice = dice == SWITCH_DEFAULT ? checkAndRoll(PINDTWELVE, 12) : dice;
-  dice = dice == SWITCH_DEFAULT ? checkAndRoll(PINDTEN, 10) : dice;
-  dice = dice == SWITCH_DEFAULT ? checkAndRoll(PINDEIGHT, 8) : dice;
-  dice = dice == SWITCH_DEFAULT ? checkAndRoll(PINDSIX, 6) : dice;
-  dice = dice == SWITCH_DEFAULT ? checkAndRoll(PINDFOUR, 4) : dice;
+  int dice = checkDice(PINDTWENTY, 20);
+  dice = dice == SWITCH_DEFAULT ? checkDice(PINDTWELVE, 12) : dice;
+  dice = dice == SWITCH_DEFAULT ? checkDice(PINDTEN, 10) : dice;
+  dice = dice == SWITCH_DEFAULT ? checkDice(PINDEIGHT, 8) : dice;
+  dice = dice == SWITCH_DEFAULT ? checkDice(PINDSIX, 6) : dice;
+  dice = dice == SWITCH_DEFAULT ? checkDice(PINDFOUR, 4) : dice;

-  return current;
+  return dice;
 }
-int checkAndRoll(int pin, int range)
+int checkDice(int pin, int range)
 {
   int switchState = digitalRead(pin);
   if (switchState == HIGH)


Update helium-us915 Example with Correct Sub Band

--- examples/helium-us915/helium-us915.ino
+++ examples/helium-us915/helium-us915.ino
@@ -305,7 +305,7 @@

     LMIC_setLinkCheckMode(0);
     LMIC_setDrTxpow(DR_SF7,14);
-    LMIC_selectSubBand(6);
+    LMIC_selectSubBand(2);

     // Start job (sending automatically starts OTAA too)
     do_send(&sendjob);


Clean up color generation code

Clean up color generation code

--- Clock.ino
+++ Clock.ino
@@ -111,17 +111,21 @@
         return hourColor;
 }

+uint32_t createColor(float r, float g, float b)
+{
+    return strip.Color(r * brightness * 255, g * brightness * 255, b * brightness * 255);
+}
+
 void regenerateColors()
 {
-    zeroColor = strip.Color(BaseBrightness * 0.50 * brightness, BaseBrightness * 0.50 * brightness, BaseBrightness * 0.50 * brightness);
-    quarterDayColor = strip.Color(0.25 * BaseBrightness * brightness, HighlightBrightness * brightness, 0.25 * BaseBrightness * brightness);
-    hourColor = strip.Color(0, BaseBrightness * brightness, 0);
-    hourAnimationColor = strip.Color(0, HighlightBrightness * brightness, 0);
-    minuteColor = strip.Color(0, 0.625 * BaseBrightness * brightness, BaseBrightness * brightness);
-    minuteAnimationColor = strip.Color(0, 0.625 * HighlightBrightness * brightness, HighlightBrightness * brightness);
-    quarterHourColor = minuteAnimationColor;
-    fiveMinuteColor = strip.Color(0, 0.625 * BaseBrightness * brightness * 1.5, BaseBrightness * brightness * 1.5);
-    secondColor = strip.Color(BaseBrightness * brightness, 0, 0);
+    zeroColor = createColor(0.25, 0.25, 0.25);
+    quarterDayColor = createColor(0.125, 1, 0.125);
+    hourColor = createColor(0, 0.5, 0);
+    hourAnimationColor = createColor(0, 1, 0);
+    minuteColor = createColor(0, 0.3125, 0.5);
+    minuteAnimationColor = quarterHourColor = createColor(0, 0.625, 1);
+    fiveMinuteColor = createColor(0, 0.5, 0.75);
+    secondColor = createColor(0.5, 0, 0);
 }

 void setupLEDs()


small tweaks in format

small tweaks in format

--- Arduino/sketches/Sensor_Module/RawSensorData.ino
+++ Arduino/sketches/Sensor_Module/RawSensorData.ino
@@ -1,6 +1,6 @@
 // UNCOMMENT ONE OF THE FOUR OPTIONS BELOW

-//#define PRINTDATA // uncomment to display raw data over serial port in format [gX     gY     gZ      aX      aY      aZ]
+#define PRINTDATA // uncomment to display raw data over serial port in format [gX     gY     gZ      aX      aY      aZ]
 //#define PRINTANGLE // identical to PRINTDATA but gyro data is in delta degrees [gX     gY     gZ      aX      aY      aZ]
 //#define PRINTANGLESUM // uncomment to display simple intigration of gyro over X axis in degrees
 //#define SAMPLERATE // uncomment to display max sampling rate over serial port updates every 2 seconds with sampleing rate in Hz
@@ -59,8 +59,6 @@
    	#if defined(PRINTANGLE)
     	printAngleData(deltaGyroAngle);
     #endif
-
-    	delayMicroseconds(650); // emperical delay between readings

 	#endif
 	#if defined(PRINTDATA)


Version 4.1 - 14th December 2021

Version 4.1 - 14th December 2021

Adds a register function.

--- ulisp.ino
+++ ulisp.ino
@@ -1,5 +1,5 @@
-/* uLisp AVR Version 4.0b - www.ulisp.com
-   David Johnson-Davies - www.technoblogy.com - 31st August 2021
+/* uLisp AVR Version 4.1 - www.ulisp.com
+   David Johnson-Davies - www.technoblogy.com - 14th December 2021

    Licensed under the MIT license: https://opensource.org/licenses/MIT
 */
@@ -213,21 +213,29 @@
 LOGNOT, ASH, LOGBITP, EVAL, GLOBALS, LOCALS, MAKUNBOUND, BREAK, READ, PRIN1, PRINT, PRINC, TERPRI,
 READBYTE, READLINE, WRITEBYTE, WRITESTRING, WRITELINE, RESTARTI2C, GC, ROOM, SAVEIMAGE, LOADIMAGE, CLS,
 PINMODE, DIGITALREAD, DIGITALWRITE, ANALOGREAD, ANALOGREFERENCE, ANALOGREADRESOLUTION, ANALOGWRITE,
-DACREFERENCE, DELAY, MILLIS, SLEEP, NOTE, EDIT, PPRINT, PPRINTALL, FORMAT, REQUIRE, LISTLIBRARY, KEYWORDS,
-
+DACREFERENCE, DELAY, MILLIS, SLEEP, NOTE, REGISTER, EDIT, PPRINT, PPRINTALL, FORMAT, REQUIRE, LISTLIBRARY,
+KEYWORDS,
 K_LED_BUILTIN, K_HIGH, K_LOW,
 #if defined(CPU_ATmega328P)
-K_INPUT, K_INPUT_PULLUP, K_OUTPUT, K_DEFAULT, K_INTERNAL, K_EXTERNAL,
+K_INPUT, K_INPUT_PULLUP, K_OUTPUT, K_DEFAULT, K_INTERNAL, K_EXTERNAL, K_PORTB, K_DDRB, K_PINB, K_PORTC,
+K_DDRC, K_PINC, K_PORTD, K_DDRD, K_PIND,
 #elif defined(CPU_ATmega1284P)
-K_INPUT, K_INPUT_PULLUP, K_OUTPUT, K_DEFAULT, K_INTERNAL1V1, K_INTERNAL2V56, K_EXTERNAL,
+K_INPUT, K_INPUT_PULLUP, K_OUTPUT, K_DEFAULT, K_INTERNAL1V1, K_INTERNAL2V56, K_EXTERNAL, K_PORTA, K_DDRA,
+K_PINA, K_PORTB, K_DDRB, K_PINB, K_PORTC, K_DDRC, K_PINC, K_PORTD, K_DDRD, K_PIND,
 #elif defined(CPU_ATmega2560)
-K_INPUT, K_INPUT_PULLUP, K_OUTPUT, K_DEFAULT, K_INTERNAL1V1, K_INTERNAL2V56, K_EXTERNAL,
+K_INPUT, K_INPUT_PULLUP, K_OUTPUT, K_DEFAULT, K_INTERNAL1V1, K_INTERNAL2V56, K_EXTERNAL, K_PORTA, K_DDRA,
+K_PINA, K_PORTB, K_DDRB, K_PINB, K_PORTC, K_DDRC, K_PINC, K_PORTD, K_DDRD, K_PIND, K_PORTE, K_DDRE,
+K_PINE, K_PORTF, K_DDRF, K_PINF, K_PORTG, K_DDRG, K_PING, K_PORTJ, K_DDRJ, K_PINJ,
 #elif defined(CPU_ATmega4809)
 K_INPUT, K_INPUT_PULLUP, K_OUTPUT, K_DEFAULT, K_INTERNAL, K_VDD, K_INTERNAL0V55, K_INTERNAL1V1,
-K_INTERNAL1V5, K_INTERNAL2V5, K_INTERNAL4V3, K_EXTERNAL,
+K_INTERNAL1V5, K_INTERNAL2V5, K_INTERNAL4V3, K_EXTERNAL, K_PORTA_DIR, K_PORTA_OUT, K_PORTA_IN,
+K_PORTB_DIR, K_PORTB_OUT, K_PORTB_IN, K_PORTC_DIR, K_PORTC_OUT, K_PORTC_IN, K_PORTD_DIR, K_PORTD_OUT,
+K_PORTD_IN, K_PORTE_DIR, K_PORTE_OUT, K_PORTE_IN, K_PORTF_DIR, K_PORTF_OUT, K_PORTF_IN,
 #elif defined(CPU_AVR128DX48)
 K_INPUT, K_INPUT_PULLUP, K_OUTPUT, K_DEFAULT, K_VDD, K_INTERNAL1V024, K_INTERNAL2V048, K_INTERNAL4V096,
-K_INTERNAL2V5, K_EXTERNAL, K_ADC_DAC0, K_ADC_TEMPERATURE,
+K_INTERNAL2V5, K_EXTERNAL, K_ADC_DAC0, K_ADC_TEMPERATURE, K_PORTA_DIR, K_PORTA_OUT, K_PORTA_IN,
+K_PORTB_DIR, K_PORTB_OUT, K_PORTB_IN, K_PORTC_DIR, K_PORTC_OUT, K_PORTC_IN, K_PORTD_DIR, K_PORTD_OUT,
+K_PORTD_IN, K_PORTE_DIR, K_PORTE_OUT, K_PORTE_IN, K_PORTF_DIR, K_PORTF_OUT, K_PORTF_IN,
 #endif
 USERFUNCTIONS, ENDFUNCTIONS, SET_SIZE = INT_MAX };

@@ -310,9 +318,11 @@
 const char noargument[] PROGMEM = "missing argument";
 const char nostream[] PROGMEM = "missing stream argument";
 const char overflow[] PROGMEM = "arithmetic overflow";
+const char divisionbyzero[] PROGMEM = "division by zero";
 const char indexnegative[] PROGMEM = "index can't be negative";
 const char invalidarg[] PROGMEM = "invalid argument";
 const char invalidkey[] PROGMEM = "invalid keyword";
+const char illegalclause[] PROGMEM = "illegal clause";
 const char invalidpin[] PROGMEM = "invalid pin";
 const char oddargs[] PROGMEM = "odd number of arguments";
 const char indexrange[] PROGMEM = "index out of range";
@@ -1078,11 +1088,11 @@
 object *lispstring (char *s) {
   object *obj = newstring();
   object *tail = obj;
-  char ch = *s++;
-  while (ch) {
+  while(1) {
+    char ch = *s++;
+    if (ch == 0) break;
     if (ch == '\\') ch = *s++;
     buildstring(ch, &tail);
-    ch = *s++;
   }
   return obj;
 }
@@ -2292,7 +2302,7 @@
 }

 object *tf_if (object *args, object *env) {
-  if (args == NULL || cdr(args) == NULL) error2(IF, PSTR("missing argument(s)"));
+  if (args == NULL || cdr(args) == NULL) error2(IF, toofewargs);
   if (eval(first(args), env) != nil) return second(args);
   args = cddr(args);
   return (args != NULL) ? first(args) : nil;
@@ -2301,7 +2311,7 @@
 object *tf_cond (object *args, object *env) {
   while (args != NULL) {
     object *clause = first(args);
-    if (!consp(clause)) error(COND, PSTR("illegal clause"), clause);
+    if (!consp(clause)) error(COND, illegalclause, clause);
     object *test = eval(first(clause), env);
     object *forms = cdr(clause);
     if (test != nil) {
@@ -2329,7 +2339,7 @@
   args = cdr(args);
   while (args != NULL) {
     object *clause = first(args);
-    if (!consp(clause)) error(CASE, PSTR("illegal clause"), clause);
+    if (!consp(clause)) error(CASE, illegalclause, clause);
     object *key = car(clause);
     object *forms = cdr(clause);
     if (consp(key)) {
@@ -2502,7 +2512,7 @@
   (void) env;
   object *arg = first(args);
   if (listp(arg)) return number(listlength(LENGTH, arg));
-  if (!stringp(arg)) error(LENGTH, PSTR("argument is not a list or string"), arg);
+  if (!stringp(arg)) error(LENGTH, invalidarg, arg);
   return number(stringlength(arg));
 }

@@ -2731,7 +2741,7 @@
   args = cdr(args);
   while (args != NULL) {
     int arg = checkinteger(DIVIDE, car(args));
-    if (arg == 0) error2(DIVIDE, PSTR("division by zero"));
+    if (arg == 0) error2(DIVIDE, divisionbyzero);
     #if defined(checkoverflow)
     if ((result == INT_MIN) && (arg == -1)) error2(DIVIDE, overflow);
     #endif
@@ -2745,7 +2755,7 @@
   (void) env;
   int arg1 = checkinteger(MOD, first(args));
   int arg2 = checkinteger(MOD, second(args));
-  if (arg2 == 0) error2(MOD, PSTR("division by zero"));
+  if (arg2 == 0) error2(MOD, divisionbyzero);
   int r = arg1 % arg2;
   if ((arg1<0) != (arg2<0)) r = r + arg2;
   return number(r);
@@ -3409,6 +3419,17 @@
     playnote(pin, note, octave);
   } else nonote(pin);
   return nil;
+}
+
+object *fn_register (object *args, object *env) {
+  (void) env;
+  object *arg = first(args);
+  int addr;
+  if (keywordp(arg)) addr = checkkeyword(REGISTER, arg);
+  else addr = checkinteger(REGISTER, first(args));
+  if (cdr(args) == NULL) return number(*(volatile uint8_t *)addr);
+  (*(volatile uint8_t *)addr) = checkinteger(REGISTER, second(args));
+  return second(args);
 }

 // Tree Editor
@@ -3768,70 +3789,152 @@
 const char string160[] PROGMEM = "millis";
 const char string161[] PROGMEM = "sleep";
 const char string162[] PROGMEM = "note";
-const char string163[] PROGMEM = "edit";
-const char string164[] PROGMEM = "pprint";
-const char string165[] PROGMEM = "pprintall";
-const char string166[] PROGMEM = "format";
-const char string167[] PROGMEM = "require";
-const char string168[] PROGMEM = "list-library";
-const char string169[] PROGMEM = "";
-const char string170[] PROGMEM = ":led-builtin";
-const char string171[] PROGMEM = ":high";
-const char string172[] PROGMEM = ":low";
+const char string163[] PROGMEM = "register";
+const char string164[] PROGMEM = "edit";
+const char string165[] PROGMEM = "pprint";
+const char string166[] PROGMEM = "pprintall";
+const char string167[] PROGMEM = "format";
+const char string168[] PROGMEM = "require";
+const char string169[] PROGMEM = "list-library";
+const char string170[] PROGMEM = "";
+const char string171[] PROGMEM = ":led-builtin";
+const char string172[] PROGMEM = ":high";
+const char string173[] PROGMEM = ":low";
 #if defined(CPU_ATmega328P)
-const char string173[] PROGMEM = ":input";
-const char string174[] PROGMEM = ":input-pullup";
-const char string175[] PROGMEM = ":output";
-const char string176[] PROGMEM = ":default";
-const char string177[] PROGMEM = ":internal";
-const char string178[] PROGMEM = ":external";
-const char string179[] PROGMEM = "";
+const char string174[] PROGMEM = ":input";
+const char string175[] PROGMEM = ":input-pullup";
+const char string176[] PROGMEM = ":output";
+const char string177[] PROGMEM = ":default";
+const char string178[] PROGMEM = ":internal";
+const char string179[] PROGMEM = ":external";
+const char string180[] PROGMEM = ":portb";
+const char string181[] PROGMEM = ":ddrb";
+const char string182[] PROGMEM = ":pinb";
+const char string183[] PROGMEM = ":portc";
+const char string184[] PROGMEM = ":ddrc";
+const char string185[] PROGMEM = ":pinc";
+const char string186[] PROGMEM = ":portd";
+const char string187[] PROGMEM = ":ddrd";
+const char string188[] PROGMEM = ":pind";
+const char string189[] PROGMEM = "";
 #elif defined(CPU_ATmega1284P)
-const char string173[] PROGMEM = ":input";
-const char string174[] PROGMEM = ":input-pullup";
-const char string175[] PROGMEM = ":output";
-const char string176[] PROGMEM = ":default";
-const char string177[] PROGMEM = ":internal1v1";
-const char string178[] PROGMEM = ":internal2v56";
-const char string179[] PROGMEM = ":external";
-const char string180[] PROGMEM = "";
+const char string174[] PROGMEM = ":input";
+const char string175[] PROGMEM = ":input-pullup";
+const char string176[] PROGMEM = ":output";
+const char string177[] PROGMEM = ":default";
+const char string178[] PROGMEM = ":internal1v1";
+const char string179[] PROGMEM = ":internal2v56";
+const char string180[] PROGMEM = ":external";
+const char string181[] PROGMEM = ":porta";
+const char string182[] PROGMEM = ":ddra";
+const char string183[] PROGMEM = ":pina";
+const char string184[] PROGMEM = ":portb";
+const char string185[] PROGMEM = ":ddrb";
+const char string186[] PROGMEM = ":pinb";
+const char string187[] PROGMEM = ":portc";
+const char string188[] PROGMEM = ":ddrc";
+const char string189[] PROGMEM = ":pinc";
+const char string190[] PROGMEM = ":portd";
+const char string191[] PROGMEM = ":ddrd";
+const char string192[] PROGMEM = ":pind";
+const char string193[] PROGMEM = "";
 #elif defined(CPU_ATmega2560)
-const char string173[] PROGMEM = ":input";
-const char string174[] PROGMEM = ":input-pullup";
-const char string175[] PROGMEM = ":output";
-const char string176[] PROGMEM = ":default";
-const char string177[] PROGMEM = ":internal1v1";
-const char string178[] PROGMEM = ":internal2v56";
-const char string179[] PROGMEM = ":external";
-const char string180[] PROGMEM = "";
+const char string174[] PROGMEM = ":input";
+const char string175[] PROGMEM = ":input-pullup";
+const char string176[] PROGMEM = ":output";
+const char string177[] PROGMEM = ":default";
+const char string178[] PROGMEM = ":internal1v1";
+const char string179[] PROGMEM = ":internal2v56";
+const char string180[] PROGMEM = ":external";
+const char string181[] PROGMEM = ":porta";
+const char string182[] PROGMEM = ":ddra";
+const char string183[] PROGMEM = ":pina";
+const char string184[] PROGMEM = ":portb";
+const char string185[] PROGMEM = ":ddrb";
+const char string186[] PROGMEM = ":pinb";
+const char string187[] PROGMEM = ":portc";
+const char string188[] PROGMEM = ":ddrc";
+const char string189[] PROGMEM = ":pinc";
+const char string190[] PROGMEM = ":portd";
+const char string191[] PROGMEM = ":ddrd";
+const char string192[] PROGMEM = ":pind";
+const char string193[] PROGMEM = ":porte";
+const char string194[] PROGMEM = ":ddre";
+const char string195[] PROGMEM = ":pine";
+const char string196[] PROGMEM = ":portf";
+const char string197[] PROGMEM = ":ddrf";
+const char string198[] PROGMEM = ":pinf";
+const char string199[] PROGMEM = ":portg";
+const char string200[] PROGMEM = ":ddrg";
+const char string201[] PROGMEM = ":ping";
+const char string202[] PROGMEM = ":portj";
+const char string203[] PROGMEM = ":ddrj";
+const char string204[] PROGMEM = ":pinj";
+const char string205[] PROGMEM = "";
 #elif defined(CPU_ATmega4809)
-const char string173[] PROGMEM = ":input";
-const char string174[] PROGMEM = ":input-pullup";
-const char string175[] PROGMEM = ":output";
-const char string176[] PROGMEM = ":default";
-const char string177[] PROGMEM = ":internal";
+const char string174[] PROGMEM = ":input";
+const char string175[] PROGMEM = ":input-pullup";
+const char string176[] PROGMEM = ":output";
+const char string177[] PROGMEM = ":default";
+const char string178[] PROGMEM = ":internal";
+const char string179[] PROGMEM = ":vdd";
+const char string180[] PROGMEM = ":internal0v55";
+const char string181[] PROGMEM = ":internal1v1";
+const char string182[] PROGMEM = ":internal1v5";
+const char string183[] PROGMEM = ":internal2v5";
+const char string184[] PROGMEM = ":internal4v3";
+const char string185[] PROGMEM = ":external";
+const char string186[] PROGMEM = ":porta-dir";
+const char string187[] PROGMEM = ":porta-out";
+const char string188[] PROGMEM = ":porta-in";
+const char string189[] PROGMEM = ":portb-dir";
+const char string190[] PROGMEM = ":portb-out";
+const char string191[] PROGMEM = ":portb-in";
+const char string192[] PROGMEM = ":portc-dir";
+const char string193[] PROGMEM = ":portc-out";
+const char string194[] PROGMEM = ":portc-in";
+const char string195[] PROGMEM = ":portd-dir";
+const char string196[] PROGMEM = ":portd-out";
+const char string197[] PROGMEM = ":portd-in";
+const char string198[] PROGMEM = ":porte-dir";
+const char string199[] PROGMEM = ":porte-out";
+const char string200[] PROGMEM = ":porte-in";
+const char string201[] PROGMEM = ":portf-dir";
+const char string202[] PROGMEM = ":portf-out";
+const char string203[] PROGMEM = ":portf-in";
+const char string204[] PROGMEM = "";
+#elif defined(CPU_AVR128DX48)
+const char string174[] PROGMEM = ":input";
+const char string175[] PROGMEM = ":input-pullup";
+const char string176[] PROGMEM = ":output";
+const char string177[] PROGMEM = ":default";
 const char string178[] PROGMEM = ":vdd";
-const char string179[] PROGMEM = ":internal0v55";
-const char string180[] PROGMEM = ":internal1v1";
-const char string181[] PROGMEM = ":internal1v5";
+const char string179[] PROGMEM = ":internal1v024";
+const char string180[] PROGMEM = ":internal2v048";
+const char string181[] PROGMEM = ":internal4v096";
 const char string182[] PROGMEM = ":internal2v5";
-const char string183[] PROGMEM = ":internal4v3";
-const char string184[] PROGMEM = ":external";
-const char string185[] PROGMEM = "";
-#elif defined(CPU_AVR128DX48)
-const char string173[] PROGMEM = ":input";
-const char string174[] PROGMEM = ":input-pullup";
-const char string175[] PROGMEM = ":output";
-const char string176[] PROGMEM = ":default";
-const char string177[] PROGMEM = ":vdd";
-const char string178[] PROGMEM = ":internal1v024";
-const char string179[] PROGMEM = ":internal2v048";
-const char string180[] PROGMEM = ":internal4v096";
-const char string181[] PROGMEM = ":internal2v5";
-const char string182[] PROGMEM = ":external";
-const char string183[] PROGMEM = ":adc-dac0";
-const char string184[] PROGMEM = ":adc-temperature";
-const char string185[] PROGMEM = "";
+const char string183[] PROGMEM = ":external";
+const char string184[] PROGMEM = ":adc-dac0";
+const char string185[] PROGMEM = ":adc-temperature";
+const char string186[] PROGMEM = ":porta-dir";
+const char string187[] PROGMEM = ":porta-out";
+const char string188[] PROGMEM = ":porta-in";
+const char string189[] PROGMEM = ":portb-dir";
+const char string190[] PROGMEM = ":portb-out";
+const char string191[] PROGMEM = ":portb-in";
+const char string192[] PROGMEM = ":portc-dir";
+const char string193[] PROGMEM = ":portc-out";
+const char string194[] PROGMEM = ":portc-in";
+const char string195[] PROGMEM = ":portd-dir";
+const char string196[] PROGMEM = ":portd-out";
+const char string197[] PROGMEM = ":portd-in";
+const char string198[] PROGMEM = ":porte-dir";
+const char string199[] PROGMEM = ":porte-out";
+const char string200[] PROGMEM = ":porte-in";
+const char string201[] PROGMEM = ":portf-dir";
+const char string202[] PROGMEM = ":portf-out";
+const char string203[] PROGMEM = ":portf-in";
+const char string204[] PROGMEM = "";
 #endif

 // Insert your own function names here
@@ -4001,70 +4104,152 @@
   { string160, fn_millis, 0x00 },
   { string161, fn_sleep, 0x11 },
   { string162, fn_note, 0x03 },
-  { string163, fn_edit, 0x11 },
-  { string164, fn_pprint, 0x12 },
-  { string165, fn_pprintall, 0x01 },
-  { string166, fn_format, 0x2F },
-  { string167, fn_require, 0x11 },
-  { string168, fn_listlibrary, 0x00 },
-  { string169, NULL, 0x00 },
-  { string170, (fn_ptr_type)LED_BUILTIN, 0 },
-  { string171, (fn_ptr_type)HIGH, DIGITALWRITE },
-  { string172, (fn_ptr_type)LOW, DIGITALWRITE },
+  { string163, fn_register, 0x12 },
+  { string164, fn_edit, 0x11 },
+  { string165, fn_pprint, 0x12 },
+  { string166, fn_pprintall, 0x01 },
+  { string167, fn_format, 0x2F },
+  { string168, fn_require, 0x11 },
+  { string169, fn_listlibrary, 0x00 },
+  { string170, NULL, 0x00 },
+  { string171, (fn_ptr_type)LED_BUILTIN, 0 },
+  { string172, (fn_ptr_type)HIGH, DIGITALWRITE },
+  { string173, (fn_ptr_type)LOW, DIGITALWRITE },
 #if defined(CPU_ATmega328P)
-  { string173, (fn_ptr_type)INPUT, PINMODE },
-  { string174, (fn_ptr_type)INPUT_PULLUP, PINMODE },
-  { string175, (fn_ptr_type)OUTPUT, PINMODE },
-  { string176, (fn_ptr_type)DEFAULT, ANALOGREFERENCE },
-  { string177, (fn_ptr_type)INTERNAL, ANALOGREFERENCE },
-  { string178, (fn_ptr_type)EXTERNAL, ANALOGREFERENCE },
-  { string179, NULL, 0x00 },
+  { string174, (fn_ptr_type)INPUT, PINMODE },
+  { string175, (fn_ptr_type)INPUT_PULLUP, PINMODE },
+  { string176, (fn_ptr_type)OUTPUT, PINMODE },
+  { string177, (fn_ptr_type)DEFAULT, ANALOGREFERENCE },
+  { string178, (fn_ptr_type)INTERNAL, ANALOGREFERENCE },
+  { string179, (fn_ptr_type)EXTERNAL, ANALOGREFERENCE },
+  { string180, (fn_ptr_type)&PORTB, REGISTER },
+  { string181, (fn_ptr_type)&DDRB, REGISTER },
+  { string182, (fn_ptr_type)&PINB, REGISTER },
+  { string183, (fn_ptr_type)&PORTC, REGISTER },
+  { string184, (fn_ptr_type)&DDRC, REGISTER },
+  { string185, (fn_ptr_type)&PINC, REGISTER },
+  { string186, (fn_ptr_type)&PORTD, REGISTER },
+  { string187, (fn_ptr_type)&DDRD, REGISTER },
+  { string188, (fn_ptr_type)&PIND, REGISTER },
+  { string189, NULL, 0x00 },
 #elif defined(CPU_ATmega1284P)
-  { string173, (fn_ptr_type)INPUT, PINMODE },
-  { string174, (fn_ptr_type)INPUT_PULLUP, PINMODE },
-  { string175, (fn_ptr_type)OUTPUT, PINMODE },
-  { string176, (fn_ptr_type)DEFAULT, ANALOGREFERENCE },
-  { string177, (fn_ptr_type)INTERNAL1V1, ANALOGREFERENCE },
-  { string178, (fn_ptr_type)INTERNAL2V56, ANALOGREFERENCE },
-  { string179, (fn_ptr_type)EXTERNAL, ANALOGREFERENCE },
-  { string180, NULL, 0x00 },
+  { string174, (fn_ptr_type)INPUT, PINMODE },
+  { string175, (fn_ptr_type)INPUT_PULLUP, PINMODE },
+  { string176, (fn_ptr_type)OUTPUT, PINMODE },
+  { string177, (fn_ptr_type)DEFAULT, ANALOGREFERENCE },
+  { string178, (fn_ptr_type)INTERNAL1V1, ANALOGREFERENCE },
+  { string179, (fn_ptr_type)INTERNAL2V56, ANALOGREFERENCE },
+  { string180, (fn_ptr_type)EXTERNAL, ANALOGREFERENCE },
+  { string181, (fn_ptr_type)&PORTA, REGISTER },
+  { string182, (fn_ptr_type)&DDRA, REGISTER },
+  { string183, (fn_ptr_type)&PINA, REGISTER },
+  { string184, (fn_ptr_type)&PORTB, REGISTER },
+  { string185, (fn_ptr_type)&DDRB, REGISTER },
+  { string186, (fn_ptr_type)&PINB, REGISTER },
+  { string187, (fn_ptr_type)&PORTC, REGISTER },
+  { string188, (fn_ptr_type)&DDRC, REGISTER },
+  { string189, (fn_ptr_type)&PINC, REGISTER },
+  { string190, (fn_ptr_type)&PORTD, REGISTER },
+  { string191, (fn_ptr_type)&DDRD, REGISTER },
+  { string192, (fn_ptr_type)&PIND, REGISTER },
+  { string193, NULL, 0x00 },
 #elif defined(CPU_ATmega2560)
-  { string173, (fn_ptr_type)INPUT, PINMODE },
-  { string174, (fn_ptr_type)INPUT_PULLUP, PINMODE },
-  { string175, (fn_ptr_type)OUTPUT, PINMODE },
-  { string176, (fn_ptr_type)DEFAULT, ANALOGREFERENCE },
-  { string177, (fn_ptr_type)INTERNAL1V1, ANALOGREFERENCE },
-  { string178, (fn_ptr_type)INTERNAL2V56, ANALOGREFERENCE },
-  { string179, (fn_ptr_type)EXTERNAL, ANALOGREFERENCE },
-  { string180, NULL, 0x00 },
+  { string174, (fn_ptr_type)INPUT, PINMODE },
+  { string175, (fn_ptr_type)INPUT_PULLUP, PINMODE },
+  { string176, (fn_ptr_type)OUTPUT, PINMODE },
+  { string177, (fn_ptr_type)DEFAULT, ANALOGREFERENCE },
+  { string178, (fn_ptr_type)INTERNAL1V1, ANALOGREFERENCE },
+  { string179, (fn_ptr_type)INTERNAL2V56, ANALOGREFERENCE },
+  { string180, (fn_ptr_type)EXTERNAL, ANALOGREFERENCE },
+  { string181, (fn_ptr_type)&PORTA, REGISTER },
+  { string182, (fn_ptr_type)&DDRA, REGISTER },
+  { string183, (fn_ptr_type)&PINA, REGISTER },
+  { string184, (fn_ptr_type)&PORTB, REGISTER },
+  { string185, (fn_ptr_type)&DDRB, REGISTER },
+  { string186, (fn_ptr_type)&PINB, REGISTER },
+  { string187, (fn_ptr_type)&PORTC, REGISTER },
+  { string188, (fn_ptr_type)&DDRC, REGISTER },
+  { string189, (fn_ptr_type)&PINC, REGISTER },
+  { string190, (fn_ptr_type)&PORTD, REGISTER },
+  { string191, (fn_ptr_type)&DDRD, REGISTER },
+  { string192, (fn_ptr_type)&PIND, REGISTER },
+  { string193, (fn_ptr_type)&PORTE, REGISTER },
+  { string194, (fn_ptr_type)&DDRE, REGISTER },
+  { string195, (fn_ptr_type)&PINE, REGISTER },
+  { string196, (fn_ptr_type)&PORTF, REGISTER },
+  { string197, (fn_ptr_type)&DDRF, REGISTER },
+  { string198, (fn_ptr_type)&PINF, REGISTER },
+  { string199, (fn_ptr_type)&PORTG, REGISTER },
+  { string200, (fn_ptr_type)&DDRG, REGISTER },
+  { string201, (fn_ptr_type)&PING, REGISTER },
+  { string202, (fn_ptr_type)&PORTJ, REGISTER },
+  { string203, (fn_ptr_type)&DDRJ, REGISTER },
+  { string204, (fn_ptr_type)&PINJ, REGISTER },
+  { string205, NULL, 0x00 },
 #elif defined(CPU_ATmega4809)
-  { string173, (fn_ptr_type)INPUT, PINMODE },
-  { string174, (fn_ptr_type)INPUT_PULLUP, PINMODE },
-  { string175, (fn_ptr_type)OUTPUT, PINMODE },
-  { string176, (fn_ptr_type)DEFAULT, ANALOGREFERENCE },
-  { string177, (fn_ptr_type)INTERNAL, ANALOGREFERENCE },
+  { string174, (fn_ptr_type)INPUT, PINMODE },
+  { string175, (fn_ptr_type)INPUT_PULLUP, PINMODE },
+  { string176, (fn_ptr_type)OUTPUT, PINMODE },
+  { string177, (fn_ptr_type)DEFAULT, ANALOGREFERENCE },
+  { string178, (fn_ptr_type)INTERNAL, ANALOGREFERENCE },
+  { string179, (fn_ptr_type)VDD, ANALOGREFERENCE },
+  { string180, (fn_ptr_type)INTERNAL0V55, ANALOGREFERENCE },
+  { string181, (fn_ptr_type)INTERNAL1V1, ANALOGREFERENCE },
+  { string182, (fn_ptr_type)INTERNAL1V5, ANALOGREFERENCE },
+  { string183, (fn_ptr_type)INTERNAL2V5, ANALOGREFERENCE },
+  { string184, (fn_ptr_type)INTERNAL4V3, ANALOGREFERENCE },
+  { string185, (fn_ptr_type)EXTERNAL, ANALOGREFERENCE },
+  { string186, (fn_ptr_type)&PORTA_DIR, REGISTER },
+  { string187, (fn_ptr_type)&PORTA_OUT, REGISTER },
+  { string188, (fn_ptr_type)&PORTA_IN, REGISTER },
+  { string189, (fn_ptr_type)&PORTB_DIR, REGISTER },
+  { string190, (fn_ptr_type)&PORTB_OUT, REGISTER },
+  { string191, (fn_ptr_type)&PORTB_IN, REGISTER },
+  { string192, (fn_ptr_type)&PORTC_DIR, REGISTER },
+  { string193, (fn_ptr_type)&PORTC_OUT, REGISTER },
+  { string194, (fn_ptr_type)&PORTC_IN, REGISTER },
+  { string195, (fn_ptr_type)&PORTD_DIR, REGISTER },
+  { string196, (fn_ptr_type)&PORTD_OUT, REGISTER },
+  { string197, (fn_ptr_type)&PORTD_IN, REGISTER },
+  { string198, (fn_ptr_type)&PORTE_DIR, REGISTER },
+  { string199, (fn_ptr_type)&PORTE_OUT, REGISTER },
+  { string200, (fn_ptr_type)&PORTE_IN, REGISTER },
+  { string201, (fn_ptr_type)&PORTF_DIR, REGISTER },
+  { string202, (fn_ptr_type)&PORTF_OUT, REGISTER },
+  { string203, (fn_ptr_type)&PORTF_IN, REGISTER },
+  { string204, NULL, 0x00 },
+#elif defined(CPU_AVR128DX48)
+  { string174, (fn_ptr_type)INPUT, PINMODE },
+  { string175, (fn_ptr_type)INPUT_PULLUP, PINMODE },
+  { string176, (fn_ptr_type)OUTPUT, PINMODE },
+  { string177, (fn_ptr_type)DEFAULT, ANALOGREFERENCE },
   { string178, (fn_ptr_type)VDD, ANALOGREFERENCE },
-  { string179, (fn_ptr_type)INTERNAL0V55, ANALOGREFERENCE },
-  { string180, (fn_ptr_type)INTERNAL1V1, ANALOGREFERENCE },
-  { string181, (fn_ptr_type)INTERNAL1V5, ANALOGREFERENCE },
+  { string179, (fn_ptr_type)INTERNAL1V024, ANALOGREFERENCE },
+  { string180, (fn_ptr_type)INTERNAL2V048, ANALOGREFERENCE },
+  { string181, (fn_ptr_type)INTERNAL4V096, ANALOGREFERENCE },
   { string182, (fn_ptr_type)INTERNAL2V5, ANALOGREFERENCE },
-  { string183, (fn_ptr_type)INTERNAL4V3, ANALOGREFERENCE },
-  { string184, (fn_ptr_type)EXTERNAL, ANALOGREFERENCE },
-  { string185, NULL, 0x00 },
-#elif defined(CPU_AVR128DX48)
-  { string173, (fn_ptr_type)INPUT, PINMODE },
-  { string174, (fn_ptr_type)INPUT_PULLUP, PINMODE },
-  { string175, (fn_ptr_type)OUTPUT, PINMODE },
-  { string176, (fn_ptr_type)DEFAULT, ANALOGREFERENCE },
-  { string177, (fn_ptr_type)VDD, ANALOGREFERENCE },
-  { string178, (fn_ptr_type)INTERNAL1V024, ANALOGREFERENCE },
-  { string179, (fn_ptr_type)INTERNAL2V048, ANALOGREFERENCE },
-  { string180, (fn_ptr_type)INTERNAL4V096, ANALOGREFERENCE },
-  { string181, (fn_ptr_type)INTERNAL2V5, ANALOGREFERENCE },
-  { string182, (fn_ptr_type)EXTERNAL, ANALOGREFERENCE },
-  { string183, (fn_ptr_type)ADC_DAC0, ANALOGREAD },
-  { string184, (fn_ptr_type)ADC_TEMPERATURE, ANALOGREAD },
-  { string185, NULL, 0x00 },
+  { string183, (fn_ptr_type)EXTERNAL, ANALOGREFERENCE },
+  { string184, (fn_ptr_type)ADC_DAC0, ANALOGREAD },
+  { string185, (fn_ptr_type)ADC_TEMPERATURE, ANALOGREAD },
+  { string186, (fn_ptr_type)&PORTA_DIR, REGISTER },
+  { string187, (fn_ptr_type)&PORTA_OUT, REGISTER },
+  { string188, (fn_ptr_type)&PORTA_IN, REGISTER },
+  { string189, (fn_ptr_type)&PORTB_DIR, REGISTER },
+  { string190, (fn_ptr_type)&PORTB_OUT, REGISTER },
+  { string191, (fn_ptr_type)&PORTB_IN, REGISTER },
+  { string192, (fn_ptr_type)&PORTC_DIR, REGISTER },
+  { string193, (fn_ptr_type)&PORTC_OUT, REGISTER },
+  { string194, (fn_ptr_type)&PORTC_IN, REGISTER },
+  { string195, (fn_ptr_type)&PORTD_DIR, REGISTER },
+  { string196, (fn_ptr_type)&PORTD_OUT, REGISTER },
+  { string197, (fn_ptr_type)&PORTD_IN, REGISTER },
+  { string198, (fn_ptr_type)&PORTE_DIR, REGISTER },
+  { string199, (fn_ptr_type)&PORTE_OUT, REGISTER },
+  { string200, (fn_ptr_type)&PORTE_IN, REGISTER },
+  { string201, (fn_ptr_type)&PORTF_DIR, REGISTER },
+  { string202, (fn_ptr_type)&PORTF_OUT, REGISTER },
+  { string203, (fn_ptr_type)&PORTF_IN, REGISTER },
+  { string204, NULL, 0x00 },
 #endif

 // Insert your own table entries here
@@ -4762,7 +4947,7 @@
   initworkspace();
   initenv();
   initsleep();
-  pfstring(PSTR("uLisp 4.0 "), pserial); pln(pserial);
+  pfstring(PSTR("uLisp 4.1 "), pserial); pln(pserial);
 }

 // Read/Evaluate/Print loop


BUG: Default bit length not being set for RCMM in IRMQTTServer example. (#456)

--- examples/IRMQTTServer/IRMQTTServer.ino
+++ examples/IRMQTTServer/IRMQTTServer.ino
@@ -1111,7 +1111,7 @@
 #if SEND_RCMM
     case RCMM:  // 21
       if (bits == 0)
-        bits == RCMM_BITS;
+        bits = RCMM_BITS;
       irsend.sendRCMM(code, bits, repeat);
       break;
 #endif


Reformat and update to use new autoprobe and print functions

--- examples/RTCx_example/RTCx_example.ino
+++ examples/RTCx_example/RTCx_example.ino
@@ -32,75 +32,45 @@
 #include <Wire.h>
 #include <RTCx.h>

-void printTm(Stream &str, struct RTCx::tm *tm)
-{
-  str.print(tm->tm_year + 1900);
-  str.print('-');
-  str.print(tm->tm_mon + 1);
-  str.print('-');
-  str.print(tm->tm_mday);
-  str.print('T');
-  str.print(tm->tm_hour);
-  str.print(':');
-  str.print(tm->tm_min);
-  str.print(':');
-  str.print(tm->tm_sec);
-  str.print(" yday=");
-  str.print(tm->tm_yday);
-  str.print(" wday=");
-  str.println(tm->tm_wday);
-}
-
 void setup(void)
 {
-  Serial.begin(9600);
-  Wire.begin();
-  // The address used by the DS1307 is also used by other devices (eg
-  // MCP3424 ADC). Test for a MCP7941x device first.
-  uint8_t addressList[] = {RTCx::MCP7941xAddress,
-			   RTCx::DS1307Address};
+	if (F_CPU > 8000000UL)
+		Serial.begin(115200);
+	else
+		Serial.begin(9600);
+	Wire.begin();

-  // Autoprobe to find a real-time clock.
-  if (rtc.autoprobe(addressList, sizeof(addressList))) {
-    // Found something, hopefully a clock.
-    Serial.print("Autoprobe found ");
-    switch (rtc.getDevice()) {
-      case RTCx::DS1307:
-	Serial.print("DS1307");
-	break;
-    case RTCx::MCP7941x:
-      Serial.print("MCP7941x");
-      break;
-    default:
-      // Ooops. Must update this example!
-      Serial.print("unknown device");
-      break;
-    }
-    Serial.print(" at 0x");
-    Serial.println(rtc.getAddress(), HEX);
-  }
-  else {
-    // Nothing found at any of the addresses listed.
-    Serial.println("No RTCx found");
-    return;
-  }
+	// Autoprobe to find a real-time clock.
+	if (rtc.autoprobe()) {
+		// Found something, hopefully a clock.
+		Serial.print("Autoprobe found ");
+		Serial.print(rtc.getDeviceName());
+		Serial.print(" at 0x");
+		Serial.println(rtc.getAddress(), HEX);
+	}
+	else {
+		// Nothing found at any of the addresses listed.
+		Serial.println("No RTCx found, cannot continue");
+		while (1)
+			;
+	}

-  // Enable the battery backup. This happens by default on the DS1307
-  // but needs to be enabled on the MCP7941x.
-  rtc.enableBatteryBackup();
+	// Enable the battery backup. This happens by default on the DS1307
+	// but needs to be enabled on the MCP7941x.
+	rtc.enableBatteryBackup();

-  // rtc.clearVBAT();
-
-  // Ensure the oscillator is running.
-  rtc.startClock();
+	// rtc.clearVBAT();

-  if (rtc.getDevice() == RTCx::MCP7941x) {
-    Serial.print("Calibration: ");
-    Serial.println(rtc.getCalibration(), DEC);
-    // rtc.setCalibration(-127);
-  }
+	// Ensure the oscillator is running.
+	rtc.startClock();

-  rtc.setSQW(RTCx::freq4096Hz);
+	if (rtc.getDevice() == RTCx::MCP7941x) {
+		Serial.print("Calibration: ");
+		Serial.println(rtc.getCalibration(), DEC);
+		// rtc.setCalibration(-127);
+	}
+
+	rtc.setSQW(RTCx::freq4096Hz);
 }

@@ -110,86 +80,86 @@
 unsigned long last = 0;
 void loop(void)
 {
-  struct RTCx::tm tm;
-  if (millis() - last > 2000) {
-    last = millis();
-    rtc.readClock(tm);
-
-    printTm(Serial, &tm);
-    RTCx::time_t t = RTCx::mktime(&tm);
-    printTm(Serial, &tm);
-    Serial.print("unixtime = ");
-    Serial.println(t);
-    Serial.println("-----");
-  }
+	struct RTCx::tm tm;
+	if (millis() - last > 2000) {
+		last = millis();
+		rtc.readClock(tm);

-  while (Serial.available()) {
-    char c = Serial.read();
-    if ((c == '\r' || c == '\n' || c == '\0')) {
-      if (bufPos <= bufLen && buffer[0] == 'C') {
-	// Check time error
-	buffer[bufPos] = '\0';
-	RTCx::time_t pcTime = atol(&(buffer[1]));
-	rtc.readClock(&tm);
-	RTCx::time_t mcuTime = RTCx::mktime(&tm);
-	Serial.print("MCU clock error: ");
-	Serial.print(mcuTime - pcTime);
-	Serial.println(" s");
-	Serial.println("~~~~~");
-      }
-      if (bufPos <= bufLen && buffer[0] == 'T') {
-	// Set time
-	buffer[bufPos] = '\0';
-	RTCx::time_t t = atol(&(buffer[1]));
-	RTCx::gmtime_r(&t, &tm);
-	rtc.setClock(&tm);
-	Serial.println("Clock set");
-	Serial.println(&(buffer[0]));
-	printTm(Serial, &tm);
-	Serial.println("~~~~~");
-      }
-      if (bufPos <= bufLen && buffer[0] == 'X') {
-	// Set calibration value
-	buffer[bufPos] = '\0';
-	if (rtc.getDevice() == RTCx::MCP7941x) {
-	  int8_t oldCal = rtc.getCalibration();
-	  char *endptr;
-	  long cal = strtol(&(buffer[1]), &endptr, 0);
-	  if (cal >= -127 && cal <= 127 && endptr == &buffer[bufPos]) {
-	    Serial.print("Previous calibration: ");
-	    Serial.println(oldCal, DEC);
-	    Serial.print("Calibration: ");
-	    Serial.println(cal, DEC);
-	      rtc.setCalibration(cal);
-	  }
-	  else
-	    Serial.println("Bad value for calibration");
+		RTCx::printIsotime(Serial, tm).println();
+		RTCx::time_t t = RTCx::mktime(&tm);
+
+		Serial.print("unixtime = ");
+		Serial.println(t);
+		Serial.println("-----");
 	}
-	else {
-	  Serial.println("Cannot set calibration: not a MCP7941x");
+
+	while (Serial.available()) {
+		char c = Serial.read();
+		if ((c == '\r' || c == '\n' || c == '\0')) {
+			if (bufPos <= bufLen && buffer[0] == 'C') {
+				// Check time error
+				buffer[bufPos] = '\0';
+				RTCx::time_t pcTime = atol(&(buffer[1]));
+				rtc.readClock(&tm);
+				RTCx::time_t mcuTime = RTCx::mktime(&tm);
+				Serial.print("MCU clock error: ");
+				Serial.print(mcuTime - pcTime);
+				Serial.println(" s");
+				Serial.println("~~~~~");
+			}
+			if (bufPos <= bufLen && buffer[0] == 'T') {
+				// Set time
+				buffer[bufPos] = '\0';
+				RTCx::time_t t = atol(&(buffer[1]));
+				RTCx::gmtime_r(&t, &tm);
+				rtc.setClock(&tm);
+				Serial.println("Clock set");
+				Serial.println(&(buffer[0]));
+				RTCx::printIsotime(Serial, tm);
+				Serial.println("~~~~~");
+			}
+			if (bufPos <= bufLen && buffer[0] == 'X') {
+				// Set calibration value
+				buffer[bufPos] = '\0';
+				if (rtc.getDevice() == RTCx::MCP7941x) {
+					int8_t oldCal = rtc.getCalibration();
+					char *endptr;
+					long cal = strtol(&(buffer[1]), &endptr, 0);
+					if (cal >= -127 && cal <= 127 && endptr == &buffer[bufPos]) {
+						Serial.print("Previous calibration: ");
+						Serial.println(oldCal, DEC);
+						Serial.print("Calibration: ");
+						Serial.println(cal, DEC);
+						rtc.setCalibration(cal);
+					}
+					else
+						Serial.println("Bad value for calibration");
+				}
+				else {
+					Serial.println("Cannot set calibration: not a MCP7941x");
+				}
+			}
+			if (bufPos <= bufLen && buffer[0] == 'M') {
+				// Set SQW mode
+				buffer[bufPos] = '\0';
+				char *endptr;
+				long mode = strtol(&(buffer[1]), &endptr, 0);
+				if (mode >= RTCx::freq1Hz && mode <= RTCx::freqCalibration
+					&& endptr == &buffer[bufPos]) {
+					if (rtc.setSQW((RTCx::freq_t)mode)) {
+						Serial.print("SQW: ");
+						Serial.println(mode, DEC);
+					}
+					else
+						Serial.println("Could not set SQW");
+				}
+				else
+					Serial.println("Bad value for SQW");
+			}
+			bufPos = 0;
+		}
+		else if (bufPos < bufLen)
+			// Store character
+			buffer[bufPos++] = c;
 	}
-      }
-      if (bufPos <= bufLen && buffer[0] == 'M') {
-	// Set SQW mode
-	buffer[bufPos] = '\0';
-	  char *endptr;
-	  long mode = strtol(&(buffer[1]), &endptr, 0);
-	  if (mode >= RTCx::freq1Hz && mode <= RTCx::freqCalibration
-	      && endptr == &buffer[bufPos]) {
-	    if (rtc.setSQW((RTCx::freq_t)mode)) {
-	      Serial.print("SQW: ");
-	      Serial.println(mode, DEC);
-	    }
-	    else
-	      Serial.println("Could not set SQW");
-	  }
-	  else
-	    Serial.println("Bad value for SQW");
-      }
-      bufPos = 0;
-    }
-    else if (bufPos < bufLen)
-      // Store character
-      buffer[bufPos++] = c;
-  }
 }


Re-organise the bluetooth initialisation code so that it only happens if the device is accessible, and remove the delay that waits for a connection before starting the main loop.

--- Arduino/BlueCube/BlueCube.ino
+++ Arduino/BlueCube/BlueCube.ino
@@ -72,7 +72,10 @@
 void setup(void)
 {
   Serial.begin(115200);
-
+
+  // Set the pin connected to "MOD" on the bluetooth module to output
+  pinMode(BLUEFRUIT_UART_MODE_PIN, OUTPUT);
+
   // Serial port options for control of the Cube using serial commands are:
   // 0: Control via the USB connector (most common).
   // 1: Control via the RXD and TXD pins on the main board.
@@ -99,58 +102,50 @@
   // instruction
   setDelegate(userFunctionHandler);

-  pinMode(BLUEFRUIT_UART_MODE_PIN, OUTPUT);
-
-  Serial.println(F("Adafruit Bluefruit App Controller Example"));
-  Serial.println(F("-----------------------------------------"));
-
   /* Initialise the module */
-  Serial.print(F("Initialising the Bluefruit LE module: "));
+  if (VERBOSE_MODE)
+  {
+    Serial.println("Initialising Bluetooth");
+  }

   if ( !ble.begin(VERBOSE_MODE) )
-  {
-    Serial.println(F("Couldn't find Bluefruit, make sure it's in CoMmanD mode & check wiring?"));
-  }
-  Serial.println( F("OK!") );
-
-  /* Disable command echo from Bluefruit */
-  ble.echo(false);
-
-  Serial.println("Requesting Bluefruit info:");
-  /* Print Bluefruit information */
-  ble.info();
-
-  Serial.println("MAC Address:");
-  ble.sendCommandCheckOK("AT+BLEGETADDR");
-  Serial.println();
-
-  Serial.println(F("Please use Adafruit Bluefruit LE app to connect in Controller mode"));
-  Serial.println(F("Then activate/use the sensors, color picker, game controller, etc!"));
-  Serial.println();
-
-  ble.verbose(false);  // debug info is a little annoying after this point!
-
-  /* Wait for connection */
-  while (! ble.isConnected()) {
-      delay(500);
-  }
-
-  Serial.println(F("******************************"));
-
-  // LED Activity command is only supported from 0.6.6
-  if ( ble.isVersionAtLeast(MINIMUM_FIRMWARE_VERSION) )
-  {
-    // Change Mode LED Activity
-    Serial.println(F("Change LED activity to " MODE_LED_BEHAVIOUR));
-    ble.sendCommandCheckOK("AT+HWModeLED=" MODE_LED_BEHAVIOUR);
-  }
-
-  // Set Bluefruit to DATA mode
-  Serial.println( F("Switching to DATA mode!") );
-  ble.setMode(BLUEFRUIT_MODE_DATA);
-
-  Serial.println(F("******************************"));
-
+  { // Bluetooth couldn't be started,
+    Serial.println("Couldn't find Bluetooth");
+  } else {
+    // Bluetooth has been started
+    if (VERBOSE_MODE)
+    {
+      Serial.println("OK!");
+    }
+
+    // Disable command echo from Bluetooth
+    ble.echo(false);
+
+    if (VERBOSE_MODE)
+    {
+      // Print Bluetooth information */
+      Serial.println("Requesting Bluetooth info");
+      ble.info();
+    }
+
+    // Bluetooth debug info is a little annoying after this point!.
+    ble.verbose(false);
+
+    if (VERBOSE_MODE)
+    {
+      Serial.println("Set to data mode");
+    }
+
+    // LED Activity command is only supported from 0.6.6
+    if ( ble.isVersionAtLeast(MINIMUM_FIRMWARE_VERSION) )
+    {
+      // Change Mode LED Activity
+      ble.sendCommandCheckOK("AT+HWModeLED=" MODE_LED_BEHAVIOUR);
+    }
+
+    // Set Bluetooth to DATA mode
+    ble.setMode(BLUEFRUIT_MODE_DATA);
+  }
 }

 void loop(void)


way improved state display on uView

way improved state display on uView

--- uArm.ino
+++ uArm.ino
@@ -377,5 +377,12 @@
 				suspendStore = true;
 			}
 		}
+	} else {
+		widgetL->setValue(servoL.read());
+		widgetR->setValue(servoR.read());
+		widgetRot->setValue(servoRot.read());
+		widgetHRot->setValue(servoHRot.read());
+		widgetH->setValue(servoH.read());
+		uView.display();
 	}
 }


Added log messages

Added log messages

--- arduino/brew_kettle/brew_kettle.ino
+++ arduino/brew_kettle/brew_kettle.ino
@@ -173,19 +173,27 @@
   if (value < 0) {
     value = 0;
   }
-  /* Serial << STATMSG << "Set duty cycle to " << value << ENDMSG; */
+  Serial << STATMSG << "Set duty cycle to " << value << ENDMSG;
   dutyCycle = double(value);
 }

 void heaterOn() {
-  digitalWrite(heaterPin, HIGH);
+  if (!heaterIsOn) {
+    digitalWrite(heaterPin, HIGH);
+    Serial << STATMSG << "Turning heater on" << dutyCycle << ENDMSG;
+  }
   heaterIsOn = HIGH;
 }

 void heaterOff() {
-  digitalWrite(heaterPin, LOW);
+  if (heaterIsOn) {
+    digitalWrite(heaterPin, LOW);
+    Serial << STATMSG << "Turning heater off" << dutyCycle << ENDMSG;
+  }
   heaterIsOn = LOW;
 }
+// 30 sec
+const unsigned long windowSize = 10000;

 void controlHeater() {
   // Convert double duty cycle to long for calculation
@@ -217,9 +225,6 @@
     if (!inDutyCycleMode) {
       windowStartTime = currentMillis;
     }
-
-    // 1min is 60'000 ms
-    const unsigned long windowSize = 60000;

     // The onTime is windowSize * dutyCycle and since
     // dutyCycle is in percent we divide by 100


Reformatted layout, introduced temperature control

--- UTFT_AdvancedButtons.ino
+++ UTFT_AdvancedButtons.ino
@@ -49,6 +49,12 @@
 // Finally we set up multiButtons :)
 multiButtons  multiButtons(&myGLCD, &myTouch);

+//Prepare Globals
+int butL1, butL2, butL3, butR1, butR2, butR3, butUp, butDn, pressed_button;
+boolean default_colors = true, buttonState;
+double dblTempSetPoint;
+
+//Set up the interface
 void setup()
 {

@@ -66,28 +72,17 @@

   Serial.println("init");

+  //Draw the button sheet
+  drawButtonSheet();
+
+  //Set initial temparature
+  tempSetPoint(21.5);
+
+
 }

 void loop()
 {
-    int butL1, butL2, butL3, butL4, butR1, butR2, butR3, butR4, pressed_button;
-    boolean default_colors = true, buttonState;
-    butL1 = multiButtons.addButton( 10, 160, 300,  70, "Trap",0,"right",true,true,false);
-    butL2 = multiButtons.addButton( 10, 240, 300,  70, "Ventilatie achter",0,"right",true,true,false);
-    butL3 = multiButtons.addButton( 10, 320, 300,  70, "Ventilatie dak",0,"right",true,false,false);
-    butR4 = multiButtons.addButton( 10, 400, 300,  70, "Verwarming",0,"right",true,false,false);
-
-    butR1 = multiButtons.addButton( 490, 160, 300,  70, "LPG",0,"left",true,true,true);
-    butR2 = multiButtons.addButton( 490, 240, 300,  70, "Drinkwater",0,"left",true,true,true);
-    butR3 = multiButtons.addButton( 490, 320, 300,  70, "Warm water",0,"left",true,false,false);
-    butR4 = multiButtons.addButton( 490, 400, 300,  70, "Afvalwater",0,"left",false,true,true);
-    multiButtons.drawButtons();
-    multiButtons.disableButton(butR4,false);
-
-    //Set initial measurements
-     multiButtons.setPercentage(butR1,30);
-     multiButtons.setPercentage(butR2,60);
-     multiButtons.setPercentage(butR4,100);

 //    myGLCD.print("You pressed:", CENTER, 10);
@@ -101,25 +96,29 @@
         pressed_button = multiButtons.checkButtons();

         switch(pressed_button){
-          case 0:
+          case 1:
               //myGLCD.print("Button 1", CENTER, 30 );
           break;
-          case 1:
+          case 2:
               //myGLCD.print("Button 2", CENTER, 30 );
           break;
-          case 2:
+          case 3:
               //myGLCD.print("Button 3", CENTER, 30 );
           break;
-          case 3:
+          case 4:
               //myGLCD.print("Button 4", CENTER, 30 );

           break;
-          case 4:
+          case 5:
               //myGLCD.print("Button 5", CENTER, 30 );
           break;
-          case 5:
-                //myGLCD.print("Button 6", CENTER, 30 );
+          case 6:
+                tempSetPoint(0.5);
           break;
+          case 7:
+                tempSetPoint(-0.5);
+          break;
+
           case -1:
                 //myGLCD.print("Button 0", CENTER, 30 );
           break;
@@ -128,3 +127,35 @@
     }
 }

+void drawButtonSheet(){
+      int butL1, butL2, butL3, butR1, butR2, butR3, butUp, butDn, pressed_button;
+    boolean default_colors = true, buttonState;
+    butL1 = multiButtons.addButton( 10, 240, 300,  70, "Trap",0,"right",true,true,false);
+    butL2 = multiButtons.addButton( 10, 320, 300,  70, "Ventilatie achter",0,"right",true,true,false);
+    butR3 = multiButtons.addButton( 10, 400, 300,  70, "Warm water",0,"right",true,false,false);
+
+    butR1 = multiButtons.addButton( 490, 240, 300,  70, "LPG",0,"left",true,true,true);
+    butR2 = multiButtons.addButton( 490, 320, 300,  70, "Drinkwater",0,"left",true,true,true);
+    butR3 = multiButtons.addButton( 490, 400, 300,  70, "Afvalwater",0,"left",false,true,true);
+
+    butUp = multiButtons.addButton( 370, 240, 70,  70, "+",0,"center",false,false,false);
+    butDn = multiButtons.addButton( 370, 400, 70,  70, "-",0,"center",false,false,false);
+
+
+    multiButtons.drawButtons();
+    multiButtons.disableButton(butR3,false);
+
+    //Set initial measurements
+     multiButtons.setPercentage(butR1,0);
+     multiButtons.setPercentage(butR2,0);
+     multiButtons.setPercentage(butR3,0);
+
+}
+
+
+void tempSetPoint(double dDelta){
+    dblTempSetPoint = dblTempSetPoint + dDelta;
+    myGLCD.printNumF(dblTempSetPoint, 1, CENTER, 340);
+    //myGLCD.print(dblTempSetPoint , CENTER, 340);
+}
+


Added filter. It works, but it needs some tunning. The lower values are too fast.

--- ServerSketch/ServerSketch.ino
+++ ServerSketch/ServerSketch.ino
@@ -52,9 +52,9 @@

 #define DIGITAL_VOLTAGE_THRESHOLD  0.5

-#define TOTAL_NUM_OF_PAST_VALUES  10 // Filtering buffer
-
-//char** g_caaPinNames[20][PIN_LABEL_SIZE];
+#define TOTAL_NUM_OF_PAST_VALUES  1000 // Filtering buffer
+
+float g_afFilterDeltas[] = {1,0.8,0.6,0.4,0.2,0.1,0.075,0.050,0.025,0.010};

 typedef struct Pin {
   char label[PIN_LABEL_SIZE];
@@ -69,23 +69,12 @@
   int is_timer_on;
   float timer_value;
   int damping;
+  int prev_damping;
   boolean connections[TOTAL_NUM_OF_PINS];
-  float past_values[TOTAL_NUM_OF_PAST_VALUES];
+//  float past_values[TOTAL_NUM_OF_PAST_VALUES];
+  float prev_values;
 }
 Pin;
-
-  /*
-  {"status":<OK,ERROR>,  "pins":{"<0,1,…,13,A0,…,A5>":  {
-  "label":"<label text>",
-	"is_analog":"<true,false>",
-	"is_input":"<true,false>",
-“sensitivity”:”<0.0,1.0>”,
-“is_inverted”:”<true,false>”,
-“is_visible”:”<true,false>”,
-"value":"<0.0,1.0>",  },  ...,  },
-"connections":[ {"source":"<0,1,…,13,A0,…,A5>","target":"<0,1,…,13,A0,…,A5>",”is_connected”:”<true,false>”},  ...,  ]  }
-  */
-

 Pin g_aPins[TOTAL_NUM_OF_PINS];

@@ -258,7 +247,7 @@
 }

 // Testing
-char pcTestBuffer[512] = "{\"status\":OK,\"pins\":{\"14\":{\"label\":\"A0\",\"is_analog\":\"true\",\"is_input\":\"true\",\"value\":\"0.5\"},\"3\":{\"label\":\"PWM3\",\"is_analog\":\"true\",\"is_input\":\"false\",\"value\":\"0.0\"}},\"connections\":[{\"source\":\"14\",\"target\":\"3\"}]}\"";
+//char pcTestBuffer[512] = "{\"status\":OK,\"pins\":{\"14\":{\"label\":\"A0\",\"is_analog\":\"true\",\"is_input\":\"true\",\"value\":\"0.5\"},\"3\":{\"label\":\"PWM3\",\"is_analog\":\"true\",\"is_input\":\"false\",\"value\":\"0.0\"}},\"connections\":[{\"source\":\"14\",\"target\":\"3\"}]}\"";

 /* lyt_protocol*/
 static int
@@ -441,6 +430,7 @@
 // **********************************
 // Send pin status to the Website
 // **********************************
+/*
 int  sendStatusToWebsite(struct libwebsocket *wsi)
 {
   int n;
@@ -474,7 +464,7 @@

   return n;
 }
-
+*/

 int  sendStatusToWebsiteNew(struct libwebsocket *wsi)
 {
@@ -611,12 +601,14 @@
     g_aPins[i].is_visible = true;
     g_aPins[i].value = 0.0;

-    for(int j=0; j<TOTAL_NUM_OF_PAST_VALUES; j++)
-      g_aPins[i].past_values[j] = 0.0;
+ //   for(int j=0; j<TOTAL_NUM_OF_PAST_VALUES; j++)
+  //    g_aPins[i].past_values[j] = 0.0;
+    g_aPins[i].prev_values = 0.0;

     g_aPins[i].is_timer_on = false;
     g_aPins[i].timer_value = 0.0;
     g_aPins[i].damping = 0;
+    g_aPins[i].prev_damping = 0;

     // Set pin connections
     memset(g_aPins[i].connections, '\0', sizeof(g_aPins[i].connections));
@@ -744,96 +736,85 @@

 float getFilteredPinValue(int _iInPinNum)
 {
+  static float fFiltered = 0.0;
+
+//  float fDelta = 1.0/pow(10,g_aPins[_iInPinNum].damping);
+//  float fDelta = 1.0 - 0.99/9.0*float(g_aPins[_iInPinNum].damping);
+  float fDelta = g_afFilterDeltas[g_aPins[_iInPinNum].damping];
+
+  Serial.print("fDelta: "); Serial.println(fDelta);
+
+  if( fFiltered < g_aPins[_iInPinNum].value )
+  {
+    fFiltered += fDelta;
+    if(fFiltered>g_aPins[_iInPinNum].value)
+      fFiltered = g_aPins[_iInPinNum].value;
+  }
+  else if( fFiltered > g_aPins[_iInPinNum].value )
+  {
+    fFiltered -= fDelta;
+    if( fFiltered < g_aPins[_iInPinNum].value)
+      fFiltered = g_aPins[_iInPinNum].value;
+  }
+  else
+  {
+    fFiltered = g_aPins[_iInPinNum].value;
+  }
+
+Serial.print("fFiltered: "); Serial.println(fFiltered);
+Serial.print("Value: "); Serial.println(g_aPins[_iInPinNum].value);
+
+
+  /*
+  // Check if the damping value has changed
+  if( g_aPins[_iInPinNum].damping != g_aPins[_iInPinNum].prev_damping )
+  {
+    // Clear the history values
+    for(int i=0; i<TOTAL_NUM_OF_PAST_VALUES; i++)
+      g_aPins[_iInPinNum].past_values[i] = 0.0;
+  }
+
+  g_aPins[_iInPinNum].damping
+
+  g_aPins[_iInPinNum].value
+  g_aPins[_iInPinNum].prev_value
+ */
+  return fFiltered;
+}
+
+/*
+float getFilteredPinValue(int _iInPinNum)
+{
+  // Check if the damping value has changed
+  if( g_aPins[_iInPinNum].damping != g_aPins[_iInPinNum].prev_damping )
+  {
+    // Clear the history values
+    for(int i=0; i<TOTAL_NUM_OF_PAST_VALUES; i++)
+      g_aPins[_iInPinNum].past_values[i] = 0.0;
+  }
+
+  // Update
+  g_aPins[_iInPinNum].prev_damping =   g_aPins[_iInPinNum].damping;
+
   // Update tap value
-  float fFilterTab = 1.0/(g_aPins[_iInPinNum].damping+1); // The sampling rate is so slow this filter can see it.
+//  float fFilterTab = 1.0/(g_aPins[_iInPinNum].damping+1); // The sampling rate is so slow this filter can see it.
+  float fFilterTab = 1.0/(g_aPins[_iInPinNum].damping*100+1); // The sampling rate is so slow this filter can see it.
   Serial.print("fFilterTab: "); Serial.println(fFilterTab);
   // Shift previous values
   for(int i=0; i<TOTAL_NUM_OF_PAST_VALUES-1; i++)
-  {
       g_aPins[_iInPinNum].past_values[i+1] = g_aPins[_iInPinNum].past_values[i];
-  }

   // Add new data
   g_aPins[_iInPinNum].past_values[0] = g_aPins[_iInPinNum].value;
     Serial.print("value: "); Serial.println(g_aPins[_iInPinNum].value);
   // Multiply and accumulate
   float fMultAndAccum = 0.0;
-  for(int i=0; i<=g_aPins[_iInPinNum].damping; i++)
+  for(int i=0; i<=g_aPins[_iInPinNum].damping*100; i++)
       fMultAndAccum += fFilterTab*g_aPins[_iInPinNum].past_values[i];
   Serial.print("MultAndAccum: "); Serial.println(fMultAndAccum);
   return fMultAndAccum;
 }
-
-float getTotalPinAnalogValue(int _iPinNum)
-{
-  float fPinValSum = 0;
-  int iConnCount = 1; // Pins are always connected to themselves
-
-  for(int i=0; i<TOTAL_NUM_OF_PINS; i++)
-  {
-    // Checking what pins are connected to iPinNum
-    if( _iPinNum != i) // Ignore the value set to the pin and only use connected pin values
-    {
-      if(g_aPins[_iPinNum].connections[i])
-      {
-        iConnCount++;
-        fPinValSum += g_aPins[i].value;
-        Serial.print(i); Serial.print(" --> "); Serial.print(_iPinNum);
-        Serial.print(" value: "); Serial.println(g_aPins[i].value);
-      }
-    }
-  }
-
-  if(fPinValSum > 1.0)
-    fPinValSum = 1.0;
-
-  if( 1 == iConnCount ) // No other connections found besides itself
-    fPinValSum = g_aPins[_iPinNum].value;
-  else
-    g_aPins[_iPinNum].value = fPinValSum;
-
-  Serial.print("Analog Pin #: "); Serial.print(_iPinNum); Serial.print(" Total Value: "); Serial.println(fPinValSum);
-
-  return fPinValSum;
-}
-
-////////////////////////////////////////////////////////////////////////////
-// If an output pin has connections, return the sum of all its connections
-////////////////////////////////////////////////////////////////////////////
-int getTotalPinDigitalValue(int _iPinNum)
-{
-  int iRetValue = 0;
-  int iConnCount = 1; // Pins are always connected to themselves
-
-  for(int i=0; i<TOTAL_NUM_OF_PINS; i++)
-  {
-    // Checking what pins are connected to iPinNum
-    if( _iPinNum != i) // Ignore the value set to the pin and only use connected pin values
-    {
-      if(g_aPins[_iPinNum].connections[i])
-      {
-        iConnCount++;
-        if(g_aPins[i].value >= DIGITAL_VOLTAGE_THRESHOLD) // Digital threshold
-        {
-          iRetValue = 1;
-          break;
-        }
-        else
-          iRetValue = 0;
-      }
-    }
-  }
-
-  if( 1 == iConnCount ) // No other connections found besides itself
-    iRetValue = g_aPins[_iPinNum].value;
-  else
-   g_aPins[_iPinNum].value = iRetValue;
-
-  //g_aPins[_iPinNum].value = iRetValue;
-//  Serial.print("Digital Pin #: "); Serial.print(_iPinNum); Serial.print(" Total Value: "); Serial.println(iRetValue);
-
-  return iRetValue;
-}
+*/

 ////////////////////////////////////////////////
 // Get the board state and return a JSON object
@@ -1256,7 +1237,7 @@
   initWebsocket();

 }
-
+/*
 char g_acMessage[1000];
 int g_ToggleFlag = 0;
 char g_acPin3_On[] = "{\"status\":\"OK\",\"pins\":{ \"13\":{\"label\":\"Pin 13\",\"is_analog\":\"false\",\"is_input\":\"false\",\"value\":\"1\"}, \"2\":{\"label\":\"Pin 2\",\"is_analog\":\"false\",\"is_input\":\"false\",\"value\":\"1\"}, \"4\":{\"label\":\"Pin 4\",\"is_analog\":\"false\",\"is_input\":\"false\",\"value\":\"1\"}, \"7\":{\"label\":\"Pin 7\",\"is_analog\":\"false\",\"is_input\":\"false\",\"value\":\"1\"}, \"8\":{\"label\":\"Pin 8\",\"is_analog\":\"false\",\"is_input\":\"false\",\"value\":\"1\"}, \"12\":{\"label\":\"Pin 12\",\"is_analog\":\"false\",\"is_input\":\"false\",\"value\":\"1\"}, \"3\":{\"label\":\"Pin 3\",\"is_analog\":\"true\",\"is_input\":\"false\",\"value\":\"0.9\"}, \"5\":{\"label\":\"Pin 5\",\"is_analog\":\"true\",\"is_input\":\"false\",\"value\":\"0.9\"}, \"6\":{\"label\":\"Pin 6\",\"is_analog\":\"true\",\"is_input\":\"false\",\"value\":\"0.9\"}, \"9\":{\"label\":\"Pin 9\",\"is_analog\":\"true\",\"is_input\":\"false\",\"value\":\"0.9\"}, \"10\":{\"label\":\"Pin 10\",\"is_analog\":\"true\",\"is_input\":\"false\",\"value\":\"0.9\"}, \"11\":{\"label\":\"Pin 11\",\"is_analog\":\"true\",\"is_input\":\"false\",\"value\":\"0.9\"}   }}";
@@ -1266,7 +1247,7 @@
 char g_acPin13_On_3_Analog[] = "{\"status\":\"OK\",\"pins\":{ \"13\":{\"label\":\"Pin 13\",\"is_analog\":\"false\",\"is_input\":\"false\",\"value\":\"1\"}, \"3\":{\"label\":\"Pin 3\",\"is_analog\":\"true\",\"is_input\":\"false\",\"value\":\"0.0\"}  }}";
 char g_acConnA0_TO_3[] = "{\"status\":\"OK\",\"connections\":[{\"source\":\"14\",\"target\":\"3\"},{\"source\":\"15\",\"target\":\"3\"}]}";
 int g_iDebugState = 0;
-
+*/
 unsigned long last_print = 0;

 void loop()


add comments for future

add comments for future

--- Attic_Controller/Attic_Controller.ino
+++ Attic_Controller/Attic_Controller.ino
@@ -2,6 +2,8 @@

 //----------------------------------------------------------------------------------------------------------------
 // Attic_Controller.ino
+//
+// This sketch is designed to run on a WeMos D1 mini.  Other controllers will require extensive tweaking.
 //
 // Handles communicating with the roof sensors, as well as reading attic temperature / humidity
 // Processes that information, and passes it on via MQTT


Added "volatile" attribute to RINT1Trigd & RINT2Trigd

This fixes some occurrences of failure of interrupts test step

--- SRC/ArincShieldAutoTest.ino
+++ SRC/ArincShieldAutoTest.ino
@@ -8,6 +8,9 @@
 //   - 16MHz (serial production)
 //
 // Version V1.02 (18/01/2018) : added a test step for RS422 loopback check
+//
+// Version V1.03 (14/05/2019) : added "volatile" attribute to RINT1Trigd & RINT2Trigd variables
+//                              to fix some occurences of failed interrupts tests
 //
 // This program is distributed in the hope that it will be useful, but without any
 // warranty; without even the implied warranty of merchantability or fitness for a
@@ -50,13 +53,13 @@
 );

 // interrupt service routine for digital input #3 (RINT1)
-bool RINT1Trigd;
+volatile bool RINT1Trigd; // JPP V1.03
 void isr1() {
   RINT1Trigd = true;
 }

 // interrupt service routine for digital input #2 (RINT2)
-bool RINT2Trigd;
+volatile bool RINT2Trigd; // JPP V1.03
 void isr2() {
   RINT2Trigd = true;
 }


Larger Number of LEDs Used

Larger Number of LEDs Used

Caveats noted.

--- MasterVolume/MasterVolume.ino
+++ MasterVolume/MasterVolume.ino
@@ -4,16 +4,20 @@
 void setup(){
   //Serial baud rate 9600.
   Serial.begin(9600);
-  //1/5
+  //Ten LED configuration +
+  //One statue LED.
+  //At least two LEDs should use MOSFETS.
   pinMode(2, OUTPUT);
-  //2/5
   pinMode(3, OUTPUT);
-  //3/5
   pinMode(4, OUTPUT);
-  //4/5
   pinMode(5, OUTPUT);
-  //5/5
   pinMode(6, OUTPUT);
+  pinMode(7, OUTPUT);
+  pinMode(8, OUTPUT);
+  pinMode(9, OUTPUT);
+  pinMode(10, OUTPUT);
+  pinMode(11, OUTPUT);
+  pinMode(12, OUTPUT);
 }
 //Main loop.
 void loop(){
@@ -25,41 +29,126 @@
   switch (input_byte){
     case 0:
       Serial.print("THIS IS ARDUINO!");
+      digitalWrite(2, HIGH);
       break;
     case 1:
-      digitalWrite(2, HIGH);
-      digitalWrite(3, LOW);
-      digitalWrite(4, LOW);
-      digitalWrite(5, LOW);
-      digitalWrite(6, LOW);
-      break;
-    case 2:
-      digitalWrite(2, HIGH);
       digitalWrite(3, HIGH);
       digitalWrite(4, LOW);
       digitalWrite(5, LOW);
       digitalWrite(6, LOW);
+      digitalWrite(7, LOW);
+      digitalWrite(8, LOW);
+      digitalWrite(9, LOW);
+      digitalWrite(10, LOW);
+      digitalWrite(11, LOW);
+      digitalWrite(12, LOW);
       break;
-    case 3:
-      digitalWrite(2, HIGH);
+    case 2:
       digitalWrite(3, HIGH);
       digitalWrite(4, HIGH);
       digitalWrite(5, LOW);
-      digitalWrite(6, LOW);
+      digitalWrite(7, LOW);
+      digitalWrite(8, LOW);
+      digitalWrite(9, LOW);
+      digitalWrite(10, LOW);
+      digitalWrite(11, LOW);
+      digitalWrite(12, LOW);
       break;
-    case 4:
-      digitalWrite(2, HIGH);
+    case 3:
       digitalWrite(3, HIGH);
       digitalWrite(4, HIGH);
       digitalWrite(5, HIGH);
       digitalWrite(6, LOW);
+      digitalWrite(7, LOW);
+      digitalWrite(8, LOW);
+      digitalWrite(9, LOW);
+      digitalWrite(10, LOW);
+      digitalWrite(11, LOW);
+      digitalWrite(12, LOW);
       break;
-    case 5:
-      digitalWrite(2, HIGH);
+    case 4:
       digitalWrite(3, HIGH);
       digitalWrite(4, HIGH);
       digitalWrite(5, HIGH);
       digitalWrite(6, HIGH);
+      digitalWrite(7, LOW);
+      digitalWrite(8, LOW);
+      digitalWrite(9, LOW);
+      digitalWrite(10, LOW);
+      digitalWrite(11, LOW);
+      digitalWrite(12, LOW);
+      break;
+    case 5:
+      digitalWrite(3, HIGH);
+      digitalWrite(4, HIGH);
+      digitalWrite(5, HIGH);
+      digitalWrite(6, HIGH);
+      digitalWrite(7, HIGH);
+      digitalWrite(8, LOW);
+      digitalWrite(9, LOW);
+      digitalWrite(10, LOW);
+      digitalWrite(11, LOW);
+      digitalWrite(12, LOW);
+      break;
+    case 6:
+      digitalWrite(3, HIGH);
+      digitalWrite(4, HIGH);
+      digitalWrite(5, HIGH);
+      digitalWrite(6, HIGH);
+      digitalWrite(7, HIGH);
+      digitalWrite(8, HIGH);
+      digitalWrite(9, LOW);
+      digitalWrite(10, LOW);
+      digitalWrite(11, LOW);
+      digitalWrite(12, LOW);
+      break;
+    case 7:
+      digitalWrite(3, HIGH);
+      digitalWrite(4, HIGH);
+      digitalWrite(5, HIGH);
+      digitalWrite(6, HIGH);
+      digitalWrite(7, HIGH);
+      digitalWrite(8, HIGH);
+      digitalWrite(9, HIGH);
+      digitalWrite(10, LOW);
+      digitalWrite(11, LOW);
+      digitalWrite(12, LOW);
+      break;
+    case 8:
+      digitalWrite(3, HIGH);
+      digitalWrite(4, HIGH);
+      digitalWrite(5, HIGH);
+      digitalWrite(6, HIGH);
+      digitalWrite(7, HIGH);
+      digitalWrite(8, HIGH);
+      digitalWrite(9, HIGH);
+      digitalWrite(10, HIGH);
+      digitalWrite(11, LOW);
+      digitalWrite(12, LOW);
+      break;
+    case 9:
+      digitalWrite(3, HIGH);
+      digitalWrite(4, HIGH);
+      digitalWrite(5, HIGH);
+      digitalWrite(6, HIGH);
+      digitalWrite(7, HIGH);
+      digitalWrite(8, HIGH);
+      digitalWrite(9, HIGH);
+      digitalWrite(10, HIGH);
+      digitalWrite(11, HIGH);
+      digitalWrite(12, LOW);
+      break;
+    case 10:
+      digitalWrite(3, HIGH);
+      digitalWrite(4, HIGH);
+      digitalWrite(5, HIGH);
+      digitalWrite(6, HIGH);
+      digitalWrite(7, HIGH);
+      digitalWrite(8, HIGH);
+      digitalWrite(9, HIGH);
+      digitalWrite(10, HIGH);
+      digitalWrite(11, HIGH);
+      digitalWrite(12, HIGH);
       break;
   }
   //Clear message.


Cleaned up code. Added reset button.

Cleaned up code. Added reset button.

--- FumeHoodWatchDog/FumeHoodWatchDog.ino
+++ FumeHoodWatchDog/FumeHoodWatchDog.ino
@@ -1,48 +1,54 @@
 // This is a watchdog program to be run on an Adafruit Trinket

-#define watchDogPin 2
-#define resetPin 3
-#define hbPin 1
+#define watchDogPin 1
+#define resetPin 2
+#define resetButtonPin 4

-unsigned long watchDogInterval = 30000; // Needs to see a pulse at lease every 30 seconds
-unsigned long resetDuration = 5000;
-unsigned long fumeHoodMonitorBootTime = 15000;
-volatile unsigned long watchDogTimer;
-volatile bool hbState = false;
-// bool watchDogIsBeingPet = false;
-// bool watchDogHasBeenPet = false;
+static const int resetHoldTime = 5000; //ms
+static const int fumeHoodMonitorBootTime = 20000; //ms
+static const int noChangeCountResetTrigger = 300; // equals 30 seconds with a system check every 100 ms
+static const int resetButtonCountResetTrigger = 20; // equals 2 seconds with a system check every 100 ms
+static const int systemCheckInterval = 100; // ms between system checks
+int noChangeCount = 0;
+int resetButtonCount = 0;
+int watchDogInputState = 0;
+int lastWatchDogInputState = 0;

 void setup() {
   pinMode(watchDogPin, INPUT);
-  attachInterrupt(0, petWatchDog, RISING);
   pinMode(resetPin, OUTPUT);
-  pinMode(hbPin, OUTPUT);
+  pinMode(resetButtonPin, INPUT);
   digitalWrite(resetPin, HIGH);
-  digitalWrite(hbPin, hbState);
   delay(fumeHoodMonitorBootTime);
-  watchDogTimer = millis();
 }

 void loop(){
-  // watchDogIsBeingPet = digitalRead(watchDogPin) == 1;
-  // if (watchDogIsBeingPet) {
-  //   watchDogHasBeenPet = true;
-  // } else if (!watchDogIsBeingPet && watchDogHasBeenPet) {
-  //   watchDogTimer = millis();
-  //   watchDogHasBeenPet = false;
-  // }
-  unsigned long now = millis();
-  if(now - watchDogTimer >= watchDogInterval){
-    digitalWrite(resetPin, LOW);
-    delay(resetDuration);
-    digitalWrite(resetPin, HIGH);
-    delay(fumeHoodMonitorBootTime);
-    watchDogTimer = millis();
-  }
-  digitalWrite(hbPin, hbState);
+  checkSystem(); // continuously monitors input pulse and will only break if the pulse stops
+  resetSystem(); // will only execute if the watchdog is not changing state
 }

-void petWatchDog(){
-  watchDogTimer = millis();
-  hbState = !hbState;
+void checkSystem(){
+  do {
+    // Monitor watchDog pulses
+    watchDogInputState = digitalRead(watchDogPin);
+    if (watchDogInputState == lastWatchDogInputState) noChangeCount++;
+      else noChangeCount = 0;
+    lastWatchDogInputState = watchDogInputState;
+
+    // Monitor Reset Button
+    if (digitalRead(resetButtonPin) == HIGH) resetButtonCount++;
+      else resetButtonCount = 0;
+
+    delay(systemCheckInterval);
+//  } while(true);
+   } while(noChangeCount < noChangeCountResetTrigger && resetButtonCount < resetButtonCountResetTrigger);
 }
+
+void resetSystem() {
+  digitalWrite(resetPin, LOW);
+  delay(resetHoldTime);
+  digitalWrite(resetPin, HIGH);
+  delay(fumeHoodMonitorBootTime);
+  noChangeCount = 0;
+  resetButtonCount = 0;
+}


freundlicher

freundlicher

--- Projekt-Code/Projekt-Code.ino
+++ Projekt-Code/Projekt-Code.ino
@@ -32,6 +32,7 @@
       lcd.clear();
       lcd.cursor();
       lcd.blink();
+      lcd.print("Signal kommt...");
       digitalWrite(13,LOW);
       delay(500);
       digitalWrite(13,HIGH);
@@ -48,6 +49,7 @@
       d = ultras()*10/58;
       digitalWrite(8,LOW);
       digitalWrite(13,LOW);
+      lcd.clear();
       lcd.print("Abstand:");
       lcd.setCursor(3,1);
       lcd.print(d);


Adjust physical pins

Adjust physical pins

--- heartbeat_with_pulse.ino
+++ heartbeat_with_pulse.ino
@@ -15,14 +15,14 @@

 #define BAUD_RATE 9600
 #define NUM_LEDS_CH1 120
-#define LED_PIN_CH1 6
+#define LED_PIN_CH1 4
 #define NUM_LEDS_CH2 29
 #define LED_PIN_CH2 2
-#define ACCELX_PIN 1
+#define ACCELX_PIN 0
 #define ACCELY_PIN 2
-#define ACCELZ_PIN 3
-#define PULSE_PIN 5
-#define BUTTON_PIN 4
+#define ACCELZ_PIN 4
+#define PULSE_PIN 0
+#define BUTTON_PIN 6

 // ui
 int mode = 1;