Arduino debugging 1: Getting your Arduino program to tell you where it has got to

Why not have a mini-sequence of posts about Arduino debugging. Why not indeed?

Let’s start with a consideration of why the Arduino is hard to debug. The main reason is that you have no idea what is going in inside your code. If you’re writing a program on a computer with a keyboard and screen you can use any number of tools to find out what broke. There are debugging tools in Visual Studio that let you watch your program statements run one at a time and view (and even change) the values held in program variables.

The Arduino device has nothing like this. If you want to find out where your program has reached you have to put your own debugging statements. You end up writing things like this:

Serial.println(“I got this far”);

This prints out a message to the serial port tell us how far the program got. If you use the Arduino serial monitor you can view this message and know that at least the program has got this far.

This works and can be very useful. Developers call it “code instrumentation”. However, these messages can get confusing if you lots of them. What I’d really like to know is which line in the code that the program has got to. Then I can look this up in the source file. Turns out that this is quite easy. The compiler maintains two symbols called __FILE__ and __LINE__ which hold the name of the source file and the line number at that point in the program source.

So you can print this information out in your code:

Serial.print("Program is in file ");
Serial.print( __FILE__);
Serial.print(" at line " );
Serial.println(__LINE__);

These statements will tell you exactly where you have got to:

Program is in file C:\Users\Rob\Documents\Arduino\blah\blah.ino at line 12

This works well, but we can make it easier to use by putting the behaviour into a function:

void show_location(char * file, int line)
{
Serial.print("Program is in file ");
Serial.print(file);
Serial.print(" at line " );
Serial.println(line);
}

Now we can find out where our program has got to by just calling this function and passing the file and line values:

show_location(__FILE__, __LINE__);

We can now drop calls of show_location in our program to tell us exactly where the program has got to.

Of course, we have a problem in that we have to go and remove all these statements when we have finished debugging, but tomorrow I’ll show you how to make this easy too.

Green is not always my favourite colour

So I’m testing the NeoPixel drivers of an ESP32 board that Brian has designed. Everything works fine, except that the first pixel in the chain of pixels is always green.

I’m OK with green in general. I can’t imagine grass being any other colour. However, I prefer it not to show up when my program is trying to display other colours.

So… I spent quite a long time trying to work out how my code could be doing this. Was a rogue routine setting my first pixel green every now and then? Was my understanding of RGB more GRB? Nope. Everything worked. Which was annoying.

After a while I decided go search for “first neopixel is always green” and it turns out that this is a thing. This is one of these bugs that not only shouldn’t happen, but also I can’t work out how it could happen.

Anyhoo, I switched from the Adafruit neopixel drivers to the FastLed ones and the problem went away. Hardware development is like this. Sometimes you end up reconciling yourself to the fact that you have to do things that you don’t really understand simply to get the thing to work.

Starting a LED cube

We’re taking our first steps in building a LED cube. I dug out some of my old panels and we tried running them from a Raspberry Pi 4 with the Adafruit LED Panel Bonnet. We made the tweak described here to use the Raspberry Pi sound hardware to generate some of the display waveforms. This improves display stability at the price of disabling sound output from the Pi. This seems a trade well worth making, in that after the update the panel display was glitch free.

The led panels are interesting. I’ve used them with an ESP32 in the past. The way that the hardware works, only one in 32 rows of pixels are turned on at any given time. The host device must repeatedly light up all the pixels in sequence. It gets even more tricky if you want to control the brightness of individual pixels as this must be performed using pulse width modulation of the multiplexed display.

The word on the street is that a Raspberry Pi 4 can drive 6 panels of 64x64 pixels. We’ve not gone beyond 3 panels of 32x32, but we are hopeful.

Next step is to order the panels….

Playing Clank!

We had our first board game session of the year tonight. We believe in starting early. Simon came around and brought a copy of Clank! with him. It’s a deck building game where you move around a dungeon with the aim of collecting valuable artefacts and making it out alive. But make sure that you move quietly because every “clank” that you make could wake the dragon, something which never ends well. It’s great fun with lots of tension at the very end of the game as you struggle to get above ground with your hard won treasure.

Mending dishwashers

Christmas with all the family around. What better time for the dishwasher to go wrong? It still washes fine, but the trays of dishes have a habit of dropping off their support rails and plunging into the bottom of the machine when you load it.

Fortunately, I’m a lot better at repairing dishwashers than music players. A quick search of the internets revealed that it is very easy to get replacements for the wheels on the bottom of the tray. These had worn to the point of extreme wonkiness. The ones I found were identical to the originals and a lot less wonky. Result.

Home automation with Ikea Tradfri

Today finds us in Ikea eyeing up their Tradfri home automation devices. A year ago I bought some very cheap Teckin remote controlled plugs. I hooked these up to Amazon echo buttons so that I could turn all my lights on and off with a single press (of different buttons unfortunately but nothing is perfect).

They work fine, but the plugs use WiFi and I was a bit nervous about having my lighting controlled by a server in China. So today I went in search of something a bit better. The interesting news is that it seems to be possible to re-flash my plugs to allow them to be controlled locally via MQTT, but that is a project for another day.

After a bit of pondering I went home with a bunch of smart sockets, some bulbs, a gateway and two remote controls. And a bookcase, but that is just because when you’re in Ikea you have to buy a bookcase.

Anyhoo, this evening I set them up. It went smoothly enough. The smart devices use Zigbee to communicate. If you want you can work with just bulbs and Ikea remote controls. You pair one or more devices with a single remote control so that it is very easy to control a bunch of devices from one button. You can add a gateway that links Zigbee to your home network, and this is when things get interesting. There’s a Tradfri app that you can install on your phone that lets you group devices and control them all at once too.

This is quite good, but what I did was use Apple HomeKit (which Tradfri is compatible with) to set up all my home automation once I’d got the lights working. This lets you create “scenes” involving all your devices. The scenes can be selected from your phone or watch and you can also create automations that are are triggered by events such as sunrise, sunset, arriving home etc. It’s great fun and maybe even useful. Things I’ve learned:

  • You need at least one Tradfri remote control to perform the setup of devices. All the devices setup by a particular remote will be controlled by that remote.

  • Once you move into the HomeKit domain the distinction of devices and remotes vanishes, and you can combine any or all of your devices into scenes as you see fit.

  • Once you’ve set your lights to work with HomeKit you don’t need the Ikea remotes at all.

  • Your devices have different names on HomeKit and Tradfri, although you can change them to match up.

  • It is actually quite cool to be able to control your lights from your watch.

Untitled Goose Printing

If you’ve got an Xbox Game Pass you play Untitled Goose Game for free. And you should. You take the role of an annoying goose with a mission to cause havoc. The pace is nice and gentle and the animation and drawing is really well done.

And number one son has found a design on Thingiverse to print our very own goose models. You can see my first effort above. I need to work on the layering a bit but overall I’m very pleased with the results. You can fit a magnet into the beak so that your goose can hold little metal objects.

The design supplied in for the white, yellow/orange and black parts. We’ve found that ordinary “superglue” (cyano-acrylate) does a good job of holding the parts together.

My goose has a slightly rakish stance because he fell off the desk and broke his foot off which I had to glue back.

Python Ruler

I now have a ruler that will run Python. My life is complete……

Actually it is quite useful. Probably. You can program it to show up as a keyboard device and you can get your program generate keypresses when you touch the panels. The default settings are as shown above, but I’m going to make it generate the backslash character which I always have difficultly finding thanks to my liking for American keyboards.

It runs Circuit Python which means that you can just drop your code into the usb drive it mounts when connected. The only thing I don’t like is that you have to plug the ruler into an external power supply to get it to work. If it had a little battery it would be perfect.

Breaking Bad Escape Room

Today we went to an escape room. This is becoming something of a Christmas Tradition (tm). Well, we’ve done it twice. Last year were were breaking into a bank. This year we were in the lab. It was great. I think it was even better than the last one.

We managed to complete the tasks and get out in 59 minutes and 59 seconds (which may be as much a comment on the generosity of our hosts as much as anything else).

If you are in Hull you really should check out this. It’s a great experience.

Jaws board game - we're going to need a bigger boat

Another present that I got for Christmas (I must have been a really good boy last year) was the Jaws board game. At first glance it looks like something that was first released in the seventies when the movie was showing, but it turns out that it is a much more recent product.

It’s really good though.

It’s played in two acts. In the first act the human players try to locate the shark and tie it down with barrels while the shark tries to eat as many swimmers as possible. The second act switches to the ocean with the shark trying to destroy the boat and kill the crew.

It works well as a four player game, with one player taking the role of the shark and the other three the human players. However, I think it would also work really well as a two player game too. The tension builds up nicely in both acts and the end of the game was nicely balanced. We (the humans) just lost, with the shark taking out the last part of our boat just as we were getting close to seeing him off. Strongly recommended.

Sega Mini Christmas

I hope you had a great Christmas. I did. My big present was a tiny replica of a game console I never got around to owning. It’s a Sega Mini. It’s tiny, but comes with a couple of full size wired controllers. And it works a treat. It produces a nice solid HDMI output which you can scale to fit your widescreen telly and there are forty games built in. The ones I’ve played have been great fun. I really like Streets of Rage, particularly in two player mode. For the price you get a lot of entertainment.

Bye Bye HiFi Walker

I’m not having much luck with my high resolution music players. My first one, a Sony, decided to destroy its battery (and then destroy the replacement battery that I bought) by shorting it out. I suspect the charging circuitry. That went to the tip. And now my second, which had the wonderful name “HiFi Walker” has had the display fail. So, despite there being no obvious way in, today I tried to fix it. I was hoping that upon the removal of the back I’d see a dangling socket I could just reconnect to tumultuous applause.

Unfortunately that’s not how it has worked out. After using the hair dryer to loosen the glue I got the back off to find a perfectly assembled circuit board with no obvious flaws. So it was time to double down and remove the processor board completely from the case and check the display connections. Which of course all looked fine to me, even though the display was obviously still broken.

This is the a genuine “blue screen of death” in that it is all that is displayed. Oh well. At least I tried.