esphome:
name: epaperesp32
esp32:
board: esp32dev
framework:
type: arduino
# Enable logging
logger:
# Enable Home Assistant API
api:
ota:
password: "xxxxxxxxxxxxxxxxxxxx"
wifi:
ssid: !secret wifi_ssid
password: !secret wifi_password
# Enable fallback hotspot (captive portal) in case wifi connection fails
ap:
ssid: "Epaperesp32 Fallback Hotspot"
password: "xxxxxxxxxxxx"
captive_portal:
font:
- file: 'fonts/tahoma.ttf'
id: font1
size: 16
spi:
clk_pin: 13
mosi_pin: 14
display:
- platform: waveshare_epaper
cs_pin: 15
dc_pin: 27
busy_pin: 25
reset_pin: 26
model: 2.13in-ttgo
full_update_every: 30
lambda: |-
it.print(0, 0, id(font1), "Pruts");
Tag Archives: arduino
M5stick and Home Assistant
Using Esphome in HA, you can flash arduino’s using your browser.
I wanted to test with a M5stickC because of the intergrated sensors.
Steps to take:
- Install Esphome
add repo from https://esphome.io/guides/getting_started_hassio.html - Connect M5Stick to usb ( you can do this from the same machine where your browser is running ), i connected the device directly to the NUC where Home Assistant is running.
- Open EspHome integration
- New Device (First time it will ask for your default Wifi credentials)
- Give it a name, and select Pick specifiec board (M5Stick-c)
- When presented a edit field with yml, past below for first test
- Click install to flash
esphome:
name: m5stickc
esp32:
board: m5stick-c
framework:
type: arduino
# Enable logging
logger:
# Enable Home Assistant API
api:
ota:
password: "xxxxxxxxxxxxxxxxxxxxxxx"
wifi:
ssid: !secret wifi_ssid
password: !secret wifi_password
# Enable fallback hotspot (captive portal) in case wifi connection fails
ap:
ssid: "M5Stickc Fallback Hotspot"
password: "xxxxxxxxxxxxxxx"
captive_portal:
web_server:
globals:
i2c:
- id: bus_b
sda: 21
scl: 22
scan: true
- id: bus_c
sda: 32
scl: 33
scan: true
binary_sensor:
sensor:
- platform: mpu6886
i2c_id: bus_b
address: 0x68
accel_x:
name: "MPU6886 Accel X"
accel_y:
name: "MPU6886 Accel Y"
accel_z:
name: "MPU6886 Accel z"
gyro_x:
name: "MPU6886 Gyro X"
gyro_y:
name: "MPU6886 Gyro Y"
gyro_z:
name: "MPU6886 Gyro z"
temperature:
name: "MPU6886 Temperature"
spi:
clk_pin: GPIO13
mosi_pin: GPIO15
# Below is test
color:
- id: my_red
red: 100%
green: 0%
blue: 0%
- id: my_yellow
red: 100%
green: 100%
blue: 0%
- id: my_green
red: 0%
green: 100%
blue: 0%
- id: my_blue
red: 0%
green: 0%
blue: 100%
- id: my_gray
red: 50%
green: 50%
blue: 50%
#Display size 135*240
display:
- platform: st7789v
id: tft
cs_pin: GPIO5
dc_pin: GPIO23
reset_pin: GPIO18
rotation: 270
Biggest problem was finding GPIO pins for i2c.
Biltong again
In 2020 i made a Biltong drying thingy, using a Nextion and a Arduino.
Today i’m preparing for some Chilli Biltong, which i’m going to put in the drying box tomorrow.
Arduino functionality
- Heating light
- Temperature / Humidity
- Air flow
- MQTT to home automation
- Nextion Display
Recipe
Meat
1 kg Beef Cut into 1.5cm - 2cm steak slices
Spice
2 tbsp black pepper coarsely ground.
2 tbsp course Sea Salt
1/2 tbsp smoked paprika
4 tbsp coriander seeds roasted and coarsely ground.
1 tbsp chili flakes
Marinade
50 ml worcestershire sauce
100 ml apple vinegar
1 tbsp tabasco sauce



Script – get images from Reolink cam
while true; do
wget "http://ip.number.or.hostname/cgi-bin/api.cgi?cmd=Snap&channel=0&rs=123asd&user=admin&password=MYSECRETPASS" -O $(date +%Y%m%d%H%M).jpg
sleep 60
done
Script to generate MP4 (60fps)
cat *.jpg | ffmpeg -f image2pipe -r 60 -vcodec mjpeg -i - -vcodec libx264 out.mp4
My Electronics Lab
Update: 20220829 – Microscope G1200
Tools:




thingy i made last year








Bought some boxes for chips
Bluetooth Macro Keyboard for Photo Management
- Cursor pad on the left
- 1 till 5 (see below)
- star + 1-5, rates 1 till 5 stars
- outline star – removes rating
- bookmark + 1-5, color marks image
- Triangle – start slideshow
- zoom-in, rotate CCW, reset zoom, rotate CW, zoom-out
- previous image, open image, fullscreen, exit fullscreen to manager and next image
I’ve used a esp32 with 18650 battery holder.
I still have to 3d print a case 🙂
Code:
#include <BleConnectionStatus.h>
#include <BleKeyboard.h>
#include <KeyboardOutputCallbacks.h>
#define DEBUG 0micro joystick
#define STAR 16
#define FLAG 17
#define COL1 18
#define COL2 19
#define COL3 21
#define COL4 22
#define COL5 23
#define COL6 25
#define ROW1 26
#define ROW2 27
#define ROW3 32
#define ROW4 33
int flagstate = 0;
int starstate = 0;
int row1state = 0;
int row2state = 0;
int row3state = 0;
int row4state = 0;
int col1state = 0;
int col2state = 0;
int col3state = 0;
int col4state = 0;
int col5state = 0;
int col6state = 0;
int colstate = 1;
BleKeyboard bleKeyboard;
void setup() {
#ifdef DEBUG
Serial.begin(9600);
#endif
bleKeyboard.begin();
pinMode(STAR, INPUT_PULLUP);
pinMode(FLAG, INPUT_PULLUP);
pinMode(ROW1, INPUT_PULLUP);
pinMode(ROW2, INPUT_PULLUP);
pinMode(ROW3, INPUT_PULLUP);
pinMode(ROW4, INPUT_PULLUP);
pinMode(COL1, OUTPUT);
pinMode(COL2, OUTPUT);
pinMode(COL3, OUTPUT);
pinMode(COL4, OUTPUT);
pinMode(COL5, OUTPUT);
pinMode(COL6, OUTPUT);
}
void loop() {
#ifdef DEBUG
Serial.print("Colstate : ");
Serial.print(colstate);
Serial.print('\n');
#endif
if (colstate == 1) {
digitalWrite(COL1, LOW);
digitalWrite(COL2, HIGH);
digitalWrite(COL3, HIGH);
digitalWrite(COL4, HIGH);
digitalWrite(COL5, HIGH);
digitalWrite(COL6, HIGH);
}
if (colstate == 2) {
digitalWrite(COL1, HIGH);
digitalWrite(COL2, LOW);
digitalWrite(COL3, HIGH);
digitalWrite(COL4, HIGH);
digitalWrite(COL5, HIGH);
digitalWrite(COL6, HIGH);
}
if (colstate == 3) {
digitalWrite(COL1, HIGH);
digitalWrite(COL2, HIGH);
digitalWrite(COL3, LOW);
digitalWrite(COL4, HIGH);
digitalWrite(COL5, HIGH);
digitalWrite(COL6, HIGH);
}
if (colstate == 4) {
digitalWrite(COL1, HIGH);
digitalWrite(COL2, HIGH);
digitalWrite(COL3, HIGH);
digitalWrite(COL4, LOW);
digitalWrite(COL5, HIGH);
digitalWrite(COL6, HIGH);
}
if (colstate == 5) {
digitalWrite(COL1, HIGH);
digitalWrite(COL2, HIGH);
digitalWrite(COL3, HIGH);
digitalWrite(COL4, HIGH);
digitalWrite(COL5, LOW);
digitalWrite(COL6, HIGH);
}
if (colstate == 6) {
digitalWrite(COL1, HIGH);
digitalWrite(COL2, HIGH);
digitalWrite(COL3, HIGH);
digitalWrite(COL4, HIGH);
digitalWrite(COL5, HIGH);
digitalWrite(COL6, LOW);
}
delay (100);
flagstate = digitalRead(FLAG);
starstate = digitalRead(STAR);
row1state = digitalRead(ROW1);
row2state = digitalRead(ROW2);
row3state = digitalRead(ROW3);
row4state = digitalRead(ROW4);
#ifdef DEBUG
Serial.print("Rowstates : ");
Serial.print(row1state);
Serial.print(row2state);
Serial.print(row3state);
Serial.print(row4state);
Serial.print('\n');
#endif
// ROW1 = UP,DOWN,LEFT,RIGHT
if (bleKeyboard.isConnected() && colstate == 1) {
// UP
#ifdef DEBUG
Serial.print("Up Pressed ");
Serial.print('\n');
#endif
if (row1state == 0) {
bleKeyboard.press(KEY_UP_ARROW);
delay (100);
bleKeyboard.releaseAll();
}
// DOWN
if (row2state == 0) {
bleKeyboard.press(KEY_DOWN_ARROW);
delay (100);
bleKeyboard.releaseAll();
}
// LEFT
if (row3state == 0) {
bleKeyboard.press(KEY_LEFT_ARROW);
delay (100);
bleKeyboard.releaseAll();
}
// RIGHT
if (row4state == 0) {
bleKeyboard.press(KEY_RIGHT_ARROW);
delay (100);
bleKeyboard.releaseAll();
}
}
// ROW2 = (1),(star),ZOOMIN,PREVIOUS
if (bleKeyboard.isConnected() && colstate == 2) {
// 1 - star
if (row1state == 0 && starstate == 0) {
bleKeyboard.press(KEY_LEFT_CTRL);
bleKeyboard.press('1');
delay (100);
bleKeyboard.releaseAll();
}
// 1 - flag
if (row1state == 0 && flagstate == 0) {
bleKeyboard.press(KEY_LEFT_ALT);
bleKeyboard.press('1');
delay (100);
bleKeyboard.releaseAll();
}
// NO ROWSTATE2
// zoom in
if (row3state == 0) {
bleKeyboard.press('+');
delay (100);
bleKeyboard.releaseAll();
}
// PREVIOUS
if (row4state == 0) {
bleKeyboard.press(KEY_LEFT_CTRL);
bleKeyboard.press(KEY_LEFT_ARROW);
delay (100);
bleKeyboard.releaseAll();
}
}
// ROW3 = (2),unstar,CCWrotate,open
if (bleKeyboard.isConnected() && colstate == 3) {
// 2 - star
if (row1state == 0 && starstate == 0) {
bleKeyboard.press(KEY_LEFT_CTRL);
bleKeyboard.press('2');
delay (100);
bleKeyboard.releaseAll();
}
// 2 - flag
if (row1state == 0 && flagstate == 0) {
bleKeyboard.press(KEY_LEFT_ALT);
bleKeyboard.press('2');
delay (100);
bleKeyboard.releaseAll();
}
// unstar
if (row2state == 0) {
bleKeyboard.press(KEY_LEFT_CTRL);
bleKeyboard.press('0');
delay (100);
bleKeyboard.releaseAll();
}
// CCW rotate
if (row3state == 0) {
bleKeyboard.press(KEY_LEFT_CTRL);
bleKeyboard.press(KEY_LEFT_ALT);
bleKeyboard.press(KEY_LEFT_ARROW);
delay (100);
bleKeyboard.releaseAll();
}
// open
if (row4state == 0) {
bleKeyboard.press(KEY_RETURN);
delay (100);
bleKeyboard.releaseAll();
}
}
// ROW4 = (3),(flag),zoom,fullscreen
if (bleKeyboard.isConnected() && colstate == 4) {
// 3 - star
if (row1state == 0 && starstate == 0) {
bleKeyboard.press(KEY_LEFT_CTRL);
bleKeyboard.press('3');
delay (100);
bleKeyboard.releaseAll();
}
// 3 - flag
if (row1state == 0 && flagstate == 0) {
bleKeyboard.press(KEY_LEFT_ALT);
bleKeyboard.press('3');
delay (100);
bleKeyboard.releaseAll();
}
// NO ROWSTATE2
// zoom reset
if (row3state == 0) {
bleKeyboard.press('*');
delay (100);
bleKeyboard.releaseAll();
}
// fullscreen
if (row4state == 0) {
bleKeyboard.press('f');
delay (100);
bleKeyboard.releaseAll();
}
}
// ROW5 = (4),unflag,CWrotate,exit
if (bleKeyboard.isConnected() && colstate == 5) {
// 4 - star
if (row1state == 0 && starstate == 0) {
bleKeyboard.press(KEY_LEFT_CTRL);
bleKeyboard.press('4');
delay (100);
bleKeyboard.releaseAll();
}
// 4 - flag
if (row1state == 0 && flagstate == 0) {
bleKeyboard.press(KEY_LEFT_ALT);
bleKeyboard.press('4');
delay (100);
bleKeyboard.releaseAll();
}
// unflag
if (row2state == 0) {
bleKeyboard.press(KEY_LEFT_ALT);
bleKeyboard.press('0');
delay (100);
bleKeyboard.releaseAll();
}
// CW rotate
if (row3state == 0) {
bleKeyboard.press(KEY_LEFT_CTRL);
bleKeyboard.press(KEY_LEFT_ALT);
bleKeyboard.press(KEY_RIGHT_ARROW);
delay (100);
bleKeyboard.releaseAll();
}
// exit
if (row4state == 0) {
bleKeyboard.press(KEY_ESC);
delay (100);
bleKeyboard.releaseAll();
}
}
// ROW6 = (5),slideshow,zoomout,next
if (bleKeyboard.isConnected() && colstate == 6) {
// 5 - star
if (row1state == 0 && starstate == 0) {
bleKeyboard.press(KEY_LEFT_CTRL);
bleKeyboard.press('5');
delay (100);
bleKeyboard.releaseAll();
}
// 5 - flag
if (row1state == 0 && flagstate == 0) {
bleKeyboard.press(KEY_LEFT_ALT);
bleKeyboard.press('5');
delay (100);
bleKeyboard.releaseAll();
}
// slideshow
if (row2state == 0) {
bleKeyboard.press(KEY_ESC);
bleKeyboard.press(KEY_LEFT_CTRL);
bleKeyboard.press('s');
delay (100);
bleKeyboard.releaseAll();
}
// zoom out
if (row3state == 0) {
bleKeyboard.press('-');
delay (100);
bleKeyboard.releaseAll();
}
// next
if (row4state == 0) {
bleKeyboard.press(KEY_LEFT_CTRL);
bleKeyboard.press(KEY_RIGHT_ARROW);
delay (100);
bleKeyboard.releaseAll();
}
}
colstate++;
if (colstate == 7) {
colstate = 1;
}
}
Hex Dimmer
Control a dimmer using a hex wireless box.
Parts
- Wemos Mini
- MPU6050 – Gyroscope Module
- 10k Resistor
- TP4056 – Battery Charger Module
- Mini Battery
- Wireless Charger
Put the box flat on the table to switch off.
When you put it on one side, it will controll your lights brightness.
20,40,60,80 and 100%, just by rotating and putting it down on its sides.
Schematics (without the wireless charging part)
Node-Red Controll part (source below)
Nice to have’s :
Arduino-sleep mode, wakeup with a movement sensor.
Arduino Code
#include <Wire.h>
//#include <SPI.h>
#include <PubSubClient.h>
//#include <string.h>
//#include <stdio.h>
#include <ESP8266WiFi.h>
// Wifi settings
const char* ssid = "xxxxxx";
const char* password = "xxxxxxxxxx";
const char* mqtt_server = "10.1.0.17";
// I2C address of the MPU-6050 - 0x68 or 0x69 if AD0 is pulled HIGH
const int MPU = 0x68;
int16_t AcX, AcY, AcZ, GyX, GyY, GyZ;
float gForceX, gForceY, gForceZ, rotX, rotY, rotZ;
// Wifi MAC address
byte mac[]= { 0xDE, 0xED, 0xBA, 0xFE, 0xFE, 0xED };
WiFiClient espClient;
IPAddress ip;
PubSubClient mqttClient(espClient);
// IP address of your MQTT server
const char* server = "10.1.0.17";
//const char* outTopic = "test/";
//const char* server = "iot.eclipse.org";
void dataReceiver(){
Wire.beginTransmission(MPU);
Wire.write(0x3B); // starting with register 0x3B (ACCEL_XOUT_H)
Wire.endTransmission(false);
Wire.requestFrom(MPU,14,true); // request a total of 14 registers
AcX = Wire.read()<<8|Wire.read(); // 0x3B (ACCEL_XOUT_H) & 0x3C (ACCEL_XOUT_L)
AcY = Wire.read()<<8|Wire.read(); // 0x3D (ACCEL_YOUT_H) & 0x3E (ACCEL_YOUT_L)
AcZ = Wire.read()<<8|Wire.read(); // 0x3F (ACCEL_ZOUT_H) & 0x40 (ACCEL_ZOUT_L)
GyX = Wire.read()<<8|Wire.read(); // 0x43 (GYRO_XOUT_H) & 0x44 (GYRO_XOUT_L)
GyY = Wire.read()<<8|Wire.read(); // 0x45 (GYRO_YOUT_H) & 0x46 (GYRO_YOUT_L)
GyZ = Wire.read()<<8|Wire.read(); // 0x47 (GYRO_ZOUT_H) & 0x48 (GYRO_ZOUT_L)
processData();
}
void processData(){
gForceX = AcX / 16384.0;
gForceY = AcY / 16384.0;
gForceZ = AcZ / 16384.0;
rotX = GyX / 131.0;
rotY = GyY / 131.0;
rotZ = GyZ / 131.0;
}
void debugFunction(int16_t AcX, int16_t AcY, int16_t AcZ, int16_t GyX, int16_t GyY, int16_t GyZ){
// Print the MPU values to the serial monitor
Serial.print("Accelerometer: ");
Serial.print("X="); Serial.print(gForceX);
Serial.print("|Y="); Serial.print(gForceY);
Serial.print("|Z="); Serial.println(gForceZ);
Serial.print("Gyroscope:");
Serial.print("X="); Serial.print(rotX);
Serial.print("|Y="); Serial.print(rotY);
Serial.print("|Z="); Serial.println(rotZ);
}
void reconnect() {
// Loop until we're reconnected
while (!mqttClient.connected()) {
Serial.print("Attempting MQTT connection...");
// Attempt to connect
if (mqttClient.connect("arduinoClient")){
Serial.println("connected");
}
else {
Serial.print("failed, rc=");
Serial.print(mqttClient.state());
Serial.println(" try again in 5 seconds");
// Wait 5 seconds before retrying
delay(1000);
}
}
}
void setup(){
Serial.begin(9600);
setup_wifi();
Wire.begin(0,2);
Wire.beginTransmission(MPU);
Wire.write(0x6B); // PWR_MGMT_1 register
Wire.write(0); // set to zero (wakes up the MPU-6050)
Wire.endTransmission(true);
mqttClient.setServer(server, 1883);
// Ethernet.begin(mac);
// ip = Ethernet.localIP();
Serial.println(ip);
Serial.println(server);
//delay(1500);
}
char* init(float val){
char buff[100];
for (int i = 0; i < 100; i++) {
dtostrf(val, 4, 2, buff); //4 is mininum width, 6 is precision
}
return buff;
}
void setup_wifi() {
delay(10);
// We start by connecting to a WiFi network
Serial.println();
Serial.print("Connecting to ");
Serial.println(ssid);
WiFi.begin(ssid, password);
while (WiFi.status() != WL_CONNECTED) {
delay(500);
Serial.print(".");
}
Serial.println("");
Serial.println("WiFi connected");
Serial.println("IP address: ");
Serial.println(WiFi.localIP());
}
void dataAcc(){
char mpu6050X[100]= "";
strcat(mpu6050X,init(gForceX));
char mpu6050Y[100]= "";
strcat(mpu6050Y,init(gForceY));
char mpu6050Z[100]= "";
strcat(mpu6050Z,init(gForceZ));
// accelerometer - "topic, mpu6050"
mqttClient.publish("AcX/", mpu6050X);
mqttClient.publish("AcY/", mpu6050Y);
mqttClient.publish("AcZ/", mpu6050Z);
// mqttClient.publish(outTopic, "text to send via mqtt");
}
void dataGy(){
char mpu6050X[100]= "";
strcat(mpu6050X,init(rotX));
char mpu6050Y[100]= "";
strcat(mpu6050Y,init(rotY));
char mpu6050Z[100]= "";
strcat(mpu6050Z,init(rotZ));
// gyroscope - "topic, mpu6050"
mqttClient.publish("GyX/", mpu6050X);
mqttClient.publish("GyY/", mpu6050Y);
mqttClient.publish("GyZ/", mpu6050Z);
// mqttClient.publish(outTopic, "text to send via mqtt");
}
void loop(){
dataReceiver();
debugFunction(AcX,AcY,AcZ,GyX,GyY,GyZ);
if (!mqttClient.connected()) {
reconnect();
}
mqttClient.loop();
dataAcc();
dataGy();
delay(2000);
}
Nodered Flow
[
{
"id": "7550958a.b29dec",
"type": "mqtt in",
"z": "a0126a6a.9c70b8",
"name": "",
"topic": "hex/x",
"qos": "2",
"broker": "8c74c5f6.9a7a48",
"x": 270,
"y": 100,
"wires": [
[
"d251dd79.5700d"
]
]
},
{
"id": "e84b0a1.18096f8",
"type": "mqtt in",
"z": "a0126a6a.9c70b8",
"name": "",
"topic": "hex/y",
"qos": "2",
"broker": "8c74c5f6.9a7a48",
"x": 270,
"y": 180,
"wires": [
[
"9c27bc8f.b62dd"
]
]
},
{
"id": "6a1a0d8d.b3e754",
"type": "mqtt in",
"z": "a0126a6a.9c70b8",
"name": "",
"topic": "hex/z",
"qos": "2",
"broker": "8c74c5f6.9a7a48",
"x": 270,
"y": 260,
"wires": [
[]
]
},
{
"id": "2d2a911a.6af3fe",
"type": "ui_gauge",
"z": "a0126a6a.9c70b8",
"name": "",
"group": "d43a9f25.6c874",
"order": 23,
"width": 0,
"height": 0,
"gtype": "gage",
"title": "gauge",
"label": "units",
"format": "{{value}}",
"min": "0",
"max": "100",
"colors": [
"#00b500",
"#e6e600",
"#ca3838"
],
"seg1": "",
"seg2": "",
"x": 1010,
"y": 120,
"wires": []
},
{
"id": "d251dd79.5700d",
"type": "function",
"z": "a0126a6a.9c70b8",
"name": "Get level from box",
"func": "var my=msg.payload;\nmsg.payload = {};\nif (my == 0.85){\n msg.payload=20;\n return msg;\n}\nelse if (my == 0.86){\n msg.payload=20;\n return msg;\n}\nelse if (my == 0.87){\n msg.payload=20;\n return msg;\n}\n\nelse if (my == 0.03){\n msg.payload=40;\n return msg;\n}\nelse if (my == 0.02){\n msg.payload=40;\n return msg;\n}\n\nelse if (my == 3.17){\n msg.payload=60;\n return msg;\n}\nelse if (my == 3.18){\n msg.payload=60;\n return msg;\n}\n\nelse if (my == 0.04){\n msg.payload=80;\n return msg;\n}\nelse if (my == 0.05){\n msg.payload=80;\n return msg;\n}\n\nelse if (my == 3.95){\n msg.payload=100;\n return msg;\n}\nelse if (my == 3.96){\n msg.payload=100;\n return msg;\n}\nelse {\n return msg;\n \n}\n",
"outputs": 1,
"noerr": 0,
"x": 510,
"y": 120,
"wires": [
[
"ecd746cc.fce348",
"8721e902.45d8b8",
"39c8f1ac.86affe"
]
]
},
{
"id": "39c8f1ac.86affe",
"type": "function",
"z": "a0126a6a.9c70b8",
"name": "Set Living spots level (idx 5)",
"func": "var level = Number(msg.payload);\nmsg.payload = {};\nmsg.payload.idx = 5;\nmsg.payload.switchcmd = (\"Set Level\");\nmsg.payload.command = \"switchlight\";\nmsg.payload.level = level;\nreturn msg; ",
"outputs": 1,
"noerr": 0,
"x": 820,
"y": 260,
"wires": [
[
"bc0d6507.1d7748"
]
]
},
{
"id": "bc0d6507.1d7748",
"type": "mqtt out",
"z": "a0126a6a.9c70b8",
"name": "",
"topic": "domoticz/in",
"qos": "",
"retain": "",
"broker": "8c74c5f6.9a7a48",
"x": 1080,
"y": 260,
"wires": []
},
{
"id": "9c27bc8f.b62dd",
"type": "function",
"z": "a0126a6a.9c70b8",
"name": "Flat or standing up",
"func": "var mya=msg.payload;\nmsg.payload = {};\nif (mya < -3.80){\n flow.set(\"levely\",1);\n msg.payload = \"plat\";\n }\nelse {\n flow.set(\"levely\",2);\n msg.payload = \"rechtop\";\n}\nreturn msg;",
"outputs": 1,
"noerr": 0,
"x": 450,
"y": 200,
"wires": [
[
"ecd746cc.fce348"
]
]
},
{
"id": "ecd746cc.fce348",
"type": "debug",
"z": "a0126a6a.9c70b8",
"name": "",
"active": true,
"tosidebar": true,
"console": false,
"tostatus": false,
"complete": "false",
"x": 640,
"y": 340,
"wires": []
},
{
"id": "8721e902.45d8b8",
"type": "function",
"z": "a0126a6a.9c70b8",
"name": "Gate for level ",
"func": "\nvar x = msg.payload;\ny = flow.get(msg.payload);\nvar y = flow.get('levely') || 0;\n\nif (y == 1){\n msg.payload = {};\n msg.payload = 0;\n} else {\n msg.payload = x;\n}\n\nreturn msg;",
"outputs": 1,
"noerr": 0,
"x": 810,
"y": 120,
"wires": [
[
"2d2a911a.6af3fe",
"da72437e.88376"
]
]
},
{
"id": "da72437e.88376",
"type": "debug",
"z": "a0126a6a.9c70b8",
"name": "",
"active": true,
"tosidebar": true,
"console": false,
"tostatus": false,
"complete": "false",
"x": 890,
"y": 200,
"wires": []
},
{
"id": "8c74c5f6.9a7a48",
"type": "mqtt-broker",
"z": "",
"name": "10.1.0.17",
"broker": "10.1.0.17",
"port": "1883",
"clientid": "",
"usetls": false,
"compatmode": true,
"keepalive": "15",
"cleansession": true,
"birthTopic": "",
"birthQos": "0",
"birthPayload": "",
"closeTopic": "",
"closePayload": "",
"willTopic": "",
"willQos": "0",
"willPayload": ""
},
{
"id": "d43a9f25.6c874",
"type": "ui_group",
"z": "",
"name": "Control",
"tab": "739541e2.18396",
"order": 1,
"disp": true,
"width": "6",
"collapse": false
},
{
"id": "739541e2.18396",
"type": "ui_tab",
"z": "",
"name": "7inch",
"icon": "dashboard",
"order": 1,
"disabled": false,
"hidden": false
}
]
Mattermost Mqtt Flag Integration
UPDATE 20231020 – Via USB Serial (also schematic for below integration)
https://www.henriaanstoot.nl/2023/10/20/thunderbird-mail-notification-flag-via-usb/
Using a servo which is MQTT controlled, and a slash command in Mattermost, i can be notified by friends and colleages.
Flag, and monitor-stand are 3D printed.
ESP is a simple wemos mini.
Laser pointer web controlled
Coline sometimes plays games with her sisters online using my streaming server. (Due to Covid)
Some games are difficult because you have to point to a location on the table. So i came up with a laser pointer solution.



The idea is: Send a url to the players with a streaming camera, you see the game on your screen but you can click on a location on the screen to move a laser pointer to that location.
Below is a proof of concept using the Lasercut worldmap on the wall and a website with a worldmap.


Code to place on the ESP:
This will connect to the MQTT broker and listens for messages on the servo/pan and tilt topic.
#include <ESP8266WiFi.h>
#include <PubSubClient.h>
#include <Servo.h>
Servo pan;
Servo tilt;
const char* ssid = "MYSSI";
const char* password = "MYWIFIPASS";
const char* mqtt_server = "IPMQTTBROKER";
const char* topic_pan = "servo/pan";
const char* topic_tilt = "servo/tilt";
WiFiClient espClient;
PubSubClient client(espClient);
long lastMsg = 0;
char msg[50];
int value = 0;
void setup() {
pan.attach(D5);
tilt.attach(D6);
setup_wifi();
client.setServer(mqtt_server, 1883);
client.setCallback(callback);
}
void setup_wifi() {
delay(5);
WiFi.begin(ssid, password);
while (WiFi.status() != WL_CONNECTED) {
delay(500);
}
}
void callback(char* topic, byte* payload, unsigned int length) {
String string;
for (int i = 0; i < length; i++) {
string+=((char)payload[i]);
}
int pos = string.toInt();
if ( strcmp(topic, topic_pan) == 0 ) {
pan.write(pos);
}
if ( strcmp(topic, topic_tilt) == 0 ) {
tilt.write(pos);
}
delay(15);
}
void reconnect() {
while (!client.connected()) {
if (client.connect("ESP8266Client")) {
client.subscribe(topic_pan);
client.subscribe(topic_tilt);
} else {
delay(5000);
}
}
}
void loop() {
if (!client.connected()) {
reconnect();
}
client.loop();
delay(100);
}
Website PHP code:
This has some calibration code to get coordinates lined-up
<?Php
$foo_x=$_POST['foo_x'];
$foo_y=$_POST['foo_y'];
echo "X=$foo_x, Y=$foo_y ";
$x=160 - round($foo_x/30);
$y=38 - round($foo_y/100);
system('/usr/bin/mosquitto_pub -h 10.1.0.17 -t servo/pan -m "' . $x . '"');
system('/usr/bin/mosquitto_pub -h 10.1.0.17 -t servo/tilt -m "' . $y . '"');
?>
<form action='' method=post>
<input type="image" alt=' Finding coordinates of an image' src="worldmap.jpg"
name="foo" style=cursor:crosshair;/>
</form>
POC
Action LSC Alarm/Siren
Update 20221208 – removed internals

I’ve modded several LSC devices, most of them i could flash with esp-easy or tasmota.
Why mod it? Because it uses the cloud .. i’d like to keep control myself.
Just connect/solder a USB to TTL Converter UART Module like below.
(See other posts)

But this alarm was different, i ended up removing the chip and replace it with a ESP12.

So now i had to figure out which GPIO pins and how to control them.
#1/bin/bash
# Flashed ESP Easy on this one
# When i did this, 2019, you needed version 2.1-beta1
# GPIO 4 controls LED
sleep 10
curl http://10.1.1.251/control?cmd=GPIO,4,1
sleep 1
curl http://10.1.1.251/control?cmd=GPIO,4,0
sleep 1
curl http://10.1.1.251/control?cmd=GPIO,4,1
sleep 2
curl http://10.1.1.251/control?cmd=GPIO,4,0
sleep 5
# Sending rtttl ringtone
curl "http://10.1.1.251/control?cmd=rtttl,5:d=4,o=5,b=112:8a,8a,a,8a,8a,a,8a,8c6,8f.,16g,2a,8a-,8a-,8a-.,16a-,8a-,8a,8a.,16a,8a,8g,8g,8a,g,c6"
alarm sound
curl "http://10.1.1.251/control?cmd=rtttl,5:d=4,o=5,b=160:2g,2c6,2g,2c6,2g,2c6,2g,2c6"
pager
curl "http://10.1.1.251/control?cmd=rtttl,5:d=4,o=5,b=160:8d6,16p,2d6,16p,8d6,16p,2d6,16p,8d6,16p,2d6"
Update 20221208 – removed internals
Removed my old hack and replaced it with a Wemos D1.
Added a LED
Next to do .. add a amplifier using a LM356/358
Music Page Turner
UPDATE: 20230320 new version
My first version of the Bluetooth page turner.
This was made using an Arduino and some buttons.
I’m using Fbreader and Ebookdroid on the tablet.
Code:
Note: Volume buttons work for both apps, if you want to use other keys, you need to put a keymap.xml file in your fbreader books directory on your android device to remap those!
#include <BleKeyboard.h>
#define RIGHT_TURN 4
#define LEFT_TURN 5
BleKeyboard bleKeyboard("fashpageturner", "Bluetooth Device Manufacturer", 100);
void setup() {
bleKeyboard.begin();
pinMode(LEFT_TURN, INPUT_PULLUP);
pinMode(RIGHT_TURN, INPUT_PULLUP);
}
void loop() {
if (bleKeyboard.isConnected() && !digitalRead(RIGHT_TURN)) {
bleKeyboard.press(KEY_MEDIA_VOLUME_UP);
delay (100);
bleKeyboard.releaseAll();
}
if (bleKeyboard.isConnected() && !digitalRead(LEFT_TURN)) {
bleKeyboard.press(KEY_MEDIA_VOLUME_DOWN);
delay (100);
bleKeyboard.releaseAll();
}
}
NEW Version



















