<?xml version="1.0" encoding="utf-8" standalone="yes"?>
<rss version="2.0" xmlns:atom="http://www.w3.org/2005/Atom">
	<channel>
		<title>JavaScript on Charlie Howlett</title>
		<link>https://charliehowlett.co.uk/tags/javascript/</link>
		<description>Recent content in JavaScript on Charlie Howlett</description>
		<generator>Hugo</generator>
		<language>en-gb</language>
		
		
		
		
			<lastBuildDate>Fri, 19 Jun 2026 00:00:00 +0000</lastBuildDate>
		
			<atom:link href="https://charliehowlett.co.uk/tags/javascript/index.xml" rel="self" type="application/rss+xml" />
			<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>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>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>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>
	</channel>
</rss>
