<?xml version="1.0" encoding="utf-8" standalone="yes"?>
<rss version="2.0" xmlns:atom="http://www.w3.org/2005/Atom">
	<channel>
		<title>Software on Charlie Howlett</title>
		<link>https://charliehowlett.co.uk/tags/software/</link>
		<description>Recent content in Software on Charlie Howlett</description>
		<generator>Hugo</generator>
		<language>en-gb</language>
		
		
		
		
			<lastBuildDate>Sat, 22 Aug 2026 00:00:00 +0000</lastBuildDate>
		
			<atom:link href="https://charliehowlett.co.uk/tags/software/index.xml" rel="self" type="application/rss+xml" />
			<item>
				<title>Automating Backing Tracks</title>
				<link>https://charliehowlett.co.uk/posts/2026-08-22-automating-backing-tracks/</link>
				<pubDate>Sat, 22 Aug 2026 00:00:00 +0000</pubDate>
				<guid>https://charliehowlett.co.uk/posts/2026-08-22-automating-backing-tracks/</guid>
				<description>&lt;p&gt;When rehearsing, alone or with others, I sometimes like to play along to backing tracks with a few of the original instrument parts removed. My &lt;a href=&#34;https://charliehowlett.co.uk/posts/2025-05-03-building-compact-hybrid-drumming/&#34;&gt;hybrid drumming rig&lt;/a&gt; works well for this, but preparing the backing tracks can be a pain. Typically, I&amp;rsquo;d download an MP3 of the song, manually upload it to a stem-separation service, then re-export it in the TM-2’s expected format: stereo 44.1 kHz PCM WAV. This works, but preparing a couple of songs for a rehearsal can take quite a bit of time.&lt;/p&gt;</description>
			</item>
			<item>
				<title>Managing My Homelab with Ansible</title>
				<link>https://charliehowlett.co.uk/posts/2026-08-18-managing-my-homelab-with-ansible/</link>
				<pubDate>Tue, 18 Aug 2026 00:00:00 +0000</pubDate>
				<guid>https://charliehowlett.co.uk/posts/2026-08-18-managing-my-homelab-with-ansible/</guid>
				<description>&lt;p&gt;In previous posts, I described how I set up my &lt;a href=&#34;https://charliehowlett.co.uk/posts/2026-05-22-repurposing-a-laptop-as-a-home-server/&#34;&gt;repurposed laptop server&lt;/a&gt; and &lt;a href=&#34;https://charliehowlett.co.uk/posts/2026-06-12-raspberry-pi-server-rack/&#34;&gt;Raspberry Pi server rack&lt;/a&gt;. Together, they have grown into a useful little homelab.&lt;/p&gt;&#xA;&#xA;&#xA;&#xA;&#xA;&#xA;&#xA;&#xA;&#xA;&#xA;&#xA;&#xA;&lt;img&#xA;  class=&#34;image-large&#34;&#xA;  src=&#34;https://charliehowlett.co.uk/posts/2026-08-18-managing-my-homelab-with-ansible/homelab-topology.svg&#34;&#xA;  alt=&#34;Topology diagram showing SSD directly connected to Raspberry Pi 3, with all hosts connected to a shared Ethernet bus.&#34;&#xA;  decoding=&#34;async&#34;&gt;&#xA;&#xA;&#xA;&lt;p&gt;The top-level topology is simple, but the deployed services and their configuration complicate things quickly.&lt;/p&gt;&#xA;&#xA;&#xA;&#xA;&#xA;&#xA;&#xA;&#xA;&#xA;&#xA;&#xA;&#xA;&lt;img&#xA;  class=&#34;image-large&#34;&#xA;  src=&#34;https://charliehowlett.co.uk/posts/2026-08-18-managing-my-homelab-with-ansible/homelab-topology--services.svg&#34;&#xA;  alt=&#34;Topology diagram showing applications deployed on each homelab host: the server laptop runs Super Productivity, a productivity planner; every host runs Alloy; Pi 2 also runs device monitoring and Git Auto Sync, while Pi 3 hosts SSD storage, Samba, PostgreSQL, and the Grafana and Loki monitoring stack.&#34;&#xA;  decoding=&#34;async&#34;&gt;&#xA;&#xA;&#xA;&lt;p&gt;It can be tricky to keep track of:&lt;/p&gt;</description>
			</item>
			<item>
				<title>Automating LinkedIn Cross-Posting</title>
				<link>https://charliehowlett.co.uk/posts/2026-08-05-linkedin-cross-posting/</link>
				<pubDate>Wed, 05 Aug 2026 00:00:00 +0000</pubDate>
				<guid>https://charliehowlett.co.uk/posts/2026-08-05-linkedin-cross-posting/</guid>
				<description>&lt;p&gt;I&amp;rsquo;ve been writing posts here for quite a while, and during that time the site has grown to cover a fairly wide mix of topics. I felt it would be nice to share that work with a larger audience, so I decided to implement a CI/CD pipeline for automatically cross-posting to LinkedIn.&lt;/p&gt;&#xA;&lt;h2 id=&#34;implementation&#34;&gt;Implementation&lt;/h2&gt;&#xA;&lt;p&gt;I originally considered using Zapier for this, but the free tier did not offer the functionality I needed, so I built a small publishing pipeline myself using GitHub Actions.&lt;/p&gt;</description>
			</item>
			<item>
				<title>Jar Light Display</title>
				<link>https://charliehowlett.co.uk/posts/2026-07-28-old-jar-led-display/</link>
				<pubDate>Tue, 28 Jul 2026 00:00:00 +0000</pubDate>
				<guid>https://charliehowlett.co.uk/posts/2026-07-28-old-jar-led-display/</guid>
				<description>&lt;p&gt;Almost every night I light a candle before going to bed as part of my nighttime routine, so I have heaps of leftover glass jars that seem too nice to throw away. Last weekend my girlfriend and I had the idea to turn one into a nice-looking enclosure for an interactive LED light project.&lt;/p&gt;&#xA;&lt;p&gt;The first step was cleaning out the old wax and wick.&lt;/p&gt;&#xA;&#xA;&#xA;&#xA;&#xA;&#xA;&#xA;&#xA;&#xA;&#xA;&#xA;&lt;picture&gt;&#xA;  &lt;source&#xA;    type=&#34;image/webp&#34;&#xA;    srcset=&#34;https://charliehowlett.co.uk/posts/2026-07-28-old-jar-led-display/1_empty_candle_jar_hu_31707ab996fb18c3.webp 720w, https://charliehowlett.co.uk/posts/2026-07-28-old-jar-led-display/1_empty_candle_jar_hu_8d94c3ca15194886.webp 1440w&#34;&#xA;    sizes=&#34;(max-width: 700px) 90vw, 720px&#34;&gt;&#xA;  &lt;img&#xA;    class=&#34;image-large&#34;&#xA;    src=&#34;https://charliehowlett.co.uk/fallback-images/posts/2026-07-28-old-jar-led-display/1_empty_candle_jar.jpg&#34;&#xA;    alt=&#34;The empty amber candle jar before the electronics were fitted&#34;&#xA;    width=&#34;3083&#34;&#xA;    height=&#34;2467&#34;&#xA;    decoding=&#34;async&#34;&gt;&#xA;&lt;/picture&gt;&#xA;&#xA;&#xA;&lt;p&gt;Next, we made a display that exactly fits the unique shape of the jar. We bought a strip of individually addressable LEDs, cut it into shorter sections, and wired them together into a flexible circular matrix.&lt;/p&gt;</description>
			</item>
			<item>
				<title>Mobile Dev Setup</title>
				<link>https://charliehowlett.co.uk/posts/2026-07-03-mobile-dev-setup/</link>
				<pubDate>Fri, 03 Jul 2026 00:00:00 +0000</pubDate>
				<guid>https://charliehowlett.co.uk/posts/2026-07-03-mobile-dev-setup/</guid>
				<description>&lt;p&gt;I&amp;rsquo;ve always felt quite restless once I start working on a project. If I&amp;rsquo;m sitting in a park, on a train, or away from my desk with an idea in my head, I often want to make a quick change or keep a thread of work moving. But without my laptop I&amp;rsquo;ve always had to settle for doing something else. Still, I have always been curious about what options were available so years ago I looked into Termux, an app that provides a terminal on your phone. I wanted to try coding on the go, but writing productive code from such a small screen and keyboard felt impractical. However, when AI agents came along the idea started to seem much more realistic so I decide to try again.&lt;/p&gt;</description>
			</item>
			<item>
				<title>Optimizing Hugo Image Loading Time</title>
				<link>https://charliehowlett.co.uk/posts/2026-06-24-optimizing-image-loading-time/</link>
				<pubDate>Wed, 24 Jun 2026 00:00:00 +0000</pubDate>
				<guid>https://charliehowlett.co.uk/posts/2026-06-24-optimizing-image-loading-time/</guid>
				<description>&lt;p&gt;As I&amp;rsquo;ve added more posts to &lt;a href=&#34;https://charliehowlett.co.uk/&#34;&gt;charliehowlett.co.uk&lt;/a&gt;, the site has gradually accumulated lots of screenshots, photos, and short animations. I usually upload whatever media files I have available without first optimising them for web, which can increase site size and negatively impact page load times. At first I thought to simply enable the &lt;code&gt;img-bot&lt;/code&gt; GitHub action to automatically optimise images, but unfortunately the service&amp;rsquo;s free tier does not extend to private repositories. So I spent some time implementing my own automatic image optimisation process.&lt;/p&gt;</description>
			</item>
			<item>
				<title>Reverse Engineering Roland TM-2</title>
				<link>https://charliehowlett.co.uk/posts/2026-06-19-trigger-module-reader/</link>
				<pubDate>Fri, 19 Jun 2026 00:00:00 +0000</pubDate>
				<guid>https://charliehowlett.co.uk/posts/2026-06-19-trigger-module-reader/</guid>
				<description>&lt;p&gt;While building my &lt;a href=&#34;https://charliehowlett.co.uk/posts/2025-05-03-building-compact-hybrid-drumming/&#34;&gt;compact hybrid drumming rig&lt;/a&gt;, I became very familiar with the Roland TM-2. The module has an enormous number of settings and even lets users save configurations to an SD card as &lt;code&gt;.TM0&lt;/code&gt; files. One day, I opened one of these files on my computer to see what was inside. I found mostly unreadable raw binary data, with a short string of plain English text at the top: the name of my save file. This led me to wonder whether I could reverse engineer the format and display all the information in a web-based user interface.&lt;/p&gt;</description>
			</item>
			<item>
				<title>Monitoring My Homelab with Grafana</title>
				<link>https://charliehowlett.co.uk/posts/2026-06-17-monitoring-my-homelab-with-grafana/</link>
				<pubDate>Wed, 17 Jun 2026 00:00:00 +0000</pubDate>
				<guid>https://charliehowlett.co.uk/posts/2026-06-17-monitoring-my-homelab-with-grafana/</guid>
				<description>&lt;p&gt;Once I had several processes running continuously in my homelab, I needed a single place to inspect what they were doing. Connecting to a machine via SSH and reading logs directly is useful, but hardly convenient, so I set up an observability platform. I use Grafana for querying and visualising logs, Loki for storing and querying logs, and Grafana Alloy for collecting and forwarding logs. The components run as Docker containers on a Raspberry Pi with an attached SSD for persistent storage.&lt;/p&gt;</description>
			</item>
			<item>
				<title>Hugo Teletext</title>
				<link>https://charliehowlett.co.uk/posts/2026-06-15-building-hugo-teletext/</link>
				<pubDate>Mon, 15 Jun 2026 00:00:00 +0000</pubDate>
				<guid>https://charliehowlett.co.uk/posts/2026-06-15-building-hugo-teletext/</guid>
				<description>&lt;p&gt;Earlier this year, I decided to revamp my personal site&amp;rsquo;s style and introduce a blog. I chose the static site generator Hugo because it keeps post content, written in raw Markdown, cleanly separated from site styling. Which should help reduce maintenance time and make cross-posting easier.&lt;/p&gt;&#xA;&lt;p&gt;I originally planned to use a third-party Hugo theme, but after stumbling across the Teletext font at &lt;a href=&#34;https://www.galax.xyz&#34;&gt;galax.xyz&lt;/a&gt;, I was inspired to design my own reusable teletext-inspired theme.&lt;/p&gt;</description>
			</item>
			<item>
				<title>Git Auto Sync</title>
				<link>https://charliehowlett.co.uk/posts/2026-06-14-git-auto-sync/</link>
				<pubDate>Sun, 14 Jun 2026 00:00:00 +0000</pubDate>
				<guid>https://charliehowlett.co.uk/posts/2026-06-14-git-auto-sync/</guid>
				<description>&lt;p&gt;After setting up my &lt;a href=&#34;https://charliehowlett.co.uk/posts/2026-06-12-raspberry-pi-server-rack/&#34;&gt;Raspberry Pi home lab&lt;/a&gt;, I deployed a small project onto one of the Pis and immediately wanted a cleaner method for continuous deployment. The app lived in a Git repository, and I wanted the running copy on the Pi to update automatically whenever the repo changed.&lt;/p&gt;&#xA;&lt;p&gt;The obvious approach would have been a webhook: GitHub sends a request, a local service receives it, and the Pi pulls the latest code. I decided against that for security reasons. I did not want to expose a service on my home network just so GitHub could tell it that a commit had landed, and I did not want to build a tunnel or webhook receiver for something that could be solved more simply.&lt;/p&gt;</description>
			</item>
			<item>
				<title>Monitoring Devices on My Home Network</title>
				<link>https://charliehowlett.co.uk/posts/2026-06-13-device-monitoring/</link>
				<pubDate>Sat, 13 Jun 2026 00:00:00 +0000</pubDate>
				<guid>https://charliehowlett.co.uk/posts/2026-06-13-device-monitoring/</guid>
				<description>&lt;p&gt;My router gives me a basic view of the devices currently connected to my network, but it does not expose historical information. I started this project to fill that gap: a small Raspberry Pi service that scans the LAN, records which devices it sees, and shows that data in a dashboard.&lt;/p&gt;&#xA;&lt;h2 id=&#34;implementation&#34;&gt;Implementation&lt;/h2&gt;&#xA;&lt;p&gt;The service periodically runs &lt;code&gt;arp-scan&lt;/code&gt; to discover devices on the local network, then stores the results in a database with both the current device state and a history of online/offline events. That split lets the system track when a device first appeared, when it was last seen, and how its presence changed across a day or week.&lt;/p&gt;</description>
			</item>
			<item>
				<title>GitHub Action to Automate Screenshots</title>
				<link>https://charliehowlett.co.uk/posts/2026-05-06-update-screenshots-action/</link>
				<pubDate>Wed, 06 May 2026 00:00:00 +0000</pubDate>
				<guid>https://charliehowlett.co.uk/posts/2026-05-06-update-screenshots-action/</guid>
				<description>&lt;p&gt;Screenshots can make project documentation much clearer, but they quickly become misleading when they fall out of date. I built update-screenshots-action to automate that maintenance: capture a web page, save the image in the repository, and update a known section of a Markdown file.&lt;/p&gt;&#xA;&lt;h2 id=&#34;implementation&#34;&gt;Implementation&lt;/h2&gt;&#xA;&lt;p&gt;The action takes a URL, opens it in Chromium through Playwright, and captures either a PNG or an animated GIF at a repository-relative path. It then rewrites a marked block in a Markdown file so the reference remains in sync with the generated asset. Optional commit-and-push support allows the action to run on a schedule or after changes to a site without requiring additional workflow steps. Even within that narrow scope, running reliably in CI required handling several operational details. Navigation is retried while local preview servers start, and commits are only created when one of the managed files has actually changed.&lt;/p&gt;</description>
			</item>
			<item>
				<title>Framing Six Years at MindLink</title>
				<link>https://charliehowlett.co.uk/posts/2025-07-04-mindlink-shadowbox/</link>
				<pubDate>Fri, 04 Jul 2025 00:00:00 +0000</pubDate>
				<guid>https://charliehowlett.co.uk/posts/2025-07-04-mindlink-shadowbox/</guid>
				<description>&lt;p&gt;For software engineers, the ethereal nature of our work often means we&amp;rsquo;re left without many physical reminders that it ever happened. That can make it surprisingly hard to look back and celebrate what we&amp;rsquo;ve actually done, especially after constantly moving from one project to the next. I&amp;rsquo;ve certainly felt that myself, so I&amp;rsquo;ve made a point of holding on to a few keepsakes over the years. After finding several of them during a recent spring clean, I decided to turn them into a display for my office shelf.&lt;/p&gt;</description>
			</item>
			<item>
				<title>Building an Arduino Robot Car in a Day</title>
				<link>https://charliehowlett.co.uk/posts/2024-06-12-arduino-robot-car-in-a-day/</link>
				<pubDate>Wed, 12 Jun 2024 00:00:00 +0000</pubDate>
				<guid>https://charliehowlett.co.uk/posts/2024-06-12-arduino-robot-car-in-a-day/</guid>
				<description>&lt;p&gt;I set myself a small challenge: build a working Arduino robot car in a single day, using only electronics parts I already had around the flat.&lt;/p&gt;&#xA;&#xA;&#xA;&#xA;&lt;div class=&#34;video-frame teletext-box&#34;&gt;&#xA;  &lt;iframe&#xA;    class=&#34;video-frame__iframe&#34;&#xA;    src=&#34;https://www.youtube-nocookie.com/embed/JiTKMaDml5Y&#34;&#xA;    title=&#34;Arduino robot car one-day build timelapse&#34;&#xA;    loading=&#34;lazy&#34;&#xA;    allow=&#34;accelerometer; autoplay; clipboard-write; encrypted-media; gyroscope; picture-in-picture; web-share&#34;&#xA;    referrerpolicy=&#34;strict-origin-when-cross-origin&#34;&#xA;    allowfullscreen&gt;&#xA;  &lt;/iframe&gt;&#xA;&lt;/div&gt;&#xA;&#xA;&lt;p&gt;I decided to build it because I had found a TB6612FNG motor driver lying around, along with an Arduino Mini, a battery pack, and a couple of small wheels with DC motors. For the body, I used a little wooden board I had spare and fixed the motors and other parts to it with some metal joinery pieces.&lt;/p&gt;</description>
			</item>
			<item>
				<title>Arduino LoRa Monitoring System</title>
				<link>https://charliehowlett.co.uk/posts/2022-01-11-arduino-monitoring/</link>
				<pubDate>Tue, 11 Jan 2022 00:00:00 +0000</pubDate>
				<guid>https://charliehowlett.co.uk/posts/2022-01-11-arduino-monitoring/</guid>
				<description>&lt;p&gt;I rent a small drumming practice space that I share with several other musicians on a timetable basis. I built this monitoring system to understand how often people were using their booked time slots and how the room&amp;rsquo;s environmental conditions changed over time. Since the space has no Wi-Fi and unreliable mains power, the project became an interesting challenge involving low-power hardware, long-range radio communication, and remote data collection.&lt;/p&gt;&#xA;&#xA;&#xA;&#xA;&#xA;&#xA;&#xA;&#xA;&#xA;&#xA;&#xA;&lt;picture&gt;&#xA;  &lt;source&#xA;    type=&#34;image/webp&#34;&#xA;    srcset=&#34;https://charliehowlett.co.uk/posts/2022-01-11-arduino-monitoring/ArduinoMonitoring_hu_febdf34626a4b6ed.webp 520w, https://charliehowlett.co.uk/posts/2022-01-11-arduino-monitoring/ArduinoMonitoring_hu_2626646897062a3e.webp 1040w&#34;&#xA;    sizes=&#34;(max-width: 700px) 90vw, 520px&#34;&gt;&#xA;  &lt;img&#xA;    class=&#34;image-medium&#34;&#xA;    src=&#34;https://charliehowlett.co.uk/fallback-images/posts/2022-01-11-arduino-monitoring/ArduinoMonitoring.jpg&#34;&#xA;    alt=&#34;The Arduino monitoring hardware with sensors and radio module&#34;&#xA;    width=&#34;1500&#34;&#xA;    height=&#34;1500&#34;&#xA;    decoding=&#34;async&#34;&gt;&#xA;&lt;/picture&gt;&#xA;&#xA;&#xA;&lt;h2 id=&#34;sensor-node&#34;&gt;Sensor node&lt;/h2&gt;&#xA;&lt;p&gt;The sensing node is built around a 3.3V Arduino Pro Mini with sensors for PIR motion, humidity, temperature, and ambient light. Every ten minutes, it wakes up, collects readings, packs them into a small JSON payload, transmits the result by radio, and returns to sleep. I spent a significant amount of time reducing its power consumption so the device could run for roughly six months from three AA batteries. For this project, reliable long-term monitoring mattered more than collecting readings more frequently.&lt;/p&gt;</description>
			</item>
			<item>
				<title>Llama Bot</title>
				<link>https://charliehowlett.co.uk/posts/2022-01-01-llama-bot/</link>
				<pubDate>Sat, 01 Jan 2022 00:00:00 +0000</pubDate>
				<guid>https://charliehowlett.co.uk/posts/2022-01-01-llama-bot/</guid>
				<description>&lt;p&gt;This project started with a burst stress toy llama that seemed too good to throw away. I decided to give it a second life as a singing, dancing robot, which turned a cute toy into a compact embedded engineering project involving electronics, power, motion, and control logic.&lt;/p&gt;&#xA;&#xA;&#xA;&#xA;&#xA;&#xA;&#xA;&#xA;&#xA;&#xA;&lt;div class=&#34;image-pair&#34;&gt;&#xA;  &lt;figure class=&#34;image-pair__item&#34;&gt;&#xA;    &#xA;      &lt;picture&gt;&#xA;  &lt;source&#xA;    type=&#34;image/webp&#34;&#xA;    srcset=&#34;https://charliehowlett.co.uk/posts/2022-01-01-llama-bot/profile_hu_bb229bcdbc1415ae.webp 360w, https://charliehowlett.co.uk/posts/2022-01-01-llama-bot/profile_hu_42e164e8b5cf5700.webp 720w&#34;&#xA;    sizes=&#34;(max-width: 700px) 90vw, 360px&#34;&gt;&#xA;  &lt;img&#xA;    class=&#34;image-large&#34;&#xA;    src=&#34;https://charliehowlett.co.uk/fallback-images/posts/2022-01-01-llama-bot/profile.jpg&#34;&#xA;    alt=&#34;The finished llama bot from the side&#34;&#xA;    width=&#34;3648&#34;&#xA;    height=&#34;2736&#34;&#xA;    decoding=&#34;async&#34;&gt;&#xA;&lt;/picture&gt;&#xA;&#xA;    &#xA;  &lt;/figure&gt;&#xA;  &lt;figure class=&#34;image-pair__item&#34;&gt;&#xA;    &#xA;      &lt;picture&gt;&#xA;  &lt;source&#xA;    type=&#34;image/webp&#34;&#xA;    srcset=&#34;https://charliehowlett.co.uk/posts/2022-01-01-llama-bot/innards_hu_4c71458ebf06693e.webp 360w, https://charliehowlett.co.uk/posts/2022-01-01-llama-bot/innards_hu_f77a78b3f52ae29c.webp 720w&#34;&#xA;    sizes=&#34;(max-width: 700px) 90vw, 360px&#34;&gt;&#xA;  &lt;img&#xA;    class=&#34;image-large&#34;&#xA;    src=&#34;https://charliehowlett.co.uk/fallback-images/posts/2022-01-01-llama-bot/innards.jpg&#34;&#xA;    alt=&#34;The llama bot opened up to show the internal electronics and structure&#34;&#xA;    width=&#34;1280&#34;&#xA;    height=&#34;960&#34;&#xA;    decoding=&#34;async&#34;&gt;&#xA;&lt;/picture&gt;&#xA;&#xA;    &#xA;  &lt;/figure&gt;&#xA;&lt;/div&gt;&#xA;&#xA;&lt;h2 id=&#34;implementation&#34;&gt;Implementation&lt;/h2&gt;&#xA;&lt;p&gt;The electronics were built around an Adafruit Feather HUZZAH ESP8266, with a servo for movement, a buzzer for playing songs, and a rechargeable LiPo battery connected to the board&amp;rsquo;s micro-USB charging port. I also added an on/off switch by grounding the ESP8266 enable pin, allowing the toy to draw effectively no current while switched off instead of slowly draining the battery. Inside the llama, a structure made from cardboard, copper wire, and hot glue held the components in place and made the damaged toy sturdy enough to survive repeated movement.&lt;/p&gt;</description>
			</item>
			<item>
				<title>Automating Lights with a Raspberry Pi</title>
				<link>https://charliehowlett.co.uk/posts/2021-09-02-pi-lights/</link>
				<pubDate>Thu, 02 Sep 2021 00:00:00 +0000</pubDate>
				<guid>https://charliehowlett.co.uk/posts/2021-09-02-pi-lights/</guid>
				<description>&lt;p&gt;Pi Lights was a fairly simple idea and my first exploration into DIY home automation: measure the ambient light level throughout the day using a Raspberry Pi, then switch Wi-Fi lights on or off automatically.&lt;/p&gt;&#xA;&#xA;&#xA;&#xA;&lt;div class=&#34;video-frame teletext-box&#34;&gt;&#xA;  &lt;iframe&#xA;    class=&#34;video-frame__iframe&#34;&#xA;    src=&#34;https://www.youtube-nocookie.com/embed/ZpO6WK41Bb8&#34;&#xA;    title=&#34;Pi lights demo video&#34;&#xA;    loading=&#34;lazy&#34;&#xA;    allow=&#34;accelerometer; autoplay; clipboard-write; encrypted-media; gyroscope; picture-in-picture; web-share&#34;&#xA;    referrerpolicy=&#34;strict-origin-when-cross-origin&#34;&#xA;    allowfullscreen&gt;&#xA;  &lt;/iframe&gt;&#xA;&lt;/div&gt;&#xA;&#xA;&lt;h2 id=&#34;implementation&#34;&gt;Implementation&lt;/h2&gt;&#xA;&lt;p&gt;The system polls several light-dependent resistors and averages their readings before deciding whether to switch the lights. Using multiple sensors and rate-limiting changes made the automation less sensitive to brief shadows or sudden changes in brightness. A dedicated light-sensing Raspberry Pi HAT would have been more accurate, but I wanted to see if I could build a first pass using components I already had lying around. I ran the software as a Linux service so it would start automatically and continue working in the background without needing any attention.&lt;/p&gt;</description>
			</item>
			<item>
				<title>Anti-Lock Braking System</title>
				<link>https://charliehowlett.co.uk/posts/2019-03-17-abs-speed-dreams-driver/</link>
				<pubDate>Sun, 17 Mar 2019 00:00:00 +0000</pubDate>
				<guid>https://charliehowlett.co.uk/posts/2019-03-17-abs-speed-dreams-driver/</guid>
				<description>&lt;picture&gt;&#xA;  &lt;source&#xA;    type=&#34;image/webp&#34;&#xA;    srcset=&#34;https://charliehowlett.co.uk/posts/2019-03-17-abs-speed-dreams-driver/speeddreams_hu_e871b52763968274.webp 720w, https://charliehowlett.co.uk/posts/2019-03-17-abs-speed-dreams-driver/speeddreams_hu_aa3f85930aafb293.webp 1119w&#34;&#xA;    sizes=&#34;(max-width: 700px) 90vw, 720px&#34;&gt;&#xA;  &lt;img&#xA;    class=&#34;image-large&#34;&#xA;    src=&#34;https://charliehowlett.co.uk/fallback-images/posts/2019-03-17-abs-speed-dreams-driver/speeddreams.png&#34;&#xA;    alt=&#34;The ABS controller running inside a Speed Dreams simulation&#34;&#xA;    width=&#34;1119&#34;&#xA;    height=&#34;685&#34;&#xA;    decoding=&#34;async&#34;&gt;&#xA;&lt;/picture&gt;&#xA;&#xA;&#xA;&lt;h2 id=&#34;overview&#34;&gt;Overview&lt;/h2&gt;&#xA;&lt;p&gt;My final year at university was primarily focused on my dissertation, for which I chose to implement and evaluate an anti-lock braking system. The idea was suggested to me by a professor who noted that an accurate, open-source ABS model would aid his research. To achieve this, I based the ABS control loop on a Bosch algorithm described in engineering literature and ran simulations using the open-source software &amp;ldquo;Speed Dreams 2&amp;rdquo;, which features advanced vehicle physics.&lt;/p&gt;</description>
			</item>
			<item>
				<title>Procedurally Generated Clouds</title>
				<link>https://charliehowlett.co.uk/posts/2019-03-04-sky-sketch/</link>
				<pubDate>Mon, 04 Mar 2019 00:00:00 +0000</pubDate>
				<guid>https://charliehowlett.co.uk/posts/2019-03-04-sky-sketch/</guid>
				<description>&lt;iframe&#xA;  class=&#34;sketch-frame&#34;&#xA;  src=&#34;https://charliehowlett.co.uk/sketches/sky-p5/index.html&#34;&#xA;  title=&#34;Sky p5.js sketch&#34;&#xA;  loading=&#34;lazy&#34;&#xA;  style=&#34;--sketch-frame-height: 340px;&#34;&#xA;  allowfullscreen&gt;&#xA;&lt;/iframe&gt;&#xA;&#xA;&lt;p&gt;&lt;a href=&#34;https://charliehowlett.co.uk/sketches/sky-p5/index.html&#34;&gt;Fullscreen&lt;/a&gt;&lt;/p&gt;&#xA;&lt;p&gt;While at university I first started thinking about building a personal site, and from the beginning I knew I wanted it to feel unique and a little artistic. So in 2019 I built the procedurally generated p5.js sketch above and deployed it as a simple single-page app on Netlify, along with some basic contact information.&lt;/p&gt;&#xA;&lt;p&gt;Each cloud is created algorithmically rather than relying on static images, which means every run produces a slightly different scene. I later expanded the sketch with mountains, a moon, stars, and a dark/light switcher to make the whole scene feel more complete.&lt;/p&gt;</description>
			</item>
			<item>
				<title>University Game Development</title>
				<link>https://charliehowlett.co.uk/posts/2019-02-19-universe-city/</link>
				<pubDate>Tue, 19 Feb 2019 00:00:00 +0000</pubDate>
				<guid>https://charliehowlett.co.uk/posts/2019-02-19-universe-city/</guid>
				<description>&lt;p&gt;Universe City was born from a group software project I worked on during my Computer Science degree at the University of York. Our brief was to create a game in Unity, and our team decided to build a turn-based strategy game inspired by Risk, replacing countries and armies with a deliberately light-hearted version of university life.&lt;/p&gt;&#xA;&#xA;&#xA;&#xA;&lt;div class=&#34;video-frame teletext-box&#34;&gt;&#xA;  &lt;iframe&#xA;    class=&#34;video-frame__iframe&#34;&#xA;    src=&#34;https://www.youtube-nocookie.com/embed/bE0K3BXcJbY&#34;&#xA;    title=&#34;Universe City gameplay video&#34;&#xA;    loading=&#34;lazy&#34;&#xA;    allow=&#34;accelerometer; autoplay; clipboard-write; encrypted-media; gyroscope; picture-in-picture; web-share&#34;&#xA;    referrerpolicy=&#34;strict-origin-when-cross-origin&#34;&#xA;    allowfullscreen&gt;&#xA;  &lt;/iframe&gt;&#xA;&lt;/div&gt;&#xA;&#xA;&lt;p&gt;Players represented University of York colleges such as Halifax and Derwent, competing to capture sectors across the map and eliminate the other factions. The game supported between two and four human players. Alongside the main strategy systems, we built menus, resource displays, victory detection, and a Vice-Chancellor dressup minigame.&lt;/p&gt;</description>
			</item>
			<item>
				<title>Raspberry Pi Digital Lock</title>
				<link>https://charliehowlett.co.uk/posts/2018-11-02-prom-keypad/</link>
				<pubDate>Fri, 02 Nov 2018 00:00:00 +0000</pubDate>
				<guid>https://charliehowlett.co.uk/posts/2018-11-02-prom-keypad/</guid>
				<description>&lt;picture&gt;&#xA;  &lt;source&#xA;    type=&#34;image/webp&#34;&#xA;    srcset=&#34;https://charliehowlett.co.uk/posts/2018-11-02-prom-keypad/clean_wiring_hu_9dcf58a94585cfa6.webp 720w, https://charliehowlett.co.uk/posts/2018-11-02-prom-keypad/clean_wiring_hu_ef0052c3d807e7e.webp 1440w&#34;&#xA;    sizes=&#34;(max-width: 700px) 90vw, 720px&#34;&gt;&#xA;  &lt;img&#xA;    class=&#34;image-large&#34;&#xA;    src=&#34;https://charliehowlett.co.uk/fallback-images/posts/2018-11-02-prom-keypad/clean_wiring.jpg&#34;&#xA;    alt=&#34;The final keypad lock wiring after we cleaned up the hardware&#34;&#xA;    width=&#34;1920&#34;&#xA;    height=&#34;1080&#34;&#xA;    decoding=&#34;async&#34;&gt;&#xA;&lt;/picture&gt;&#xA;&#xA;&#xA;&lt;p&gt;This first-year group project started with a simple brief: build a keypad-controlled digital lock using a Raspberry Pi. It was a small project, but a very rewarding one, and it introduced me to some great people. Ultimately, our project was chosen by the lecturer to be demonstrated at subsequent university open days.&lt;/p&gt;&#xA;&lt;p&gt;The main constraint was that we were not allowed to rely on interrupt-driven input for the membrane keypad. Instead, we had to detect key presses by polling the Pi&amp;rsquo;s pins and working through the keypad matrix ourselves. On top of the basic four-digit passcode entry, we added status LEDs for correct and incorrect codes, a short delay after failed attempts to make brute forcing less practical, and a text-based interface for changing settings after the user had gained access. We also wrote software to attack our own system by generating electrical signals that mimicked key presses.&lt;/p&gt;</description>
			</item>
			<item>
				<title>Decoding a Pen</title>
				<link>https://charliehowlett.co.uk/posts/2018-10-23-decoding-an-hmgcc-pen/</link>
				<pubDate>Tue, 23 Oct 2018 00:00:00 +0000</pubDate>
				<guid>https://charliehowlett.co.uk/posts/2018-10-23-decoding-an-hmgcc-pen/</guid>
				<description>&lt;p&gt;I recently came across a HMGCC recruitment pen with a curious message printed along the side. It seemed to be a small hexadecimal puzzle, which piqued my curiosity enough to see if I could decode it.&lt;/p&gt;&#xA;&#xA;&#xA;&#xA;&#xA;&#xA;&#xA;&#xA;&#xA;&#xA;&#xA;&lt;picture&gt;&#xA;  &lt;source&#xA;    type=&#34;image/webp&#34;&#xA;    srcset=&#34;https://charliehowlett.co.uk/posts/2018-10-23-decoding-an-hmgcc-pen/hmgcc-pen_hu_7aac2eff41ff146.webp 520w, https://charliehowlett.co.uk/posts/2018-10-23-decoding-an-hmgcc-pen/hmgcc-pen_hu_4b66f196bb066d02.webp 1040w&#34;&#xA;    sizes=&#34;(max-width: 700px) 90vw, 520px&#34;&gt;&#xA;  &lt;img&#xA;    class=&#34;image-medium&#34;&#xA;    src=&#34;https://charliehowlett.co.uk/fallback-images/posts/2018-10-23-decoding-an-hmgcc-pen/hmgcc-pen.jpg&#34;&#xA;    alt=&#34;An HMGCC pen with a hexadecimal code printed along the side&#34;&#xA;    width=&#34;1075&#34;&#xA;    height=&#34;1075&#34;&#xA;    decoding=&#34;async&#34;&gt;&#xA;&lt;/picture&gt;&#xA;&#xA;&#xA;&lt;p&gt;After manually transcribing the hexadecimal values from the pen, I first played around in &lt;a href=&#34;https://gchq.github.io/CyberChef/&#34;&gt;CyberChef&lt;/a&gt; to get a feel for how the message might be encoded. Once I had a likely approach, I wrote a short Python script to put the decoding steps somewhere concrete:&lt;/p&gt;</description>
			</item>
			<item>
				<title>Go-playing Bot</title>
				<link>https://charliehowlett.co.uk/posts/2017-03-17-monte-carlo-go/</link>
				<pubDate>Fri, 17 Mar 2017 00:00:00 +0000</pubDate>
				<guid>https://charliehowlett.co.uk/posts/2017-03-17-monte-carlo-go/</guid>
				<description>&lt;video&#xA;  class=&#34;animation animation-medium&#34;&#xA;  autoplay&#xA;  loop&#xA;  muted&#xA;  playsinline&#xA;  preload=&#34;metadata&#34;&#xA;  aria-label=&#34;The Go bot interface, including the board and move history&#34;&gt;&#xA;  &lt;source src=&#34;https://charliehowlett.co.uk/posts/2017-03-17-monte-carlo-go/go.mp4&#34; type=&#34;video/mp4&#34;&gt;&#xA;  The Go bot interface, including the board and move history&#xA;&lt;/video&gt;&#xA;&#xA;&lt;h2 id=&#34;monte-carlo-go-bot&#34;&gt;Monte Carlo Go Bot&lt;/h2&gt;&#xA;&lt;p&gt;One of the earliest substantial software projects I built was a Go-playing bot for my Extended Project Qualification in sixth form. I had initially planned to build a chess bot, but once I realised how well simple brute-force algorithms could perform in chess, I decided to take on a more challenging problem. I turned my attention to Go because, at the time, it was one of the few classical board games in which human players still regularly beat machines.&lt;/p&gt;</description>
			</item>
	</channel>
</rss>
