Writing boilerplate code for different MCUs and operating systems is often a tedious, repetitive task that drains developer productivity. Each platform demands its own initialization routines, peripheral drivers, and OS-specific abstractions, forcing engineers to reinvent the wheel before they can even begin solving the real problem. This fragmentation slows down innovation and makes starting a new project unnecessarily complex. A unified framework that abstracts away these differences can dramatically simplify development, allowing engineers to focus on application logic instead of low-level setup. By standardizing common components and offering cross-platform APIs, such a framework empowers developers to spin up new projects quickly, reduces onboarding friction, and accelerates time-to-market.
Leveraging the arduprof-template brings significant benefits to embedded developers by unifying support across multiple platforms. Instead of juggling separate boilerplate setups for Arduino FreeRTOS on ESP32, Arduino Mbed/FreeRTOS on Raspberry Pi Pico/Pico2, and Zephyr on nRF52840, developers can rely on a single, consistent project structure. This reduces friction when switching between MCUs and operating systems, accelerates prototyping, and ensures portability of application logic. By abstracting away repetitive initialization and OS-specific details, the template allows engineers to focus on building features rather than reworking infrastructure. Ultimately, it streamlines cross-platform development, shortens project startup time, and fosters cleaner, more maintainable codebases.
Supported Hardware (ESP32, ESP32-S3, ESP32C3, Pi Pico/Pico2)The following boards are supported by this project:
- ESP32-DevKitC V1
- ESP32-S3-DevKitC-1 v1.1
- ESP32C3-CORE
- XIAO ESP32C3
- Raspberry Pi Pico
- W5100S-EVB-Pico
- WizFi360-EVB-Pico
- Raspberry Pi Pico2
- Noridic nRF52840 DK
- ProMicro nRF52840
- Install Arduino IDE 2.3.7+ for Arduino
- Install Arduino-ESP32
- Install Arduino DebugLog
- Install ArduinoJson v7+
- Install ArduProf v2.3.1+
- Install Arduino IDE 2.3.7+ for Arduino
- Install Arduino Mbed OS RP2040 Boards 4.0.6+
- Install Arduino Pico 5.4.1+
- Install Arduino DebugLog
- Install ArduinoJson v7+
- Install ArduProf v2.3.1+
- Install nRF Connect Toolchain and SDK v3.3.0+
- Install ArduProf v2.3.1+
- clone this repo by "git clone https://github.com/teamprof/arduprof-template.gif"
- Launch Arduino IDE
- Open "arduino-app.ino" under "arduino-app" folder
- On Arduino IDE, click menu "Tools" -> "Board: " -> "Board Manager..." -> "Raspberry Pi Pico - Raspberry Pi Pico/RP2040/RP2350" or "Raspberry Pi Pico 2"
- On Arduino IDE, click menu "Tools" -> "Debug Port" -> "Serial"
- On Arduino IDE, click menu "Tools" -> "CPU Speed" -> "133 MHz" or "150 MHz" for Pi Pico2
- On Arduino IDE, click menu "Tools" -> "Operation System" -> "FreeRTOS SMP"
- Build the code by clicking Menu -> “Sketch” -> “Compile/Verify”If everything goes smoothly, you should see the following screen.
- On Arduino IDE, click Menu -> “Sketch” -> “Upload”If everything goes smoothly, you should see the following screen.
- On Arduino IDE, open Serial monitor and then reset the boardIf everything goes smoothly, you should see the following screen.
- Open "arduino-app.ino" under "arduino-app" folder under Arduino IDE
- On Arduino IDE, click menu "Tools" -> "Board: " -> "Board Manager..." -> "Raspberry Pi Pico - Arduino Mbed OS RP2040 Boards"
- On Arduino IDE, click menu "Tools" -> "Debug Port" -> "Serial"
- On Arduino IDE, click menu "Tools" -> "CPU Speed" -> "133 MHz"
- On Arduino IDE, click menu "Tools" -> "Operation System" -> "Mbed OS"
- Build the code by clicking Menu -> “Sketch” -> “Compile/Verify”If everything goes smoothly, you should see the following screen.
Note that uploading the Pi Pico Mbed firmware through the IDE may be challenging. A more robust approach is to drag the generated.uf2 file directly onto the Pi Pico board.
Run firmware- On Arduino IDE, open Serial monitor and then reset the boardIf everything goes smoothly, you should see the following screen.
- Open "arduino-app.ino" under "arduino-app" folder under Arduino IDE
- On Arduino IDE, click menu "Tools" -> "Board: " -> "Board Manager..." ->"RAKwirelss RAK3112" or"ESP32S3 Dev Module" or"XIAO_ESP32C3" or"ESP32C3 Dev Module" or"DOIT ESP32 DEVKIT V1" or"ESP32 Dev Module"
- On Arduino IDE, click menu "Tools" -> "USB CDC On Boot:" -> "Enable"
- Build the code by clicking Menu -> “Sketch” -> “Compile/Verify”If everything goes smoothly, you should see the following screen.
- - On Arduino IDE, click Menu -> “Sketch” -> “Upload”If everything goes smoothly, you should see the following screen.
- On Arduino IDE, open Serial monitor and then reset the boardIf everything goes smoothly, you should see the following screen.
Nordic nRF52840 (Zephyr)Build firmware
- clone this repo by "git clone https://github.com/teamprof/arduprof-
- template.gif"change to "nrf" folder and download submodule
cd nrf
git submodule update --init --recursive- Launch VS code, switch to nRF Connect panel, open existing application under "nrf" folder
- Add or edit build config, as below
- Click "Generate and Build"If everything goes smoothly, you should see the following screen.
- Add or edit build config, as below
- Click "Generate and Build"If everything goes smoothly, you should see the following screen.
Run firmwareNoridic nRF52840 DK
- Click "Debug" on nRF Connect panelIf everything goes smoothly, you should see the following screen
- Launch a serial terminal likes TeraTerm or minicom, set as 8N1 115200bpsIf everything goes smoothly, you should see the following screen if you use TeraTerm.
- Double click ProMicro nRF52840 Reset pin within 0.5s to enter Bootloder mode
- Copy the "zephyr.uf2" under ""folder to the drive of the board
- Launch a Serial Terminal software likes TeraTerm, set to 115200bps and 8N1If everything goes smoothly, you should see the following screen if you use TeraTerm.
In a typical Arduino setup(), both QueueMain and ThreadApp are initialized. QueueMain runs within the Arduino loop(), while ThreadApp executes in parallel. The purpose of QueueMain is to establish a communication channel between the Arduino loop() and other threads.
static void startTasks(void)
{
auto ctx = getAppContext();
if (ctx->queueMain)
{
static_cast<QueueMain *>(ctx->queueMain)->start(ctx);
}
if (ctx->threadApp)
{
ctx->threadApp->start(ctx);
}
}
void loop()
{
...
auto ctx = getAppContext();
auto qMain = static_cast<QueueMain *>(ctx->queueMain);
assert(qMain);
qMain->messageLoop(0); // non-blocking
// qMain->messageLoop(); // blocking until event received and proceed
// qMain->messageLoopForever(); // never return
// delay(1000); // delay 1s
delay(100); // delay 0.1s
}Add new thread(s)- Copy the files "ThreadApp.cpp" and "ThreadApp.h" and rename them, for example "ThreadGui"
- Edit "ThreadGui.h", modify the CLASSNAME macro as below:
#define CLASSNAME ThreadGui- Edit "AppContext.h", modify the AppContext struct as below:
typedef struct _AppContext
{
ardufreertos::MessageQueue *queueMain;
ardufreertos::ThreadBase *threadApp;
ardufreertos::ThreadBase *threadGui;
} AppContext;
typedef struct _AppContext
{
ardumbedos::MessageQueue *queueMain;
ardumbedos::ThreadBase *threadApp;
ardumbedos::ThreadBase *threadGui; // <= add code here
} AppContext;- Edit "AppContext.cpp", modify the AppContext code as below:
static AppContext appContext = {
.queueMain = &queueMain,
.threadApp = ThreadApp::getInstance(),
.threadGui = ThreadGui::getInstance(), // <= add code here
};- Edit "arduino-app.ino", modify the startTasks code as below:
static void startTasks(void)
{
auto ctx = getAppContext();
if (ctx->queueMain)
{
static_cast<QueueMain *>(ctx->queueMain)->start(ctx);
}
if (ctx->threadApp)
{
ctx->threadApp->start(ctx);
}
//////////////////////////////////////////////////////
// add code here
//////////////////////////////////////////////////////
if (ctx->threadGui)
{
ctx->threadGui->start(ctx);
}
}- The new ThreadGui is added. Build the updated code, upload the new firmware, the new thread should run in parellel with ThreadApp and QueueMain.
- Please refer to ArduProf about sending and handling messages between threads
- The project is licensed under GNU GENERAL PUBLIC LICENSE Version 3
- Copyright 2026 teamprof.net@gmail.com. All rights reserved.







Comments