3D-printed Chess Board with Piece Recognition and Connection with Lichess
main controller: ESP32-WROOM w/ OLED display
RFID reader: mini RC522 modules
piece RFID: NTAG213 stickers
diagram:
part 1: Assembly
part 2: Demo
Prototype Projects - experiments on theoretical electronics/electrical designs and actual prototype circuits.
3D-printed Chess Board with Piece Recognition and Connection with Lichess
main controller: ESP32-WROOM w/ OLED display
RFID reader: mini RC522 modules
piece RFID: NTAG213 stickers
diagram:
part 1: Assembly
part 2: Demo
3D-printed WALL-E replica - Wi-Fi controlled using ESP32, with OLED display and audio output.
main controller: ESP32 DEVKIT (with local web server)
motors: 2x 37GB520 (wheels/tracks - driven using TB6612FNG) and 7x MG90S servos
other accessories: 1x OLED display, 1x microSD interface, 1x audio-amplifier
credits:
original 3D design: thingiverse.com/thing:3703555
DIY rechargeable mini-chess-clock using SAMD21 mini board and 0.91" 128x32 OLED display.
Cheap CMSIS-DAP/DAPLink SWD module based on NS32F103CBT6 (an STM32-clone?). It has both a debugger and a serial/UART port on a single USB device just like the J-Link OB v2 debugger (based on STM32F072) - better than those ST-Link debugger clones.
MCU interface:
Firmwares:
(*should work also on chips with smaller ROM STM32F103C8 (like the BluePill C8)
Tested only on Ubuntu host.
sample kernel logs if using original FW:
usb 1-1: new full-speed USB device number 44 using xhci_hcd
usb 1-1: New USB device found, idVendor=c251, idProduct=f001, bcdDevice= 1.00
usb 1-1: New USB device strings: Mfr=1, Product=2, SerialNumber=3
usb 1-1: Product: CMSIS_DAP
usb 1-1: Manufacturer: CMSIS-DAP by ARM
usb 1-1: SerialNumber: 202108120001
cdc_acm 1-1:1.0: ttyACM0: USB ACM device
hid-generic 0003:C251:F001.0015: hiddev0,hidraw2: USB HID v1.00 Device [CMSIS-DAP by ARM CMSIS_DAP] on usb-0000:00:14.0-1/input2
Sample kernel logs if using the modified FW:
usb 1-1: new full-speed USB device number 52 using xhci_hcd
usb 1-1: device descriptor read/64, error -71
usb 1-1: new full-speed USB device number 53 using xhci_hcd
usb 1-1: New USB device found, idVendor=0d28, idProduct=0204, bcdDevice= 1.00
usb 1-1: New USB device strings: Mfr=1, Product=2, SerialNumber=3
usb 1-1: Product: DAPLink CMSIS-DAP
usb 1-1: Manufacturer: ARM
usb 1-1: SerialNumber: 20220218979699080605210b3030153632303030
cdc_acm 1-1:1.0: ttyACM0: USB ACM device
usbcore: registered new interface driver cdc_acm
usbhid 1-1:1.2: couldn't find an input interrupt endpoint
usbcore: registered new interface driver usbhid
usbhid: USB HID core driver
Sample openocd configuration:
source [find interface/cmsis-dap.cfg]If using the original FW, need to add these on the configuration:
transport select swd
source [find target/stm32f4x.cfg]
adapter speed 4000
init
targets
reset halt
cmsis_dap_vid_pid 0xc251 0xf001
cmsis_dap_backend hid
Not tested:
size comparison (from left to right) :
Reference:

[ 2555.447630] usb 1-1: new high-speed USB device number 13 using xhci_hcd [ 2555.601320] usb 1-1: New USB device found, idVendor=048d, idProduct=9308, bcdDevice= 1.00 [ 2555.601325] usb 1-1: New USB device strings: Mfr=1, Product=2, SerialNumber=3 [ 2555.601329] usb 1-1: Product: DGI1011 [ 2555.601331] usb 1-1: Manufacturer: Atlanta DTH, Inc. [ 2555.601333] usb 1-1: SerialNumber: 000000





$ export JAVA_OPTS='-XX:+IgnoreUnrecognizedVMOptions --add-modules java.se.ee' $ export ANDROID_HOME=$HOME/android/sdk $ export ANDROID_SDK_ROOT=$ANDROID_HOME
$ ./tools/bin/sdkmanager "platform-tools" "platforms;android-25" "emulator" $ ./tools/bin/sdkmanager --install "system-images;android-25;google_apis;x86_64"

$ cd $ANDROID_SDK_ROOT/system-images/android-25/google_apis/x86_64 $ dd if=/dev/zero bs=1M count=512 >> ./system.img $ e2fsck -f system.img $ resize2fs system.img

$ wget http://dl.android-x86.org/houdini/7_y/houdini.sfs -O houdini_7_y.sfs $ mkdir -p systemfs $ sudo mount -o loop -t ext4 system.img systemfs $ sudo unsquashfs -d systemfs/lib/arm houdini_7_y.sfs $ sudo cp systemfs/lib/arm/libhoudini.so systemfs/lib/ $ sudo cp systemfs/lib/arm/houdini systemfs/bin/

$ sudo setfattr -n security.selinux -v u:object_r:system_file:s0 systemfs/bin/houdini $ sudo setfattr -n security.selinux -v u:object_r:system_file:s0 systemfs/lib/libhoudini.so $ sudo setfattr -n security.selinux -v u:object_r:system_file:s0 systemfs/lib/arm $ sudo setfattr -n security.selinux -v u:object_r:system_file:s0 systemfs/lib/arm/* $ sudo setfattr -n security.selinux -v u:object_r:system_file:s0 systemfs/lib/arm/nb/*
$ sudo mkdir -p systemfs/etc/binfmt_misc $ echo ":arm_dyn:M::\x7f\x45\x4c\x46\x01\x01\x01\x00\x00\x00\x00\x00\x00\x00\x00\x00\x03\x00\x28::/system/bin/houdini:" | sudo tee systemfs/etc/binfmt_misc/arm_dyn $ echo ":arm_exe:M::\x7f\x45\x4c\x46\x01\x01\x01\x00\x00\x00\x00\x00\x00\x00\x00\x00\x02\x00\x28::/system/bin/houdini:" | sudo tee systemfs/etc/binfmt_misc/arm_exe $ sudo nano systemfs/build.propadd the following properties to the build.prop (overwrite if existing):
ro.enable.native.bridge.exec=1 ro.product.cpu.abilist=x86_64,x86,armeabi-v7a,armeabi ro.product.cpu.abilist32=x86,armeabi-v7a,armeabi
$ echo '<permissions><feature name="android.hardware.usb.host"/></permissions>' | sudo tee systemfs/etc/permissions/android.hardware.usb.host.xml
$ echo 'SUBSYSTEM=="usb", ATTRS{idVendor}=="048d", ATTRS{idProduct}=="9308", GROUP="kvm"' | sudo tee /etc/udev/rules.d/89-usb-android.rules
$ sudo udevadm control --reload-rules$ sudo mv systemfs/xbin/su systemfs/xbin/_s_uii.
$ sync $ sudo umount systemfs
$ mkdir -p ramdiskfs $ cd ramdiskfs $ gzip -dc ../ramdisk.img | cpio -i $ nano default.prop
# Enable native bridge for target executables
on early-init
mount binfmt_misc binfmt_misc /proc/sys/fs/binfmt_misc
on property:ro.enable.native.bridge.exec=1
copy /system/etc/binfmt_misc/arm_exe /proc/sys/fs/binfmt_misc/register
copy /system/etc/binfmt_misc/arm_dyn /proc/sys/fs/binfmt_misc/register
$ cd .. $ wget https://github.com/xiaolu/mkbootimg_tools/raw/master/mkbootfs $ chmod +x mkbootfs $ ./mkbootfs ./ramdiskfs | gzip > ramdisk.img
$ ./tools/bin/avdmanager --verbose create avd --force --name "avd_7_1_x86_64" --device "tv_720p" \ --package "system-images;android-25;google_apis;x86_64" --tag "google_apis" --abi "x86_64"

$ ./tools/emulator @avd_7_1_x86_64 -show-kernel -verbose -memory 2048 \ -qemu -usb -device usb-host,vendorid=0x048d,productid=0x9308
$ adb install ../apks/TVplus\ GO_v1.0.28_apkpure.com.apk






![]() | ![]() | ![]() |
![]() | ![]() | ![]() |
![]() | ![]() | ![]() |
wifi.setmode(wifi.STATION) wifi.sta.config("WIFI_SSID","WIFI_PASSWORD") local GP0 = 3 local GP2 = 4 local port = 3456 print(wifi.sta.getip()) srv=net.createServer(net.UDP) srv:on("receive", function(cli, rcv) --print(rcv) rx={} for i, s in string.gmatch(rcv, "(%w+)=(%w+)") do rx[i]=s --print(i, rx[i]) end if rx.d0 then pwm.setduty(GP0,rx.d0) --print("GP0 duty",rx.d0) elseif rx.d2 then pwm.setduty(GP2,rx.d2) --print("GP2 duty",rx.d2) elseif rx.f0 and rx.c0 then pwm.setup(GP0,rx.f0,rx.c0) pwm.start(GP0) print("GP0 freq",rx.f0,"cycles", rx.c0) elseif rx.f2 and rx.c2 then pwm.setup(GP2,rx.f2,rx.c2) pwm.start(GP2) print("GP2 freq",rx.f2,"cycles", rx.c2) end cli:send(rcv) end) srv:listen(port)
wifi.setmode(wifi.STATION) wifi.sta.config("WIFI_SSID","WIFI_PASSWORD") local DAT = 4 local CLK = 3 function DL() gpio.write(DAT, gpio.LOW) gpio.mode(DAT, gpio.OUTPUT) end function DH() gpio.mode(DAT, gpio.INPUT) gpio.write(DAT, gpio.HIGH) end function CL() gpio.write(CLK, gpio.LOW) end function CH() gpio.write(CLK, gpio.HIGH) end function DR() gpio.mode(DAT, gpio.INPUT) return gpio.read(DAT) end function W8() for i = 1, 100 do tmr.delay(10000) if DR() == gpio.LOW then return true end end return false end function RB() local val = 0 for i = 0, 7 do CH() val = val*2 + DR() CL() end return val end function shtread(cmd) DH() CH() DL() CL() CH() DH() CL() for i = 0, 7 do if bit.band(cmd, 2^(7-i))==0 then DL() else DH() end CH() CL() end CH() CL() if not W8() then return nil end DH() local val = RB() DH() DL() CH() CL() DH() val = val*256 + RB() DH() CH() CL() return val end page=[[<head><meta charset="utf-8"/> <link href="http://projectproto.blogspot.com/favicon.ico" rel="icon"/> <title>ESP+SHT</title></head> <body><h1>ESP8266 and SHT1x</h1><h2 id="T">T??</h2><h2 id="H">H??</h2> <script> function update(){ var xrq = new XMLHttpRequest(); xrq.onreadystatechange=function(){ if (xrq.readyState==4 && xrq.status==200){ var th=JSON.parse(xrq.responseText); var t0=th["t"], h0=th["h"]; var t=(t0*0.01)-39.7; var hl=(0.0367*h0)+(-0.0000015955*h0*h0)-2.0468; var h=(t-25.0)*(0.01+(0.00008*h0))+hl; document.getElementById("T").innerHTML="Temperature: "+t.toFixed(2)+"°C"; document.getElementById("H").innerHTML="Humidity: "+h.toFixed(2)+"%";} } xrq.open("GET","/get/sht",true); xrq.overrideMimeType("application/json"); xrq.send(null); }setInterval(update, 1000); </script></body>]] srv=net.createServer(net.TCP) srv:listen(80,function(conn) conn:on("receive", function(client,request) local buf = ""; local _, _, mtd, path, _ = string.find(request, "([A-Z]+) (.+)?(.+) HTTP"); if(mtd == nil)then _, _, mtd, path = string.find(request, "([A-Z]+) (.+) HTTP"); end if path == "/" then buf = buf..page elseif path == "/get/sht" then t = shtread(3) h = shtread(5) if (t ~= nil and h ~= nil) then buf = buf.."{\"t\":"..t..", \"h\":"..h.."}" end end client:send(buf) client:close() collectgarbage() end) end)