0:14
Hello and welcome to Controllers Tech. In today’s session, we will continue
0:19
with the STM32 IoT series using the ESP8266 Wi-Fi transceiver module.
0:26
In the previous video, we learned how to connect the STM32 to the ESP8266 module,
0:33
how to configure the UART, and finally how to connect both the
0:37
module and the board to a Wi-Fi network. We will now continue from that point. In
0:43
this video, our focus will be on sending data to a cloud server, specifically using ThingSpeak.
0:51
For this demonstration, I will use the BME280 sensor to measure temperature, pressure,
0:56
and humidity. Once we capture these values, we will upload them to the ThingSpeak cloud.
1:04
If you haven’t watched the first part of this series, I strongly recommend watching it first,
1:09
because in this video I will assume that your STM32 is already connected to the internet.
1:16
Now, before we dive into coding and uploading data, let’s first set up a channel on ThingSpeak.
1:23
Start by opening the website: thingspeak.mathworks.com.
1:28
Click on the “Get Started for Free” button. If you don’t already have an account,
1:33
you’ll need to create one here. Since I already have an account, I will simply log in.
1:41
You can see that I already have one channel here, which I was using for testing purposes.
1:47
But let’s go ahead and create a new channel by clicking on “New Channel”.
1:52
Give your channel a meaningful name, for example: STM32 ESP8266.
2:00
Next, we need to enable the fields for this channel. Think of these
2:05
fields as columns in a table — this is where your sensor data will be stored.
2:10
Since I want to display three values — temperature, pressure, and humidity — I
2:15
will enable three fields. You can also rename each field to match the parameter it represents.
2:23
Leave the other settings at their default values, and then click Save Channel to create it.
2:29
Once the channel is created, you will immediately see three charts,
2:33
one for each of the fields we enabled. ThingSpeak also allows you to add widgets like
2:39
gauges, numeric displays, lamps, or even image displays, to make your dashboard more interactive.
2:48
For example, let’s add a Gauge widget. This gauge needs to be linked to one of
2:53
the fields we defined earlier, so I’ll connect it to the temperature field.
2:59
Here, you can adjust parameters like the minimum and maximum values, the measurement unit, and even
3:05
define a warning range using the red zone. By default, the update interval is set to
3:12
15 seconds, and that’s also the minimum allowed in the free version of ThingSpeak.
3:17
This means you cannot push new data more frequently than once every 15 seconds.
3:23
Now, you can see that our gauge is displaying correctly
3:27
according to the settings we just configured. You can also make your channel available for
3:32
public viewing by changing the sharing settings. Go to the Settings tab if you want to edit
3:39
channel information such as its name, description, or fields.
3:44
In the Sharing tab, you can either share the channel with specific email
3:48
addresses or simply make it public. Once shared, the charts and widgets
3:53
you created will also be visible publicly, as you can see here.
3:58
The next important step is the API Keys section. This is one of the
4:03
most critical parts of ThingSpeak. API keys allow you to either write
4:08
data to your channel or read data from it. For writing data, you will use the Write API Key.
4:16
The request includes the key itself, the field you want to update, and the value to be stored.
4:23
We’ll take a closer look at how this API request works in just a moment.
4:28
Before we begin writing the main project, let’s first test the AT
4:32
commands using a serial terminal. For this test, I have connected the
4:38
ESP8266 module directly to a USB-to-TTL converter, such as the FT232. The converter is then connected
4:47
to the computer through a USB cable. The wiring is simple: the TX pin of
4:52
the ESP module goes to the RX pin of the converter, and the RX pin of the
4:57
module connects to the TX pin of the converter. As we already established in the previous video,
5:04
the ESP8266 communicates at a baud rate of 115200. So, make sure you open the
5:12
serial terminal with the same baud rate. Also, remember to add a carriage return and
5:18
line feed at the end of each command you send. Now, let’s begin by sending a basic AT command.
5:27
The module responds with OK, which confirms that everything is working fine.
5:33
Next, let’s restart the module once. After restarting, the ESP8266
5:40
connects automatically to the Wi-Fi network that we configured earlier.
5:45
This happens because the module stores the Wi-Fi credentials in its flash memory,
5:49
so you don’t need to re-enter them every time. Now that the module is connected to the Wi-Fi,
5:56
we can move ahead and test a new set of commands. I have already prepared the commands we
6:02
will use for this demonstration. Let’s begin with the CIPSTART command.
6:08
This command allows us to create either a TCP or UDP connection to a remote server.
6:14
In this case, we will establish a TCP connection with api.thingspeak.com.
6:21
We will use Port 80, which is the standard port for HTTP requests. While this connection
6:28
is unsecured, it is much simpler and perfectly suitable for our project.
6:33
When we send this command, the ESP8266 responds with CONNECT followed by OK.
6:40
This response is very important because, in our actual code, we will rely on it to
6:46
confirm and automate the connection process. The next step is to send the CIPSEND command,
6:52
where we specify the number of bytes of data that will be transmitted in the following request.
6:58
Here, I am instructing the ESP8266 module that I will be sending 68 bytes
7:04
of data after this command. The module responds with a
7:08
greater-than symbol ( > ), which means it is ready to receive the 68 bytes.
7:13
Next, we send the Write Channel Feed command for ThingSpeak.
7:18
It is important to insert the Write API Key at the correct position in this command.
7:24
This command itself contains 66 characters, including the spaces. The remaining 2 characters
7:31
are the carriage return and line feed, which make the total length exactly 68 bytes.
7:37
Once the ESP module receives this data, it transmits it to the remote server — in
7:43
this case, the ThingSpeak server. The server, in turn, sends back a
7:49
response to the module. This incoming data is displayed on the console as IPD packets.
7:56
In this particular case, the server sent back just 1 byte of data, which is the number 1.
8:03
This number is very significant because it represents the Entry ID or Update ID. In
8:09
other words, it tells us how many updates have been made to the channel so far.
8:15
Finally, the TCP connection is closed, either by the ThingSpeak server or by the ESP8266 module
8:25
let’s go back and check the ThingSpeak channel. As you can see, all the fields have successfully
8:32
received the values we just transmitted. The Gauge widget is also showing
8:37
the temperature reading correctly. Let’s try sending another set of values.
8:44
Just like before, we need to start from the beginning and send all the commands again.
8:50
This time, I’ll set different values for all three fields.
8:55
Since I’m using two-digit values again, the length of the command remains the same.
9:01
After sending the command, we receive another success message from the server. This time,
9:08
the Entry ID is 2, which means the second update to the channel has been completed.
9:14
If we check the channel now, we can see the new set of data has been
9:18
successfully updated in all three fields. This demonstrates how we can send data
9:24
to the ThingSpeak server. The next step is to automate this entire process in our STM32 code.
9:32
Along with the ESP8266, I am also using the BME280 sensor with its library files.
9:40
I have already explained how the BME280 sensor works with STM32 in a separate video. If you
9:47
haven’t watched that yet, you can check it out from the link in the top-right corner.
9:53
The BME280 library files are actually part of this project itself.
9:59
Once you download the project, you can find these files inside the Source and Include
10:04
folders. Simply extract them from there, so we can include them in our STM32 project.
10:12
Now let’s start setting up the project. I am going to continue with the same project we
10:18
created in the previous video. However, I will rename it as Part 2 for better organization.
10:25
While renaming, make sure to select the “Update Reference” option. This
10:30
ensures that all project references from Part 1 are updated to Part 2 correctly.
10:37
Alright, the renaming process is complete. Everything has been updated to Part 2,
10:43
except for the Debug Configuration. Let’s delete this debug configuration
10:49
along with the Debug folder. Don’t worry, these will be regenerated automatically
10:55
once we launch the debug process again. Next, we need to add I2C functionality so that
11:02
the BME280 sensor can communicate with the STM32. Open the CubeMX file,
11:09
and configure I2C1 for this purpose. Here, pins PB6 and PB7 are assigned as
11:16
the I2C clock (SCL) and data (SDA) pins. We will look at the exact wiring
11:21
and pin connections in just a moment. The I2C configuration is kept at its default
11:27
settings, which means we are using the standard mode with a 100 KHz clock for the BME280 sensor.
11:35
Now, let’s regenerate the project. Since we need new functions,
11:40
delete the old ESP8266 library files from the previous project. After that, copy the updated
11:48
library files into the project — place the source files inside the Source directory and the header
11:54
files inside the Include directory. Let’s take a look at what has changed
11:59
inside the ESP8266 source file. The first few functions remain
12:05
the same as in our earlier project. However, I have added a new function
12:11
called sendToThingSpeak, which will handle sending sensor data to the cloud server.
12:17
Now, you might notice a float formatting error inside this function.
12:22
This happens because we are trying to convert a floating-point value
12:26
into character format using printf. To fix this, right-click on the project
12:32
and open Project Properties. Go to C/C++ Build → Settings.
12:38
Under MCU/MPU Settings, enable the option to use float with printf.
12:45
Click Apply and Close, and this error will disappear.
12:49
Now let’s understand what the sendToThingSpeak function actually does.
12:55
The parameters of this function are: the ThingSpeak Write API Key,
13:01
and three float values for the three data fields.
13:06
If you plan to use fewer than 3 fields, or more than 3 fields, you can easily
13:11
modify the function parameters accordingly. The function begins by sending the CIPSTART
13:17
command to establish a connection with the ThingSpeak API server.
13:22
After that, it waits for the CONNECT response from the ESP8266 module. We saw this behavior
13:30
earlier during the AT command testing. Once the connection is confirmed,
13:36
the function constructs the channel’s write feed URL and stores it in a buffer.
13:42
This URL contains the API key along with the values passed to the function as parameters.
13:48
If you don’t want to use all three fields, you can modify this URL. For example:
13:55
To remove Field 3, simply delete that portion from the URL.
14:01
To use only one field, remove both Field 2 and Field 3.
14:06
Remember that the carriage return and line feed characters are also included
14:10
in the URL. Their length is calculated before transmitting the URL to the module.
14:17
Once the URL is prepared, the function sends the CIPSEND command, which specifies how
14:23
many bytes of data will be transmitted next. After sending this command, the function waits
14:30
for the greater-than symbol ( > ), which confirms that the ESP8266 is ready to receive the data.
14:37
Next, it sends the URL itself and then waits for the SEND OK response from the module.
14:44
However, there’s something important to note: the ESP8266 may return SEND OK even if it
14:51
receives an incorrect number of bytes. That’s why, to confirm that the data
14:57
actually reached ThingSpeak, we must also check for the +IPD response.
15:03
From this response, we can extract the Entry ID (Update ID), which appears after the colon (:).
15:10
Receiving this ID confirms that ThingSpeak has acknowledged and stored the data we sent.
15:17
That’s all the changes I made to the ESP8266 source file.
15:22
Now, let’s quickly move to the BME280 source file. Here, the main function of interest is the
15:30
BME280_Config function. This function configures the BME280 registers and initializes the sensor.
15:39
I have already explained this in detail in my BME280 article and video,
15:44
so for now, we will simply use the same initialization code from there.
15:50
Alright, with that covered, let’s move on and start writing the actual code.
15:56
First, include the BME280 header file along with the ESP8266 header file.
16:02
Inside the main function, once the ESP8266 successfully connects to Wi-Fi, call the
16:09
BME280_Config function to initialize the sensor. Next, define three float variables to store the
16:16
values of temperature, pressure, and humidity. Inside the while loop, call the BME280_Measure
16:23
function to measure and update these variables with the latest sensor readings.
16:29
Before sending this data to the ThingSpeak server, we need to confirm
16:33
that the ESP8266 is still connected to Wi-Fi. The enumeration ESP8266_ConnectionState defines
16:42
all possible connection states of the ESP8266. In the ESP8266 source file, there is a
16:50
variable called ESP_ConnState, which holds the current connection state.
16:55
So, inside the loop, we will check if the ESP8266 is connected and has an IP address.
17:03
If the connection is active, then we will call the function ESP_SendToThingSpeak and pass the
17:08
temperature, pressure, and humidity values to it. Make sure to add a delay of at least 15 seconds
17:16
before sending the next set of data. As I mentioned earlier, ThingSpeak’s
17:21
free accounts require a minimum interval of 15 seconds between updates.
17:27
We also need to pass the Channel Write API Key to the function. So,
17:32
let’s define this key as a variable in the code. Now pass this key to the ThingSpeak function
17:39
call along with the sensor values. Alright, let’s build the project now.
17:46
The build completed successfully with no errors, so we’re ready to flash the code
17:51
onto the STM32 board. Before we do that,
17:55
let’s quickly review the hardware connections. The ESP8266 wiring with STM32 was already
18:04
explained in detail in the previous video, but let’s go over it again.
18:08
The RX pin of the ESP8266 connects to PA0 (UART4 TX) of STM32.
18:17
The TX pin of the ESP8266 connects to PA1 (UART4 RX).
18:23
I am using an ESP adapter, which is powered with 5 volts from the STM32 board itself.
18:30
If you plan to connect the ESP module directly without the adapter,
18:34
you can refer to the connection diagram in the article linked in the description.
18:39
Now, let’s look at the BME280 connections. The BME280 is connected via I2C1.
18:48
The data pin (SDI or SDA) of the sensor connects to PB6 (I2C1 SDA) on STM32.
18:58
The clock pin (SCK) of the sensor connects to PB7 (I2C1 SCL).
19:05
One important note: If your BME280 module also supports SPI mode (like the one shown in the
19:12
image), you must connect the SDO pin to GND. Otherwise, the I2C slave address will change.
19:20
If your module only supports I2C, you can ignore the SDO pin and simply connect SDA
19:26
to SDA and SCL to SCL. The BME280 is powered
19:32
using 3.3 volts from the STM32 MCU. In addition to the ESP8266 and BME280 modules,
19:42
I have also connected a USB-to-TTL converter (FT232) so we can view logs in the console.
19:50
This is connected through UART1, where the TX pin of the MCU is connected
19:55
to the RX pin of the converter. That’s all for the hardware setup.
20:01
Now, let’s head over to the ThingSpeak channel settings and clear the channel
20:05
before we start logging new data. Clearing the channel will remove
20:10
all the test data we sent earlier. As you can see, the channel has now been cleared.
20:16
Let’s go back to the project and flash the firmware to the board.
20:21
Now, let’s open the serial console and observe the logs.
20:26
I have only enabled user logs, so the output stays clean and minimal.
20:31
As you can see, the ESP8266 has been initialized, and it is now connecting to the Wi-Fi network.
20:40
After connecting, the module waits until an IP address is assigned.
20:45
Once the IP address is obtained, the module immediately sends the
20:49
data to the ThingSpeak server. If the data is received correctly
20:53
by ThingSpeak, the server responds with an Entry ID (also called Update ID). This
21:00
ID is then printed on the console. This confirms that the data has been
21:05
successfully logged to the ThingSpeak channel. After a 15-second delay, another set of data is
21:13
sent. If the update is successful, you will see the Entry ID increase by one each time.
21:20
Now, let’s check the ThingSpeak channel. We can clearly see two values under each
21:26
field. The temperature values look correct, but notice that the pressure
21:31
values are being sent in pascals. To make them easier to read,
21:36
let’s modify the main function so that the pressure is reported in kilopascals instead.
21:42
Rebuild and flash the project again. We need to clear the channel once more,
21:48
otherwise the chart will look odd — switching from values like 94000 to 94 after the change.
21:56
Now I’ll fast-forward the video so you can watch the updates happening in real time.
22:02
With every update, ThingSpeak returns an incremented Entry ID,
22:06
which shows the total number of updates sent to the channel so far.
22:11
To make the dashboard more meaningful, we can also update the titles of the charts so they
22:16
clearly show what each field represents. Now everything is working as expected.
22:29
The STM32 successfully measures the current temperature, pressure, and humidity using the
22:35
BME280 sensor, and the ESP8266 uploads these readings to the ThingSpeak cloud.
22:42
With that, we have successfully completed Part 2 of this IoT series.
22:48
In the next video, we will move forward and implement MQTT client functionality.
22:55
In that setup, the STM32 along with the ESP8266 will act as an MQTT client, which will be able
23:02
to both subscribe to topics and publish messages. We will also explore how to use the received data
23:09
in a practical way — for example, by controlling an LED or displaying the values on an LCD.
23:16
That brings us to the end of this video. If you’d like to read the full article
23:22
and download the project files, you’ll find the link in the description below.
23:28
Feel free to leave a comment if you have any questions or doubts.
23:33
Thank you for watching, and have a great day ahead!