Clicky Test Keyboard

For the finished keys I’ll fill in the gaps in the legends

Me and Claude (well, mostly Claude) are making a Cyberdeck Keyboard. I’ve decided to use very cheap and tiny surface mount clicky switches underneath the keys. Which led to a concern. I was worried that if I put a long key (for example space bar) on top of the keyswitch the key would pivot if you pressed the edges and not trigger the switch. I wondered if it would be a good idea to mount long keys on two switches.

This is not the kind of thing that you can decide by just thinking about it so I asked Claude to make a mock PCB with spaces to insert the switches I’m using, and then build a test keyboard around it. You can see what I ended up with above.

There are two versions of each long key, one supported by two switches and the other supported by one. It turns out that the 4u key on a single switch works fine. The space bar tips when you press one end, but not far enough to stop the switch from registering. Using two switches actually makes things worse, as you seem to have to press both of them down to make the key work. And now I’ve got a nice little fidget toy to play with…..

Tiny Software Engineer at the Hardware Meetup

Ross showed me the video above, which describes a tiny software engineer. You can connect it to your AI agent and it mimics what the agent is doing, whether it is thinking, typing or finished. It uses a bunch of servos, an ESP32 and 3D printed components. I want folks in the Hardware Group to have a go at building it and then we can try to get a bunch of them working together. If you fancy having a go, come along to our next Hardware Meetup. There’s one on Wednesday next week (the 7th October).

Cyberdeck Keyboard

I’ve decided to try and make a keyboard for a Cyberdeck I’m building. I’m using Claude to do all the work. I want to use it to design a printed circuit board, case and 3D printable keys. The starting point will be a JSON file which describes everything. So I also need a design program. Claude “thought” for a while and came up with the above program. I showed it my programs for FreeCAD which make the wordsearch clock and told it to use that idea to make a keyboard design.

The keys printed out rather well. I’ve now asked for the design to be inverted so that I can print the keys with the text close to the print bed, which will make them a lot smoother. I’ve got a policy of not fiddling with what has been produced because I want to see how far AI can get on its own. So far it is doing very well.

Batman: Legacy of the Dark Night on Switch 2

When the Lego “Batman - Legacy of the Dark Knight” first came out I read the reviews (everyone seemed to like it) and decided to wait for the Switch edition as I like playing games on the Switch. I normally download games directly from the Nintendo store because I’m lazy, but this time I ended up buying the physical game because it was quite a bit cheaper on Amazon. This of course makes no sense.

When the box arrived I discovered that what I had actually bought was a cartridge that serves as a key to download and run a copy of the game. So anyone getting the boxed version to try and avoid buying more storage for their Switch will be disappointed.

The game itself is, er, fine. From the reviews I was expecting things to have moved along a bit from earlier games, which I enjoyed a lot, but no - you get the usual stuff (including a really annoying driving mission early on). The cut scenes are very good, the city is well rendered and everything moves along nicely. If you’re thinking of buying it you could do worse.

The Innkeeper is not always your friend

We played Dominion tonight. It’s a great game. I had this theory that going all in on innkeepers might be a great plan.

It wasn’t. You get through lots of cards, but you always seem to end up with the same amount of treasure.

Oh well. I think it is worth going for if you have got yourself a few gold coins. Which is what I plan to try next time it comes up.

When .local Stops Being Local

I have a Raspberry Pi server called bigbrain. Normally I can reach this machine on my local network using:

bigbrain.local

This works using mDNS (Multicast DNS). Addresses ending with .local are handled specially. Rather than asking an outside world name server to resolve a name to an address, when a device sees an address ending .local it will use a local service that listens for devices that broadcast addressing information on the local network. On a Raspberry Pi, mDNS is normally provided by a service called Avahi. Avahi announces the name of the machine on the local network so that other devices can find it without needing an entry in a conventional DNS server.

This morning I noticed that bigbrain.local didn’t work any more. This was a bit worrying, it’s the machine that hosts the custard cream server, among other things. I logged in using the Raspberry Pi Connect service and was pleased to discover that the machine was still working. The first thing to I needed to check was whether or not the Avahi service was running. I opened a terminal window and typed:

systemctl status avahi-daemon

Avahi was running, but the output contained an important clue:

Host name conflict, retrying with bigbrain-2

and:

Server startup complete. Host name is bigbrain-2.local.

This explained why bigbrain.local wasn't working. Avahi thought that another machine on the network was already using that name. Rather than create a conflict, it had renamed its mDNS identity to:

bigbrain-2.local

Was there another Bigbrain?

My first thought was that I might have booted another Raspberry Pi containing an old copy of the bigbrain system. If two machines both have the hostname bigbrain, they will both attempt to advertise themselves as bigbrain.local.

But I wasn't certain that I'd actually done this, which raised a slightly less comfortable question: was an unknown device appearing on my network?

Fortunately, the system log provided some more information.

The conflict had occurred at 02:55 on 22 September:

Sep 22 02:55:17 bigbrain avahi-daemon[585]:
Host name conflict, retrying with bigbrain-2

Looking at the Avahi journal around this time showed something interesting. For several minutes before the conflict, Avahi had been repeatedly registering and withdrawing network addresses.

At 02:55:17 it withdrew the addresses associated with both network interfaces and then registered them again. Five seconds later NetworkManager reported:

dhcp4 (eth0): state changed new lease, address=192.168.7.107

So something was definitely happening to the network at the same time that Avahi decided there was another bigbrain.

The missing piece

I use a system called eero to provide Wi-Fi access at home. It turned out that the eero network had automatically updated its software earlier that morning. The update caused the network infrastructure to restart. At 02:19 on 22nd September. That provided a much more convincing explanation.

As the network came back, DHCP leases, IPv6 addresses, multicast groups and mDNS advertisements all had to be re-established. The Avahi logs showed exactly this kind of activity.

There was another complication. bigbrain was connected to the same local network in two different ways:

              bigbrain
             /        \
          WiFi       Ethernet
           |             |
    192.168.7.22   192.168.7.107
           \             /
            local network

Both interfaces were therefore participating in mDNS on the same network and both represented the same machine with the same hostname.

Normally this works. But during the disruption caused by the network restart, Avahi apparently saw enough conflicting information to conclude that somebody else was already advertising bigbrain.local.

It did the safe thing and changed its advertised name to bigbrain-2.local.

Once the network had settled, restarting Avahi:

sudo systemctl restart avahi-daemon

allowed it to register bigbrain.local normally again.There was no evidence here of an unknown machine or a security compromise (which was nice). The hostname conflict occurred during a period of substantial network reconfiguration following an eero software update. But the incident did expose an unnecessary complication in the server configuration.

The Raspberry Pi was connected to the same LAN using both Ethernet and Wi-Fi.

There are situations where having multiple network interfaces is useful, but a fixed server generally isn't one of them. Two connections to the same network mean two IP addresses, two routes onto the LAN and two interfaces participating in multicast protocols such as mDNS. Most of the time the networking software sorts everything out. When the network is being restarted or reconfigured, however, things can get more interesting.

For a Raspberry Pi being used as a server, the simplest rule is therefore:

If you have a wired Ethernet connection, use Ethernet and turn WiFi off. If you need WiFi, use WiFi and leave Ethernet disconnected. Don't routinely use both to connect the server to the same local network.

I’m going to disable the Wi-Fi on bigbrain. Networking is complicated enough without giving the packets a choice of doors.

Friday Widescreen

Friday finds us at a presentation at the National Science and Media Museum in Bradford. It was all about widescreen movies. Back in the days when movies were things you went to, not things you made, a plucky band of souls formed the Amateur Widescreen Association. Impressed by the widescreen movies of the day they tried to create the same experience using films and equipment available for home use. At the time cameras and projectors were entirely mechanical, so the task was to use different lenses, film gate shapes and film sizes make the biggest and most impressive wide screen effect. Every year they held an event where they all gathered to show off their latest creations. They built some amazing hardware, including one presentation that used 3 synchronised projectors. Each year they had a competition to pick the best films, and we got to see a bunch of test films, along with some of the winners. It was great fun.

Of course, nowadays widescreen is an option you click on your phone camera and image quality is just something you take for granted. But the presentation showed that with determination and ingenuity you can make tiny negatives really sing on the big screen. Some of the movies were projected as film, in one case it was the original celluloid that went to Afghanistan, was exposed and mixed there in camera and then brought back for development. Lots of material ends up as being of historical interest, as we saw scenes of places that no longer exist. Thanks to Guy Edmonds and the rest of the team for doing such a great job of bringing the past back to life.

The presentation was part of a larger Widescreen Weekend in Bradford which runs once a year. There are lots of movies on show. Maybe next year I’ll sign up and spend an entire weekend eating popcorn…

Hardware Meetup with added Claude

This is the device. Check out that welcome deal

I took everything with me to the Hardware Meetup tonight. Everything, that is, except the Raspberry Pi PICO I was supposed to be working on. Ross took pity on me and lent me an ESP32 powered display that he had brought along to play with. A while ago I’d seen a video of someone who just plugged a random device into his PC and then asked Claude to figure out what it was and how to program it. I figured I’d have a go at that. The results were deeply scary.

Claude was able to identify the device and even pull out the demonstration program inside the device memory. Then it had a look at the code and told me what the demo program did. I asked Claude to re-write the demo in Python. Claude thought for a while and then told me that Python would be too slow for the graphical update. So I suggested Claude use Rust instead. Claude then figured out that I didn’t have rust on my laptop and offered to instal it. Then Claude figured out that I was using Windows on ARM, found the correct version of the SDK, installed it, tried to build something, failed, updated some elements and rebuilt others. Then it managed to get a test program running on the device. This was in around an hour or so and is officially amazing.

It was great to see so many folks turn up and just set to building stuff. And we kind of managed to make the local pizza place look busy when we went for dinner.

I took this picture when I got back home. I now have Rust code running on the device, and Claude is decoding the original binary and writing a Rust version of it. We live in very strange times.

Use thick wires for your power signals

The black and the red wires are nice and chunky

The “Bourbon Classic Camera” is very nearly finished. It’s been in this state for the last few weeks as I add a range of “finishing touches” including things like a screen that works and a power supply. Today I was wiring in the UPS unit that I’m using to power the Pi directly and it didn’t work. That is, it would get into the boot process, reach the point where the screen is supposed to light up and then stop. Oh well. As I’ve said before, power supplies are always a problem.

I’m doing something mildly naughty, in that I’m putting the power into the Pi via the 40 pin “hat” connector. This works, but it bypasses all the funky power negotiation that you get when you use the usb c connector. It means that you can provide five volts, and only five volts, and they had better be stable and able to deliver the current the Pi needs.

Mine weren’t. Mainly because I’d used dPont cables. These are fine for moving data around (although personally I prefer to wire wrap) but they just don’t have the copper thickness for power. The wire ends up being a resistor in series with the power supply. This means that the more power the Pi wants, the lower the supply voltage gets.

In the end I used some speaker cable from way back (another reason never to throw anything away). I also soldered pin connectors directly onto the wire and made sure that they gave a good positive connection. All is well now, and the Pi gets through the boot process and works a treat. So, if the device in your build is running slow or not running at all, you might want to think about using thicker wires for the power.

What to do when your Raspberry Pi memory card wears out

My AI Picture Ink Display has been running for a few months and it’s been nice to see a different crazy picture appear every now and then. But recently it has taken to failing. I, of course, instantly assumed that my software was broken, but it turns out to be a hardware issue with the memory card in the Raspberry Pi. The Stable Diffusion program that makes the pictures works the file store very hard, repeatedly reading and writing data, and this can result in the storage device failing. I diagnosed the problem by taking a look at recent Linux kernel messages:

dmesg -T | grep -Ei 'error|ext4|mmc|i/o|corrupt'

The statement above filters the error messages for ones about storage issues. In this case, the important message was:

I/O error, dev mmcblk0, sector 22491848 ... (READ)

mmcblk0 is normally the Raspberry Pi's microSD card. An I/O error at this level means Linux attempted to read data from the storage device and the operation failed. The most precious thing on any computer is the data, in this case the pictures that had been generated, so while the system was still working I needed to get those files off the machine. I used a USB memory stick. I plugged it in, waited a few seconds for the Pi to notice it, and then checked to see what devices were available.

lsblk -f

I got this:

That told me that the usb memory key was working and had the path of “/media/rob/HP v100w” (note that this contains a space). You will get a slightly different path. Now I could copy the contents of the generated_images folder onto the USB device.

cp -av /home/rob/generated_images/ "/media/rob/HP v100w/"

The quotes around the destination are necessary because the USB drive's name, HP v100w, contains a space. The trailing / on /home/rob/generated_images/ means copy the contents of the directory into the destination directory. Once the copy was complete, the next thing to do was make sure that any cached writes to the usb drive were complete:

sync

Then then I could unmount the USB drive:

sudo umount "/media/rob/HP v100w"

Now I had a copy of the folder on the drive. If my Pi was running with the desktop this would have been much easier, I could have done it all in the File Explorer application. But the image generator runs “headless”. One tip: if the USB drive is not picked up when you plug it in, try using a different USB port. You should see blue and black usb sockets. I’ve found that for usb drives the black ones work best.

As for the suspect memory card; once I’ve got all my files off it the card is going in the bin. And I’m going to look into running the program on a device with a “proper” solid state disk. This will go faster and should not be susceptible to wear like this.

INTER/ACTIVE 26

Charles told me about INTER/ACTIVE 26 a while back and I went along today to take a look. I took the Custard Cream Camera to grab some snaps and have some fun with them.

It was great. There were folks showing off all kinds of tech, from vintage radios, military laptops, amateur radio, 3D printing and lots of hardware you could play with. Charles had brought along Penelope, his AI powered robot work in progress. You can see a slightly tampered image above. In fact, I used the camera to make a lot of slightly tampered images. Converting people to Lego was the most popular transformation.

..although watercolour and line drawings were also in the mix. If you want to see a slideshow of the pictures that I made, take a look here. Kudos to all the folks who set this up. It is exactly the kind of thing that we need to be doing to tell people about tech.