projects/build-hat
.. | index about projects posts media links

LEGO is a fun and relatively easy way to put together a robot. I competed in Robocup Junior last year and used LEGO parts to build the robot because we ran out of time to put together something more professional, and it worked out fine. However, the motors and sensors we were using are about as old as I am, and they're showing signs of age. This year I planned to use the new generation of LEGO hardware, which uses a new connector type. The hardware is really precise and reliable, which is great. They are also pretty easy to build with. In addition, the Raspberry Pi Foundation put together a Pi hat that lets you plug in these parts and talk to them. It supports a Python and C# interface, but I can't stand Python for robotics and I also despise using C# on Linux, so I foolishly decided to try to make a library to control it through good old C.

When I started working on this project, I hit the real hurdle immediately. The hat works through serial communication through the normal rx/tx pins (no SPI or I2C or anything), which meant I'd be using read and write syscalls to do everything. The problem is that it's challenging to debug this stuff. Turns out that the BuildHAT runs on the new-ish RP2040 chip, which has no onboard non-volatile storage. To account for firmware updates (I assume), the developers made a bootloader that sits on a ROM on the board through which you upload a firmware image and signature every time the board power cycles. The bootloading process is entirely undocumented. There's a 'help' command you can send it (if you're using minicom or something to talk through serial to the board), which seems like it tells you what you have to do, but it didn't work, so I went to look at the open-source Python library to see what I was doing wrong. Turns out that there are multiple magic numbers and a whole checksum generation routine that are required but fully undocumented. Luckily they were easy to copy. It's confusing to me why the RPi Foundation would provide a whole serial interface documentation PDF but totally neglect the relevant information that allow someone who is not using Python or C# (which nobody reading the serial documentation is using, clearly) to actually use the serial mode. You'd have to first run a boilerplate Python program or something to get the firmware uploaded in order to use the serial mode, but then there's no point in using serial. Anyways.

I'm not a particularly experienced C programmer, especially not with string input handling, because all my C code is usually pretty static as it runs microcontroller stuff. There was a lot of string stuff involved in sending all these runtime-determined commands to the board, and then handling confusingly unpredictable returns. There's a method to obtain the 'expected response length', but there seemingly isn't a guarantee that the response will actually fit in a buffer of that size, which is totally obnoxious and defeats the point. The current state of my library is that my slightly abstracted read/ write functions are totally broken and not usable. However, with that being said, I believe it is more C-like to make the read/write syscalls yourself on the file descriptor that is created by the firmware loading routine. The firmware loading is really the only thing that is infeasable to implement every time, everything else is just read/write calls. I'd like to have polished this a lot more, but unfortunately I lost track of time this season and we didn't make it to competition this year, so I didn't really feel motivated to finish this. Hopefully the firmware loader lowers the barrier to entry enough to let somebody else give C programming a shot for robotics.