Pi Wars Week -25: Foiled!

A quick brain teaser for you: why didn't this work? Answers below the image.

As previously mentioned, I'm using threads in my code to let the robot do more than one thing at once. Specifically, I wanted it to be able to keep reading from the distance sensors and using them to navigate, while writing to the OLED screen. Refreshing this I2C display module takes about 0.4 seconds, and most of my driving code assumes a 0.1s refresh rate (and I've seen the bot almost drive off a table when I broke that assumption) so I wanted to be able to keep the sensor-joystick-motor control part running quickly.

I wrote a test challenge which would output sensor distances to the screen as quickly as it could (2 or 3 per second) and print out the values to the terminal every 0.1s, but it would always pause for the screen refresh. To see if what I was trying to do was possible, I wrote a quick new file to just print lines to the console every 0.1s and keep updating the screen in a separate thread, and that was perfectly happy interleaving the two tasks. A similarly structured challenge running on the bot would pause for the screen to update before outputting the next set of distance values. Why?

flowchart

The best laid plans of Pis and men

The answer?

I2C. Both the screen and the sensors hang off the same I2C bus, both because I thought it would save me GPIO pins, and because Pimoroni happened to be sold out of the faster SPI screens when I bought my parts. The test code was just waiting around in the main loop, printing random nonsense to the console every 0.1s and so would happily interleave with the code updating the screen. The real example was trying to read my I2C distance sensors, which presumably blocks while the screen is busy updating, hence the pause.

Well, there goes that clever plan. The moral of the story: don't try and send text messages while driving. Where did I put those flashy LEDs...

- PKM