Project #4: BMP280 Pressure & Temperature Sensor using OLED Display!
An II2260 Project
Hello guys, back at it again with another ESP32 Project!
This week, we’ll be using an external component — you guessed it — BMP280! This time, we will be monitoring the weather (only temperature annd pressure though) using BMP280 and displaying it on an OLED display! Yay!
What is BMP280?
BMP280 is an external sensor capable of reading temperature, pressure, as well as altitude. This sensor uses I2C or SPI connection protocol to exchange data with a microcontroller like ESP32. It costs like $1 and can do so many things. This is a very cheap sensor to buy in my opinion to level up your knowledge in embedded systems!
So in this project, we’ll be setting up the libraries and other necessary steps to complete the setup of our sensor.
Why use an OLED display?
The sensor that we will use, BMP280, outputs value of temperature and pressure via the serial monitor. So if we want to see the monitored value, we have to connect our ESP32 to PC and open Arduino IDE to see it. But with OLED display, the monitored value will be displayed on the screen and you can put it anywhere — like your wall!
Setting up the Sensor
Software-wise, we will be using third-party libraries from Adafruit, that is Adafruit BMP280 Library and Adafruit Sensor Library. The other thing we should prepare is to know the I2C serial address. You can find the serial address using this code:
/*********
Rui Santos
Complete project details at https://randomnerdtutorials.com
*********/#include <Wire.h>
void setup() {
Wire.begin();
Serial.begin(115200);
Serial.println("\nI2C Scanner");
}
void loop() {
byte error, address;
int nDevices;
Serial.println("Scanning...");
nDevices = 0;
for(address = 1; address < 127; address++ ) {
Wire.beginTransmission(address);
error = Wire.endTransmission();
if (error == 0) {
Serial.print("I2C device found at address 0x");
if (address<16) {
Serial.print("0");
}
Serial.println(address,HEX);
nDevices++;
}
else if (error==4) {
Serial.print("Unknow error at address 0x");
if (address<16) {
Serial.print("0");
}
Serial.println(address,HEX);
}
}
if (nDevices == 0) {
Serial.println("No I2C devices found\n");
}
else {
Serial.println("done\n");
}
delay(5000);
}
Before we can run the code, we need to assemble the circuit first.
What you’ll need:
- Jumper cables, 4 of them
- The BMP280 sensor
- ESP32
- Breadboard
The sensor should have labels for the pins, if you can’t see it, try looking underneath the sensor.
After installing the libraries necessary for the sensor and assembling the circuit, run the above code. In most cases, the code will output the address of 0x76.
Once you get the address, Go to Files -> Example -> Adafruit BMP280 Library -> bmp280test
The code should look like this:
/***************************************************************************
This is a library for the BMP280 humidity, temperature & pressure sensorDesigned specifically to work with the Adafruit BMP280 Breakout
----> http://www.adafruit.com/products/2651These sensors use I2C or SPI to communicate, 2 or 4 pins are required
to interface.Adafruit invests time and resources providing this open source code,
please support Adafruit andopen-source hardware by purchasing products
from Adafruit!Written by Limor Fried & Kevin Townsend for Adafruit Industries.
BSD license, all text above must be included in any redistribution
***************************************************************************/#include <Wire.h>
#include <SPI.h>
#include <Adafruit_BMP280.h>#define BMP_SCK (13)
#define BMP_MISO (12)
#define BMP_MOSI (11)
#define BMP_CS (10)Adafruit_BMP280 bmp; // I2C
//Adafruit_BMP280 bmp(BMP_CS); // hardware SPI
//Adafruit_BMP280 bmp(BMP_CS, BMP_MOSI, BMP_MISO, BMP_SCK);void setup() {
Serial.begin(9600);
Serial.println(F("BMP280 test"));if (!bmp.begin()) {
Serial.println(F("Could not find a valid BMP280 sensor, check wiring!"));
while (1);
}/* Default settings from datasheet. */
bmp.setSampling(Adafruit_BMP280::MODE_NORMAL, /* Operating Mode. */
Adafruit_BMP280::SAMPLING_X2, /* Temp. oversampling */
Adafruit_BMP280::SAMPLING_X16, /* Pressure oversampling */
Adafruit_BMP280::FILTER_X16, /* Filtering. */
Adafruit_BMP280::STANDBY_MS_500); /* Standby time. */
}void loop() {
Serial.print(F("Temperature = "));
Serial.print(bmp.readTemperature());
Serial.println(" *C");Serial.print(F("Pressure = "));
Serial.print(bmp.readPressure());
Serial.println(" Pa");Serial.print(F("Approx altitude = "));
Serial.print(bmp.readAltitude(1013.25)); /* Adjusted to local forecast! */
Serial.println(" m");Serial.println();
delay(2000);
}
Notice on the setup part, there is an if statement
if (!bmp.begin()) {
Serial.println(F("Could not find a valid BMP280 sensor, check wiring!"));
while (1);
}
This code will always return the println statement if we don’t initalize the I2C address of the sensor. So, we should change the code to
if (!bmp.begin(0x76)) {
Serial.println(F("Could not find a valid BMP280 sensor, check wiring!"));
while (1);
}
To read the temperature, you can use bmp.readTemperature(), to read the pressure you can use bmp.readPressure(), and to read altitude you can use bmp.readAltitude(1013.25). As for the number, I don’t really know what that means, but I’m guessing it’s the default value.
Run the above code and open the serial monitor on 9600 baud. You can see the program will output like this:
If this works, you’re done!
But are you tired of having to open the serial monitor to see the monitored value of the sensor? If you are, let’s do something even more fun!
For this project, we will need:
- Adafruit SSD1306 OLED display 0.96 inch (this is what I use, it’s up to you)
- Additional 4 jumper cables
To be able to use the OLED display, we need to install the library first. The libraries are Adafruit_SSD1306 library and Adafruit GFX library.
Once you install the code, arrange the circuit like this
Because the OLED display use GND, VDD, SCK and SDA pins, you would need to parallel those pins with 4 other cables. As you can see from the above picture, the cables go accordingly from GND, VDD, SCK(SCL on BMP280) and SDA.
After finishing the circuit, I use this code to run it
#include <Wire.h>
#include <Adafruit_GFX.h>
#include <Adafruit_SSD1306.h>
#include <Adafruit_Sensor.h>
#include <Adafruit_BMP280.h>#define SCREEN_WIDTH 128 // OLED display width, in pixels
#define SCREEN_HEIGHT 64 // OLED display height, in pixels// Declaration for an SSD1306 display connected to I2C (SDA, SCL pins)
Adafruit_SSD1306 display(SCREEN_WIDTH, SCREEN_HEIGHT, &Wire, -1);Adafruit_BMP280 bmp; // I2Cvoid setup() {
Serial.begin(115200);// inisialisasi alamat bme280
bmp.begin(0x76);if(!display.begin(SSD1306_SWITCHCAPVCC, 0x3C)) {
Serial.println(F("SSD1306 allocation failed or couldn't find a valid bme280"));
for(;;);
}
delay(2000);
display.clearDisplay();
display.setTextColor(WHITE);
}void loop() {
delay(5000);//read temperature and humidity
float t = bmp.readTemperature();
float h = bmp.readPressure();
if (isnan(h) || isnan(t)) {
Serial.println("Failed to read from bmp sensor!");
}
// clear display
display.clearDisplay();
// display temperature
display.setTextSize(1);
display.setCursor(0,0);
display.print("Temperature: ");
display.setTextSize(2);
display.setCursor(30,10);
display.print(t);
display.print(" ");
display.setTextSize(1);
display.cp437(true);
display.write(167);
display.setTextSize(2);
display.print("C");
// display pressure
display.setTextSize(1);
display.setCursor(0, 35);
display.print("Pressure: ");
display.setTextSize(2);
display.setCursor(30, 45);
display.print(h/1000);
display.print("kPa");
display.display();
}
I found this code from this blog, and modified it to my liking. And I just realized, the blog talks about the same project and she’s from the same class as I am but a year above me hahaha. So thankyou kak, for making my work easier :D
Basically using the above code, instead of using Serial.println(bmp.readxxxx), we use display.print. The code is a bit tricky, because we have to set the position using setCursor, adjust the font size using setTextSize, etc. After we ran the code, here’s what I got
Problems I encountered during the project
There are lots of problem I encounter while doing this project
- The code won’t detect the BMP280 sensor
I was so frustrated at first, because the code won’t detect my BMP280 sensor. It turns out, it’s my faulty wiring because, I didn’t know that BME280 and BMP280 have different pin positions. At first, I thought the adjacent ports are — in order — VCC, GND, SDA, SCL, just like the BME280. Turns out, it was VCC, GND, SCL, SDA. I spend 2 days trying to figure out what’s wrong, only to realize the pin was printed IN THE BACK OF THE SENSOR :D
2. The OLED screen won’t turn on
This may be because the OLED screen I bought isn’t the original one, so if the wirings are not intact/loose, it won’t turn on
3. The OLED won’t print the desired output
This is because I set the font too big and way outside the screen size, which is 128x64. That way, I can’t see the text outside of that number
That’s it for today, thankyou for reading! Peace!