[{"content":"Earlier this year, my parents bought a John Deere Ground Force Tractor and Trailer for my son Theodore and the other grandkids to play with at the cabin. For some inexplicable reason, in 2026, this tractor includes an FM radio (2xAA lithium batteries – not included). Putting the batteries in and turning it on, hits you with a blast of static noise, since Norway has transitioned most FM to DAB since 2017.\nI could simply remove the batteries and leave it as a useless part, but\nIt\u0026rsquo;s one of the selling points of the tractor Dials and buttons are fun to use, and even more so if they actually do something! I also think it\u0026rsquo;s a good learning that when you press stuff something happens It would be a lot more fun if it worked, and I do enjoy a pointless project where I might learn a thing or two This led me to the thought: Would it be possible to broadcast a local FM signal and make my own radio channel?\nDown the rabbit hole After some quick searching I ended up finding fm_transmitter, a library to use the Raspberry Pi as a FM transmitter. I dug out a Raspberry Pi Zero 2 WH I had lying in a drawer, and quickly installed Raspberry Pi OS Lite (32-bit), and followed the installation instructions on the repository.\nNext I grabbed a Dupont wire, connected it to GPIO4 on the Pi, and extended it by connecting a Wago clip with another wire to get a length of ~84.3cm, which is the recommended length for broadcasting on 89.0MHz. More details and an \u0026ldquo;Antenna Calculator\u0026rdquo; can be found on this page describing the full process in more detail.\nMoment of truth, I ran the test command from the repository with an FM radio I had tuned to 89.0, and lo and behold the static changed into music! I honestly couldn\u0026rsquo;t believe how easy it was to get up and running, and the whole thing I was expecting to spend multiple summer evenings on, took a total of maybe 30 minutes.\nCreating a continuous feed Now I was able to take any wav files that I had and broadcast them, and it would play the song from beginning to end, but then the process would terminate and the feed would stop, and go back to static. What I wanted was a folder songs/ which I could put a bunch of mp3s into, and it would just randomly play all of them over and over.\nPlay mp3s instead of wavs fm_transmitter documents on their website how to use SoX to convert an mp3 and get it to play like this\n1 sox example.mp3 -r 22050 -c 1 -b 16 -t wav - | sudo ./fm_transmitter -f 89.0 - Unfortunately, I could not get this to work, even after installing the required libsox-fmt-mp3. Whenever I would pass it an mp3, it would spit back\nsox FAIL formats: no handler for file extension `mp3'\nI spent some time debugging and trying to understand what the issue was, but could not make it work regardless of what I tried. Eventually I figured out that the sox I was getting via apt was \u0026ldquo;compiled without libltdl dynamic-module support\u0026rdquo;, and therefore didn\u0026rsquo;t load any of the libsox-fmt-* files. I tried the workarounds using ffmpeg instead, but really didn\u0026rsquo;t feel like having to reencode each file to be able to play it. Just having a folder where I could drop an mp3 and play felt much easier.\nEnter sox_ng, a \u0026ldquo;hard fork of sox-14.4.2 aiming to sanitize SoX\u0026rdquo;. I followed the steps for compiling it from source, which gave me a sox_ng binary, and this one accepted mp3s!\nNon-stop music With mp3s playing the next step was to create something which allowed me to just continuously loop through all files in my directory, and play them back to back without interruption. Using Claude, and quite a few back-and-forths, I created a bash script which allowed me to do just that. Now I actually had a local broadcast which played the songs I wanted, and I could easily add/remove songs as I needed.\nBecoming a radio DJ Since the initial setup and wiring went much faster than I had expected, I had some extra time to dive further into the project, and what does every radio station need? Jingles! Having used ElevenLabs in the past, I figured this could be a fun way to create some short jingles that would integrate nicely with the music.\nI spent a bit of time coming up with a name for the station, then testing a few different voices and getting pronunciation right. This turned out to be more challenging since I was mixing English and Norwegian pronunciations in the same jingle. Thankfully there is native support for IPA pronunciation which made it possible.\nThen Claude helped me change the script to support playing jingles, and it now plays a random jingle after every song.\nJingles Here are some examples of jingles I created\n\u0026ldquo;You\u0026rsquo;re listening to Radio Chateau Håa\u0026rdquo;\nYour browser doesn\u0026rsquo;t support audio playback. \u0026ldquo;You\u0026rsquo;re still listening to Radio Chateau Håa\u0026rdquo;\nYour browser doesn\u0026rsquo;t support audio playback. \u0026ldquo;Psst, here\u0026rsquo;s a message for Theodore: Mommy loves you! Radio Chateau Håa\u0026rdquo;\nYour browser doesn\u0026rsquo;t support audio playback. Home Assistant Now I could just leave this running 24/7, but since we\u0026rsquo;re not there most of the time, and the tractor isn\u0026rsquo;t always used, I figured it would make sense to have a way to start/stop the broadcast. With a robust Home Assistant setup already in place, this was a natural place to add it.\nClaude helped me create a simple fm_mqtt_control.sh script which just listens and publishes state changes to MQTT, which is connected to Home Assistant as an mqtt switch:\n1 2 3 4 5 6 7 8 9 10 mqtt: switch: - name: \u0026#34;Pirate FM Radio\u0026#34; unique_id: pirate_fm_radio command_topic: \u0026#34;home/radio/set\u0026#34; state_topic: \u0026#34;home/radio/state\u0026#34; payload_on: \u0026#34;ON\u0026#34; payload_off: \u0026#34;OFF\u0026#34; qos: 1 retain: false This gives a button I can use to start/stop the broadcast without needing to touch the Pi, and also lets me automatically shut down the broadcast when leaving, and enable it when the tractor is going to be used.\nFinally I set up some systemd files for fm-radio.service and fm-radio-mqtt.service to ensure broadcast and MQTT listener run after reboot or crash.\nConclusion All in all this turned out to be a lot easier than I was expecting, but it was quite fun and nostalgic to hear the music and jingles I selected be played on an FM radio!\nFurther improvements to look into would be slightly extending the range, since today it doesn\u0026rsquo;t fully cover the whole property, and when driving to the edges it abruptly cuts off. But then again, creates a bit of a \u0026ldquo;virtual boundary\u0026rdquo; so the kids don\u0026rsquo;t set off on too big of an adventure\u0026hellip;\nResources fm_shuffle.sh 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 #!/bin/bash # fm_shuffle.sh — shuffle mp3s from a folder on loop via fm_transmitter # # The transmitter runs once, reading from a FIFO that we hold open, so the # carrier stays up between songs. Each song is decoded by sox in the # foreground and streamed into the FIFO; when sox returns, the song is done. FREQ=\u0026#34;89.0\u0026#34; MP3_DIR=\u0026#34;/home/pi/fm_transmitter/songs\u0026#34; JINGLE_DIR=\u0026#34;/home/pi/fm_transmitter/jingles\u0026#34; TRANSMITTER=\u0026#34;/home/pi/fm_transmitter/fm_transmitter\u0026#34; FIFO=\u0026#34;/tmp/fm_shuffle_pipe\u0026#34; if [ \u0026#34;$EUID\u0026#34; -ne 0 ]; then echo \u0026#34;Run this with sudo — fm_transmitter needs root for GPIO access.\u0026#34; exit 1 fi if ! command -v sox_ng \u0026gt;/dev/null; then echo \u0026#34;sox_ng not found in PATH.\u0026#34; exit 1 fi if [ ! -x \u0026#34;$TRANSMITTER\u0026#34; ]; then echo \u0026#34;Transmitter binary not found or not executable: $TRANSMITTER\u0026#34; exit 1 fi shopt -s nullglob tx_pid=\u0026#34;\u0026#34; cleanup() { trap - INT TERM EXIT exec 3\u0026gt;\u0026amp;- 2\u0026gt;/dev/null if [ -n \u0026#34;$tx_pid\u0026#34; ] \u0026amp;\u0026amp; kill -0 \u0026#34;$tx_pid\u0026#34; 2\u0026gt;/dev/null; then kill -INT \u0026#34;$tx_pid\u0026#34; 2\u0026gt;/dev/null for _ in $(seq 1 10); do kill -0 \u0026#34;$tx_pid\u0026#34; 2\u0026gt;/dev/null || break sleep 0.2 done kill -9 \u0026#34;$tx_pid\u0026#34; 2\u0026gt;/dev/null wait \u0026#34;$tx_pid\u0026#34; 2\u0026gt;/dev/null fi rm -f \u0026#34;$FIFO\u0026#34; exit } trap cleanup INT TERM EXIT start_tx() { \u0026#34;$TRANSMITTER\u0026#34; -f \u0026#34;$FREQ\u0026#34; - \u0026lt; \u0026#34;$FIFO\u0026#34; \u0026amp; tx_pid=$! # Hold the FIFO open for writing so the transmitter never sees EOF # between songs. Blocks until the transmitter has opened its end. exec 3\u0026gt; \u0026#34;$FIFO\u0026#34; # Send a single WAV header declaring an \u0026#34;infinite\u0026#34; (0xFFFFFFFF) data size, # so the transmitter never thinks the stream is finished. Songs are then # streamed as raw PCM matching this header: 22050 Hz, mono, 16-bit signed. printf \u0026#39;RIFF\\xff\\xff\\xff\\xffWAVEfmt \\x10\\x00\\x00\\x00\\x01\\x00\\x01\\x00\\x22\\x56\\x00\\x00\\x44\\xac\\x00\\x00\\x02\\x00\\x10\\x00data\\xff\\xff\\xff\\xff\u0026#39; \u0026gt;\u0026amp;3 } # Decode a file to the raw PCM format declared in the stream header. # Writes to the held-open fd 3 rather than reopening the FIFO: if the # transmitter dies mid-song, sox fails fast with EPIPE, whereas a fresh # open() of the FIFO would block forever waiting for a reader. play() { sox_ng \u0026#34;$1\u0026#34; -r 22050 -c 1 -b 16 -e signed-integer -t raw - \u0026gt;\u0026amp;3 } ensure_tx() { kill -0 \u0026#34;$tx_pid\u0026#34; 2\u0026gt;/dev/null \u0026amp;\u0026amp; return echo \u0026#34;Transmitter died, restarting...\u0026#34; exec 3\u0026gt;\u0026amp;- wait \u0026#34;$tx_pid\u0026#34; 2\u0026gt;/dev/null sleep 1 # don\u0026#39;t spin hot if the transmitter is crashing on startup start_tx } # Play a file, restarting the transmitter and retrying once (from the top of # the file) if it died before or during playback. play_song() { ensure_tx play \u0026#34;$1\u0026#34; \u0026amp;\u0026amp; return echo \u0026#34;Playback failed: $(basename \u0026#34;$1\u0026#34;)\u0026#34; ensure_tx play \u0026#34;$1\u0026#34; || echo \u0026#34;Skipping: $(basename \u0026#34;$1\u0026#34;)\u0026#34; } [ -p \u0026#34;$FIFO\u0026#34; ] || mkfifo \u0026#34;$FIFO\u0026#34; start_tx while true; do files=(\u0026#34;$MP3_DIR\u0026#34;/*.mp3) jingles=(\u0026#34;$JINGLE_DIR\u0026#34;/*.mp3) if [ ${#files[@]} -eq 0 ]; then echo \u0026#34;No .mp3 files found in $MP3_DIR, retrying in 10s...\u0026#34; sleep 10 continue fi mapfile -t shuffled \u0026lt; \u0026lt;(shuf -e -- \u0026#34;${files[@]}\u0026#34;) for song in \u0026#34;${shuffled[@]}\u0026#34;; do echo \u0026#34;Now playing: $(basename \u0026#34;$song\u0026#34;)\u0026#34; play_song \u0026#34;$song\u0026#34; if [ ${#jingles[@]} -gt 0 ]; then jingle=$(shuf -n1 -e -- \u0026#34;${jingles[@]}\u0026#34;) echo \u0026#34;Jingle: $(basename \u0026#34;$jingle\u0026#34;)\u0026#34; play_song \u0026#34;$jingle\u0026#34; fi done done fm-radio.service 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 [Unit] Description=FM Pirate Radio Shuffle [Service] Type=simple ExecStart=/home/pi/fm_shuffle.sh # SIGINT to the whole cgroup: sox dies instantly (bash can\u0026#39;t run its trap # while a foreground child runs), and fm_transmitter\u0026#39;s own SIGINT handler # shuts down the GPIO carrier cleanly. KillMode=control-group KillSignal=SIGINT TimeoutStopSec=10 Restart=on-failure RestartSec=5 User=root [Install] WantedBy=multi-user.target fm_mqtt_control.sh 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 #!/bin/bash # fm_mqtt_control.sh — start/stop the fm-radio service based on MQTT messages # # Listens on $TOPIC_CMD for ON/OFF (also accepts START/STOP/1/0, any case) # and publishes the resulting state to $TOPIC_STATE (retained) so dashboards # like Home Assistant can reflect it. BROKER=\u0026#34;\u0026lt;MQTT_BROKER_ADDRESS\u0026gt;\u0026#34; PORT=\u0026#34;\u0026lt;MQTT_BROKER_PORT\u0026gt;\u0026#34; TOPIC_CMD=\u0026#34;home/radio/set\u0026#34; TOPIC_STATE=\u0026#34;home/radio/state\u0026#34; SERVICE=\u0026#34;fm-radio.service\u0026#34; AUTH=(-u \u0026#34;\u0026lt;MQTT_USER\u0026gt;\u0026#34; -P \u0026#34;\u0026lt;MQTT_PASSWORD\u0026gt;\u0026#34;) publish_state() { mosquitto_pub -h \u0026#34;$BROKER\u0026#34; -p \u0026#34;$PORT\u0026#34; \u0026#34;${AUTH[@]}\u0026#34; -t \u0026#34;$TOPIC_STATE\u0026#34; -r -m \u0026#34;$1\u0026#34; } mosquitto_sub -h \u0026#34;$BROKER\u0026#34; -p \u0026#34;$PORT\u0026#34; \u0026#34;${AUTH[@]}\u0026#34; -t \u0026#34;$TOPIC_CMD\u0026#34; | while read -r msg; do case \u0026#34;${msg^^}\u0026#34; in ON|START|1) echo \u0026#34;MQTT: starting $SERVICE\u0026#34; systemctl start \u0026#34;$SERVICE\u0026#34; \u0026amp;\u0026amp; publish_state \u0026#34;ON\u0026#34; ;; OFF|STOP|0) echo \u0026#34;MQTT: stopping $SERVICE\u0026#34; systemctl stop \u0026#34;$SERVICE\u0026#34; \u0026amp;\u0026amp; publish_state \u0026#34;OFF\u0026#34; ;; *) echo \u0026#34;MQTT: ignoring unknown payload: $msg\u0026#34; ;; esac done # mosquitto_sub exiting means the broker connection dropped; # exit nonzero so systemd restarts us and we reconnect. exit 1 fm-radio-mqtt.service 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 [Unit] Description=MQTT start/stop control for FM Pirate Radio Wants=network-online.target After=network-online.target [Service] Type=simple ExecStart=/home/pi/fm_mqtt_control.sh # Reconnect forever if the broker goes away or isn\u0026#39;t up yet at boot. Restart=always RestartSec=5 User=root [Install] WantedBy=multi-user.target ","permalink":"https://blog.thordy.dev/posts/pimp-my-tractor/","summary":"\u003cp\u003eEarlier this year, my parents bought a \u003ca href=\"https://www.felleskjopet.no/produkt/hjem-og-fritid/fanshop/john-deere-fanshop/leker/elektrisk-traktor-med-tilhenger-for-barn-50265945_BASE\"\u003eJohn Deere Ground Force Tractor and Trailer\u003c/a\u003e for my son Theodore and the other grandkids to play with at the cabin. For some inexplicable reason, in 2026, this tractor includes an FM radio (\u003ccode\u003e2xAA\u003c/code\u003e lithium batteries – not included). Putting the batteries in and turning it on, hits you with a blast of static noise, since Norway has \u003ca href=\"https://en.wikipedia.org/wiki/Radio_in_Norway\"\u003etransitioned most FM to DAB\u003c/a\u003e since 2017.\u003c/p\u003e","title":"Pimp My Tractor"},{"content":" Ever since we built Dart Reidar at work, I\u0026rsquo;ve been wanting to create something similar to upgrade my dart setup at home. Obviously I don\u0026rsquo;t have room for anything that large, but getting lights around the board would be cool.\nBackground When we were adding lights to Dart Reidar, we were brand new to the space, and ended up with a mix of 12v and 24v lights, controlled via a Raspberry Pi using pigpihoseo. This gave us the ability to do any RGB color of lights around the board, as well as along the oche. kcapp then added support for each player to choose their own color, and when a checkout happens the lights would do a simple \u0026ldquo;blink\u0026rdquo; effect for a few seconds.\nFor another hackathon at work, we looked into adding WLED support instead, which would give a lot more options for effects and stuff, but it is yet to be finalized. Since then I\u0026rsquo;ve thought a lot about how I could get WLED setup at home with some lightstrips, but the wiring and soldering parts have always worried me a bit, and I never got around to it.\nHome improvement version One day I stumbled across pre-built WLED controllers, which sounded exactly like what I would want, and which would take away most of the worries regarding how to mount the ESP32 and mess of wires. Initially I decided to try having one strip around the board, and one on each side of the board up the wall, and a great thing about some GLEDOPTO controllers is that they have 4 outputs, so it can easily run multiple strips.\nShopping List Controller\nGLEDOPTO has quite a few different WLED controllers to choose between, and they ship to Norway from Amazon, so I decided to try one of those. I looked at a few different options but ended up with the GLEDOPTO 4D-EXMU as it seemed like their \u0026ldquo;best\u0026rdquo; one, and price difference wasn\u0026rsquo;t that big compared to the lesser versions.\nGLEDOPTO Elite 4D-EXMU LED strips\nWhen it comes to which strips to use WLED has a good comparison on their website of a lot of different strips and advantages between the different ones. I ended up choosing WS2815 since I wanted something 12v and it has a backup data line. I also don\u0026rsquo;t care about any ambient white light on these, if I did I would probably select a RGBCCT strip. Specifically I chose a 30LEDs/m to divide into sections for the left and right side of the wall, and a 60LEDs/m to go around the board.\nBTF-LIGHTING WS2815 5m 30LEDs/m BTF-LIGHTING WS2815 5m 60LEDs/m Power Supply\nInitially I chose a cheap generic 12V 10A Power Supply Adapter, but I quickly replaced it with a more suitable Mean Well power supply, since the original generated too much high pitched whining noise under load. For the future, I\u0026rsquo;m thinking about replacing this with something like MEAN WELL Switching Power Supply, RS-75-12, but as a beginner just starting out, a power supply with a barrel adapter works well, and can be just plugged directly into the GLEDOPTO controller\nMEAN WELL Original GST60A12-P1J 12V 5A Meanwell GST60A 12V 60W Diffusers\nLooking directly at LED strips isn\u0026rsquo;t very pleasurable for your eyes, especially at higher brightness. It also looks unfinished and more amateur. To improve this I found a 2 meter long 12mm black aluminium profile that I could cut for the strips on the side. I chose a \u0026ldquo;frosted\u0026rdquo; cover instead of the black one, since I wanted light to clearly be visible, and was afraid black might be too dark. For around the board I found a flexible silicone profile, but a bit of foreshadowing: This did not work \u0026hellip; more on that later\nPrima 12 1707D Aluprofil 2m I/U Sort LED Silicone Profile Black 5 m, Flexible Diffuser Channel Other\nTo connect everything together I found some 4 core electric cable which works well with the 4 wires needed for the WS2815 and a set of 4-pin JST cables to more easily unplug the strips and not have to deal with loose wires directly into the controller\n10 Metres 20 AWG, 4 x 0.5 mm² Electric Cable BTF-LIGHTING 4PIN SM JST Cable Female / Male I also discovered the 4-pin connector kits that BTF-LIGHTING has, which I picked up to more easily use the rest of the strips after I cut them. This can also be done with soldering, but these connectors make it even simpler to do\nBTF-LIGHTING SMD 4-Pin 10 mm Connector Kit On top of this, I also picked up some adhesive tape to easily mount the diffuser channels onto the wall\nBTF-LIGHTING Double-Sided Adhesive Tape Assembly Once everything arrived it was time to assemble.\nOne thing I struggled with when I first got the GLEDOPTO controller was how to connect wires to the outputs. It has these \u0026ldquo;clamps\u0026rdquo; which lift open to insert the wire, and then close. But I was having a hard time getting any wire to stick. After banging my head against the wall for a while, and some googling, I finally figured out you need to open the clamp fully to a 90° angle, and not just to the first point where they \u0026ldquo;stop\u0026rdquo;. It actually requires a surprising amount of force to open them all the way (at least the first few times)\nPartially open\nFully extended\nBoard strip This brought me the most trouble. The LED Silicone profile I had bought says it should fit 12mm strips, but I had a lot of trouble getting the strip into the channel. Even after using a xacto knife and slicing it open, I was struggling to pull the strip through. After a lot of manually moving and pushing the strip I eventually got it to sit somewhat, but not perfectly.\nNow the next issue was that I had planned the light to face outwards to the side, to not be too bright and distracting when playing. Unfortunately with nothing to reflect off of, and being inside a black silicone profile, this meant the light wouldn\u0026rsquo;t be visible at all from the front, which defeats part of the point. When we made the one for Dart Reidar we had the light at an angle so it reflected off the wall and surround, and when doing the initial WLED setup in the office a colleague 3D printed a black and white angled channel which also reflected the light a lot.\nTrying to twist the profile around and attach it to the board provided another challenge. It can\u0026rsquo;t be anything permanently attached, since I need to be able to rotate and replace both the board and the surround in the future. So since that\u0026rsquo;s all temporary it wasn\u0026rsquo;t easy to find any way to attach it securely.\nWith all these problems, I ended up shelving the board strip, and figured the best bet is probably to go the 3D print route, but that will be something for another time.\nWall strips Thankfully the wall strips did not bring any trouble. I simply measured the required lengths for each side and cut at those lengths. The strip comes assembled with a JST connector on one end, and after cutting the length I needed, I used the 4-pin connector kit and connected a JST connector so I easily could unplug each strip if required.\nThen I connected the strips to the GLEDOPTO controller like the following:\n1 2 3 4 5 # Left Right GND =\u0026gt; GND GND =\u0026gt; GND BO =\u0026gt; IO16 BO =\u0026gt; IO12 DO =\u0026gt; IO16 DO =\u0026gt; IO12 V+ =\u0026gt; +12V V+ =\u0026gt; +12V To get the +12V and GND wires to go to both strips I just used a Wago connector, which came in the box with the controller (1-to-4), and for both the data wires I simply put both into the same GPIO port on the controller.\nFor the aluminium profiles I cut them with a hacksaw to the correct length. Strips came with adhesive on the back already, so I used this to connect them into the channel. I also cut the frosted cover with a pair of wire cutters to fit the new lengths. Then I used the screw mounts fo put them on the wall plus some of the double sided adhesive for the angled parts.\nIn hindsight I would probably have chosen a 60LEDs/m for these strips as well (or even 144LEDs/m if budget wasn\u0026rsquo;t a constraint) to have more fluid effects of the lights and make the strips seem like one continuous strip of light, but it still looks decent with the current 30LEDs/m strips.\nMounted LED strip in aluminium channel Mounted LED strip with blue light Mounted LED strip with red light Wiring diagram Here is a simple diagram showing the wiring of the GLEDOPTO controller and the light strips Conclusion The controller still has two free outputs, so I\u0026rsquo;m able to get more strips connected, and I\u0026rsquo;m still hoping to find a solution to the dartboard surround strip, but for now I\u0026rsquo;m quite happy with the result, and it has definitely upgraded the look of the dartboard!\nDemo WLED Colorloop effect\nYour browser doesn\u0026rsquo;t support video playback. WLED Heartbeat effect\nYour browser doesn\u0026rsquo;t support video playback. ","permalink":"https://blog.thordy.dev/posts/light-up-my-darts/","summary":"\u003cdiv class=\"two-columns even-split\"\u003e\n\n\u003cdiv class=\"column\"\u003e\n\u003cp\u003eEver since we built \u003ca href=\"https://github.com/kcapp/frontend/wiki/Dart_Reidar\"\u003eDart Reidar\u003c/a\u003e at work, I\u0026rsquo;ve been wanting to create something similar to upgrade my dart setup at home. Obviously I don\u0026rsquo;t have room for anything that large, but getting lights around the board would be cool.\u003c/p\u003e\n\n\u003c/div\u003e\n\u003cdiv class=\"column\"\u003e\n\u003ca href=\"images/dart_reidar.jpg\" target=\"_blank\" rel=\"noopener noreferrer\" class=\"img-small-link\" style=\"max-width: 320px; \"\u003e\n  \u003cimg src=\"images/dart_reidar.jpg\" alt=\"Dart Reidar setup in office, showing the dual monitors, oche and dartboard\" class=\"img-small\" loading=\"lazy\"\u003e\n\u003c/a\u003e\n\n\u003c/div\u003e\n\n\u003c/div\u003e\n\u003ch2 id=\"background\"\u003eBackground\u003c/h2\u003e\n\u003cp\u003eWhen we were adding lights to \u003ccode\u003eDart Reidar\u003c/code\u003e, we were brand new to the space, and ended up with a mix of \u003ccode\u003e12v\u003c/code\u003e and \u003ccode\u003e24v\u003c/code\u003e lights, controlled via a Raspberry Pi using \u003ca href=\"https://github.com/fivdi/pigpio\"\u003epigpihoseo\u003c/a\u003e. This gave us the ability to do any \u003ccode\u003eRGB\u003c/code\u003e color of lights around the board, as well as along the oche. \u003ca href=\"https://github.com/kcapp/frontend/wiki\"\u003ekcapp\u003c/a\u003e then added support for each player to choose their own color, and when a checkout happens the lights would do a simple \u0026ldquo;blink\u0026rdquo; effect for a few seconds.\u003c/p\u003e","title":"Light up my darts"},{"content":"Hi, I\u0026rsquo;m Thord. This is my personal blog — mostly smart home projects, electronics, darts, and whatever cabin project I\u0026rsquo;m currently in the middle of.\n","permalink":"https://blog.thordy.dev/about/","summary":"\u003cp\u003eHi, I\u0026rsquo;m Thord. This is my personal blog — mostly smart home projects,\nelectronics, darts, and whatever cabin project I\u0026rsquo;m currently in the\nmiddle of.\u003c/p\u003e","title":"About"}]