4673

The article describes the implementation of the ESP32 microcontroller in the Water Level Monitor project, while it is programmed in the ESP-IDF framework environment. The task blocking mechanism - Queue, which is used for conditional task execution and secure data transfer, is also described.

ESP32 microcontroller can be programmed in various development environments. Arduino IDE is one of the most popular mainly due to the easy program implementation in Wiring language even for beginners. However, there is also a framework for the development of IoT applications - ESP-IDF directly from the production of Espressif Systems, which manufactures these microcontrollers. It allows closer access to the physical layer of the microcontroller, has various development tools via Python scripts and implemented tools for running the system functionalities of the microcontroller.

Framework contains various sample implementations of bus service projects, communications that use FreeRTOS - a real-time operating system that greatly simplifies project development by allowing you to run subroutines as processes that are associated with the kernel that handles it. Each process is assigned its own memory (stack), which it can use. The advantage compared to programming in the Arduino IDE is the fact that the kernel can handle several functions at the same time, so in standard programming, for example, when using the delay() function, the entire program running in the loop() task is stopped.

In this case, only the process stops for a given time, while other processes can continue to operate. Each task has an assigned stack, priority with the option to select the ESP32 kernel on which the task will be performed. Tasks related to WiFi transmission, Bluetooth connectivity can be run at the request of the user on the core of the protocol, where the WiFi / BT stack is also serviced. Standard sub-programs for measurement should be run on the second so-called Xtens processor core.

I used FreeRTOS for the last year to create a demonstration application of a sensor node on ESP32 in my diploma thesis. I decided to create a sample implementation in the Water Level Monitor project, which uses ESP32, but the program was created only in the Arduino IDE. When creating the application, I focused and set myself the goal of creating a total of 2 tasks, using inter-task communication using the queue - Queue. The queue uses a FIFO buffer, i. the first item added to the queue is read by the second task read first (First in, First out).

After an item is successfully taken from the queue, this item is deleted from the buffer. There are also advanced features for Queue handling that can select an item without deleting it from the buffer. In addition to the functions for inserting / removing an item from / into the buffer, there is also an extension with ISR, which allows their use in interrupt routines (their service is guaranteed). When writing to the queue, it is possible to write to its beginning or end. In this sample implementation, it doesn't matter because the task is performed immediately and the measurement is performed after 5 minutes, so there is never more than 1 item in the buffer.

Using a queue allows one of the tasks to wait to receive a value sent to it by another task. In my case, one task will operate the ultrasonic distance sensor and perform measurements, and the other task will wait in a cycle for the value from the measurement, which it will then send to the server, using the HTTP POST method. In practice, Queues are also used to lock access to the bus, a peripheral that can only be used in real time by an active Queue, other tasks are in "blocking" mode, as they are waiting for a value from the active Queue.

When creating the program, I first created a test "offline" program, which allows only reading the measured value from ultrasonic sensors HC-SR04, or waterproof version JSN-SR04T and write it to the UART monitor. I found the sensor library on the Githube. The second step was the implementation of the HTTP request, which is available in ESP-IDF as a demonstration project. The program implementation was only available for the static path and GET method, which is not suitable for data transfer. For this reason, I had to change the existing HTTP request header, add encoding the data transmitted by the POST method.

Combination of both projects was simple, as they both used FreeRTOS, so the function was run via this scheduler. So all you had to do was copy the functions and one line of initialization of the task to the .c program. The first test program involved sending data to a web server every 5 minutes and measuring the data every 5 seconds, while the data was written in a global variable - data. the uint32 type to which both tasks had access. The task for the HTTP request also included the initialization of the WiFi adapter together with the possibility of configuring the SSID and password via Menuconfig.

Menuconfig is called in the project directory via the CLI (command line), where the framework is operated. In the menu, it is also possible to select the method of communication in the connectivity section - by default via WiFi or via the Ethernet PHY module. In this case, Ethernet is also controlled via WiFi controller. The supported Ethernet modules are connected via the RMII interface.

The listing on the UART interface is implemented via standard C functions, e.g. printf(). However, the ESP-IDF framework also allows the use of a tagging and logging system. By tagging it is possible to mark a specific statement with the task name and via logging it is possible to assign the output text also a priority in the form of color (sample tagging http_request and ultrasonic_measurement on UART output below). Information statements (LOGI) are listed in green, warnings (LOGW) in yellow, errors (LOGE) in red. The standard output via the printf() function is neutral - orange without priority.

After connecting to the WiFi network, ESP32 obtains an IPv6 link-local address in addition to IPv4. Subsequently, I implemented a simple Queue according to the pattern for Inter-task communication: https://icircuit.net/esp32-inter-task-communication-using-freertos-queues/1946 In this case, the producer task was a measurement task and the consumer task was a sending task, which was started only after receiving data from the FIFO buffer.

The HTTP request task thus did not use vTaskDelay, but the xQueueReceive function, which performs blocking of the task after receiving data from the Queue. One of the parameters is the time interval for which the waiting loop is active. A maximum of 32-bit values ​​can be selected, which can be obtained by the variable portMAX_DELAY, which corresponds to a range of about 50 days. As soon as the data is received, an HTTP request is executed. The measurement task repeats the measurement with averaging (10 averaged values) every 300 seconds.

Try the Water Level Monitor project: http://arduino.clanweb.eu/studna_s_prekladom/?lang=en with your hardware for implementation in the Arduino IDE environment, or ESP-IDF for the ESP32 microcontroller. To compile the firmware in the ESP-IDF framework, it is also necessary to download the project folder in the project repository. The implementation was tested in ESP-IDF version 4.2, it is also compatible with 4.0. Higher versions of ESP-IDF have not been tested. Implementations are also available on the Githube in the project repository: https://github.com/martinius96/hladinomer-studna-scripty/en/