Arduino In-circuit Debugging with PlatformIO
Some Arduino boards have debugging signals exposed on the bottom side. With an inexpensive adapter you can start using the PlatformIO debugger — a tool far more powerful than print statements to track down bugs in your software.
The Board
The Arduino Nano 33 IoT is a recently released Arduino board. It comes in the typical Nano form factor and offers unique features: powerful Atmel SAMD21 micro controller, Bluetooth, WiFi, crypto chip and a 6 axis IMU (acceleration and gyroscope).
What really caught my attention were the exposed pads on the bottom side:
These aren’t just test points. They are debug signals. And for the first time, they are described on the Arduino web site (see last section of technical specification).
The description is confusing though. So here is a visual pinout:
SWD and SWCLK are the relevant signals: they are a debug port called Serial Wire Debug (abbreviated as SWD), available on all ARM-based micro controllers. And the Atmel SAMD21 is ARM-based of course. The remaining signals are less important as they are also available as regular pins.
The Debug Adapter
There are plenty of debug adapters available for Serial Wire Debug or SWD. I have used a J-Link adapter from uncle Ali for about USD 12.
The adapter is a clone of Segger J-Link Debug Probes. Many clones even carry the Segger logo although they are not a genuine product. Several variants are available and difficult to distinguish. This is the least expensive one, and it worked.
Connecting the Adapter
In order to connect the Arduino board to the debug adapter, wires need to be soldered to the debug pads. I’ve soldered wires to all five of them but in the end did not use the 3.3V wire. The GND and RST pins can also be soldered to regular pins, or if you have a board with headers pins, just connect them to the header pins. The minimum are the SWD and SWCLK wires.
I then crimped Dupont connectors onto the other end of the wires. You can also start with ready-made Dupont wires, cut off the connectors on one side and solder them to the board.
The wires need to be connected to the J-Link adapter to the following pins:
The SWD pin is called SWDIO here as this is the official J-Link label. It is sufficient to connect as single GND pin. The 3.3V wire is not connected as the board will be powered via USB.
Dupont connectors can be directly plugged onto the J-Link pins. I have used an intermediate adapter board as it simplifies plugging and unplugging the adapter. The pinout is the same.
Debug Your Program
If everything is plugged in (J-Link to computer, Arduino board to computer, Arduino board to J-Link), debugging with PlatformIO can start. J-Link is not the default debugger for the Arduino Nano 33 IoT. Therefore, the debug_tool needs to be specified in platformio.ini:
[env:nano_33_iot]
platform = atmelsam
board = nano_33_iot
framework = arduinodebug_tool = jlinklib_deps =
Arduino_LSM6DS3
The example program (main.cpp) reads gyroscope values from the IMU and prints them to the serial port:
#include <Arduino.h>
#include <Arduino_LSM6DS3.h>void setup() {
Serial.begin(9600); // Wait for serial connection to be ready
while (!Serial); if (!IMU.begin()) {
Serial.println("Failed to initialize IMU");
while (1);
}
Serial.print("Gyroscope sample rate = ");
Serial.print(IMU.gyroscopeSampleRate());
Serial.println(" Hz");
Serial.println();
Serial.println("Gyroscope in degrees/second");
Serial.println("X, Y, Z");
}void loop() {
float x, y, z;
if (IMU.gyroscopeAvailable()) {
IMU.readGyroscope(x, y, z);
Serial.print(x);
Serial.print(", ");
Serial.print(y);
Serial.print(", ");
Serial.println(z);
}
}
To start debugging, go to the debug view (1), select the PIO Debug configuration of your project (2) and click the arrow icon next to it (3). It will take a moment to compile your code again and start the debugger in the background. Then your program is started and immediately stopped in the main function in another main.cpp file (4):
You can then open your own main.cpp file and set a breakpoint by clicking next to the line number (1). A small red dot will appear. The blue array icon (2) continues the execution. The program will then likely be stuck at the check for the serial connection (3). To unlock it a serial terminal program needs to connect to the Arduino board, e.g. by running PlatformIO’s Serial Monitor. The program will run to your breakpoint and stop again. By clicking the arrow button again, the program completes an iteration of the loop function and again stops at the breakpoint in the next iteration.
Variables can easily be inspected in the debugger’s Variables view (4). There is no need anymore for adding print statements and recompiling your program to analyze your program.
Other Arduino Boards
Two further Arduino boards expose their debug signals in exactly the same way as the Arduino Nano 33 IoT: Arduino Nano 33 BLE and Arduino Nano 33 BLE Sense. They use a Nordic Semiconductor nRF52840 microcontroller and a new Mbed OS based Arduino core. This combination is now supported by PlatformIO (with a few hick-ups though).
Further Arduino boards can be connected to a debugger in the same way:
- Arduino MKR WIFI 1010
- Arduino MKR GSM 1400
- Arduino MKR NB 1500
- Arduino MKR WAN 1300
- Arduino MKR WIFI 1010
- Arduino MKR ZERO
The debug pads are also on the bottom side but look slightly different:
Additional boards with exposed debug pads are available from Adafruit and SparkFun. They all have in common that they use an Atmel SAMD21 microcontroller.
Happy debugging…