Tutorial: Git an Arduino IDE Workflow
Even small microcontroller projects require multiple iterations of the code, as the project progresses. In the past, I’ve simply used consecutive numbers, attached to the file names to mark each latest version of Arduino code. While workable, it’s clunky and not so easy to manage. In spite of the fairly modestly sized and simplistic files, keeping track of changes using the Arduino IDE, is confusing and time-consuming.
A typical Arduino-based project uses source code files that are converted to a binary format for uploading (as firmware) to an Arduino microcontroller.
Traditional Arduino modules, such as the Nano have rather modest firmware storage capacities and can only handle fairly simple read-some-inputs, do-some-computations and set-some-outputs tasks. Newer Arduino-compatible microcontrollers, like the ESP32, have vastly larger program spaces and can accommodate much bigger and more complicated applications.
Priced at around $8 each, the ESP-32 also has onboard WiFi and Bluetooth capability. Couple that with a little 320×240 color LCD screen and you have the makings of a compact, interesting sensor-display platform.
I’m working on combining a GPS module with the ESP-32 and LCD display with a 3D printed case to make a little clock that never needs resetting. It’ll get the time from all the GPS satellites floating around overhead. WiFi and BT give it possible future user interface and MQTT features.
Today we’ll look at how to use the git version control system to manage the code for an Arduino IDE workflow.
The Arduino IDE Way
I approach my projects in phases. Get the microcontroller talking to the IDE (interactive development environment) in one phase. Connect the microcontroller to the LCD display in another. A third phase could be sending data from the GPS module to the microcontroller. You get the idea.
Many times, I’m learning to use a new sensor or output device in a project. Each iteration builds upon the individual components and code modules until we have a complete system. Completing each phase helps keep the motivation going and addresses any issues. Building even simple hardware has a surprising amount of complexity.
Putting a project under git bundles everything into a convenient package layout. In the past, I’d sometimes save a new version in some default directory, then come back later and wonder where it went when I couldn’t find it. With a half-dozen projects in progress simultaneously, it’s easy to get wrapped up in time-wasting file-finding expeditions.
My initial vision of my own project is an Arduino-type microcontroller, with a small color LCD, that reads data from a GPS module and displays the current local time. Since we’re discussing workflow, project-specific technical details won’t be anywhere nearly as deep as usual.
Programming is accomplished via a USB connection to the trusty old Dell Core-i7 notebook running Xubuntu 20.04.4 LTS. I’m also running the Arduino IDE, version 1.8.13.
All Arduino firmware source code files reside in a named directory. When saving a new file, the Arduino IDE automatically generates a software directory, that mirrors the source filename. I switched the Arduino IDE sketchbook directory under the preferences tab to group all-new source directories by default. It is also important to bring any libraries over to the consolidation directory, so the Arduino IDE can access them during compilation.
Most Arduino libraries offer sample file sets that demonstrate feature usage. I opened an example program, in the Arduino IDE, from the TFT_eSPI library called TFT_Print_Test. It displays a randomly colored background with several lines of text of varying fonts and size. It’s a couple-dozen line program that’s easy to follow and mod for demonstration. Here’s a graphic of the display.
The directory for the Arduino files was configured with the following in a Xubuntu text terminal.
drtorq% cd /home/rob
drtorq% mkdir esp32-lcd
drtorq% cd mkdir esp32-lcd
Switching back to the IDE, the example file was saved to TFT_Print_Test.ino. The IDE automatically generated a TFT_Print_Test directory under the /home/rob/esp32-lcd directory.
Here is a code segment of the file after the first save in the IDE.
Next, I went back to the text terminal to set up the git instance.
drtorq% git init
drtorq% ls (to remind me of the esp32-lcd directory name, which is “TFT_Print_Test”)
drtorq% git add TFT_Print_Test
drtorq% git commit -m "initialized the esp32-lcd basic project code under git control"
drtorq% git status
As you can see we are now just tracking the ESP-LCD project files and not the libraries. You could just as easily put the library files in git, with a ‘git add *‘ command. In some cases that might be desirable, like for custom configuration files. I chose not to do it for simplicity in this case. Also, git tracks all the files at the directory level. So, whatever is added or updated in the TFT_Print_Test directory, under the /home/rob/esp32-lcd directory is tracked with git.
Add a New Feature with a New Branch
With the base code indexed in git, it’s straightforward to set up a base branch in git, for later use. To do that we need to know the git commit reference number. Use the git log command.
drtorq% git log
Here, we’ll see a rather large number, above the author line, labeled “commit”. The latest commits are at the top. Copy that number to your Linux terminal clipboard using <ctrl><shift>c.
We want to create a new branch, so that is easily done with the traditional git checkout command.
Next, paste the commit number into git checkout with the -b option and the branch name. In this case, I used “orig-state” for the name. Use a <ctrl><shift>v at the command line to paste in the number.
drtorq% git checkout -b orig-state [commit number]
Now do a git status and you’ll find that you are on the newly created orig-state branch. Exit the Arduino IDE. Don’t change anything and just flip back to the master branch with another git checkout.
drtorq% git status
drtorq% git checkout master
Actually, most users will probably want to use the newer git switch command to flip-flop between branches. It does the same thing as checkout, it’s just newer, easier to remember and has fewer characters to type. Here’s an example.
drtorq% git switch master
I added a couple of comments to the file, saved it, then exited the Arduino IDE, then did the usual git add and git commit. If you git switch back to the orig-state branch you’ll see the original “Hello, World” text when you open the Arduino IDE. Exit the IDE, git switch to master, then restart the IDE. The latest master changes will be displayed in the IDE.
Check out the latest master branch version of the file.
Now you can mod your code (on the master branch) for new features, knowing that the initial file is safely indexed back in the orig-state branch.
It is important to save and close the source file in the Arduino IDE before each commit. git handles all the versioning magic.
We discussed how to get started using git with the Arduino interactive development environment. Just remember to set your directories correctly and then save and get out of the files before you do a git add and git commit. Switch to your chosen branch. Then, reopen the file again to get your chosen version.