Hackathon: Using Go on an Arduino

Hackathon: Using Go on an Arduino

This is waaaay overdue, but we had another hackathon at work back in September of last year and even though I'm waaaay behind on blog posts, I wanted to make sure I did a short writeup on my project. During Gophercon, I received a small Arduino Nano 33 IoT. Not exactly a powerhouse, but I wanted to do something with it. I bought a breadboard, sensors, wires, and other various components. I still didn't know exactly what to create, just that I wanted the programming component to use TinyGo.


TinyGo is a fantastic project to reduce the size of compiled Go binaries. To achieve this reduced size (and because it's still in active development), it has a limited set of the Go language implemented. When I was using it for this project, it did not have garbage collection yet, but a limited form of garbage collection has been added since then. There's partial map support and limited CGO support, as well as other shortcomings. That being said, it's still perfect for most simple projects.

I started with a simple Hello World type program (I made a light blink), which turned out to be super easy to achieve. Woohoo. Next step was to get an HD44780 LCD display to work. This was the exact opposite of easy. I tried lots of different pin combinations and even modified the source code for the driver, but after a day of messing around with it, I couldn't get anything more than static to show up. I was able to confirm that the LCD display was working by using the Arduino IDE and the LiquidCrystal library to successfully display text. Something was just straight up broken in the HD44780 TinyGo driver.

The driver was broken and I didn't want to show up empty handed at the end of the hackathon, so I switched gears and moved over to just using the Arduino IDE. It uses C++, which I'm familiar with, and there's plenty of well supported libraries for various sensors floating around. I didn't have much time, so I decided to make a simple circuit for reading the temperature from a thermistor and displaying it on the LCD screen. Here's the circuit:


Reading the temperature from a thermistor isn't exactly straightforward. There's some math involved in the form of the Steinhart-Hart equation. Using this equation, one can derive the actual temperature from the raw resistance value the thermistor provides (I had some help).

float convertCelsius(float raw) {
  // convert value to resistance
  float resistance = (1023 / raw) - 1;
  resistance = SERIESRESISTOR / resistance;

  float steinhart;
  steinhart = resistance / NOMINAL_RESISTANCE; // (R/Ro)
  steinhart = log(steinhart); // ln(R/Ro)
  steinhart /= BCOEFFICIENT; // 1/B * ln(R/Ro)
  steinhart += 1.0 / (NOMINAL_TEMPERATURE + 273.15); // + (1/To)
  steinhart = 1.0 / steinhart; // invert
  steinhart -= 273.15; // convert to C

  return steinhart;

Aaaand, that's it. The final product seems to work. Not sure how accurate the temperature actually is, but it's close enough!


I learned a ton about electronics during the course of this project. Breadboards, pins, resistors, thermistors, etc. Of course it was disappointing that I was unable to complete the project in Go, but I firmly believe that TinyGo will continue to improve. My next step (if I can ever find the time) will be to try and fix the HD44780 driver. I spent several hours comparing the TinyGo driver code to the LiquidCrystal driver code. I believe I can make it work...if I can find the time and motivation.