Archive for the ‘Electronics’ Category

Debugging NuttX on the Raspberry Pi Pico

Sunday, June 11th, 2023

GDB showing thread information

At some point in the development lifecycle we will hit some unexpected application behaviour. At this point we reach for the debugger to allow us to connect to the application an interrogate the state and hopefully we will be able to determine the cause of the problem. Working with NuttX is no different from any other application. The only complication we have is connecting to application running on the PicoW requires a debug adapter. Luckily, the Raspberry Pi Foundation has an affordable solution to this problem.


The getting started guide for the Pico has instructions on how to set up the environment for Linux, Mac and Windows. This post will be following the guide for MacOS adding some hardware to allow for a stable connection between the debug probe and the PicoW.

There are two options for the debug probe:

  • The Raspberry Pi debug probe
  • Use a Pico programmed as a debug probe

I have a number of Pico and PicoW boards and so the later option, using a Pico programmed as a debug probe, is going to be the most cost effective and this is the route we will look at here.


For the purpose of discussion we will use the following terms to describe the two boards:

  • Picoprobe – Pico that is programmed to be a debug probe
  • Target – PicoW that is running the application we wish to debug

The getting stared guide shows how two Pico boards should be connected to provide both debugging and serial console output through a UART on the target board. This shows the two boards on a breadboard setup (image is taken from the Raspberry Pi Pico getting started guide under CC-BY-ND license).

Picoprobe and Pico Fritzing

Picoprobe and Pico Fritzing

The same setup can be reproduced on protoboard. This will make the setup a little more robust and permanent. Breaking out the soldering iron and the parts bin yielded the following:

Pico on Protoboard

Pico on Protoboard

The flying leads are needed to connect to the SWD debug headers on the PicoW as it was not possible to connect these through to the protoboard. The black (GND) and red (5V) wires provide power to the target board. This means that we only have one connector to the system, namely to the Picoprobe but we must take care not to exceed the power capabilities of the USB connection.

The white (SWCLK) and blue (SWDIO) flying leads provide the debug connection between the two boards. As with the permanent connections above, the black lead is a GND connection.

The blue and yellow leads connected permanently to the protoboard connect the UART from the target board through to the picoprobe. The picoprobe will use the USB connection to present the host computer with a connection through to the UART on the target board.


The first piece of software needed is the Picoprobe software itself. There are instruction on how to build this but I found the simplest thing to do was to download the latest release from the Picoprobe GitHub repository. At the time of writing this is version 1.0.2. The Picoprobe software is deployed to the Pico being used as a Picoprobe in the usual way, reset the Pico whilst hold the BootSel button and then drag and drop the firmware file onto the drive present to the host computer.

The next thing we need is a version of openocd that can talk to the Picoprobe. The machine I am using is used to develop software for multiple boards and so the preferable solution is to build the Raspberry Pi Pico version of openocd for this setup and then reference this locally rather than install the software globally. This is the same approach taken for the various development environment I use to prevent them interfering with each other.

Following the guide (for Mac) we need to execute the following commands:

cd ~/pico
git clone --branch picoprobe --depth=1 $ cd openocd
export PATH="/usr/local/opt/texinfo/bin:$PATH" 1
./configure --enable-picoprobe --disable-werror 2
make -j4

Check the latest version of the guide for instructions for your OS.

Now to try openocd… This is where I hit a problem caused by having out of date documentation. Following the latest documentation we need to execute the following command:

src/openocd -f interface/cmsis-dap.cfg -f target/rp2040.cfg -c "adapter speed 5000" -s tcl

I was following I hit two errors due to the out of date documentation:

  • Error: Can’t find a picoprobe device! Please check device connections and permissions.
  • Error: CMSIS-DAP command CMD_DAP_SWJ_CLOCK failed.

Both of these errors were corrected by using the command above to connect to the debug probe. Moral of the story, make sure you are using the latest information. If everything goes well then we should be rewarded with something similar to the following output:

Open On-Chip Debugger 0.11.0-g4f2ae61 (2023-06-10-18:20)
Licensed under GNU GPL v2
For bug reports, read
Info : auto-selecting first available session transport "swd". To override use 'transport select <transport>'.
Info : Hardware thread awareness created
Info : Hardware thread awareness created
Info : RP2040 Flash Bank Command
adapter speed: 5000 kHz

Info : Listening on port 6666 for tcl connections
Info : Listening on port 4444 for telnet connections
Info : Using CMSIS-DAPv2 interface with VID:PID=0x2e8a:0x000c, serial=E66058388356A232
Info : CMSIS-DAP: SWD  Supported
Info : CMSIS-DAP: FW Version = 2.0.0
Info : CMSIS-DAP: Interface Initialised (SWD)
Info : SWCLK/TCK = 0 SWDIO/TMS = 0 TDI = 0 TDO = 0 nTRST = 0 nRESET = 0
Info : CMSIS-DAP: Interface ready
Info : clock speed 5000 kHz
Info : SWD DPIDR 0x0bc12477
Info : SWD DLPIDR 0x00000001
Info : SWD DPIDR 0x0bc12477
Info : SWD DLPIDR 0x10000001
Info : rp2040.core0: hardware has 4 breakpoints, 2 watchpoints
Info : rp2040.core1: hardware has 4 breakpoints, 2 watchpoints
Info : starting gdb server for rp2040.core0 on 3333
Info : Listening on port 3333 for gdb connections

If we have got here then we have the the debug probe programmed and we have a copy of openocd that can communicate with the picoprobe.

Reconfiguring NuttX

In previous posts we used UART over USB to communicate with the host computer. The picoprobe gives us another option, using the UART on the target board which is routed through the picoprobe. We must reconfigure NuttX in order to take advantage of the UART redirection. The configuration we want is raspberrypi-pico-w:nsh, so following the first post in this series and making the change to the configuration we need to execute the following:

make distclean
./tools/ -l raspberrypi-PicoW:nsh
make -j

At the end of this process we should have a new nuttx.uf2 file configured to use the UART port on the target board to communicate with the NuttX shell. This UF2 file can be deployed using the usual deployment process (Bootsel and reset followed by drag and dropping the file) to the target board.

At this point we should have two Pico boards programmed, one to be the picoprobe and one to be the target board (with NuttX). Now we can connect the boards (in my case using the protoboard shown above) and verify that NuttX is active and communicating through the UART.

Plugging the Pico (picoprobe) and the PicoW (target board) into the protoboard and then connecting the host computer to the picoprobe through USB presents the computer with a new serial port, usbmodem14302. Connecting to this port and hitting enter shows the nsh prompt. Asking for help shows the expected output.

nsh> help
help usage:  help [-v] [<cmd>]

    .         cat       df        free      mount     rmdir     truncate  
    [         cd        dmesg     help      mv        set       uname     
    ?         cp        echo      hexdump   printf    sleep     umount    
    alias     cmp       env       kill      ps        source    unset     
    unalias   dirname   exec      ls        pwd       test      uptime    
    basename  date      exit      mkdir     reboot    time      usleep    
    break     dd        false     mkrd      rm        true      xd        

Builtin Apps:
    nsh  sh   

So we have a good UART connection and openocd can connect to the picoprobe.

Now we need to connect the debugger to openocd.


To debug the board we will start with GDB, specifically arm-none-eabi-gdb-py as this has Python scripting enabled. We can use the scripting engine to automate some tasks later.

First thing to do is add a .gdbinit file to the directory we will be executing GDB from, in this case we will use the nuttx directory. The following commands should setup GDB and openocd ready for debugging. The nuttx ELF file will be loaded for us so by the time the GDB prompt is show we will have the symbol file loaded. Our .gdbinit file should look something like this:

set history save on
set history size unlimited
set history remove-duplicates unlimited
set history filename ~/.gdb_history

set output-radix 16
set mem inaccessible-by-default off

set remote hardware-breakpoint-limit 4
set remote hardware-watchpoint-limit 2

set confirm off

file nuttx
add-symbol-file -readnow nuttx

target extended-remote :3333
mon gdb_breakpoint_override hard

To debug we will need two terminal sessions open. In the first session run openocd as described above. In the second session start GDB (simply enter the command arm-none-eabi-gdb-py in the terminal session) making sure that you are in the directory containing the nuttx file and the .gdbinit file. If you are successful then you will see something like this:

GNU gdb (GDB) 13.1
Copyright (C) 2023 Free Software Foundation, Inc.
License GPLv3+: GNU GPL version 3 or later <>
This is free software: you are free to change and redistribute it.
There is NO WARRANTY, to the extent permitted by law.
Type "show copying" and "show warranty" for details.
This GDB was configured as "x86_64-apple-darwin22.3.0".
Type "show configuration" for configuration details.
For bug reporting instructions, please see:
Find the GDB manual and other documentation resources online at:

For help, type "help".
Type "apropos word" to search for commands related to "word".
add symbol table from file "../nuttx/nuttx"

We can now start to debug the application on the board. A few simple tests, firstly, reset the board with the GDB command mon reset halt. We should see something like this:

target halted due to debug-request, current mode: Thread
xPSR: 0xf1000000 pc: 0x000000ea msp: 0x20041f00
target halted due to debug-request, current mode: Thread
xPSR: 0xf1000000 pc: 0x000000ea msp: 0x20041f00

We can now set a breakpoint, say in nsh_main (b nsh_main) and run the application to the breakpoint (c). If we then ask for information about the threads (info thre) we should see something like this:

  Id   Target Id                                           Frame
* 1    Thread 1 (Name: rp2040.core0, state: breakpoint)    nsh_main (argc=0x1, argv=0x20003170) at nsh_main.c:58
  2    Thread 2 (Name: rp2040.core1, state: debug-request) 0x000000ea in ?? ()


Getting debugging up and running took a little more effort than I expected but was not expensive due to the ability to use a Pico to debug a Pico. There is some excellent debugger documentation on the NuttX web site. This suggests that openocd should support NuttX however I was not able to get this working with the Raspberry Pi release of openocd. It was a question of having Pico support or NuttX support. I’m going with the Pico support for the minute.

I was hoping to use the picoprobe board to deploy the application meaning that we only have one connection between the host computer and the development hardware. A little more research is going to be necessary to see if this can be done.

Adding SMP to NuttX on the Raspberry Pi PicoW

Tuesday, June 6th, 2023

ps Command Results without SMP Enabled

So far in this series we have configured NuttX to build C++ applications on the PicoW and we have created our own custom application and successfully deployed this to the board.

In this post we will look at configuring the system to use both cores on the RP2040 processor using the configuration we have developed over the previous posts. NuttX includes a SMP configuration already, raspberrypi-pico-w:smp, this uses UART0 for communication rather than USB hence we will look at add this configuration on top of the USB configuration.

Default Configuration

It appears that the default configuration for NuttX running on the PicoW is to run the processor as a single core processor. Running the ps in the NuttX shell yields the following output:

    0     0   0 FIFO     Kthread N-- Ready              0000000000000000 001000 Idle Task
    1     1 100 RR       Task    --- Running            0000000000000000 002000 nsh_main   

From the output we see that there are only two tasks running on the system. From this we can deduce that only one of the cores is enabled. If both cores were running then we should see two Idle Tasks running, one on each core plus the nsh_main task. This is confirmed in the SMP Documentation where we find the statement:

Each CPU will have its own IDLE task.

Now we have this confirmed, let’s move on to reconfiguring the system.

Enabling SMP

According to the documentation we need set three options through the configuration system in order to turn on SMP:


Starting the configuration system with the make menuconfig we are presented with the top level options screen:

NuttX configuration system

NuttX configuration system

This poses the question “How do I find CONFIG_SMP and the rest of the options?”. Luckily, kconfig has a search option, pressing the / key presents the user with a search dialog box:

Search dialog here.

Typing SMP and pressing return shows a number of results, some are relevant to use, some are not. The longer the search term the more accurate the results will be. In our case, searching for SMP yields a number of results that are irrelevant. However, the top result looks like it is the one for us:

SMP Search results image Here.

The results give us a fair amount of information about the configuration options. If we look at the top entry for SMP (this is actually the option that we need to turn on) the system is giving us the following information:

  • The option name (SMP) which will translate to CONFIG_SMP in the various include files
  • The location of the option, in this case RTOS Features -> Tasks and Scheduling
  • In which file (and the line number) the option is defined, sched/Kconfig, line 271
  • Any other options that this option depends upon.
  • Any options that will be turned on as a result of selecting this option

You will also note a number in brackets at the side of Tasks and Scheduling. This is the short cut key, in this case 1 and pressing 1 will take us to the appropriate place in the configuration system.

RTOS Features options.

Selecting Tasks and Scheduling by pressing enter we are presented with the following:

Tasks and scheduling, no SMP.

Notice that there is no option to turn on SMP. Confused, so was I the first time I saw this. Pressing the ESC key a few times should take us back to the search results. Reading these more carefully we note the following:


So we have to ensure that three conditions are met in order to enable SMP:

  • HAVE_MULTICPU is set to turned on, this looks to be the case (ARCH_HAVE_MULTICPU [=y])
  • HAVE_TESTSET is turned on, again this looks to be the case (ARCH_HAVE_TESTSET [=y])
  • INTERRUPTSTACK has a non-zero value, this appears to be false (ARCH_INTERRUPTSTACK [=0]!=0)

It appears that we have not met all of the conditions to activate SMP. We need to look at defining a size for the interrupt stack. So using the search system again but this time for ARCH_INTERRUPTSTACK we get the following results:

Interrupt stack search results

Pressing the 1 key takes us directory to the entry we need to change. Setting the value to 2048 should be a reasonable starting point. We can always adjust this later if we find it is causing problems.

Exiting this menu and the search for ARCH_INTERRUPTSTACK we can search for SMP again. Pressing the 1 key in the search results presents us with a different view, this time we are taken to the SMP option and we can now turn this on. If we do this the system will add some new entries to the menu, one of which defines the number of CPUs available and this is set to 4. We will need to change this value to 2.

SMP Configured image.

We are now ready to build the system.

Build and Deploy NuttX

We should now be ready to build and deploy the system to the PicoW. Executing the following command will build NuttX and create the UF2 file ready for deployment:

make clean
make -j

At the end of the build process we can deploy the UF2 file to the board by putting the board in bootloader mode and dropping the file to the drive that is shown on the host computer. Se the first article in this series for more information on how to do this.

Time to connect our serial terminal to the PicoW and run the ps command once again:

SMP Enabled ps output.

As you ca see from the screen shot above, we now have two ide tasks as expected and the ps command has some additional information, notably the CPU that each task is allocated to.


Adding SMP to the system was not as simple as it first sounded. The main lesson from this was to check the dependencies in the search results. The requirement for an interrupt stack was not discussed in the SMP documentation and this caused some confusion initially. The help in the configuration system came to our rescue and the situation was easily recoverable.

If you have been following the series we are now at the point where we have think about some serious development. We now have space for our own application code, C++ is enabled and we are able to use both cores on the RP2040 microcontroller.

At this point the series will slow down a little as some of the features now need some in depth investigation most notable:

  • Using SMP correctly in NuttX
  • Interprocess communication between tasks running on different cores
  • RP2040 PIO and NuttX

Adding a User Application to NuttX

Tuesday, June 6th, 2023

Enable SSEM User Application

So far we have seen how to deploy NuttX to a Raspberry Pi PicoW and enable C++ in NuttX. Next up we will create our own application and deploy it to the PicoW.

Creating a New Application

The build system for NuttX applications uses a a makefile that is written in such a way that all we have to do to add a new application is simply create a directory containing some template files. The easiest way to do this is to use an existing application as a template. So let us start by making a copy of the helloxx application. This can be found in the apps repository in the examples directory. So we will start by making a recursive copy of this directory and renaming it ssem.

Looking inside the ssem directory we find a number of files:


Time to start editing the files.


We will start by renaming the file to represent the application name, so we will rename this to ssem_main.cxx. Now editing the file we change all occurrences of helloxx_main to ssem_main. This will allow us to verify that we have indeed deployed the application.


Make a similar change to the Makefile by changing all occurrences of helloxx to ssem. Make changes to the comments to reflect that this application is a new application. Our Makefile should now look something like this:

include $(APPDIR)/Make.defs

# SSEM Application

MAINSRC = ssem_main.cxx

# ssem built-in application info


include $(APPDIR)/


The Make.defs file conditionally adds the new application to the list of configured applications and ensures that the file will be built. This file should be edited to look something like this:

CONFIGURED_APPS += $(APPDIR)/examples/ssem


The Kconfig file allows us to define and change application parameters, something we may look at later. For the moment it simply defines the application name and title and tells the configuration system how to turn compilation on or off. Making changes similar to the above we will have a file that contains something like this:

tristate "SSEM example"
default n
depends on HAVE_CXX
    Enable the SSEM application

Build the SSEM Application

Now we have set up the application we can start to reconfigure the build system and deploy the application. First thing to do is to clean the current build environment in order to make NuttX aware of the presence of the application. Issuing the command make clean will remove the previous build components.

Now we can configure the environment by issuing the make menuconfig command. This will present the configuration menuing system we saw in the previous post. So now head over to the following menu items and disable the Hello, world example and enable the SSEM example.

  • Main menu -> Application Configuration -> “Hello, World!” C++ example
  • Main menu -> Application Configuration -> SSEM example

We should now be ready to build the system, so execute the command make -j to build the system. The build system should show output similar to the following if the changes to the system have been made correctly:

Create version.h
LN: platform/board to /Projects/NuttX/apps/platform/dummy
Register: ssem
Register: nsh
Register: sh
CPP:  /Projects/NuttX/nuttx/boards/arm/rp2040/raspberrypi-pico-w/scripts/raspberrypi-pico-flash.ld-> /Projects/NuttX/nuttx/boards/arm/rp2040/raspberrypi-pico-w/scripts/raspberrypi-pico-flash.lLD: nuttx
Generating: nuttx.uf2
tools/rp2040/elf2uf2 nuttx nuttx.uf2;

Time to deploy NuttX to the board and check to see if the application has built correctly. So copy the NuttX.uf2 file to the board and connect a serial console to the serial port. Press enter a few times until the nsh prompt appears and now type help. The new application should appear in the list of built in applications:

Builtin Apps:
    nsh   sh    ssem  

Executing the ssem application should now present something similar to the following (depending upon how you modified the helloxx_main application code):

nsh> ssem
ssem_main: Saying hello from the dynamically constructed instance
CHelloWorld::HelloWorld: Hello, World!!
ssem_main: Saying hello from the instance constructed on the stack
CHelloWorld::HelloWorld: Hello, World!!


The process of creating a new application and having this included in the NuttX build system is not a difficult task, it simply means editing a few files.

One key step is the make clean step as omitting this from a system which already contains build artefacts may not include the new application in the configuration process and hence exclude the files from the build.

In the next post we will add SMP to the configuration.

Enabling NuttX C++ Support on PicoW

Monday, June 5th, 2023

Enable C++ compiler support

In the last article we looked at getting NuttX running on the Raspberry Pi Pico. The system deployed the default applications which are written in C. In this post we will look at enabling C++ support.

The first thing to do is to follow the instructions in the previous post to get the development system downloaded and deployed. Next up we can clean any object files that may be remaining from any previous builds:

make distclean
./tools/ -l raspberrypi-pico-w:usbnsh

Now we have a clean system wew can enabled C++ compiler support. This is done through the configuration system which is accessed by executing the command:

make menuconfig

This will show the main menu for the configuration system:

NuttX configuration system

NuttX configuration system

Using the arrow and enter keys we need to navigate the menus and change the following options:

  • Main menu -> Library Routines -> Have C++ compiler
  • Main menu -> Application Configuration -> “Hello, World!” C++ example

Turning on the C++ compiler will show the following additional menu items:

Enable C++ compiler support

Enable C++ compiler support

The 12.1 release of the PicoW implementation deploys some additional applications which are not needed so we will turn these off in order to save memory. The two application to be disabled are:

  • ostest
  • getprime

These applications can be turned off using the configuration system, the menu items can be found here:

  • Application Configuration -> Testing -> OS test example
  • Application Configuration -> Testing -> getprime example

The system would be ready to be built using the make -j command. Once built, deploy the application to the board by copying the UF2 file to the board as discussed in the previous post. The board should reset automatically so connect a serial console to the board and hit enter a few times to get to the nsh prompt. Typing help at the command problem should show the built in commands plus the additional commands that have been deployed:

Builtin Apps:
    helloxx  nsh      sh

Finally we should verify that the C++ application has been built and deployed correctly by running the helloxx application. If all is well then the serial console should show the following output:

helloxx_main: Saying hello from the dynamically constructed instance
CHelloWorld::HelloWorld: Hello, World!!
helloxx_main: Saying hello from the instance constructed on the stack
CHelloWorld::HelloWorld: Hello, World!!


This is a small step forward getting C++ enabled ready for developing a new C++ application which we will look at in the next post.

In the next post we will add a new C++ user application to the system.

Deploying NuttX to the Raspberry Pi PicoW

Sunday, June 4th, 2023

Close up of Raspberry Pi PicoW

Currently taking a few weeks break and after a few days away from the computer I decided to do a little bit of research into the PicoW and NuttX. So time for a quick attempt at getting the system up and running.

I have for the last few years been working on the Meadow F7 board for Wilderness Labs. This board aims to provide a full .NET development environment bringing embedded development to a wider audience. There are three main technologies underpinning this board:

I spend much of my time working with NuttX and FreeRTOS so as you can gather, I’m not worried about working with C or C++. This gives a few options for working with the board:

  • Native development using the Pico SDK
  • NuttX
  • FreeRTOS

I decided to start with a look at NuttX as I am currently spending a lot of time working with this RTOS.

Let’s Follow the Guide

First thing to do is head over the the documentation for NuttX on the RP2040. The getting started guide is really good and I thought I would be able to use the copy of the Pico SDK I had already on my machine.

This is where I hit my first problem. NuttX requires a specific version of the Pico SDk and using this version would impact any other Pico development that I would undertake in the future. To overcome this I decided to take a second copy of the Pico SDK specifically for use when developing with NuttX.

Having said we would follow the guide, we are deviating already.

So first up we create a development environment for the PicoW (all instructions are for working on a Mac but should also work on Linux).

mkdir NuttX-PicoW
cd NuttX-PicoW
git clone -b 1.1.2
export PICO_SDK_PATH=$PWD/pico-sdk

Now we need to clone the NuttX OS and applications repositories:

git clone nuttx
git clone apps
cd nuttx

Now we have the NuttX components cloned we need to make sure we are on the current releases. This is done using git to checkout the correct branches. At the time of writing the current release is 12.1 so the following commands will checkout the correct branches:

cd apps
git checkout releases/12.1
cd ../nuttx
git checkout releases/12.1

Now we have the correct branches we need to configure the system to work with the PicoW. There are several different boards and configurations available using the RP2040, not just the pico. The following command will list all of the available board configurations available for the Pico series of boards (not just the PicoW but all of the Pico boards):

./tools/ -L | grep pico

For NuttX 12.1 this returns the following list:


The configuration that is interesting here (to get started) is the raspberrypi-PicoW:usbnsh configuration. This will redirect the console output from NuttX over USB to the host machine using serial communication. This will allow a simple terminal application to connect to the board without the need for any additional hardware. So let’s configure NuttX and build the system.

First up, clean the system and set the configuration:

make distclean
./tools/ -l raspberrypi-PicoW:usbnsh

This should clear any previous configurations (distclean) and then set the board type and specific configuration to be built.

Now we should be able to build the system.


You can also tell make to use as many cores on your system as possible with the command make -j. After a short time the system will compile the NuttX OS and applications and create a UF2 file that can be uploaded to the PicoW.

The board can be programmed by starting the board in bootloader mode (press and hold the BOOTSEL button while plugging in the USB cable). The Pico should now present itself as a USB drive on the host computer. Drag and drop the nuttx.uf2 file onto the Raspberry Pi Pico drive on the host computer. The file will be copied to the board and the board will restart.

Connecting to NuttX

Time to check that the board has been programmed correctly. Open your favourite terminal application and set your connection settings to 115200,n,8,1 and connect to the serial port presented by the PicoW. The default is something like usbmodem01. Connect to the PicoW and hit enter a couple of times. On doing this you should be presented with something like this:

NuttShell (NSH) NuttX-12.1.0

If you have got this far then you have successfully built NuttX and deployed the OS to the PicoW. Typying help in the serial console should reveal the list of deployed applications.


At this point we have NuttX running on the PicoW. This opens up some new channels for investigation:

  • Using both cores on NuttX
  • C++ application development

In the next post we will look at enabling C++ development in NuttX.

Threaded Inserts and 3D Printed Mounts

Saturday, April 1st, 2023

Threaded insert in pillar

Threaded insert in pillar

Way back in 2019, Hackaday posted an article on Threading 3D Printed Parts: How to Use Heat-set Inserts which discussed how to use brass inserts in 3D printed parts to make connecting parts easier and more robust. The article presented the changes you should make to prints in order to make adding the inserts easier to locate and some of the tools that could be purchased to make using these inserts easier.

I have been using these type of inserts for a few years now and this month came up with a slight variation on the method discussed in the above article. The process of laying out the part remains the same, the change made is to the method of fixing the brass threaded insert into the 3D printed part.

The original article discussed using special tools for heating the threaded insert and pushing the heated part into the 3D printed model. This article presents an alternative to a specialist part by using nothing more than some scrap protoboard. The beauty of this technique is that it does not require any special tools.


I regularly use a number of different microcontroller development boards and debug probes for firmware development. These boards commonly have components on the bottom of the boards and / or through hole parts where the legs of the components protrude through the board and potentially damage desks / work surfaces.

A 3D printed mount or frame keeps any components away from work surfaces protecting them from scratches and also reduces the possibility of shorting components on the boards themselves.

The process will be illustrated with a Spresense board and external adapter.

The technique should meet the following requirements:

  • Use tools that any maker should have in their workshop
  • Present a flat surface around the insert
  • Keeps tools clear of any melted material

3D Design

The external Spresense adapter board has four mounting holes and the intention is to use two of the holes to acts as locators and two holes to fix the board in place. The mount will have four pillars under the holes in the external adapter board. Two of these will have printed pins to act as locators. Two of the pillars will use threaded inserts to allow screws to fix the board in place. A picture is worth a thousand words so here is how the final design looks:

Fusion 360 design for Spresense mount

Fusion 360 design for Spresense mount

Adding the Threaded Insert

The starting point of the process is the 3D printed frame with the objective of embedding the threaded insert securely into the printed part. The pillar is a simple cylinder with a hole running through to the base of the frame.

Pillar on mount

Pillar on mount

The first step is to prepare the threaded insert for insertion into the frame. This is done by using a screw matching the insert mating the two through a piece of protoboard:

Threaded insert on protoboard

Threaded insert on protoboard

Next up, the insert in placed in the hole in the pillar and the protoboard is used to hold the insert in place. The tip of a hot soldering iron is placed on the head of the screw and a slight pressure is applied using the protoboard:

Adding threaded insert (stage 1)

Adding threaded insert (stage 1)

Continue applying pressure using the protoboard as the part sinks into the 3D printed part:

Adding threaded insert (stage 2)

Adding threaded insert (stage 2)

By continuing to apply pressure, the protoboard will finally hit the top of the pillar. At which point remove the soldering iron and hold the protoboard in place for a few seconds. This will allow the PLA to set around the insert.

Adding threaded insert (stage 3)

Adding threaded insert (stage 3)

Finally, remove the screw from the board to reveal the insert which should now be firmly embedded into the pillar.

Threaded insert in pillar

Threaded insert in pillar


The technique presented uses simple tools which are available in many makers workshops or are relatively cheap to purchase. It achieves the objectives set out earlier in this post as well as those in the original Hackaday article.

Finally, here is the assembled board and mount.

Spresense external carrier board on mount

Spresense external carrier board on mount

NE555 Variable Speed Clock

Sunday, February 9th, 2020

The first post about the NE555 presented the theory of operation of the NE555 using an astable clock circuit. This circuit is the basis of a simple low frequency (by todays standards) digital clock or PWM circuit. A clock can be used to synchronise the various components in a digit circuit and PWM is useful in circuits for such things as light (LED) brightness.

This post will look at how the circuit in the first post can be modified to provide a variable clock for a digital circuit. A variable clock can prove useful when debugging a digital circuit.

Basic Astable Circuit

A simple astable circuit looks something like the following:

Astable Logical Layout

Astable Logical Layout

The two resistors R1, R2 and the capacitor control the timing and characteristics of the pulses seen on the output pin of the NE555.

Timing Calculations

The timing calculations given in the data sheet for the NE555 are as follows.

Note that in the following calculations, resistance is expressed on Ohms, capacitance in Farads and time in seconds.

Charge Time

The charge time depends upon the capacitor and the two resistors R1 and R2 as current flows through the two resistors to charge the capacitor. The time taken to charge is given as:

tcharge = 0.693 * (R1 + R2) * C

Discharge Time

The discharge time is only dependent upon the capacitor and R2 as current does not flow through R1 when the circuit is discharging. The time take to discharge is given as:

tdischarge = 0.693 * R2 * C


The period is the sum of the two timings tcharge and tdischarge. This can be expressed as:

Period = 0.693 * (R1 + (2 * R2)) * C


The frequency of a signal is defined as 1/Period. The period of a signal from an astable NE555 is:

Frequency = 1.44 / ((R1 + 2 * R2) * C)

Duty Cycle

The duty cycle of a signal is the percentage of time the signal is high compared to the period of the signal. Thus the duty cycle is given by the following formula:

Duty Cycle (%) = 100 * (R1 + R2) / (R1 + 2 * R2)

Fixed Clock

A fixed clock can be set up easily by changing one or more of the two resistors R1, R2 or the capacitor and a simple spreadsheet will allow you to calculate the circuit characteristics. Doing this allows for the creation of a low (by modern standards) frequency clock quickly and cheaply.

Variable Clock

A variable clock can be useful in debugging digital circuits. The ability to slow the speed of the system can allow the system to be probed easily while maintaining the ability to run the circuit using a free running clock.

As with a fixed clock, the clock characteristics can be changed by varying the value of one or more of R1, R2 or the capacitor.

Variable capacitors and resistors are both available but variable resistors (potentiometers) are more readily available to the hobbyist and so we will follow this option.

This gives two options, changing R1 or R2. Looking at the calculations above it is clear that R2 has the most impact on virtually every operating characteristic of the NE555 and is the only one that can influence the discharge time.

Looking at the tdischarge formula:

tdischarge = 0.693 * R2 * C

the discharge time could theoretically be reduced to zero if R2was allowed to approach 0 Ohms. This can be prevented by replacing R2 with a combination of a fixed value resistor and a potentiometer. The fixed resistor provides for a lower limit for the discharge time of the capacitor.

A quick spreadsheet shows how the circuit will behave as R2 and C are varied:

NE555 Calculations

NE555 Calculations

From the results above it looks like a minimum value for R2 of 1 KOhm and a maximum of 100 KOhm would give a reasonable frequency for a low speed clock.


Lowering the value of R2 1 KOhm and adding a 100 KOhm potentiometer results in the following schematic:

Schematic for a variable speed clock using the NE555 timer

Variable Speed Clock Schematic

The value of the fixed resistor and the potentiometer gives a range of 1 KOhm to 101 KOhm. The additional 1 KOhm of resistance should not impact the frequency too much when the potentiometer is set to its maximum resistance as the calculation is dominated by the 100 KOhm potentiometer.

So that is the theory, how does this work in practice?

Potentiometer Set to 0 Ohms

If we set the potentiometer to 0 Ohms then according to the calculations above, the frequency should be about 48 KHz. The output on the oscilloscope is:

Oscilloscope output when potentiometer set to 0 Ohm

Potentiometer set to 0 Ohm

Potentiometer Set to 100 KOhms

Changing the potentiometer to 100 KOhms we should get a frequency of 712 Hz. The output on the oscilloscope is:

Oscilloscope output when potentiometer set to 100 KOhm

Oscilloscope output when potentiometer set to 100 KOhm

And Somewhere in the Middle

By slowly changing the resistance of the potentiometer we can achieve a steady slow clock of approximately 1 kHz:

NE555 generating a 1 KHz signal

NE555 generating a 1 KHz signal


Clocks provide the heartbeat of most digital circuits, computers certainly require a regular pulse to synchronise the various components in the circuit. The NE555 provides a simple way to generate a variable clock albeit at low frequencies.

The output on the oscilloscope varies from the ideal values given by the calculations. This can be explained by the variations in the tolerances of the various components in the circuits and from the capacitance of the breadboard itself.

NE555 Power on Reset

Monday, January 20th, 2020

It is essential that when a computer (or any other electrical device) starts, that it starts in a known good state. For a computer, this is accomplished with a power on reset circuit. This circuit is responsible for holding the various reset signals in a known state for a defined period of time when power is applied. Some computers also utilise a reset switch to manually trigger this same reset process.

This post will look at a simple reset circuit from the 1980s using the NE555 timer.


The circuit under consideration should perform the tasks:

  1. Provide two reset signals, one high (Reset) and one low (Reset).
  2. Hold the reset lines in a known state when power is applied.
  3. Provide a manual reset facility.

All of the above can be achieved using a modified monostable NE555 circuit.


The modified schematic for the monostable circuit looks like this:

NE555 Reset Circuit Schematic

NE555 Reset Circuit Schematic

The basic theory of this circuit is that a low pulse on the trigger pin generates a single shot pulse on the output pin of the NE555.

The resistor and capacitor in the right-hand part of the circuit form a standard monostable configuration. This circuit is taken from the NE555 datasheet. Using the formula in the datasheet, the period of the stable, high pulse on the output is given by the formula:

Period = 1.1 * R * C

Using the values in the circuit, R = 47K and C = 10uF. Plugging these values into the equation we find that the period of the stable pulse is 0.517 seconds.

The inverter provided by the 74LS04 allows for the generation of both a high and a low (Reset and Reset) signals from the circuit.

The resistor and capacitor on the left hand side of the circuit debounce the switch connected to the trigger of the circuit. They also hold the trigger under the 1.67V threshold for a short period of time following startup. This provides the power on reset element of the circuit.

This circuit can also be viewed using the logical layout discussed in the previous aricle on the theory of operation:

NE555 Logical Layout

NE555 Logical Layout


Putting the above circuit together on breadboard gives something like the following:

NE555 Reset Circuit on Breadboard

NE555 Reset Circuit on Breadboard


In the following, all images from the oscilloscope will show the NE555 output in yellow and where present, the signal on the trigger pin will be in blue.

At startup, it is expected that there should be a short (500ms approx) signal on the output pin of the NE555.

NE555 Power on Reset Oscilloscope Output

NE555 Power on Reset Oscilloscope Output

So far, so good. The next requirement is to allow the user to manually reset the system. This is done using the switch connected to the trigger pin on the NE555. Pressing the button shows the following on the oscilloscope:

NE555 Reset Circuit Short Button Press

NE555 Reset Circuit Short Button Press

The short press on the button generates the required reset pulse on the output pin of the NE555.

The datasheet for the NE555 warns against holding the trigger pin low for a period of time longer than the duration of the output pulse. So in this case, the trigger pin should not be held low for longer than 517ms. This could be a problem as it is easy to exceed this period in normal use. So what happens if the trigger pin is held low for an extended period of time? Changing the scale on the oscilloscope to 250ms per division and we see the following:

NE555 Reset Circuit Multiple Button Presses on Oscilloscope

NE555 Reset Circuit Multiple Button Presses on Oscilloscope

The leftmost pulse is the result of a short press of the button. As expected, the output of the NE555 goes high for 517ms.

The middle pulse shows what happens when the button is pressed and held for an extended period of time. In this case, the button was pressed for about 2s. As you can see, the reset pulse remains high for the duration of the button press and then returns low.

The rightmost pulse shows what happens when the switch is pressed once more for a short period. As you can see, the NE555 returns to its normal mode of operation and generates a 517ms pulse.


The NE555 really does deserve it’s reputation as a versatile chip. This simple circuit provides a digital circuit with the ability to start in a known state by providing a reset pulse when power is applied to the system. It also provides a mechanism for resetting a system on demand using a switch connected to the trigger pin.

And now for a piece of history, circuits such as this appeared in many of the early 8-bit computers from the 1980s.

NE555 Theory of Operation

Wednesday, July 17th, 2019

Oscilloscope Trace

Oscilloscope Trace

Ohhhh no, not another post about the NE555 timer! I’m sorry to say, yes, this is another article (or two) about the NE555, how it works and some applications.

I blog for two main reasons:

  • As an aide-memoire
  • Hopefully others will find these posts useful

So this first post will cover the theory behind the operation of the NE555 using the astable circuit as an example.

Logical Layout of the NE555

The NE555 has four logical units and they can be viewed logically in the following layout:

Logical units with NE555

NE555 Logical Layout

These logical units are:

  1. Resistor ladder
  2. Two comparators
  3. S-R latch
  4. Discharge circuit

These components allow the engineering of a wide number of circuits using this versatile chip. This series of articles will cover four applications:

  • Astable circuit (a.k.a a clock)
  • Reset circuit
  • Button debouncing a push switch
  • Button debouncing with selection (i.e. latching switch)

Let’s start with looking at the four logical components identified above.

Resistor Ladder

Resistor Ladder

Resistor Ladder

The resistor ladder in the original chip used 5K resistors. The use of three equal value resistors supply 1/3 * Vcc and 2/3 * Vcc to the two comparators.




The two comparators compare two of the input voltages to the two values from the resistor ladder, namely, 1/3 * Vcc and 2/3 * Vcc. They output a high value if the voltage on the positive input is greater than the voltage on the negative input.

The top comparator has the negative input connected to 2/3 * Vcc and the positive input connected to the threshold pin. This comparator will out a high value when the threshold is greater than 2/3 * Vcc and a low value at all other times.

The lower comparator has the negative input connected to 1/3 * Vcc and the positive input connected to the trigger input. This comparator will output a high value when the trigger is less than 1/3 * Vcc and a low value at all other times.

S-R Latch

S-R Latch

S-R Latch

The S-R latch uses the output from the two comparators to determine if the output of the NE555 should be turned on or off. The inverted output from the latch (Q) is connected to the output pin of the NE555 through an invertor.

Q is also connected to the base of the transistor connected to the discharge pin.

Discharge Circuit

Discharge Circuit

Discharge Circuit

The discharge pin is connected to ground through a transistor. The base of the transistor is connected to the inverted output of the S-R latch. So the discharge pin is connected to ground when the S-R latch is in the reset state.

So How Does it Work?

An astable circuit can be used to understand how the various components of the NE555 work together and it is this circuit we will examine next.

Astable Circuit

One of the circuits that can be constructed using the NE555 is a low frequency PWM circuit, known in NE555 parlance as an astable circuit. This can be used in a wide variety of applications from flashing LEDs to the provision of a low frequency clock signal for a digital circuit.

An simple astable circuit can be constructed using two resistors, a capacitor and the NE555 chip. Using the above logical diagram as a starting point we would connect the additional components as follows:

Astable Logical Layout

Astable Logical Layout

The reset pin should be connected to Vcc and the control pin should be connected to ground through a 100nF or 10nF capacitor.

The operation of the astable circuit will be consider by progressing through time from the point that power is applied to the circuit. It is assumed that Vcc is equal to 5V. The makes the nominal values for 1/3 * Vcc = 1.67V and 2/3 * Vcc = 3.3V.

Power On

Capacitor starts to charge

Capacitor starts to charge

At the point where the chip starts the resistor network inside the NE555 will split Vcc into two as noted above. These will appear on the two comparators negative (for comparator 1) and positive (for comparator 2) inputs.

At the same time, the capacitor C will be charged through resistors R1 and R2. At the point shortly after power up there will be very little charge on the capacitor, for argument, let us say that this is 0V. This will place 0V on both the trigger and threshold pins of the NE555.

Comparator 1 will compare the voltage on the trigger pin (negative input) to 1.67V (positive input). As 0V is less than 1.67V this will result in a high output from comparator 1. This high output is applied to the set pin of the S-R latch. Following this through, this will turn the Q output on and the inverted Q output off.

Q output drives both base of the transistor connected to the discharge pin, turning the transistor off and the output pin through the invertor, turning the output on.

Comparator 2 is comparing positive input connected to the charge on the capacitor (currently 0V) to 3.3V. Following this through as we did with comparator 1, 0V is not grester than 3.3V and so comparator 2 outputs a low signal. The low signal on the reset input in the S-R latch has no effect on the output from the S-R latch.

So shortly after power on, comparator 1 has turned the output of the NE555 on and capacitor C is charging. The various parts of the circuit have the inputs and outputs set to the values in the diagram above marked in red.

Capacitor Charge Reaches 1.67V

As time progresses, the charge on the capacitor will reach and then exceed 1.67V. The circuit will look like the following:

Capacitor continues to charge

Capacitor continues to charge

At this point a change will occur to comparator 1. The negative input voltage (from the trigger pin) will reach 1.67V. The voltage on the negative input to the comparator will no longer be greater than 1.67V and so the output of the comparator will change from high (on) to low (off). The low signal applied to the set input of the S-R latch will have no effect on the S-R latch (both set and reset inputs to the S-R latch are now low and so the previous state is remembered).

At this point there is no change to the output of the circuit, the output is still latched on and charge continues to build up on the capacitor.

Capacitor Charge Reaches 3.33V

Eventually the charge on the capacitor will reach and exceed 3.33V. This will change the circuit to the following state:

Capacitor starts to discharge

Capacitor starts to discharge

There will be no change to the output of comparator 1 as the voltage applied to the negative input of the comparator remains greater than 1.67V just as it was in the above stage.

The main change is triggered by comparator 2. The charge on the capacitor is applied to the positive input to the comparator which is now greater than or equal to the 3.33V (from the resistor ladder) applied to the negative input. This causes the comparator to set the output high.

A high output on comparator 2 is applied to the reset input of the S-R latch. This turns the set output (Q) of the latch off and the inverted output (Q) on.

Two things happen when Q is turned on:

  1. The output of the NE555 is turned off
  2. The transistor connected to the discharge pin is turned on

Turning the transistor on changes the flow of current through the circuit. So far current has been flowing through the two resistors, R1 and R2 to charge the capacitor, C. Now the current starts to flow from Vcc to ground through R1.

Current will now also start to flow from the capacitor, through R2 and the transistor to ground. At some point the charge on the capacitor will drop below 3.33V. This will be reflected on the threshold pin connected to comparator 2 and the output of this comparator will be turned off:

Middle of Capacitor Discharging

Middle of Capacitor Discharging

The output of the S-R latch will continue to hold the last state until and hence the output remains off until a signal is applied to the set pin of the S-R latch and so current continues to flow through the transistor.

Capacitor Charge Drops Below 1.67V

At some point the charge on the capacitor will drop below 1.67V and comparator 1 turns on and so Q is turned off once more. The circuit starts to behave as though the system has just been powered on with one slight difference, the charge on the capacitor C starts at 1.67V instead of 0V. The whole cycle of charging and discharging repeats continuously.

Circuit Output

Building the circuit on breadboard and then connecting up an oscilloscope to the discharge and output pin shows the following trace:

Oscilloscope Trace

Oscilloscope Trace

The output is shown in yellow and the discharge is shown in blue.

It is clear to see the charging and discharging of the capacitor coincides with the change in the output state of the NE555.

Timing Calculations

The timing calculations given in the data sheet for the NE555 are as follows.

Note that in the following calculations, resistance is expressed on Ohms, capacitance in Farads and time in seconds.

Charge Time

The charge time depends upon the capacitor and the two resistors R1 and R2 as current flows through the two resistors to charge the capacitor. The time taken to charge is given as:

tcharge = 0.693 * (R1 + R2) * C

Discharge Time

The discharge time is only dependent upon the capacitor and R2 as current does not flow through R1 when the circuit is discharging. the time take to discharge is given as:

tdischarge = 0.693 * R2 * C


The period is the sum of the two timings tcharge and tdischarge. This can be expressed as:

Period = = 0.693 * (R1 + (2 * R2)) * C

The duty cycle and frequency are easily derived from the above.

And Finally…

The NE555 is a versatile chip that can act as more than a simple oscillator. The principles of the above circuit can be used in clock generation, switch debouncing, reset circuits and a whole range of other applications, several of which will be covered in following articles.

Dave Jones (EEVBlog) has put together the Three Fives Timer Kit and has videoed the build process and also provided a run down of the theory of operation referring to the kit schematic. Key times in the video are:

  • 0 – 36 Minutes: Building the kit
  • 36 – 54 Minutes: Examination of the schematic and run through the theory of operation
  • 54 – 62 Minutes: Checking the voltages and output from the kit using an astable circuit

Netduino.Foundation – Device Drivers for Netduino

Saturday, February 10th, 2018
Netduino Foundation Banner

Netduino Foundation Banner

It has been a very busy few months both in and out of work as evidenced by the silence here. The last few months has seen a fair amount to time spent working with the Netduino boards developing documentation and libraries.

I was given a Nedtuino board in 2010 as a present and I have never looked back. The orignal Netduino Plus was upgraded to the Netduino Plus 2, the Netduino WiFi and numerous electronics projects have come about all due to that original present.

The attraction of the Netduino is the fact that you can work in C# with Visual Studio. Another big selling point is Visual Studio and the powerful debugging features available to the developer.

In summary, it’s a great prototyping and test environment. If I ever have a problem and want to test a theory quickly I always fall back to these boards.


One difficulty with Netduino was it was sometimes difficult to find drivers for sensors, displays etc. Support for devices relied upon community members having written a driver and making the source available. In fairness, many community members did just that.

Wilderness Labs have recently taken ownership of the Netduino brand and technology. A new approach has brought some innovations:

  • Support for Visual Studio for Mac
  • New community forum
  • Developer documentation for the Netduino
  • Electronics tutorials
  • Netduino.Foundtion collection of drivers and core functionality
  • Source code is available on GitHub
  • Nuget support

It is still possible to use the Netduino without using Netduino.Foundtion but the library makes a number of tasks easier and quicker.

As well as a number of core peripherals there is support for a library of drivers covering a variety of devices:

Device Description
74595 Shift Registers Everyones favourite output expander
DS323x Real time clock
Graphics Library General purpose graphics library
LCD MicroLiquidCrystal library for 16×2 and 20×4 LCD displays
Serial LCD Serial LCD backpack
SSD1306 OLED Display (128×32 and 128×64)
BME280 Temperature, pressure and humidity
HIH6130 Temperature and humidity
MPL115A2 Temperature and pressure
MPL3115A2 Temperature and pressue
SHT31D Temperature and humidity
SI7021 Temperature and humidity
TMP102 Temperature
ALS-PT19 Analog light sensor
TSL2561 Infra-red compensated light sensor
ADXL335 Triple axis accelerometer (+/- 3g)
ADXL345 Triple axis accelerometer (+/- 16g)
MAG3110 Triple axis magnetometer
PIR Motion detection
Servo Generic servo library
Analog Temperature Analog temperature sensors such as LM35/36/37 etc.

All of the drivers are supplied with source code, sample applications and comprehensive documentation.


It is great to see the Netduino with a new supporter. The new documentation and libraries make the platform easier to use.