Using OBS and chromakey (greenscreen)
3D Printing
In 2012 I started with 3D printing, I didn’t have my own yet. So it was done using shapeways.
April 2019 I ordered my own, a Creality CR-10S.
Specs
- Build Volume: 300 x 300 x 400mm
- Layer Thickness: 0.1-0.4mm
- Positioning Precision: Z-axis – 0.0025mm, X & Y-axis – 0.015mm
- Nozzle Temperature: 250°C
- Printing Speed: 200mm/s
- Filament Diameter: 1.75mm
- Printer Weight: 9kg
- Printing Filament: PLA, ABS, TPU, Wood, Carbon fiber, etc.
- Input Support: SD card/USB
- File Types: STL/OBJ/G-Code/JPG
- Supports(OS): Windows/Linux/Mac/XP
- Printing Software: Cura/Repetier-Host
- Frame & Body: Imported V-Slot Aluminum Bearings
- Power Requirement Input: AC110V~220V, Output: 12V, Power 270W
- Output: DC12V, 10A 100~120W (Support storage battery)
- Working Condition Temp:10-30°C, Humidity: 20-50%
Problem with this 3D Printer is the lack of a thermal runaway detection. My solution is a MQTT/Nodered warning system which plays an alarm and uses a shelly to disconnect the power.
https://www.henriaanstoot.nl/2022/05/11/mqtt-bash-nodered-notify/
Software I Use – see other posts
- Openscad
- Cura
- Meshroom
- Blender
- Sketchup
Hardware
- Octoprint on a raspberry pi – (with Octoscreen)
- Octoprint monitor
I’m using a filament sensor like the one in below picture
It used to be a DIY thingy using an arduino. (below)
Filament under my table ( in the “dark” )
Software on my mobile
- Octoremote
https://play.google.com/store/apps/details?id=com.kabacon.octoremote
Hints and tips
- Use painters tape against bending of the glass, it will warp because of the heat.
- Use 3D spray to fix model to base-plate.
(I used a gluestick before) - Always think of model placement, less support the better.
- Try to remember which fill-in is the best for your purpose.
- Calibrate distance print tool and glass using printing paper.
- Know your printer, make a lot of test prints when starting.
- Learn / read about 3D printing finishing. Sanding/smoothing/melting.
I’ve got some smoothing liquid (print coating) , a dremel and below tool
- Use a print model to test your leveling
( https://www.printables.com/model/69956-bed-level-calibration-square-grid ) - Learn how gcode’s work!
Want to know what filament is in your gcode?
grep M104 <file.gcode> # M104 is the temperature M104 200 -> PLA M104 240 -> PETG
Laser engraving using my 3D printer (pre lasercutter)
Websites
- Yeggi
- Thingiverse
- printables – not that much
UPDATE 20230803
Best gap filler i found which is easily sanded down with a dremel.
Alabastine Polyester Plamuur
DDC i2c monitor control
I wanted to control the input of my monitors, these are my findings.
DDC – Display Data Channel
I2C – (Inter-Integrated Circuit, eye-squared-C), alternatively known as IIC, is a synchronous, multi-master/multi-slave (controller/target) bus
Getting monitor information with the ddccontrol -p command
##### PART OF THE OUTPUT ##### Detected monitors : - Device: dev:/dev/i2c-9 DDC/CI supported: Yes Monitor Name: VESA standard monitor Input type: Digital (Automatically selected) - Device: dev:/dev/i2c-7 DDC/CI supported: Yes Monitor Name: VESA standard monitor Input type: Digital - Device: dev:/dev/i2c-6 DDC/CI supported: Yes Monitor Name: VESA standard monitor Input type: Digital Reading EDID and initializing DDC/CI at bus dev:/dev/i2c-9... I/O warning : failed to load external entity "/usr/share/ddccontrol-db/monitor/AOC2490.xml"
Switching inputs
ddcutil -b 7 setvcp 0x60 0x11 # 7 is Second monitor (starts with 6), 0x60 is the input register (see below) and 0x11 is HDMI ddcutil -b 6 setvcp 0x60 0x0f # First monitor DP (Displaylink) alternative command ddccontrol -r 0x60 -w 15 dev:/dev/i2c-7
List the control registers
ddccontrol -d dev:/dev/i2c-6 ddccontrol version 0.6.0 Copyright 2004-2005 Oleg I. Vdovikin (oleg@cs.msu.su) Copyright 2004-2006 Nicolas Boichat (nicolas@boichat.ch) This program comes with ABSOLUTELY NO WARRANTY. You may redistribute copies of this program under the terms of the GNU General Public License. Reading EDID and initializing DDC/CI at bus dev:/dev/i2c-6... I/O warning : failed to load external entity "/usr/share/ddccontrol-db/monitor/AOC2490.xml" Document not parsed successfully. EDID readings: Plug and Play ID: AOC2490 [VESA standard monitor] Input type: Analog =============================== WARNING =============================== There is no support for your monitor in the database, but ddccontrol is using a basic generic profile. Many controls will not be supported, and some controls may not work as expected. Please update ddccontrol-db, or, if you are already using the latest version, please send the output of the following command to ddccontrol-users@lists.sourceforge.net: LANG= LC_ALL= ddccontrol -p -c -d Thank you. =============================== WARNING =============================== Controls (valid/current/max) [Description - Value name]: Control 0x02: +/1/2 C [New Control Value - No changes] Control 0x04: +/0/1 C [Restore Factory Defaults] Control 0x05: +/0/1 C [Restore Brightness and Contrast] Control 0x08: +/0/1 C [Restore Factory Default Color] Control 0x10: +/90/100 C [Brightness] Control 0x12: +/50/100 C [Contrast] Control 0x14: +/5/13 C [???] Control 0x16: +/50/100 C [Red maximum level] Control 0x18: +/50/100 C [Green maximum level] Control 0x1a: +/50/100 C [Blue maximum level] Control 0x60: +/772/4 C [Input Source Select (Main)] Control 0x62: +/17/100 C [Audio Speaker Volume Adjust] Control 0x6c: +/50/100 C [Red minimum level] Control 0x6e: +/50/100 C [Green minimum level] Control 0x70: +/50/100 C [Blue minimum level] Control 0xac: +/6750/65535 [???] Control 0xae: +/6000/65535 [???] Control 0xb2: +/1/8 [???] Control 0xb6: +/3/8 C [???] Control 0xc8: +/5/65302 C [???] Control 0xc9: +/8/65535 C [???] Control 0xcc: +/4/255 [???] Control 0xd6: +/1/4 C [DPMS Control - On] Control 0xdf: +/513/65535 C [???] Control 0xfe: +/4/255 [???]
Setting volume (reg 0x62) of monitor 2
ddcutil -b 7 setvcp 0x62 0x01
AOC monitor PROBLEM
You can’t switch from an input which is not active!
So my workstation is connected via DP, and i can switch to HDMI.
Now i HAVE TO use the hdmi to switch back to DP.
A solution could be to ssh into the machine connected with HDMI (passwordless login) and switch back to DP.
I made a mqtt button sending a topic that was read by the two machines using the mqtt python program elsewhere on this site.
(Rotary Mqtt Volume control)
gddccontrol
Explaining shelly and hotel circuit (while drinking whisky and playing with 220v)
Needed to explain a method you can use with shelly devices to some colleagues.
Forgot about this test later, a friend of mine visited me a few days later and warned me about this still being there.
Colleage at work brings a Freecom Internet Radio
Big mistake 😉 It a Linux ARM system with Busybox
Less do some searching on the web.
Ah .. enable telnet
Open in a browser:
http://192.168.1.x/admin/cgi-bin/debug.cgi
Enable telnet:
Connect and install Pong:
telnet 192.168.1.x (username root) # wget http://agilo.acjs.net/files/mppong/setup.sh # chmod 755 setup.sh # ./setup.sh # ./start.sh # ./start.sh musicpal # For the normal player
Links i have to look into:
https://www.qemu.org/docs/master/system/arm/musicpal.html
Garbage display
I wanted to know when trash is being collected. So i made a dual led thingy.
When we lived in Utrecht, the website which mentions when, what is collected was easy .. like a API
We live in Hilversum now, so i had to write a scraper.
UPDATE : Script not working anymore. Site has been changed, and I’m not willing to run a headless browser (phantomjs) to scrape the info
See below my new solution
Script to set leds
#!/bin/bash set -x if [[ $# -eq 0 ]] ; then curl http://10.1.0.46/control?cmd=NeoPixel,1,0,0,0 curl http://10.1.0.46/control?cmd=NeoPixel,2,0,0,0 exit 0 fi set -x if [ $1 = "GFT" ] ;then led1="150,0,0" ;fi if [ $1 = "Rest" ] ;then led1="150,150,150" ;fi if [ $1 = "Paper" ] ;then led1="0,0,150" ;fi if [ $1 = "Plastic" ] ;then led1="75,191,0" ;fi if [ $1 = "Textiel" ] ;then led1="191,191,191" ;fi if [ $1 = "Kerstbomen" ] ;then led1="191,0,0" ;fi if [ "w$2" = "wgft" ] ;then led2="255,0,0" ;fi if [ "w$2" = "wRest" ] ;then led2="150,150,150" ;fi if [ "w$2" = "wpapier" ] ;then led2="0,0,255" ;fi if [ "w$2" = "wplastic" ] ;then led2="100,255,0" ;fi if [ "w$2" = "wTextiel" ] ;then led2="191,191,191" ;fi if [ "w$2" = "wKerstbomen" ] ;then led2="191,0,0" ;fi if [[ $# -eq 1 ]] ; then led2=$led1 fi curl http://10.1.0.46/control?cmd=NeoPixel,1,$led1 curl http://10.1.0.46/control?cmd=NeoPixel,2,$led2
Scraper ( calls setleds and mqtt )
#!/bin/bash
cd /home/pi/
./afvalleds
curl -s https://inzamelkalender.gad.nl/adres/1222HP:39 > /tmp/afvalcurl
today=$(date +%F)
tomorrow=$(date --date="next day" +%F)
for f in petfles-blik-drankpak-pmd.svg appel-gft.svg kliko-grijs-rest.svg doos-karton-papier.svg shirt-textiel.svg kerstboom.svg ; do
p1=$(cat /tmp/afvalcurl | grep -i -A2 "$f" | grep class | cut -f2 -d\> | cut -f1 -d\< | cut -f2- -d" ")
p2=$(echo $p1 | sed s/mei/may/g | sed s/okt/oct/g )
p3=$(date --date="$p2" +%F)
dater=$p3
now=$(date -d $(date --date="1 days ago" +%F) +%s)
p3epoch=$(date --date="$p3" +%s)
diff=$(expr $p3epoch - $now)
if [ $diff -lt 0 ] ; then
dater=$(date -d "$p3 1 year" +%F)
fi
whatdate=$(echo $f | sed s/petfles-blik-drankpak-pmd.svg/Plastic/g |sed s/appel-gft.svg/GFT/g | sed s/kliko-grijs-rest.svg/Rest/g | sed s/doos-karton-papier.svg/Paper/g | sed s/shirt-textiel.svg/Textiel/g | sed s/kerstboom.svg/Kerstbomen/g)
mosquitto_pub -h 127.0.0.1 -p 1883 -t "afvalwijzer/$whatdate" -m "$dater"
if [ "w$today" == "w$dater" ]; then
alltoday="$alltoday $whatdate"
fi
if [ "w$tomorrow" == "w$dater" ]; then
alltomorrow="$alltomorrow $whatdate"
fi
done
mosquitto_pub -h 127.0.0.1 -p 1883 -t "afvalwijzer/Today" -m "$alltoday"
mosquitto_pub -h 127.0.0.1 -p 1883 -t "afvalwijzer/Tomorrow" -m "$alltomorrow"
./afvalleds $alltomorrow
Utrecht scraper
#!/bin/bash set -x curl -s "http://json.mijnafvalwijzer.nl/?method=postcodecheck&postcode=3543eh&huisnummer=72&" > /tmp/afv cat /tmp/afv | python -mjson.tool > /tmp/afv.json today=$(cat /tmp/afv.json | grep -A1 $(date +%Y-%m-%d) | grep nameType | cut -f4 -d\" | paste -sd "/" -) today=$(echo $today | sed s/\ /,/g) tomorrow=$(cat /tmp/afv.json | grep -A1 $(date -d "+1 days" +%Y-%m-%d) | grep nameType | cut -f4 -d\" | paste -sd "/" -) tomorrow=$(echo $tomorrow" | sed s/\ /,/g) cat /tmp/afv.json | grep -B1 nameType | grep -B1 gft | cut -f4 -d\" | grep 202 > /tmp/gft.afv cat /tmp/afv.json | grep -B1 nameType | grep -B1 papier | cut -f4 -d\" | grep 202 > /tmp/papier.afv cat /tmp/afv.json | grep -B1 nameType | grep -B1 plastic | cut -f4 -d\" | grep 202 > /tmp/plastic.afv cat /tmp/afv.json | grep -B1 nameType | grep -B1 kerst | cut -f4 -d\" | grep 202 > /tmp/kerst.afv ( ( for f in $(seq 1 31) ; do dater=$(date -d "+$f days" +%Y-%m-%d) grep $dater /tmp/gft.afv > /dev/null && echo "$dater GFT" | head -1 done ) | head -1 ( for f in $(seq 1 31) ; do dater=$(date -d "+$f days" +%Y-%m-%d) grep $dater /tmp/papier.afv > /dev/null && echo "$dater Papier" | head -1 done ) | head -1 ( for f in $(seq 1 31) ; do dater=$(date -d "+$f days" +%Y-%m-%d) grep $dater /tmp/plastic.afv > /dev/null && echo "$dater Plastic" | head -1 done ) | head -1 ( for f in $(seq 1 31) ; do dater=$(date -d "+$f days" +%Y-%m-%d) grep $dater /tmp/kerst.afv > /dev/null && echo "$dater Kerstboom" | head -1 done ) | head -1 ) | sort -n -k1 | sed s/\ /,/g > /tmp/afv.sorted gft=$(cat /tmp/afv.sorted | grep GFT | cut -f1 -d,) papier=$(cat /tmp/afv.sorted | grep Papier | cut -f1 -d,) plastic=$(cat /tmp/afv.sorted | grep Plastic | cut -f1 -d,) mosquitto_pub -h 127.0.0.1 -p 1883 -t "afvalwijzer/Today" -m "$today " mosquitto_pub -h 127.0.0.1 -p 1883 -t "afvalwijzer/Tomorrow" -m "$tomorrow " mosquitto_pub -h 127.0.0.1 -p 1883 -t "afvalwijzer/Papier" -m "$papier" mosquitto_pub -h 127.0.0.1 -p 1883 -t "afvalwijzer/GFT" -m "$gft" mosquitto_pub -h 127.0.0.1 -p 1883 -t "afvalwijzer/Plastic" -m "$plastic"
Update new solution
My home assistant has a hacs addon installed which does the heavy lifting for me.
Why not use this info?
I wrote about NR and HA here
So getting the info for NR to parse:
I only need to use the lightblue node bottom right!
It is the current state node, inject a timestamp every day to get new values.
Parse this and send using Mqtt to my Led display thingy
Old phones, organisers and gadgets
Old ones
- Ericsson PF768?
- One in between ?? with fancy wood cover
- Nokia 7110 (Symbian)
- Nokia 7650 (Symbian 6)
- Nokia 6630 (Symbian 8)










Playing around with these i made a :
- MMS server
- Wap server
- SMS gateway
- Netsaint ( pre check_mk/icinga/nagios ) web thingy
Androids
- G1 – First android phone (2009)
- HTC Desire Z (2011)
- Nexus (2013)
- OnePlusOne (2015)
- Realme (2019)

Work phones
- ??
- Iphone for work ( stopped using this crap )
- (funny story, got more for cheap to embed in my flightsim dash)
- Sony Xperia XZ for work
Organizers
- Multiple sharps
- Xircom Rex
- Sharp Zaurus SL-5500 (Linux)
- Nokia 770








Organizing programs
- Hyper (dos) – hyplus.exe (1989)
- Twiki/Foswiki
- Google docs
- Joplin (Current)
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
Cocktail pictures and notebook
I like mixology
Some pictures of the drinks i’ve made, in the last years.
Most are in my notebook, i can perfect the drink now individually for a person.
I really have to put the names of the drinks on this page.
(And the tasting notes!)




































Lidar POC for Vincent
Using Python, Raspberry, a lidar module, a servo, display .. and a 3Dprinted holder.
Proof of concept was to see if it was easy to implement a lidar radar for boat navigation.
#!/usr/bin/env python
import math
import random
import pygame
from pygame.locals import *
import time
import serial
import pigpio
GPIO = 18
ser = serial.Serial("/dev/ttyUSB0", 115200)
pi = pigpio.pi()
distance = 0
pygame.init()
screen = pygame.display.set_mode((480, 320))
while True:
screen.fill((0,0,0))
pygame.draw.circle(screen, (0,128,0), (240,320), 100,1)
pygame.draw.circle(screen, (0,128,0), (240,320), 200,1)
pygame.draw.circle(screen, (0,128,0), (240,320), 300,1)
for deze in range(10,170,5):
count = ser.in_waiting
if count > 8:
recv = ser.read(9)
ser.reset_input_buffer()
if recv[0] == 'Y' and recv[1] == 'Y': # 0x59 is 'Y'
low = int(recv[2].encode('hex'), 16)
high = int(recv[3].encode('hex'), 16)
global distance
distance = low + high * 256
res = distance
#print res
x = res * math.cos(math.radians(deze))
y = res * math.sin(math.radians(deze))
xreal = x + 240
yreal = 320 - y
pygame.draw.line(screen, (0, 255, 0), (240, 320), (xreal, yreal))
pygame.time.wait(15)
pygame.display.flip()
#print(res)
pi.set_servo_pulsewidth(GPIO, deze * 11 + 500)
time.sleep(0.2)
screen.fill((0,0,0))
pygame.draw.circle(screen, (0,128,0), (240,320), 100,1)
pygame.draw.circle(screen, (0,128,0), (240,320), 200,1)
pygame.draw.circle(screen, (0,128,0), (240,320), 300,1)
for deze in range(170,10,-5):
count = ser.in_waiting
if count > 8:
#print count
recv = ser.read(9)
ser.reset_input_buffer()
if recv[0] == 'Y' and recv[1] == 'Y': # 0x59 is 'Y'
low = int(recv[2].encode('hex'), 16)
high = int(recv[3].encode('hex'), 16)
global distance
distance = low + high * 256
res = distance
x = res * math.cos(math.radians(deze))
y = res * math.sin(math.radians(deze))
xreal = x + 240
yreal = 320 - y
pygame.draw.line(screen, (0, 255, 0), (240, 320), (xreal, yreal))
pygame.time.wait(15)
pygame.display.flip()
pi.set_servo_pulsewidth(GPIO, deze * 11 + 500)
time.sleep(0.2)
#pi.set_servo_pulsewidth(GPIO, 0)















