Der er mange der med succes har brugt Wii Balance Board (Wii-Fit) som badevægt. Der er da også ganske meget information tilgængelig:
- http://wiibrew.org/wiki/Wii_Balance_Board beskriver selve protokollen
- FitScales for Android der kan installeres direkte på din telefon fra Google Play. kildetekst https://github.com/paulburton/fitscales
- xwiimote med programmet xwiishow, viser sensor output fra bl.a. Wii-Fit
kildetekst https://github.com/dvdhrm/xwiimote - Python bindinger for wiimote https://github.com/dvdhrm/xwiimote-bindings
Plus dem vi så på i mit sidste indlæg Badevægt, problemet med de løsninger var permanent parring. så det skal vi lige have styr på først.
Der er sket meget med bluetooth på Linux siden 2008, da den oprindelige kode blev skrevet, dengang klarede applikationerne stortset det hele selv. Og de løsninger jeg præsenterede sidste gang baserede sig alle på den rå bluetooth adgang.
I dag er abstrakstions niveauet hævet, og mange af de basale operationer klares af Bluez, som bluetooth frame-work hedder under Linux. Dermed kan man parre Wii-Fit direkte fra en GUI Bluetooth manager, eller hvis man er mere til kommando-linien så brug bluetoothctl således:
$ bluetoothctl [NEW] Controller B8:27:EB:C6:64:03 raspberrypi [default] [NEW] Device 34:AF:2C:2D:A8:C2 Nintendo RVL-WBC-01 [CHG] Device 34:AF:2C:2D:A8:C2 Connected: yes [CHG] Device 34:AF:2C:2D:A8:C2 Connected: no [CHG] Device 34:AF:2C:2D:A8:C2 Connected: yes # herover kommer der løbende status # nedenfor en kommando prompt - prøv help [bluetooth]# scan on [bluetooth]# pair 34:AF:2C:2D:A8:C2 [bluetooth]# trusted 34:AF:2C:2D:A8:C2 # når man trykker på knappen bliver enheden tændt og forbundet # for at bruge enheden udfør nedenstående [bluetooth]# connect 34:AF:2C:2D:A8:C2 # og når vi er færdige med at bruge den [bluetooth]# disconnect 34:AF:2C:2D:A8:C2
Der er allerede en driver hid-wiimote installeret under Linux, og når enheden først er parret vil den dukke op når Wii-Fit bliver tændt og fjernet når man disconnecter. Nedenfor er output fra dmesg:
$ dmesg ... wiimote 0005:057E:0306.0004: unknown main item tag 0x0 wiimote 0005:057E:0306.0004: hidraw2: BLUETOOTH HID v6.00 Gamepad [Nintendo RVL-WBC-01] on b8:27:eb:c6:64:03 wiimote 0005:057E:0306.0004: New device registered wiimote 0005:057E:0306.0004: detected device: Nintendo Wii Balance Board wiimote 0005:057E:0306.0004: detected extension: Nintendo Wii Balance Board input: Nintendo Wii Remote Balance Board as /devices/platform/soc/3f201000.uart/tty/ttyAMA0/hci0/hci0:13/0005:057E:0306.0004/input/input3 ... wiimote 0005:057E:0306.0004: Device removed
Så prøver vi: batteri, ud, batteri ind igen og Wii-Fit bliver automatisk detekteret igen når vi trykker på knappen, men ikke med den samme device. Så problemet er allerede løst, der er en hid-driver, så nu kommer vi til det svære LÆS MANUALEN: man xwiimote
Her står bl.a. hvor man kan finde sin wii-fit device i mit tilfælde:
ls -l /sys/module/hid_wiimote/drivers/hid:wiimote/0005:057E:0306.0005 -r--r--r-- 1 root root 4096 Jan 27 02:42 bboard_calib -r--r--r-- 1 root root 4096 Jan 27 02:42 country -r--r--r-- 1 root root 4096 Jan 27 02:42 devtype lrwxrwxrwx 1 root root 0 Jan 27 02:42 driver -> ../../../../../../../../../bus/hid/drivers/wiimote -rw-rw-r-- 1 root root 4096 Jan 27 02:42 extension drwxr-xr-x 3 root root 0 Jan 27 02:31 hidraw drwxr-xr-x 3 root root 0 Jan 27 02:41 input drwxr-xr-x 3 root root 0 Jan 27 02:42 leds -r--r--r-- 1 root root 4096 Jan 27 02:42 modalias drwxr-xr-x 2 root root 0 Jan 27 02:42 power drwxr-xr-x 3 root root 0 Jan 27 02:42 power_supply -r--r--r-- 1 root root 4096 Jan 27 02:42 report_descriptor lrwxrwxrwx 1 root root 0 Jan 27 02:42 subsystem -> ../../../../../../../../../bus/hid -rw-r--r-- 1 root root 4096 Jan 27 02:42 uevent
Og der er jo det hele. HID device med Kalibrerings data, lysdiode, batteri information, osv.
På manualsiden var der også en henvisning til xwiishow, et C-program med kildetekst, der viser status på alle Wii-enheder dynamisk, med fin character grafik. Alle sensor-værdierne kan ses og lysdioden kan tændes og slukkes, knappen er dog ikke med.
HID enheder kan normalt bruges uden at der skal installeres drivere.
Hello World
I min verden er det første program man laver et der skriver “Hello World”, blot for at få alt det basale på plads og vise at der er hul igennem, så det vil jeg også gøre her. Den eneste output enhed der er på Wii-Fit er den blå lysdiode, så det bliver den.
Jeg vil gerne måle vægten automatisk hver gang der er nogen der bruger den, ikke noget med at man skal starte et program via GUI eller kommando-linie
Under Linux er det udev der holder styr på devices der kommer og går. Vi kan følge med i hvad der sker via:
$ udevadm monitor # only relevant lines shown monitor will print the received events for: UDEV - the event which udev sends out after rule processing KERNEL - the kernel uevent KERNEL[275.636718] add /devices/pci0000:00/0000:00:14.0/usb1/1-7/1-7:1.0/bluetooth/hci0/hci0:256 (bluetooth) UDEV [275.639448] add /devices/pci0000:00/0000:00:14.0/usb1/1-7/1-7:1.0/bluetooth/hci0/hci0:256 (bluetooth) KERNEL[275.702511] add /devices/pci0000:00/0000:00:14.0/usb1/1-7/1-7:1.0/bluetooth/hci0/hci0:256/0005:057E:0306.0002 (hid) KERNEL[275.712277] add /module/hid_wiimote (module) KERNEL[275.712913] add /devices/pci0000:00/0000:00:14.0/usb1/1-7/1-7:1.0/bluetooth/hci0/hci0:256/0005:057E:0306.0002/hidraw/hidraw1 (hidraw) KERNEL[275.713030] add /bus/hid/drivers/wiimote (drivers) UDEV [275.713266] add /module/hid_wiimote (module) UDEV [275.713363] add /devices/pci0000:00/0000:00:14.0/usb1/1-7/1-7:1.0/bluetooth/hci0/hci0:256/0005:057E:0306.0002 (hid) UDEV [275.715145] add /bus/hid/drivers/wiimote (drivers) UDEV [275.718351] add /devices/pci0000:00/0000:00:14.0/usb1/1-7/1-7:1.0/bluetooth/hci0/hci0:256/0005:057E:0306.0002/hidraw/hidraw1 (hidraw) KERNEL[275.771624] add /devices/pci0000:00/0000:00:14.0/usb1/1-7/1-7:1.0/bluetooth/hci0/hci0:256/0005:057E:0306.0002/leds/0005:057E:0306.0002:blue:p0 (leds) UDEV [275.776623] add /devices/pci0000:00/0000:00:14.0/usb1/1-7/1-7:1.0/bluetooth/hci0/hci0:256/0005:057E:0306.0002/leds/0005:057E:0306.0002:blue:p0 (leds) KERNEL[275.841784] add /devices/pci0000:00/0000:00:14.0/usb1/1-7/1-7:1.0/bluetooth/hci0/hci0:256/0005:057E:0306.0002/input/input18 (input) KERNEL[275.841969] add /devices/pci0000:00/0000:00:14.0/usb1/1-7/1-7:1.0/bluetooth/hci0/hci0:256/0005:057E:0306.0002/input/input18/event16 (input) KERNEL[275.842166] add /devices/pci0000:00/0000:00:14.0/usb1/1-7/1-7:1.0/bluetooth/hci0/hci0:256/0005:057E:0306.0002/input/input18/js1 (input) KERNEL[275.842271] change /devices/pci0000:00/0000:00:14.0/usb1/1-7/1-7:1.0/bluetooth/hci0/hci0:256/0005:057E:0306.0002 (hid) UDEV [275.847737] add /devices/pci0000:00/0000:00:14.0/usb1/1-7/1-7:1.0/bluetooth/hci0/hci0:256/0005:057E:0306.0002/input/input18 (input) KERNEL[275.851425] change /devices/pci0000:00/0000:00:14.0/usb1/1-7/1-7:1.0/bluetooth/hci0/hci0:256/0005:057E:0306.0002/power_supply/wiimote_battery_34:af:2c:2d:69:fe (power_supply) UDEV [275.854009] add /devices/pci0000:00/0000:00:14.0/usb1/1-7/1-7:1.0/bluetooth/hci0/hci0:256/0005:057E:0306.0002/input/input18/js1 (input) ... KERNEL[277.005331] remove /devices/pci0000:00/0000:00:14.0/usb1/1-7/1-7:1.0/bluetooth/hci0/hci0:256/0005:057E:0306.0002/input/input18/event16 (input) KERNEL[277.028347] remove /devices/pci0000:00/0000:00:14.0/usb1/1-7/1-7:1.0/bluetooth/hci0/hci0:256/0005:057E:0306.0002/input/input18/js1 (input) KERNEL[277.060483] remove /devices/pci0000:00/0000:00:14.0/usb1/1-7/1-7:1.0/bluetooth/hci0/hci0:256/0005:057E:0306.0002/input/input18 (input) KERNEL[277.060543] remove /devices/pci0000:00/0000:00:14.0/usb1/1-7/1-7:1.0/bluetooth/hci0/hci0:256/0005:057E:0306.0002/leds/0005:057E:0306.0002:blue:p0 (leds) UDEV [277.070917] add /devices/pci0000:00/0000:00:14.0/usb1/1-7/1-7:1.0/bluetooth/hci0/hci0:256/0005:057E:0306.0002/input/input18/event16 (input) UDEV [277.075802] change /devices/pci0000:00/0000:00:14.0/usb1/1-7/1-7:1.0/bluetooth/hci0/hci0:256/0005:057E:0306.0002 (hid) UDEV [277.079230] remove /devices/pci0000:00/0000:00:14.0/usb1/1-7/1-7:1.0/bluetooth/hci0/hci0:256/0005:057E:0306.0002/input/input18/event16 (input) UDEV [277.079341] remove /devices/pci0000:00/0000:00:14.0/usb1/1-7/1-7:1.0/bluetooth/hci0/hci0:256/0005:057E:0306.0002/input/input18/js1 (input) UDEV [277.079990] remove /devices/pci0000:00/0000:00:14.0/usb1/1-7/1-7:1.0/bluetooth/hci0/hci0:256/0005:057E:0306.0002/leds/0005:057E:0306.0002:blue:p0 (leds) UDEV [277.080135] change /devices/pci0000:00/0000:00:14.0/usb1/1-7/1-7:1.0/bluetooth/hci0/hci0:256/0005:057E:0306.0002/power_supply/wiimote_battery_34:af:2c:2d:69:fe (power_supply) UDEV [277.081084] remove /devices/pci0000:00/0000:00:14.0/usb1/1-7/1-7:1.0/bluetooth/hci0/hci0:256/0005:057E:0306.0002/input/input18 (input) KERNEL[277.084245] remove /devices/pci0000:00/0000:00:14.0/usb1/1-7/1-7:1.0/bluetooth/hci0/hci0:256/0005:057E:0306.0002/power_supply/wiimote_battery_34:af:2c:2d:69:fe (power_supply) KERNEL[277.084431] remove /devices/pci0000:00/0000:00:14.0/usb1/1-7/1-7:1.0/bluetooth/hci0/hci0:256/0005:057E:0306.0002/hidraw/hidraw1 (hidraw) KERNEL[277.084509] remove /devices/pci0000:00/0000:00:14.0/usb1/1-7/1-7:1.0/bluetooth/hci0/hci0:256/0005:057E:0306.0002 (hid) UDEV [277.086365] remove /devices/pci0000:00/0000:00:14.0/usb1/1-7/1-7:1.0/bluetooth/hci0/hci0:256/0005:057E:0306.0002/power_supply/wiimote_battery_34:af:2c:2d:69:fe (power_supply) UDEV [277.088054] remove /devices/pci0000:00/0000:00:14.0/usb1/1-7/1-7:1.0/bluetooth/hci0/hci0:256/0005:057E:0306.0002/hidraw/hidraw1 (hidraw) UDEV [277.089331] remove /devices/pci0000:00/0000:00:14.0/usb1/1-7/1-7:1.0/bluetooth/hci0/hci0:256/0005:057E:0306.0002 (hid) KERNEL[279.064318] remove /devices/pci0000:00/0000:00:14.0/usb1/1-7/1-7:1.0/bluetooth/hci0/hci0:256 (bluetooth) UDEV [279.065836] remove /devices/pci0000:00/0000:00:14.0/usb1/1-7/1-7:1.0/bluetooth/hci0/hci0:256 (bluetooth)
Den enkleste måde at få vores program til at starte når Wii-Fit bliver tændt er at lave en en ny regel: /etc/udev/rules.d/99-wiibb.rules
# to see what we have available just print all ENV to file # you could get same information using this command "udevadm monitor -p" DRIVERS=="wiimote", RUN+="/bin/sh -c '(date;set) >>/tmp/wiibb-log'"
FIXME: Virker ikke under Ubuntu-16.10 efter reboot, da / var monteret read-only da systemd-udevd blev startet see discussion here: http://askubuntu.com/questions/883843/udev-rules-scripts-has-only-read-only-access-to-ubuntu16-10
Så tænder vi og slukker et par gange, og kigger på de mange variable vi kan se i /tmp/wiibb-log, Her lægger vi specielt mærke til:
- Der bliver oprettet flere devices, den sidste har ACTION=change SUBSYSTEM=hid, det bruger vi reglen for at kalde vores program
- HID_NAME=“Nintendo RVL-WBC-01” udelukker andre Wii enheder
- HID_UNIQ er mac-adressen for Wii-Fit
- DEVPATH fortæller hvor vi kan få fat i enheden denne gang
Næste trin er at lade udev kalde et program der morser “hello world” og derefter slukker enheden, og det er præcis hvad dette shell-script gør:
#!/bin/bash # wiibb.sh Copyright Peter@Lorenzen.us Januar 2017, This is BSD-style free software # called with DEVPATH and HID_UNIQ set export PATH=/usr/local/bin:/usr/local/sbin:$PATH LED=/sys/$DEVPATH/leds/$(basename $DEVPATH):blue:p0/brightness MAC=$(echo $HID_UNIQ | tr a-f A-F) h="...."; e="."; l=".-.."; o="---"; w=".--"; r=".-."; d="-.." led_on() { (echo 1; sleep $1; echo 0) > $LED; } echo Wii Board $MAC installed at $DEVPATH | sudo tee /dev/kmsg >/dev/console echo connect $MAC | bluetoothctl text="hello world" for word in $text; do chars=(`echo $word | fold -w1`) for ch in "${chars[@]}"; do eval 'morse="${'"$ch"'}"' c_array=(`echo $morse | fold -w1`) for cm in "${c_array[@]}"; do case $cm in .) led_on 1; sleep 1;; -) led_on 3; sleep 1;; esac done sleep 2 done sleep 4 done echo 1 > $LED; sleep 1; # when it turns off it indicates device is off echo disconnect $MAC | bluetoothctl echo Wii Board $MAC done | sudo tee /dev/kmsg >/dev/console
Hmm – Det virkede ikke for mig og ganske rigtigt der er en BUG i bluetoothctl der kun kommer til udtryk når man kører det fra et script, interaktivt virker det fint. Ubuntu-16.10 har bluez-5.41, Raspian har bluez-5.23. Problemet er løst i bluez-5.43. Jeg har beskrevet hvordan man installerer den nyeste version fra Zesty under Ubuntu 16.04 eller 16.10 her http://askubuntu.com/a/884062/655086, Der sker følgende:
#!/bin/bash sudo apt-get install devscripts debhelper dh-autoreconf flex bison libdbus-glib-1-dev libglib2.0-dev libcap-ng-dev libudev-dev l ibreadline-dev libical-dev check dh-systemd libebook1.2-dev wget https://launchpad.net/ubuntu/+archive/primary/+files/bluez_5.43.orig.tar.xz wget https://launchpad.net/ubuntu/+archive/primary/+files/bluez_5.43-0ubuntu1.debian.tar.xz wget https://launchpad.net/ubuntu/+archive/primary/+files/bluez_5.43-0ubuntu1.dsc tar xf bluez_5.43.orig.tar.xz cd bluez-5.43 tar xf ../bluez_5.43-0ubuntu1.debian.tar.xz # install patches relevant for rpi-3 bluetooth . /etc/os-release if [ $ID = raspbian ]; then wget https://gist.github.com/pelwell/c8230c48ea24698527cd/archive/3b07a1eb296862da889609a84f8e10b299b7442d.zip cd debian/patches unzip ../../3b07a1eb296862da889609a84f8e10b299b7442d.zip for i in c8230c48ea24698527cd-3b07a1eb296862da889609a84f8e10b299b7442d/*;do mv $i . basename $i >> series done rmdir c8230c48ea24698527cd-3b07a1eb296862da889609a84f8e10b299b7442d cd ../.. fi # end of Raspian related patches debchange --local=~lorenzen 'Backport to Xenial' debuild -b -j4 cd .. sudo dpkg -i *.deb
Ovenstående virker også under Raspian, alternativt se her
http://stackoverflow.com/questions/41707164/connect-ble-devices-with-raspberry-pi-3-b
Man kunne også blot installere bluez fra debian stretch, eller vente et par måneder så er det standard
how-to-use-stretch-testing-packages
Når det så virker installeres shell-scriptet i /usr/local/sbin/wiibb.sh, og en opdateret version af vores udev-rule /etc/udev/rules.d/99-wiibb.rules skal være som nedenfor
# Whenever a Wii Balance Board is turned on wiibb.sh is called # wiibb.sh reads the weight and turns the device off when done SUBSYSTEM=="hid", ENV{HID_NAME}=="Nintendo RVL-WBC-01" ACTION=="change", DRIVERS=="wiimote", RUN+="/usr/sbin/wiibb.sh"
Hvis man så er radio-amatør (oz1dmk), kan man forvisse sig om at hele frame-worket virker, der er endda log-entries i dmesg.
Det var sådan set det hele, resten er blot at skrive et program til at læse vægten. Vælg et programmerings-sprog og kom igang.
Næste gang laver vi lige et sådant program i C
You must be logged in to post a comment.