0% found this document useful (0 votes)
15 views13 pages

Lab2 v2.0

This document outlines a laboratory exercise focused on visualizing temperature, humidity, and air pressure data using an STM32 Nucleo board and an Arduino Sensor Kit. The lab involves setting up a PlatformIO project, programming the microcontroller to communicate with sensors, and displaying the acquired data on an OLED screen. Students are required to complete specific coding tasks, document their processes, and answer related questions for evaluation.

Uploaded by

Carla Ash
Copyright
© © All Rights Reserved
We take content rights seriously. If you suspect this is your content, claim it here.
Available Formats
Download as PDF, TXT or read online on Scribd
0% found this document useful (0 votes)
15 views13 pages

Lab2 v2.0

This document outlines a laboratory exercise focused on visualizing temperature, humidity, and air pressure data using an STM32 Nucleo board and an Arduino Sensor Kit. The lab involves setting up a PlatformIO project, programming the microcontroller to communicate with sensors, and displaying the acquired data on an OLED screen. Students are required to complete specific coding tasks, document their processes, and answer related questions for evaluation.

Uploaded by

Carla Ash
Copyright
© © All Rights Reserved
We take content rights seriously. If you suspect this is your content, claim it here.
Available Formats
Download as PDF, TXT or read online on Scribd
You are on page 1/ 13

Data Acquisition Systems

(SADQ)
LAB 2: Visualization of
Temperature, Humidity and
Air pressure on an OLED
Screen Using a
Microcontroller.

Víctor Manuel Bautista Loza


Mario Garrido Gálvez
Luis Fernando D’Haro Enríquez
Index
1. Introduction .......................................................................................................................... 3
2. Equipment and Components ................................................................................................ 3
3. Lab Task. ............................................................................................................................... 3
3.1 First Steps ......................................................................................................................... 4
3.2 Temperature Sensor......................................................................................................... 8
3.3 Humidity Sensor ............................................................................................................... 9
3.3.1 Humidity Measurement and Display ............................................................................... 9
3.3.2 Circular Buffer .................................................................................................................. 9
3.4 Air Pressure Sensor ........................................................................................................ 11
3.5 Measuring the I2C Protocol with the Oscilloscope ........................................................ 11

2
1. Introduction
In this lab, we use an STM32 Nucleo board to interface with the Arduino Sensor Kit and display
processed information on an OLED screen. The objective is to establish communication between
the microcontroller and various sensors, acquire real-time data, and process them to generate
meaningful outputs. The procedure follows the structure of a given initial program skeleton,
which will be modified and completed by implementing the necessary functions for each sensor
in different sections. We implement data acquisition, processing, and visualization techniques
while ensuring proper integration of hardware and software components. This exercise helps to
develop skills in embedded systems programming, peripheral interfacing, and real-time data
representation, which are essential in engineering. You can get more information and examples
related to the Arduino Sensor Kit at https://sensorkit.arduino.cc/. At the end of the tasks
proposed in this program of activities, the student should be able to:
• Program the STM32 Nucleo board.
• Communicate with the sensors of the board using the I2C protocol.
• Display the processed information on an OLED screen.

2. Equipment and Components


We will use the following equipment and components:

• STM32 Nucleo board, which contains the STM32-F411RE microcontroller.


• The Arduino Sensor Kit integrated board, which contains temperature, humidity (DHT20)
and pressure (BMP280) sensors, and an organic light-emitting diode (OLED) screen
(SSD1315).
• Dual-channel digital oscilloscope.

Cables and connectors:

• Three Grove wires.


• Two oscilloscope probes with coaxial cable and BNC type connector.
• Three Arduino wires.

3. Lab Task.
This is the lab task you must carry out and report for evaluation. It is important that you take
notes on every step of your experiments to complete the report document that will be
uploaded through Moodle as the result of your laboratory work.
You must carefully follow all steps while writing down the specific results that you will be asked
about. The lab steps are numbered as x.x.
The grades of this task will depend upon the quality of the report document. Thus, on the report
you will be required to answer each of the questions indicated as Qx.
The report must be 5 pages long maximum. It is recommended to add screenshots that can be
taken with your mobile phone or with the OpenChoice software in the case of using the
Oscilloscope. A cover page on the report document is always welcome (does not count among
the 5 pages). A template for the report is provided in Moodle.

3
3.1 First Steps
In this section we are going to set up the PlatformIO project. It is assumed that the student has
completed the STM32 Tutorial, so the VSCode, PlatformIO and STM32 drivers are already
installed in the computer and understood by the student.

INITIALIZING THE PLATFORMIO PROJECT:

• Open VSCode and click on the extension of PlatformIO .


• Click on QUICK ACCESS->PIO Home->Open to open the graphical interface of PlatformIO.
• Click on New Project in the Home default window.
• Initialize the project with the name Practica2, the board ST Nucleo F411RE, the framework
Arduino, and finally unclick the box of using default location to store this project in a
desired path of your computer.
• Click on Finish.
The Practica2 folder will be created with a basic template of a standard of a PlatformIO project.
The file platformio.ini is the configuration file of our project, where the board that we are using,
and the framework are specified. If the project was correctly initialized, it must appear as:
[env:nucleo_f11re]
platform = ststm32
board = nucleo_f411re
framework = arduino

INCLUDING THE ARDUINO SENSOR KIT LIBRARY:


We need to attach the library of the Arduino Sensor Kit to our project. This library includes the
necessary functions and definitions to communicate with the sensors and actuators from our
microcontroller. However, this library by default only supports Arduino boards. We also need to
adapt it to compile it together with our STM32 board.

• Click on the PlatformIO extension on the left extension bar . Two panels are unfolded
on the left part of the screen: PROJECT TASKS and QUICK ACCESS panels.
• Click on QUICK ACCESS -> PIO Home -> Libraries. The graphic interface of PIO Home will
appear in a new window.
• Search for Arduino_Sensorkit and click on the library developed by Leonard George.
• Ensure that the version is 1.4.0 and click on Add to Project.
• Select project Practica2. The files of this library are included in .pio/libdeps/
nucleo_f411re/Arduino_Sensorkit.
• Confirm that the platformio.ini file has included the dependency of this library:

[env:nucleo_f411re]
platform = ststm32
board = nucleo_f411re
framework = arduino
lib_deps = arduino-libraries/Arduino_Sensorkit@^1.4.0

4
• In the project path, open the file .pio/libdeps/nucleo_f411re/Arduino_Sensorkit/
src/Arduino_SensorKit.h.
• Modify the definitions by adding the text highlighted as below:
#if defined(ARDUINO_ARCH_AVR) || defined(ARDUINO_ARCH_MEGAAVR) ||
defined(ARDUINO_UNOR4_MINIMA) || defined(ARDUINO_UNOR4_WIFI)
#define _PIN_SDA SDA
#define _PIN_SCL SCL
#define _WIRE Wire
#elif defined(STM32F4xx)
#define _PIN_SDA SDA
#define _PIN_SCL SCL
#define _WIRE Wire
#elif defined(ARDUINO_GIGA)
#define _PIN_SDA I2C_SDA1
#define _PIN_SCL I2C_SCL1
#define _WIRE Wire1
#else
#error "This board is not supported by Arduino_SensorKit"
#endif

• Save and close the file. The library is now configured to support our ST board.

PROGRAMMING THE STM32 NUCLEO

• Open src/main.cpp and copy-paste the next code that is the template for the lab work in
which we are going to work fill in and modify functions along the lab 2. When copy-pasting
the code, make sure that the page numbers of this document are not copied to the VSCode.
The code is also available in Moode and you can download it from there.

#include "Arduino_SensorKit.h"

// Define DHT20 (black sensor)


#define Environment Environment_I2C
// Define sample rate
#define SAMPLE_RATE 1000
// Define buffer lengths
#define HUMD_BUFF_LEN 3
#define PRES_BUFF_LEN 3

// Function prototypes
float get_temperature_celsius();
float get_temperature_fahrenheit();
void display_temperature(float data1, float data2);
float mean(int length, float buffer[]);
void store_humidity();
void display_humidity(float data);
void store_pressure_hectopascals();

5
void display_pressure(float data);

// Global variables
float humd_buffer[HUMD_BUFF_LEN]; // Buffer
int humd_i = 0; // Position
float humd_mean = 0.0;
float pres_buffer[PRES_BUFF_LEN]; // Buffer
int pres_i = 0; // Position
float pres_mean = 0.0;

void setup() {
// Initialize I2C
Wire.begin();
// Initialization of the OLED screen
Oled.begin();
Oled.setFlipMode(true); // Sets the rotation of the screen
Oled.setFont(u8x8_font_chroma48medium8_r); // Sets the font
Oled.clearDisplay();
// DHT20 sensor (Temperature and humidity)
Environment.begin();
// BMP280 sensor (Air pressure)
Pressure.begin();
// Initialize all values of the buffer to 0
for(int i=0; i<HUMD_BUFF_LEN; i++){
humd_buffer[i] = 0.0;
}
for(int i=0; i<PRES_BUFF_LEN; i++){
pres_buffer[i] = 0.0;
}
}
void loop() {
delay(SAMPLE_RATE);
// Get and display temperature
float temp_celsius = get_temperature_celsius();
float temp_fahrenheit = get_temperature_fahrenheit();
display_temperature(temp_celsius, temp_fahrenheit);
// Get and display humidity
/* TODO : COMMENT THE LINE BELOW */
humd_mean = Environment.readHumidity();
/* TODO : UNCOMMENT THE LINES BELOW */
//store_humidity();
//humd_mean = mean(HUMD_BUFF_LEN, humd_buffer);
display_humidity(humd_mean);
// Get and display Pressure
store_pressure_hectopascals();
pres_mean = mean(PRES_BUFF_LEN, pres_buffer);
display_pressure(pres_mean);
}
float mean(int length, float buffer[]){

6
/* MODIFY ME */
return -1.0;
}
float get_temperature_celsius(){
return Environment.readTemperature();
}
float get_temperature_fahrenheit(){
/* MODIFY ME */
return -1.0;
}
void display_temperature(float data1, float data2){
Oled.setCursor(0, 1);
Oled.print("T = ");
Oled.print(data1);
Oled.print(" C");
Oled.refreshDisplay();
Oled.setCursor(0, 3);
Oled.print("T = ");
Oled.print(data2);
Oled.print(" F");
Oled.refreshDisplay();
}
void store_humidity(){
humd_buffer[humd_i] = Environment.readHumidity();
humd_i++;
if (humd_i==HUMD_BUFF_LEN)
humd_i=0;
}
void display_humidity(float data){
/* FILL ME */
}
void store_pressure_hectopascals(){
/* FILL ME */
}
void display_pressure(float data){
/* FILL ME */
}

If you have already done the Counter Tutorial, the structure of this program may be familiar.
First, we include the Arduino Sensor Kit library to call the different sensors that are included in
the board. Then, we define some constants, as the buffer lengths. After the constants, we define
the prototypes of the functions. The prototypes are the headers of the functions defined by the
user, whose body is placed at the end. Then, we include the code of the setup function. This
function is run only once at the beginning of the execution. It initializes the I2C communication,
the screen, the sensors, and gives default values to the global array variables. Then, we write
the loop function. This function runs iteratively. It calls the user functions sequentially and then
waits for some time to adjust the sampling rate of the sensors.
Some functions of the code are already completed, and others must be written by the student,

7
following the steps of this document. Specifically, the student has to fill in the body of the
functions marked with the /* FILL ME*/ and /* MODIFY ME*/ comments, when necessary,
along the document.

CONECTING THE HARDWARE:


• Connect the Arduino Sensor Kit to the top of the STM32 nucleo board. The female pins of
the STM32 nucleo matches the male pins of the Arduino sensor kit. Be specially careful when
connecting the boards to avoid that the pins bend.
• Plug the STM32 Nucleo into the computer.

3.2 Temperature Sensor

In this task, we are going to obtain the temperature of the room from the DHT20 sensor of the
Arduino Sensor Kit and display it on the OLED screen. The temperature is going to be displayed
in both Celsius and Fahrenheit degrees.

• Connect the Grove wires to the module of the board where the sensor is located. It appears
on the board with the name Temperature & Humidity. Remember that the sensor
communicates with the STM32 by the I2C protocol, so the sensor must be connected to an
I2C connector.
• Modify the body of the prototype function:
float get_temperature_fahrenheit()
This function first reads the value of the temperature from the DHT20 sensor and returns
the value converted into Fahrenheit using the appropriate formula. Remember that Celsius
and Fahrenheit degrees are related by the formula:
9
𝐹𝐹 = ∙ 𝐶𝐶 + 32
5
• Upload the code to the STM32 Nucleo.
• Observe the OLED screen to verify that the information of both the Celsius and Fahrenheit
units are correctly displayed.

Questions:

Q1: Take a photograph of the complete board so that the connections and the screen are clearly
shown. Do the calculations to verify that the degrees in Celsius and Fahrenheit fulfil the formula
that relates them.

Q2: Copy the code of the get_temperature_fahrenheit() function and explain any special
considerations that you have taken into account to carry out the calculations.

8
3.3 Humidity Sensor

3.3.1 Humidity Measurement and Display

During this task, the humidity information is obtained, processed and displayed on the OLED
screen along with the temperature information. The humidity information is obtained from the
DHT20 sensor, which also measures the temperature. Additionally, we will modify the code to
implement a circular buffer to store data and process it. A circular buffer considers an array of
length L. When the array is full and we want to store new data, the data of the first position of
the array is discarded and replaced by the new data obtained. This way, the data stored in the
circular buffer always includes the last L samples that have been received. We are going to
implement the mean operation of the data stored in the buffer and compare its output to the
original raw data. First, we are going to see the raw data that is read from the humidity sensor.
For this:

• Complete the body of the function


void display_humidity(float data).
This function must print the value of the parameter data in the OLED screen of the Arduino
Sensor Kit. The humidity is given as a percentage, and must appear in a new line right
under the temperature data in the OLED screen, so that we can see a total three lines of
information (two for temperature and one for humidity).
You can used as an example the function
void display_temperature(float data1, float data2).
This function prints in the OLED screen of the Arduino Sensor Kit the data given by the
parameters, with extra characters.
• Upload the code to the STM32 Nucleo and verify that the information of the humidity is
added to the OLED screen and can be seen under the temperature information.

Questions:

Q3: Take a photograph of the complete board, so that the connections and the screen are clearly
shown. Copy the code of your display_humidity(float data). Explain how you achieve
that the humidity measurement is aligned properly on the OLED screen.

Q4: Put your finger on top of the temperature and humidity sensor. How do the measurements
displayed on the screen vary?

3.3.2 Circular Buffer

Now, we are going to study the behavior of the circular buffer. In order to see the values that
are stored in the circular buffer, we are going to use the debugger. The debugger lets the user

9
run the code line by line and stop to see the value of the variables at each point of the
execution. The intention is to see the humidity values stored in the circular buffer to study how
it is filled with new information, and how the mean value is calculated as new data is stored.
For this:

• Program the function


float mean(int length, float buffer[]).
This function must return the mean operation of the data stored in a generic array buffer
of length length, given as parameters to the function.
• In the void loop() function, comment the line below /* TODO : COMMENT THE LINE
BELOW */ .
• In the void loop() function, uncomment the two lines below /* TODO : UNCOMMENT
THE LINES BELOW */. These two lines are used to store the humidity in a buffer and
calculate the mean value.
• In the void loop() function, add a breakpoint in the line when calling
store_humidity();
so that the debugger can stop the execution each time the function is called. A breakpoint
is placed by clicking on the blank space at the left of the number that indicates the line of
the code.
• Click on Run -> Start Debugging, or press and then . The computer will connect
with the ST Linker of the STM32 Nucleo board and will upload the code, but it will stop in
the first command of the execution. Additionally, the RUN AND DEBUG view is displayed
on the left part of the VSCode window.
• Click on . This will execute the code until your first breakpoint. Note that the program
stops right before executing the line with the breakpoint.
• In RUN AND DEBUG view, open VARIABLES->Global. All the global variables used by the
program are displayed. We are going to focus on the circular buffer, humd_buffer, the
variable that stores the position of the array, humd_i, and the mean of the buffer,
humd_mean. Right click on these variables and click on Add to Watch, so that these
variables are grouped apart, and we can see them more clearly. We can further expand
the variable humd_buffer to see the value of each element of the array. In the first stop,
you will see all the values of the buffer instantiated to zero, the variable humd_i initialized
to zero, and also the mean value humd_mean initialized to zero.
• You can continue clicking on to execute the next line or to advance the execution
of the program until the breakpoint.
• Observe how the buffer is filled and how the mean value of the humidity changes
compared to the individual values that are being stored.

Questions:

Q5: Restart the debugger and annotate the values of the variables humd_buffer, humd_i and
humd_mean during six iterations of the loop() function. This means that the buffer is filled
during the first three iterations and replaced with new data during the next three iterations.
Show the behavior of the circular buffer and verify that the value returned by the mean function
is correct. What are the potential advantages of using the mean compared to using raw values?

Q6: Copy the code of your mean function and explain how you have implemented it.

10
3.4 Air Pressure Sensor

During this task, the air pressure information is obtained, processed and displayed on the OLED
screen under the temperature and humidity information. The air pressure information is
obtained from the BMP280 sensor. For this task:

• Connect the necessary cables to the module of the board where the “Air pressure” sensor
is located. Remember that the sensor communicates with the STM32 through the I2C
protocol, so the sensor must be connected to an I2C connector.
• Complete the body of the prototype function:
void store_pressure_hectopascals()
This function first reads the value of the air pressure from the BMP280, which gives the value
of air pressure in Pascals. Then, the function must convert this value to hectopascals using
the appropriate formula and finally store the value into the circular buffer pres_buffer.
HINT: Observe how the pressure sensor is initialized in the setup.
• Complete the body of the prototype function
void display_pressure(float data)
which prints in the OLED screen of the Arduino Sensor Kit the data given by the parameter,
with extra characters, including the units of the measurement.
• Upload the code to the STM32 Nucleo and verify that the air pressure information is added
to the OLED screen and can be seen under the temperature and humidity information.

Questions:

Q7: Take a photograph of the complete board so that the connections and the screen are clearly
shown. Copy the code of the function store_pressure_hectopascals() and the function
display_pressure(float data). Explain how you have implemented them.

3.5 Measuring the I2C Protocol with the Oscilloscope

In this section the Inter-integrated circuit (I2C) protocol will be studied and analyzed with the
oscilloscope. The I2C protocol allows us to connect several sensors or other devices such as
screens with just a few wires. One wire is used for the clock (SCL) and the other is used for
transmitting data (SDA). The I2C protocol is based on reading/writing data from/to a register
that is inside the chips of the sensors. The data message through SDA is organized as follows:

Read/Write

Start 0111001 1 0 11010011 0 00001111 0 Stop

7 bit address ACK 8 bit data ACK 8 bit data ACK

It consists of a serial communication, which means that data is sent bit after bit. These bits are
synchronized with the rising edges of the SCL signal. The microcontroller is in charge of starting

11
the transmission by sending first a ‘0’. Then the microcontroller sends 7 bits of the address of
the sensor and indicates with the next bit if data must be read (1) or written (0). If data must be
read, then the sensor sends the data that are stored in the sensor’s register. If data must be
written, then the microcontroller sends the new data to be stored in the sensor’s registers.

To measure the I2C signals SDA and SCL:

• Connect one Arduino wire to SDA, another Arduino wire to SCL and a third Arduino wire to
GND of the Arduino Sensor Kit board. The pins are the ones shown in the figure below.

GND

SDA
SCL

• Take two oscilloscope probes and measure the SDA voltage using Channel 1 of the
oscilloscope and SCL voltage using Channel 2. Remember to connect the ground of the board
to the ground cable of the oscilloscope.
• Remember that the oscilloscope probes and the oscilloscope configuration of the channels
must be in the same mode (10:1 or 1:1).
• Capture a data frame with the oscilloscope. For this, adjust the trigger level to the middle
level of the SCL signal. By default, the trigger is configured for CH1, but you can change it by
pressing MENU button in the trigger options (right part of the oscilloscope). Then, the source
that is displayed in the oscilloscope’s screen must change to CH2 that is the channel reserved
for the SCL signal. Finally, click on Single button in the right upper panel of the oscilloscope,
which captures a data frame of both SDA and SCL.
• Ensure that, minimum, 10 periods of the SCL signal are captured and can be clearly seen.
Otherwise, capture a new data frame.
• Adjust the vertical position of both signals so that one channel overlaps the other one.

Questions:

Q8: Take a photo of the oscilloscope screen, so that the SDA and SCL signals are clearly shown.
Remember that at least 10 periods of SCL must be clearly shown. Measure the period of the SCL
signal. How much is it?

12
Q9: According to the signals captured by the oscilloscope, which is the address of the register?
Provide it in binary and decimal. According to the table below, which sensor belongs this address
to?

Sensor Address
OLED Screen 0111100
DHT20 0111000
BMP280 1110111

Q10: According to the signals captured by the oscilloscope, is the register read or written by the
microcontroller?

13

You might also like