
Create an IoT project with freertos on c++, and master real-time operating systems. Learn wifi connectivity, read and filter sensor data, and build a Python-based IoT backend and client interface.
Gather an ESP32 dev kit with a compatible variant and soldered headers, plus a capacitive soil moisture sensor, USB cable, jumper cables, a computer, and LAN access.
Explore the IoT full project using an ESP32 devkit, wiring a soil sensor, sending readings over wifi to a backend for storage, and displaying the latest reading on a client.
assemble the ESP32 dev kit, moisture sensor, USB cable, and jumpers, wiring VCC to 3.3V, GND to ground, and sensor’s analog output to pin 35, while keeping sensor dry.
Install Visual Studio Code on Ubuntu and set up the ESP IDF extension. Create the project folder, use a hello world template, and build, flash, and monitor the ESP32 output.
Install and configure Visual Studio Code on Windows, install the ESP IDF extension, set up drivers and Python, then create, build, flash a hello world ESP32 project and monitor output.
Explore embedded software and IoT software concepts, compare no-OS and OS-based designs, and learn how FreeRTOS and the ESP-IDF framework enable scheduler-driven concurrency on ESP32.
Create a live code project in VS Code using the isp edf template. Rename main to cpp, bridge c++ with c for idf, and configure freertos and esp log output.
Customize app_main to log more information by initializing flash memory for logging and reporting the heap memory available using isp irt and isp log on ESP IDF.
Add a setup function that runs once at startup, returns an error on failure, logs startup details, and aligns with the Arduino pattern and ISP IDF framework.
Create moisture measurement task in FreeRTOS on ESP32, using app main to connect wifi, publish data to local server, and deep sleep; explore xTaskCreate and static vs dynamic task creation.
Understand the monster tracker flow on the ESP32. Initialize ADC, measure moisture, and post via Wi-Fi before entering deep sleep for long battery life.
Modularize the moisture tracker project by defining four components—tasks, moisture sensor, WiFi handle, and live config—each with a clear interface and specialized responsibilities.
Create a new components module, register it with IDF, and add moisture tracker.cpp with headers. Outline the moisture tracker task that connects to wifi, reads moisture, and enters deep sleep.
Create the moisture tracker header in the include directory, define header guards and public interfaces, document the moisture tracker task function, and specify parameters in microseconds for the IoT project.
Add the moisture tracker task to the main ESP IDF project, configure a requires line, include the moisture tracker header, create the FreeRTOS task with xTaskCreate, and implement error handling.
Learn to add a leaf config component with header interfaces, set up cmake and include structure, and initialize wifi credentials and plant info through modularity in an IoT project.
Develop the leaf config module by creating header and cpp files, loading wifi credentials, and copying strings with reinterpret cast and string copy to plant name and wifi fields.
Apply the leaf_config component in main.cpp to initialize wifi credentials and live config, resolve extern and type casting issues, and ensure credentials isolation in an IoT project.
Create a wifi handler component for an esp32 project using freeRTOS event loops and event groups to manage wifi and ip events, enabling robust WAN connectivity.
Implement an ip event handler that listens for got ip events, retrieves ip info with netif, logs the address, and signals the got ip event via an event group.
Add an http event handler to process backend responses using a static output buffer, handling header, data, and finish events with memory management and logging.
Implement a start wifi connection routine that initializes the http client with a persistent post url and server url, and registers the http event handler.
Add a stop wifi function in the wifi handler, implement robust error handling with logs, and reinitialize wifi after stopping to ensure continued operation.
Add a function to post a moisture reading by building a JSON payload from the moisture value and sending it via HTTP to the backend.
Integrate the wifi handler into the moisture tracker task by importing leaf config, configuring http client and json formatting, and posting moisture readings over wifi.
Fix and validate the ESP32 WiFi connection by reviewing the WiFi handler and moisture tracker integration, correcting compile errors, and setting a local server URL for posting moisture readings.
Develop the moisture sensor component with a header and implementation, using adc readings, a reading buffer, calibration, and robust mean calculations for reliable moisture readings.
Implement the adc calibration function, initialize a calibration scheme, use board-saved values to correct raw adc measurements, and apply a robust mean filter to moisture sensor readings.
Implement the private populate_readings_buffer function (step 22) to populate a global readings buffer by reading raw ADC moisture values, calibrating them, and storing calibrated readings in a std::vector.
Compute a robust moisture reading using a ten-sample readings buffer and a median-based robust min, verified by buffer validation, sorting with std::sort, and clearing after calculation.
Implement the get moisture rating function to read moisture robust mean, round to int, update readings buffer, and include ESP IDF ADC in cmakelists.txt for the moisture tracker task.
Learn to integrate the moisture sensor into the moisture tracker task by initializing the sensor, obtaining moisture readings, and posting readings, with project setup in the CMake lists.
Fix typos and add calibration, logging, and the moisture tracker tag to enable the ESP32 moisture sensor to connect to wifi, read values, and post to a backend.
Set up a backend to receive esp32 measurements and store them in a database, runnable on a Raspberry Pi or your machine, using a venv and Flask.
Define the backend environment with env_variables, setting the database path, host, and port. Build the plants api with hello, submit reading, and get readings by plant name routes, with swagger.
Create a database tools folder and initialize a sqlite3 database for plant readings, defining a plants readings table with id, plant_name, moisture, and server_timestamp default current_timestamp.
Create the say hello route by adding a routes package with __init__.py and say_hello.py, using flask and flask-restx to define a namespace, resource class, and get method with swagger.
Create and run a run debug mode.py script to test the say hello route on a Flask backend, with optional unicorn deployment, verify routes with swagger, and understand localhost:5000 behavior.
Add the get readings by plant name route, using Flask-RESTX and sqlite3 to return moisture and server timestamp readings for a given plant, with an optional count parameter.
Test the ESP32 with the backend by configuring the server URL and the get readings by plant name route, then verify moisture readings with Swagger.
In this hands-on course, you’ll deepen your knowledge of C, C++, and Python while learning how to build a complete IoT system from the ground up.
By the end of this course, you’ll have created a fully functional IoT plant moisture tracker, capable of monitoring your plants’ health, sending real-time data to your backend, and displaying the information on your client interface.
What You’ll Learn
The course is divided into three key parts:
Part 1:
We’ll start by using C and C++ with the ESP-IDF framework to program the ESP-32 microcontroller. You’ll learn how to write efficient code to measure soil moisture and transmit the data wirelessly (WiFi).
Part 2:
Next, we’ll build the backend using Python and Flask. This server will process and store incoming data from the IoT device, acting as the backbone of the system.
Part 3:
Finally, we’ll design an intuitive client interface using Python and Kivy, where you can view moisture readings retrieved from the backend in real time.
Who Should Take This Course?
This course is designed for individuals with a basic understanding of C, C++, and Python, who are eager to:
Advance their programming skills to an intermediate level.
Learn core concepts of IoT development through hands-on projects.
Explore frameworks like ESP-IDF, Flask, and Kivy while working with microcontrollers and backend systems.
To complete this course, you will need to purchase the following materials using your own means (you can get a PDF file from the Lecture 2 => Resources with example purchase links, you are not required to buy the course in order to download this file), the total cost of the kit should be around 30 EUR / USD.
1. ESP32 DEVKIT-V1 BOARD
2. USB-A to Micro-USB cable
3. Capacitive Soil Moisture Sensor V1.2
4. Male to Female Jumper cables