Getting Started with .NET nanoFramework Development for ESP32-Pico Applications

This article is a beginner-friendly, step-by-step tutorial on .NET nanoFramework, providing basic introductory programs and introducing the fundamental knowledge of developing with .NET nanoFramework on the ESP32-S2-Pico.

1. Background

1.1 .NET IoT and .NET nanoFramework

.NET supports the development of Internet of Things (IoT) applications, offering .NET IoT libraries that allow us to run applications on IoT devices running Windows and Linux, utilizing GPIO, SPI, I2C, PWM, and serial ports to interface with hundreds of sensors, displays, and input devices. However, this does not apply to constrained embedded devices such as ESP32, M5Stack, STM32, etc. For these constrained embedded devices, .NET nanoFramework provides a great solution suitable for these microcontrollers, allowing managed code to be written for limited embedded devices. Developers can quickly write applications using familiar IDE Visual Studio and .NET (C#) knowledge without worrying about the low-level hardware complexities of the microcontroller. Moreover, using Visual Studio allows for writing, deploying, and debugging code directly on real hardware.

1.2 Microcontrollers

The benefits of using microcontrollers are evident, especially with prices around 20 to 50 yuan, making them very affordable for many applications, particularly those requiring mass production. Additionally, while being compact, microcontrollers offer strong programmability and extensibility, allowing their functions to be defined through programming. This makes microcontrollers applicable in many different fields and very convenient to modify when functionality needs to change.

Getting Started with .NET nanoFramework Development for ESP32-Pico Applications
Pico & ESP32

Note: The left three in the above image are Raspberry Pi Pico series, and the far right is ESP32-S2-Pico, with blue boards being products from Microchip.

1.3 Introduction to the Development Board

Support for the Raspberry Pi Pico series in .NET nanoFramework is planned, although there have been some unofficial attempts by enthusiasts, but the project seems to have stopped updating, so we will wait for official support. However, .NET nanoFramework does support ESP32, so I recently bought an ESP32 board to try some experiments.

The ESP32-S2-Pico is compact, has a rich set of peripheral interfaces, integrates a low-power Wi-Fi system-on-chip (SoC) and large memory, and supports the development board ecosystem of Raspberry Pi Pico expansion boards. It features hardware encryption accelerators, RNG, HMAC, and digital signature modules, meeting IoT security requirements. Additionally, it has various low-power operating modes to meet the power consumption needs in applications such as IoT, mobile devices, wearable electronics, and smart homes.

2. Setting Up the .NET nanoFramework Development Environment

To set up the .NET nanoFramework development environment, you first need to install Visual Studio 2022 (also supports VS 2019), and then install the extensions and tools. Additionally, the SDK must have .NET 6.0 runtime (or .NET 6.0 SDK) installed.

2.1 Installing Extensions

Open Visual Studio, open/create any project or directly select “Continue without code” to enter the main interface. Open the “Manage Extensions” dialog by selecting the menu “Extensions” > “Manage Extensions”. Select the “Online” category on the left, then enter “nano” in the search box.

Getting Started with .NET nanoFramework Development for ESP32-Pico Applications
Installing Extensions

Select “.NET nanoFramework Extension” to download and install, the system will prompt you to restart Visual Studio to complete the installation of the extension, at this point, just close Visual Studio to continue the operation.

Getting Started with .NET nanoFramework Development for ESP32-Pico Applications
Confirm Installation

2.2 Installing the Tool Library

Next, we need to install the .NET nanoFramework firmware tool library, which will be used later. This is a .NET Core Tool that can flash firmware (nanoBooter and nanoCLR) to .NET nanoFramework targets, deploy applications (all assemblies required to run .NET applications), and restore previously saved deployment images. For more information about this toolbox, you can visit the official repository: https://github.com/nanoframework/nanoFirmwareFlasher/blob/main/README.zh-cn.md

Open the console and use the following .NET Core CLI command to install the .NET nanoFramework Firmware flash tool:

dotnet tool install -g nanoff

After successful installation, it will display the invocation instructions and the version of the installed tool.

Getting Started with .NET nanoFramework Development for ESP32-Pico Applications
nanoff

3. Installing Firmware

In this section, we need to flash the .NET nanoFramework firmware onto the circuit board.

3.1 Device Connection

First, we need to enter the download mode of the ESP32. Different boards have different methods; here we can refer to the instruction manual of the purchased product. For the ESP32-S2-Pico to download the update, you need to press and hold the BOOT button, then press the RESET button and release or disconnect USB while holding the BOOT button to power on. At this point, the ESP32-S2’s UART0 (GPIO43, GPIO44) and USB can burn the program.

Getting Started with .NET nanoFramework Development for ESP32-Pico Applications
Connecting Device

Here I connect the BOOT button while connecting to the USB port of the computer; at this point, we can see the newly inserted USB serial device in the device manager.

Getting Started with .NET nanoFramework Development for ESP32-Pico Applications
COM

If there are multiple existing COM devices on the computer, remember to note the changes after connecting the device; you need to remember the COM port number, which will be used later.

Of course, you can also use the previously installed nanoff to list available serial ports with the following command:

nanoff --listports
Getting Started with .NET nanoFramework Development for ESP32-Pico Applications
nanoff listports

Here we can see that the newly connected ESP32-S2-Pico’s serial port is COM5.

3.2 Flashing Firmware

When flashing firmware, we need to provide the correct target name to execute the firmware flash; otherwise, the board may not work. In terms of platforms, .NET nanoFramework supports esp32, stm32, cc13x2, gg11, and you need to specify the target when flashing firmware. Although different boards use ESP32, there may be some differences in their designs. The construction list for ESP32 boards can be viewed here: https://github.com/nanoframework/nf-interpreter#esp32-modules-and-boards.

For this board, if we use the official introductory tutorial, you will encounter the following error:

For ESP32-S2 series nanoff isn't able to make an educated guess on the best target to use. Please provide a valid target name using this option '--target MY_ESP32_S2_TARGET' instead of '--platform esp32'. Error E9000: Invalid or missing arguments.
Getting Started with .NET nanoFramework Development for ESP32-Pico Applications
Error E9000

It’s not surprising to get an error, as this board is not on the official list, and it is normal to not be able to guess. Although it is designed to belong to the Pico series, using ESP32_PICO is invalid, and the device cannot start after flashing. We can directly use the following command to flash the same ESP32-S2 series FEATHER_S2, updating the firmware of the ESP32 board connected to COM5 to the latest available version:

nanoff --target FEATHER_S2 --serialport COM5 --update

Wait about 30 seconds for the flashing to succeed.

Getting Started with .NET nanoFramework Development for ESP32-Pico Applications
Flashing Successful

By the way, before flashing, the basic information of the board is printed. If you want to directly view board information, you can use the following command:

nanoff --platform esp32 --serialport COM5 --devicedetails
Getting Started with .NET nanoFramework Development for ESP32-Pico Applications
Device Details

3.3 Device Firmware Check

After the firmware flashing is complete, the device is still in firmware refresh status. We need to press the RESET button to restore the device to normal status or simply unplug and replug the USB. At this point, if the computer does not respond, check if the flashing failed.

After a successful refresh, we can see the device in the device manager of Visual Studio. The Device Explorer can be opened by going to “View” > “Other Windows” > “Device Explore”.

Getting Started with .NET nanoFramework Development for ESP32-Pico Applications
Device Explore

3.4 Flashing a Specific Version

Sometimes the latest firmware may have compatibility or other issues, and we need to install another stable version. Using the following command, we can list all stable versions:

nanoff --listboards --platform esp32

If you want to flash a specific version like FEATHER_S2 1.8.0.741, you can use the following command:

nanoff --target FEATHER_S2 --fwversion 1.8.0.741 --serialport COM5 --update

3.5 Assembly Version Alignment

The reason for introducing the installation of specific versions is that the NuGet packages referenced between different versions need to be consistent with the flashed fixed. If they are inconsistent, the following error will occur:

Couldn't find a valid assembly required by mscorlib...

At this point, we need to adjust the version of the installed NuGet packages to match the requirements of the flashed fixed. In the device manager, click on “Device Capabilities” to view the assembly version and verification information:

Getting Started with .NET nanoFramework Development for ESP32-Pico Applications
Device Capabilities

As shown in the figure, a red inconsistent package information has been marked. According to the introduction of the component package, it can be changed to be consistent.

Getting Started with .NET nanoFramework Development for ESP32-Pico Applications
Package Information

4. Writing Programs

Now that we have made the necessary preparations, we can start the enjoyable coding time. One point to note is: when creating a .NET nanoFramework project, do not apply any dropdown filtering restrictions, you can search for “nano” to see the project templates. If an error occurs when creating the project for the first time, it can be ignored, just close the window and open the generated sln in the folder.

Getting Started with .NET nanoFramework Development for ESP32-Pico Applications
Creating Project

4.1 Writing a “Hello World” Application

When creating a .NET nanoFramework project for the first time, the template will be at the top since it is new; directly select the “Blank Application” template to create the project.

Getting Started with .NET nanoFramework Development for ESP32-Pico Applications
Creating Project

This template is a simple Hello World application. If an error occurs in the project, you may need to manually install the missing NuGet packages by searching for “nano” in the package manager and installing the core package “nanoFramework.CoreLibrary”.

Getting Started with .NET nanoFramework Development for ESP32-Pico Applications
Installing NuGet Package

After installing the missing NuGet packages, you can click run, and remember to select the device you want to run in “Device Explore”. The following is the information after successful execution:

Getting Started with .NET nanoFramework Development for ESP32-Pico Applications
Running Status

The current code only prints Hello World in the debug information, but this seems to have nothing to do with the board. Next, we will use its serial port to output Hello World information.

4.2 Serial Port Output “Hello World”

Using the serial port, we only need to slightly modify the code. Here we need to install the nanoFramework.System.IO.Ports package via NuGet:

static SerialPort _serialDevice;
public static void Main(){
    Debug.WriteLine("Hello from nanoFramework!");
    // Get available serial ports
    var ports = SerialPort.GetPortNames();
    Debug.WriteLine("Available ports: ");
    foreach (string port in ports)    {
        Debug.WriteLine($" {port}");
    }
    _serialDevice = new SerialPort("COM1");
    // Set parameters
    _serialDevice.BaudRate = 9600;
    _serialDevice.Parity = Parity.None;
    _serialDevice.StopBits = StopBits.One;
    _serialDevice.Handshake = Handshake.None;
    _serialDevice.DataBits = 8;
    // Set buffer size
    _serialDevice.ReadBufferSize = 2048;
    // Open the serial port with the above settings
    _serialDevice.Open();
    _serialDevice.WriteTimeout = 500;
    for (; ; )    {
        _serialDevice.WriteLine(DateTime.UtcNow + " hello from nanoFramework!");
        Thread.Sleep(2000);
    }
}

Compile and deploy the above code to the ESP32 board, and click the RESET button to start the program. At this point, we can connect to the serial port to see the printed Hello World information.

Getting Started with .NET nanoFramework Development for ESP32-Pico Applications
Serial Port Output

4.3 Serial Port Connection

This section mainly introduces how to connect the serial port of the ESP32 device. In the previous section, we printed the serial port situation before outputting information. Based on the printed information, we can see that SerialPort.GetPortNames() shows two available serial ports: COM1 and COM2. Here we use COM1, and the hardware interface shows that UART0’s TX and RX are GP43 and GP44, respectively.

Getting Started with .NET nanoFramework Development for ESP32-Pico Applications
ESP32-S2-Pico Hardware Interface

Here, we use a USB to TTL device for wiring, connecting TX to GP44, RX to GP43, and GND to any GND pin of the ESP32, such as physical pin 3. Remember to set the voltage of the USB to TTL shorting cap to 3V3.

Getting Started with .NET nanoFramework Development for ESP32-Pico Applications
USB to TTL

After connecting these three wires to the serial port, you can use serial port tools (such as MobaXterm) to open the serial port and view the information printed by the ESP32.

Note: Serial port baud rate is 9600, and others are default. You can refer to the following figure:

Getting Started with .NET nanoFramework Development for ESP32-Pico Applications
MobaXterm

5. Conclusion

Overall, the development experience of .NET nanoFramework is very friendly to those familiar with .NET. It provides a familiar development environment that allows you to develop using Visual Studio and C#. In addition, .NET nanoFramework supports the same language features and APIs as .NET Framework, so you can easily migrate code to .NET nanoFramework.

In the future, I will continue to study .NET nanoFramework-related topics, and interested readers can follow along. Thank you!

Leave a Comment