Introduction
NuttX is a highly versatile and configurable real-time operating system (RTOS) that stands out for its emphasis on standards compliance and a minimal footprint. Designed to be scalable across a wide range of microcontroller environments, NuttX supports everything from 8-bit to 64-bit architectures. This flexibility makes it an excellent choice for a diverse array of embedded systems, including those based on the ESP32 microcontroller.
One of the key strengths of NuttX is its commitment to adhering to industrial standards, specifically POSIX (Portable Operating System Interface) and ANSI (American National Standards Institute). This adherence ensures a familiar and standardized development environment for programmers, making NuttX a robust choice for embedded system projects.
In this post we will see a brief introduction to the environment and how to send data through Serial1 port.
Requirements
Installing the environment
Start by installing some packages:
sudo apt install automake bison build-essential flex gperf git libncurses5-dev libtool libusb-dev pkg-config
And create a directory where all files will stay:
mkdir nuttxspace && cd nuttxspace
While inside the directory, clone this two Git repositories:
git clone https://github.com/apache/incubator-nuttx.git nuttx
git clone https://github.com/apache/incubator-nuttx-apps.git apps
After that, use this command:
sudo apt install kconfig-frontends
Next, download this TAR file and extract its contents:
curl https://dl.espressif.com/dl/xtensa-esp32-elf-gcc8_2_0-esp-2020r2-linux-amd64.tar.gz | tar -xz
Now create a folder under /opt and move the contents of the TAR there, like so:
sudo mkdir /opt/xtensa
sudo mv xtensa-esp32-elf /opt/xtensa
Modify the PATH variable to add the path we created:
export PATH=$PATH:/opt/xtensa-esp32-elf/bin
You can also add it inside your shell configuration to make the PATH changes permanent.
Install the esptool package using pip3:
pip3 install esptool
Then, create another folder named esp-bins and download the following binaries there:
mkdir esp-bins
curl -L "https://github.com/espressif/esp-nuttx-bootloader/releases/download/latest/bootloader-esp32.bin" -o esp-bins/bootloader-esp32.bin
curl -L "https://github.com/espressif/esp-nuttx-bootloader/releases/download/latest/partition-table-esp32.bin" -o esp-bins/partition-table-esp32.bin
Finally, compile the shell and inject the code to the ESP32 PLC. You will need to be part of the dialout group:
cd nuttx
./tools/configure.sh esp32-devkitc:nsh
make
make download ESPTOOL_PORT=/dev/ttyUSB0 ESPTOOL_BAUD=115200 ESPTOOl_BINDIR=../esp-bins
picocom -b 115200 /dev/ttyUSB0
Now reset the PLC, and you should see a prompt like nsh> , you have successfully configured your Nuttx environment on an ESP32 PLC! To exit picocom, use Ctrl-A + Ctrl-X.
Configuring the RTOS
The next steps enable the serialblaster example and properly configures it.
- Enabling the example:
cd nuttxspace/nuttx
make distclean
./tools/configure.sh esp32-devkitc:nsh
make menuconfig
Using the up and down arrows of the keyboard, navigate to "Application Configuration", then "Examples" and select "Serial Blaster example" using y. Make sure to change the "Serial device path" to /dev/ttyS1, and finally exit the menu via "Exit" and save the configuration.
- "Serial Driver support": Make sure the Serial Driver support is enabled.
From the start of make menuconfig command, head to "Device Drivers" and select (using y) "Serial Device Driver Support".
- Enable serial port /dev/ttyS1:
Again in make menuconfig, go to "System Type", then "ESP32 Peripheral Selection" and enable "UART 1". Exit to "System Type" again, then go to "UART Configuration" and change pins of UART1 Tx to 17 and Rx to 16. Exit and save.
After this steps, by performing again:
cd nuttx
./tools/configure.sh esp32-devkitc:nsh
make
make download ESPTOOL_PORT=/dev/ttyUSB0 ESPTOOL_BAUD=115200 ESPTOOL_BINDIR=../esp-bins
picocom -b 115200 /dev/ttyUSB0
You should be able to see the serialblaster example by typing "?" in the prompt
Arduino IDE program
The serialblaster example sends through Serial1 (pins 16 and 17) the string "abcdefghijklmnopqrstuvwxyz" (check the file serialblaster_main.c located inside apps/examples/serialblaster. To be able to read the string itself, we will build a program for another Industrial Shields PLC. This second PLC can be Arduino or ESP32 based, as it does not matter.
As we will only be writing to the serial port whatever we receive from Serial1, use the following code:
void setup() {
// Begin serial port
Serial.begin(115200);
// Begin Serial1 port
Serial1.begin(115200);
}
void loop() {
if (Serial1.available()) {
byte tx = Serial1.read();
Serial.write(tx);
}
}
Connections
The connections will be very simple. Following the serigraphy on the PLCs, connect ESP32 PLC's Serial1 Tx to the second PLC's Serial1 Rx and ESP32 PLC's Serial1 Rx to the second PLC's Serial1 Tx.
In addition, make sure that switch number 3 from the ESP32 based PLC is ON. Also, make the proper configuration to the other PLC.
For more information, check the User Guides.
Final test
After all the previous preparations, it's time to test the example. While inside picocom, type serialblaster. After 1-2 seconds, you should see the alphabet transmitted to the second PLC!
Conclusions
In this post we have seen how to work with Apache Nuttx, and to interact with serial communications, such as Serial1 from the ESP32 PLC. Now it's your time to explore the depths of Nuttx RTOS and build your own application there, taking advantage of the I/Os that the PLC offers and more!
First Steps with Apache Nuttx RTOS and ESP32 PLC