Tiny Arduino for Hackers

A dime-sized, ARM-based Arduino complete with a programming/development system.

Similar projects worth following
Hardware and software design to make a tiny Arduino are shown. Project Logs present project details. Here is how this project unfolds:
First Version - STM32L031G6
My first design, and what I learned that drove me to a second version.
Second Version - STM32L071KBU
Second design. Includes both the tiny version (tArmDuino) and the breadboard version.
Adding tArmDuino to the Arduino IDE
How to add a custom version to the Arduino IDE. This would work for any board, but has specifics for tArmDuino.
tArmDuino Programming and Debug
Making a custom board show up in Arduino is one thing, actually programming it from there is another! Here are the details.
G-Debugger for tArmDuino
To really get the most from an ARM-based processor, gdb is highly desirable. Here's how to use it with tArmDuino.
Uploading Clip for tArmDuino
Creating a tiny Arduino is good, but somehow a programming header must be connected to the board. This section shows how.

Once again finding myself in need of a tiny, cheap, yet powerful Arduino that didn't seem to exist, I decided to create one. What a tiny Arduino should provide is access to as many Arduino hardware features as possible, plenty of flash memory, a programming connection, and a small board size. An ARM with 3.3V I/O seems like the right processor choice, and STMicrosystems makes a huge selection. Program development is done with the Arduino environment since ST has provided libraries for Arduino. Why use Arduino? Libraries can do many tasks and save development time allowing me to focus on "value added" tasks without having to build infrastructure first.

Studying the STM32 product line, I narrowed down my possible choices to the STM32L0 series. My intent was to choose a processor that provided most (possibly all) of the capabilities of an Arduino UNO, with more memory if possible, all while being suitable for battery power. I was not concerned with having more I/O, so a 28 or 32 pin version seemed satisfactory. The STM32L031G6 seemed like a good choice and was my first design. For reasons I'll discuss, the STM32L071KB emerged as a better choice.

Working in KiCAD and utilizing the debug connector scheme first described in POV programmer, I created the board seen in the picture (the one with parts on it L031G6 version). As mentioned above, this led to the creation of the very similar other design shown (L071KB version). The only parts on the board are the microprocessor and the decoupling capacitors. The reset line is pinned out so a button can be added if desired. Cycling power will also cause a reset. The SWD debug interface goes to the programming footprint. The idea is to provide maximum flexibility so the application can be as small and targeted as desired with no extra baggage. Downloading and debugging is done using the SWD interface. So it's not plug and play like an Arduino or Teensy, but it's not difficult. USB can be added to the serial port, but I typically don't use it for most projects.

To make prototyping as easy as possible, a bread-board compatible version is necessary. The SWD interface lines are pinned out on the breadboard version so jumpers can be user to program and debug. Not that the tiny version can't be breadboarded, it's just less convenient. The programming header, while very workable, is still harder to connect and may necessitate disconnecting some other pins. Using a breadboard version makes life easier through early stages of development. Once an application is mostly working then it can be moved to the tiny version.

Creating a new Arduino and adding it to the Arduino environment requires several software steps. Without these, even the slickest hardware won't be satisfactory. I'll explain these steps as I go along.


Spacer or frame for the uploading clip. Ready to slice.

sla - 20.20 kB - 01/13/2021 at 05:35



Solder paste stencil for the clip.

gtp - 479.00 bytes - 01/13/2021 at 05:34


Clip gerbers ready to order boards.

Zip Archive - 4.12 kB - 01/13/2021 at 05:34



Clip KiCAD library file.

lib - 789.00 bytes - 01/13/2021 at 05:34



Clip KiCAD schematic.

x-kicad-schematic - 2.13 kB - 01/13/2021 at 05:34


View all 23 files

  • Uploading Clip for tArmDuino

    doctek6 days ago 0 comments

    The uploading clip, mentioned in the Details section above, is slightly modified from the original. Following is a description of the version used for tArmDuino, how it's assembled, and how it's connected to the ST-Link.

    The circuit board and connector are unchanged. The KiCAD files have been placed in the Files section and include the gerbers and the solder paste stencil. Here is the board with the contactor in place.

    The spacer or frame around the contactor is also modified compared to the original version. It now has locating tabs on two sides and is designed to fit tArmDuino. The stl version is in the Files section. After printing, it should be adjusted to 1.75 +/- 0.05mm thick. It's purpose is to keep the contactors from being crushed beyond their elastic limits, while still allowing them to make firm contact with the pads on the tArmDuino.

    This shows the board with the contactor, and the tArmDuino in place on the frame.

    Here is the frame in place on the contactor. Note the orientation of the tARmDuino. Obviously, it gets flipped over to mate with the contactor, but note the alignment of the lettering.

    Shown here is the frame on the tArmDuino contact pads. Again, note the position of the lettering.

    This is the stack up of the contactor, frame, and tArmDuino. The clothes pin is just used as a support here.

    To hold the programming connector in place, an ordinary clothes pin is used. It is slightly modified using a file or rasp to make it fit securely and hold the connector squarely against the board. The pictures show the idea pretty clearly. Here it is shown in place. The white tape I placed on the wiring plug indicates pin 1, and the circle emphasizes the position of the two capacitors in the corner of tArmDuino (one larger than the other). These serve as a useful reference for correct orientation of the clip.

    Here is the wiring to the ST-Link. Note that the pin names of the pins on the programming clip are changed for programming the tArmDuino. Pin 1 is nRst, 2 is Gnd, 3 is Vcc, 4 is SWC, 5 is Gnd, 6 is SWD. There is no need to connect both grounds, pick your favorite. Note that Vcc to the ST-Link must be connected as well to the 3.3V powering the tArmDuino (from the 3.3V power connector on the Nucleo, possibly).

    I used the Blink demo program (from Arduino/File/Examples/Basics) as discussed in the "tArmDuino Programming and Debug" build log above, changing led to 7 (PA8). The sketch was uploaded to the tArmDuino breadboard version, labeled "Small ARM 32", to make sure it worked. Not surprisingly, it worked! Then I wired up the debug clip as shown above and clipped it to the tArmDuino tiny version and uploaded to it. It works as expected. The tArmDuino is fully ready for whatever projects I can come up with!

    These pictures show the tArmDuino hooked up to blink a led on a breadboard.

    Since the ST-Link is used to upload tArmDuino, it clearly could be used with gdb for debugging if needed. I personally prefer to debug using the Small ARM 32 (breadboard) version, then uploading to the tArmDuino, but there are times when it makes sense to debug directly on the tArmDuinon. This works fine, but sometimes any wires soldered to it can get in the way.

  • G-Debugger for tArmDuino

    doctek01/06/2021 at 04:32 0 comments

    The g-debugger (gdb) provides a very powerful debugging tool, but takes some extra effort to configure and use. It requires two parts that run in separate terminal windows. A gdb server must run in one terminal window and connects to the ST-Link. The gdb client runs in another terminal and communicates with the device being debugged via the server. The client is controlled by the person doing the debugging. The existence of this debugger is a strong argument for using an ARM processor! It provides much more robust and in depth debugging compared to the printf method, but requires more effort. I find it especially useful for hardware interaction problems. To use gdb, connect the ST-Link as described above, plug in the USB, start a new terminal window (I like UXTerm), and type ST-LINK_gdbserver. This will invoke the script in ~/bin and start the gdb server. It should now be waiting for the client to connect. I'll show this in action below.

    To make the most of gdb, I compile my sketch with Tools/Optimize set to Debug (-g). This causes symbols to be available for gdb to use. When I build my sketch, I just click Verify, not upload. Next I locate the elf file for my sketch. This will be found in /tmp/arduino_build_#####, where ##### is some random number that is created by Arduino. Arduino creates a new directory (and number) for each sketch that you compile, so, I make sure the correct sketch name appears in the directory, and that the creation time is correct. For example, if the sketch I'm working on is named My_Sketch, then I look for a file named My_Sketch.ino.elf. That's the one I will load with gdb. To do that, I will use the gdb supplied with the stm32duino package. On my system, I find arm-none-eabi-gdb in ~/.arduino15/packages/STM32/tools/xpack-arm-none-eabi-gcc/9.2.1-1.1/bin. Following Al Pacini's lead, I created another script to invoke gdb - named ARM_gdb - placed it in ~/bin, and made it executable. Here is the script:

    ~/.arduino15/packages/STM32/tools/xpack-arm-none-eabi-gcc/9.2.1-1.1/bin/*gdb "$@"

    Here is what the server terminal looks like when the server is started:

     Here is the client terminal window starting the gdb client

    Now the client connects with "target remote :61234"

    ... and the server responds:

    next the client causes programming of the flash with "load"

    The server responds

    and the debugging session can begin! The server responses are not used during debugging, but this is what you would expect to see if you use gdb. Enter "cont" in the client terminal to start the loaded program. Use "^C" to stop gdb when a sketch is running, then "quit" and "y" to leave gdb. Entering "^C" in the server window will stop the server. There is no need to stop the server if you plan to use gdb again. Be sure to stop it if you want to upload using Arduino IDE.

    While those are the most basic gdb commands, that is a pretty boring example. Here is gdb being used for a typical, and more interesting, problem.

    I intended to use nRF24L01 radio with the L071 tArmDuino as part of a control scheme. To control the nRF24L01, the SPI interface is used. The sketch compiled fine, but would not communicate using SPI. As a simple start to debugging, I created a sketch which just did a simple SPI loop back. (The sketch L071_SPI_LoopBack1.ino is in Files if you want to play.) Using the process just described, I loaded the sketch for gdb debugging.

    Have a look at the sketch. It's very simple. The loop runs to simply transmit a byte and receive the same byte. Examining the three variables with gdb will verify that the SPI works in this simple way. If this doesn't work, then I have to fix it. If it works, then more debug is needed.

    To start, I set a breakpoint with gdb at loop. Then I run the sketch with "cont". The sketch stops the first time loop is to be executed, as expected. Then I "cont" again expecting loop to execute once and stop just before executing again. At this point, I could examine the variables and see if the SPI is working. But,...

    Read more »

  • tArmDuino Programming and Debug

    doctek01/04/2021 at 01:08 0 comments

    After adding the tArmDuino to the Arduino IDE, it is still not possible to program or debug it. The hardware and software tools to do that must be put in place. Programming and debugging tools for tArmDuino are all courtesy of ST. Although it's a large package, I recommend downloading and installing STM32CubeIDE. Since I use other STM devices, I find the Cube IDE useful, although the Arduino IDE is much easier to use for the tArmDuino. I will explain how to configure the programming and debug tools needed based on installing STM32CubeIDE. Although it may be simpler to install STM32CubeProgrammer instead, you still need STM32CubeIDE to get the gdb server. Al Pacini provided most of the hints and details that got my tools working.

    The directory ~/STMicroelectronics/STM32Cube/STM32CubeProgrammer/ must be created if it does not exist. This directory was not created when I installed STM32CubeIDE, so I had to do it. If you install STM32CubeProgrammer (as Al Pacini suggests), it may be created for you. On my system (Ubuntu 16.04), the tools I needed were found in /opt/st/stm32cubeide_1.5.0/plugins/ Copy all the folders from that directory to ~/STMicroelectronics/STM32Cube/STM32CubeProgrammer/. When you are done, that directory should contain the folders bin, Data_Base, doc, and lib. Next, go to /opt/st/stm32cubeide_1.5.0/plugins/ and copy all the files in that directory to ~/STMicroelectronics/STM32Cube/STM32CubeProgrammer/bin. From the software tools side, tArmDuino can now be programmed from the Arduino IDE. If you try this yourself, note that the numbers in the file names given may vary, but should be close enough to guide you. I went the step farther and followed Al Pacini's suggestion to create a ~/bin directory and put a couple of scripts in it to make the programming tools easily available from the command line. The udev rules should be in the right place following installation of STM32CubeIDE, so those files are not needed.

    To program tArmDuino from Arduino IDE, an ST-Link programmer is needed. The cheapest and easiest way to get one of these that I have found is to buy a suitable Nucleo-64 board. I like the NUCLEO-L053R8 board. Following the manual for it, I remove the jumpers on CN2 (marked ST-LINK) and connect the CN4 (SWD) header to the breadboard version of tArmDuino. Plug the pcb into a breadboard for experimenting. Connect CN4-Pin 1 to the positive rail of the breadboard. This does not power the L071 during programming! 3.3V must be supplied; I use the 3.3V from the Arduiono header on the Nucleo. CN4-Pin 2 goes to SWC, CN4-Pin 3 goes to ground, CN4-Pin 4 goes to SWD, and CN4-Pin 5 goes to NRST. Here's how it looks in a typical setup.

    Note 3.3V from Nucleo board to breadboard.

    Note colors of wires. The picture below shows them connected to the STM32L071 tArmDuino.

    Once the ST-Link is connected, programming is easy. I select Board: tArmDuinoL071, Flash size: 128k, Optimize: smallest, Library: Nano (default), U(S)ART: disabled, and Upload method: Cube Programmer (SWD). I plug in a USB cable to the Nucleo/ST-Link. Then I load the Blink sketch from the Arduino Examples/Basics menu, change the led number to 7, and click verify to be sure it all builds cleanly. Then I click upload to burn it to flash on the tArmDuino. An led must be hooked to Pin PA8 via a resistor to ground or Vcc. Once the sketch is uploaded, the led should be blinking. The variant.h file in SMALL_LO71K has the mapping of Arduino pin numbers to tArmDuino pins named on the pcbs.

    While the method just described works great, there are two shortcomings. First, there is no serial port available so the usual printf debugging is out. (The L071K has a UART, but I haven't implemented it.) Second, the powerful gdb (g-debugger) is not supported by the Arduino IDE. The use of gdb will be the subject...

    Read more »

  • Adding tArmDuino to the Arduino IDE

    doctek12/29/2020 at 21:04 0 comments

    The stm32duino project supports a large number of ST microprocessors and boards. One of the processors it supports is the STM32L071! So the first step in developing software for the tArmDuino is to add these files to Arduino. I followed the Getting Started section at the stm32duino github page.  After following the directions, I restarted Arduino, and verified that I now had a heading in the Tools/Board menu that said "STM32 Boards (selected from sub-menu)" with a number of selections below it. I don't really use any of this, but the libraries that accompany the package are just what I need.

    There is no entry in the STM32 Boards menu that is specific to the STM32L071, so I had to create a board definition and add it to Arduino. While there is a lot of documentation available, most of it seems to be for the commercial developer and contains way more information than the individual needs to just add a single board. At the same time, key details seem to be glossed over. So some detective work and a lot of experimentation was necessary to add the tArmDuino! These references were particularly helpful: Arduino documentation, Stm32duino documentationRick Kimball's excellent example.

    Mining these resources, I discovered three key details. First, I needed a board.txt file which defines the features of my board, and a platform.txt file which would define my progamming method. Mostly, this means definitions that will be pulled into the recipes for compiling, linking, and uploading the code for the board. Modifications started by copying the boards.txt and platform.txt from the stm32duino download. (These were in ~/.arduino/packages/STM32/hardware/stm32/1.9.0 on my system). Making an educated guess, I modified the boards.txt file to only include the Nucleo_L031 board and changed the occurrences of "31" to "71". Another change was to put the definition "[name].core=STM32:arduino" in which caused Arduino to use the tools in the STM32 Boards area that I previously installed. Finally, I caused a menu to appear in the Arduino Tools drop-down so that the memory size could be specified. Another menu allows choosing the upload method, although the only choice is to use SWD. There were already menus for optimization, C runtime library, and U(S)ART selection (not implemented yet). The platform.txt file was edited to only include the SWD upload method. Have a look at the versions I provide in the archive.

    The second detail is to provide a variant directory with the same name as is in the boards.txt file. In this case, that is SMALL_L071K (name is arbitrary). Inside that directory, the files PeripheralPins.c, variant.h and variant.cpp define the pins on my board, the functions they support, and the mapping to Arduino digital and analog pin numbers (like D0 or A5). I started by copying from the Nucleo_L031 board and carefully modified the files for the tArmDuino. While I'm still experimenting in this area, it all seems to work!

    The third and final detail is exactly where to put the files so that my boards will show up in the Arduino Tools/Board menu and my code will be compiled properly for them. I'll skip the details of the many experiments I tried before I figured this out. The trick is to build a suitable directory structure and put that in the correct location. Cut to the chase: Build the structure shown and put it in the Arduino home directory in the hardware folder. The following pictures show how it fits together.

    For anyone wanting to duplicate this, download the file and unzip it into the Arduino hardware folder. Restart Arduino and you will find entries for "tArmDuinoL031" amd "tArmDuinoL071" under the title "tArmDuino Boards", right after the many entries defined for official Arduino boards. The L031 version only works with the 28 pin first version. I include it as a useful example and because I still use it sometimes. This method of adding a new board to the Arduino environment is not the official one! But the...

    Read more »

  • Second Version - STM32L071KBU

    doctek12/28/2020 at 23:09 0 comments

    Using all that I had learned from my initial design, I bravely launched into a revision. It is called "tArmDuino". The STM32L071 seemed like the right family and I expected to use a 28 pin version again. But the 28 pin version only supported 32K of memory! To gain access to the larger flash memories, I would have to use a 32 pin package. Fortunately, the re-design was not difficult and the resulting board is only 1mm longer, and the same width, so no changes to the frame for the programmer were needed. The breadboard version is 26 pins vice 24 pins. Note that pin PB4 is a no-connect, according to the errata sheet. Actually, it's not totally clear to me what versions this applies to, so I'm just not using PB4. The complete part number is STM32L071KBU6 for the 128K part. Change the B to a Z for the 192K part. It's worth noting that there is an STM32L072KBU that has the same footprint and pin-out, and adds two DACs and crystalless USB. I haven't tried this chip yet.

    Here are the schematics for the tiny version of the tArmDuino and the small (breadboard) version.

    Besides dividing the pin connections into 4 connectors instead of two, the main difference is that the SWD and SWC lines (used for programming and debug) are brought out to the connectors on the debug version, while they are routed to the debug footprint on the tiny version. The pictures of the two boards follow.

    The tArmDuino is shown sitting on the debug alignment frame. The breadboard version is shown in use. Details on connecting the STLink programmer will be given in another project log.

    Building both boards uses standard process. The boards were produced by OSHPark. The solder paste stencils were cut on my Silhouette Portrait in 2 mil mylar. I stenciled on the paste, placed the parts, and reflowed using my modified toaster oven. Any required touch-up is done by hand.

    The KiCAD files are in the Files section for both boards. Also included are the gerbers and the gerber for the solder paste stencil. Note that the stencil has rectangle vice rounded rectangle shapes for all pads. If I use rounded rectangles, then cutting the stencils with the Portrait takes a painfully long time! Since all the KiCAD files are available, a different stencil could be created if desired.

  • First Version - STM32L031G6

    doctek12/22/2020 at 02:04 0 comments

    For the initial design of a tiny Arduino, I chose the STM32L031G6 microprocessor. I had already determined that the SWD programming and debug port would work with the footprint I had developed for the ATTINY84 (link above in the Description). The 28 pin version seemed to cover all Uno functionality, plus. And I naively thought that 32K of flash (same as an Uno and Teensy2) would be plenty. There was a Nucleo 32 board with a 32 pin version of the L031 which I bought for testing. The first two boards (the tiny version and a breadboard version) were designed and are pictured below.

    The resulting tiny version was not quite as small as an ATTINY85, but it's still pretty small! There are only three decoupling caps on the tiny version due to it's small size. Some might quibble with that decision, but it works so far. The BOOT0 pin is tied low since the SWD port is used to load code and debug. Everything else found on an Uno is omitted. I add circuitry if it is needed for a particular application. So far, I have had to add the I2C pull-up resistors.  A voltage source must be provided in the 1.8V to 3.6V range - I use 3 to 3.3V typically. Note the notches on the sides of the board. These are to position the programmer. (Described later.) The breadboard version is also useful as just a low-cost Arduino to use with projects. Here is the schematic and a view of the board design for the tiny version.

    Since this version has been deprecated, the KiCAD files are not included.

    While I thought the hard part of the design would be the hardware, I expected the software to be easy. I knew that there was a version of the ST software for Arduino (via the usual Library Manager) and I expected to just use that. However, when I tried a simple I2C program, I was shocked and saddened to see that it took 22K of flash (70%)! Since a similar program on a Teensy2 takes only 5K (15%), this was a show stopper! There followed many months of learning much more about the Arduino environment and the internals of the ST32L031 than I ever intended. I won't bore you with details of the forum posts and how to use the LL version of the ST library vice the HAL version, but the result was that the I2C program now ran in only 3.7K  (12%) of memory. More work was required to make analog pins (ADC and PWM) work properly, implement a timer, and have GPIO working. I still needed to implement SPI and the UART. To get things this far, I had modified the STM Arduino Library to use my code and to recognize my unique board. (I'll discuss necessary modifications in the next Build Log.) But I realized there is no future in this path! I don't plan to support custom software which might have to track new versions. And much better integration with the Arduino environment is needed.

    Getting to this stage took over a year. I spent another 6 months or so mulling over how to proceed with this project. I really liked the concept, but the software details were killing me. Fortunately, by this time ST had introduced the STML071 series. This series had much more flash: 64K, 128K and even 192K. There was also a new rev of the Arduino Library. A few experiments convinced me that I could use unmodified code and fit it easily into these larger memories. The ST code is still bloated for these small processors, but the additional memory makes them usable. On to the next version!

View all 6 project logs

Enjoy this project?



doctek wrote 12/21/2020 at 22:15 point

Thanks for the encouragement! Many details to follow - keep an eye on the build logs.

I have no plan to produce these, but I have no problem if others would like to. I'll release all hardware and software design to the public domain.

  Are you sure? yes | no

David Wilson wrote 12/21/2020 at 18:36 point

Nice project; I'm looking forward to seeing more on it. Are you planning to manufacture and sell this design?

  Are you sure? yes | no

Similar Projects

Does this project spark your interest?

Become a member to follow this project and never miss any updates