Embedded System Project 4: ESP32 External Sensors

Michelle Lim
7 min readMar 4, 2023

--

Hi, I’m Michelle and today I’ll be continuing my blog series of the embedded systems project! ✨🤩 (You can read the previous blog here 🤗)

The fourth project I’ll be doing is about external sensors. On the previous blog, we’ve experimented interacting with the environment by using ESP32 internal sensor, this time we’ll be interacting by using external sensors 🤩. There are various kinds of external sensors that can be experimented with the ESP32 development board, as shown in the picture below.

External sensors that can be used together with ESP32

As for this experiment, I will be using the BME 280 sensor. BME 280 is a digital temperature, humidity, and barometic pressure sensor. With the barometic pressure value read, this sensor can also provide us with an estimated altitude information using Arduino IDE. The BME 280 sensor uses I2C or SPI communication protocol to exchange data with the microcontroller. I bought it in Tokopedia and requested it to be soldered by the seller.

BME 280 Sensor — soldered

In this project, we only need the basic few components & tools:

  1. ESP32 Development Board
  2. Micro-USB Cable
  3. Breadboard
  4. BME 280 Sensor
  5. Male-to-male jumper cables
  6. Laptop/PC with Arduino IDE installed and set

Pre-Project: Installing BME280 Library in Arduino IDE

To get readings from BME280 sensor module, we need to use the Adafruit_BME280 library.

1. Open your Arduino IDE, go to Sketch > Include Library > Manage Libraries.

Sketch > Include Library > Manage Libraries

2. The Library Manager should be open. Search for “Adafruit BME280” on the Search column and install the library, together with all the missing dependencies.

Search for “adafruit bme280” > Install > Install All
  • brief explanation: we need the Adafruit Unified Sensor library to use the Adafruit BME280 Library, hence the choice of “Install All” so that we don’t need to search and install the Adafruit Unified Sensor library anymore.

3. After installing the libraries, restart the Arduino IDE.

Finally, we’re all set to begin the project! 😄👍

Project: Schematics

As the BME 280 sensor communicates using the I2C communication protocol, we will be wiring the sensor to the ESP32 SDA and SCL pins. The pinout is shown in the picture below.

Pinout of BME280 to ESP32

The schematic we’ll be following is shown in the picture below.

Schematic of ESP32 with BME280 using I2C
My schematics for reference

The purple wire connects the 3V3 pin in ESP32 to VIN pin in BME280; The orange wire connects the GND pin in ESP32 to GND pin in BME280; The green wire connects GPIO21 pin in ESP32 to SDA pin in BME280; The yellow pin connects the GPIO22 pin in ESP32 to SCL pin in BME280;

Project: Code

In this experiment, we’ll be using an example code provided by the Adafruit BME280 Library with a slight modification.

Open the Arduino IDE, go to File > Examples > Adafruit BME280 Library > bme280test.

File > Examples > Adafruit BME280 Library > bme280test

After that, a window of code should pop up.

bme280test code example

To make it fully compatible with the ESP32, I made several modifications to the code, resulting:

#include <Wire.h>
#include <Adafruit_Sensor.h>
#include <Adafruit_BME280.h>

/*#include <SPI.h>
#define BME_SCK 18
#define BME_MISO 19
#define BME_MOSI 23
#define BME_CS 5*/

#define SEALEVELPRESSURE_HPA (1013.25)

Adafruit_BME280 bme; // I2C
//Adafruit_BME280 bme(BME_CS); // hardware SPI
//Adafruit_BME280 bme(BME_CS, BME_MOSI, BME_MISO, BME_SCK); // software SPI

unsigned long delayTime;

void setup() {
Serial.begin(9600);
Serial.println(F("BME280 test"));

bool status;

// default settings
// (you can also pass in a Wire library object like &Wire2)
status = bme.begin(0x76);
if (!status) {
Serial.println("Could not find a valid BME280 sensor, check wiring!");
while (1);
}

Serial.println("-- Default Test --");
delayTime = 1000;

Serial.println();
}


void loop() {
printValues();
delay(delayTime);
}

void printValues() {
Serial.print("Temperature = ");
Serial.print(bme.readTemperature());
Serial.println(" *C");

// Convert temperature to Fahrenheit
/*Serial.print("Temperature = ");
Serial.print(1.8 * bme.readTemperature() + 32);
Serial.println(" *F");*/

Serial.print("Pressure = ");
Serial.print(bme.readPressure() / 100.0F);
Serial.println(" hPa");

Serial.print("Approx. Altitude = ");
Serial.print(bme.readAltitude(SEALEVELPRESSURE_HPA));
Serial.println(" m");

Serial.print("Humidity = ");
Serial.print(bme.readHumidity());
Serial.println(" %");

Serial.println();
}

— Code Explanation:

We first call the Adafruit Library with this line of code:

#include <Wire.h>
#include <Adafruit_Sensor.h>
#include <Adafruit_BME280.h>

After that, there are several functions from Adafruit that we will be using, which are:

  1. readTemperature: reads the temperature value in Celcius.
  2. readPressure: reads the pressure value in hPa.
  3. readAltitute: reads the altitude value in meter.
  4. readHumidity: reads the humidity value in percentage.

for more references on Adafruit BME280 Library, you can visit this link.

Project: Experiment

After compiling and uploading the code, open the serial monitor at baud rate of 9600 baud and you’ll see the sensor’s reading by a delay of 1 second.

temperature, pressure, altitude, humidity readings shown on serial monitor

It’s a bit blurry on the gif attached so this is a gif capture of the experiment:

readings change when the sensor is pressed and not pressed.

As seen on the pictures, when the sensor is touched with a finger, which has a higher temperature than the surroundings, the temperature value increases from 29˚C when not touched to 32˚C when touched. The humidity also increases from 58% to 64%, this is because our finger has more moisture than the environment. As for the pressure, it shouldn’t have changed if you only touch the sensor, but I pressed it down so the pressure hence the approximate altitude changed. Due to the pressure reading, I decided to give it another try with only touching the sensor without pressing it down. Here’s the result!

readings when sensor is touched, not pressed

Gif captures:

readings change when sensor is touched and untouched.

As seen on the pictures, the temperature changes from 27˚C to 28˚C when the sensor is touched, the humidity also increases from 43% to 66%. However, the pressure value and approximate altitude no longer change as much as when it was pressed.

Project: More Explorations

After finishing the first experiment, which was a success as I can see the values read on the serial monitor, I decided to do a little bit of experiment with the LED built in ESP32.

The schematics are still the same, but I altered the code a little in the loop() and setup().

#include <Wire.h>
#include <Adafruit_Sensor.h>
#include <Adafruit_BME280.h>

/*#include <SPI.h>
#define BME_SCK 18
#define BME_MISO 19
#define BME_MOSI 23
#define BME_CS 5*/

#define SEALEVELPRESSURE_HPA (1013.25)

Adafruit_BME280 bme; // I2C
//Adafruit_BME280 bme(BME_CS); // hardware SPI
//Adafruit_BME280 bme(BME_CS, BME_MOSI, BME_MISO, BME_SCK); // software SPI

unsigned long delayTime;

void setup() {
Serial.begin(9600);
Serial.println(F("BME280 test"));

bool status;

// default settings
// (you can also pass in a Wire library object like &Wire2)
status = bme.begin(0x76);
if (!status) {
Serial.println("Could not find a valid BME280 sensor, check wiring!");
while (1);
}

Serial.println("-- Default Test --");
delayTime = 1000;

Serial.println();
pinMode(LED_BUILTIN, OUTPUT);
}


void loop() {
printValues();
if (bme.readTemperature()>28){
digitalWrite(LED_BUILTIN, HIGH);
}else{
digitalWrite(LED_BUILTIN, LOW);
}
delay(delayTime);
}

void printValues() {

Serial.print("Temperature = ");
Serial.print(bme.readTemperature());
Serial.println(" *C");

// Convert temperature to Fahrenheit
/*Serial.print("Temperature = ");
Serial.print(1.8 * bme.readTemperature() + 32);
Serial.println(" *F");*/

Serial.print("Pressure = ");
Serial.print(bme.readPressure() / 100.0F);
Serial.println(" hPa");

Serial.print("Approx. Altitude = ");
Serial.print(bme.readAltitude(SEALEVELPRESSURE_HPA));
Serial.println(" m");

Serial.print("Humidity = ");
Serial.print(bme.readHumidity());
Serial.println(" %");

Serial.println();
}

I added pinMode(LED_BUILTIN, OUTPUT) in the setup to initialize digital pin LED_BUILTIN as an output, and an if code in the loop to turn the LED_BUILTIN on when the temperature is more than 28˚C, and off otherwise. This added function has no crucial meaning as the borderline is 28˚C. However, this function will be useful if the border value is changed to 37.5˚C to indicate someone is having fever or higher body temperature than usual. However, I decided to still go with 28˚C for now as I cannot test out the 37.5˚C. Here’s the result:

LED_BUILTIN blink when temperature > 28˚C

gif captures:

LED blink with different readings

As seen on the picture, when the temperature is 27˚C, the LED is not on, but when it is touched and the temperature read is 28˚C or higher, the LED is on.

So yea, that’s the end of our fourth Embedded System Project: ESP32 External Sensors. (yeah!! 🥳) Stay tune for the next projects and stay safe and healthy 🥰

--

--