#4 — The ESP32 with I2C Communication

It’s integrating time!

Carissa Aurelia
I learn ESP32 (and you should too).
5 min readFeb 24, 2020

--

Integration. Photo by Clay Banks on Unsplash

So we’ve tried measuring the temperature, altitude, pressure, and sea level pressure using the BMP180 sensor. And we’ve tried displaying several kind of texts on the LCD screen. Now it’s time to combine them.

Did I just say combine? What do they have in common?

I2C Communication Protocol

You’ve probably noticed that I mentioned I2C quite a lot in my medium blogs. The BMP180 sensor uses I2C to communicate with the ESP32 board. And the LCD that I used is “backpacked” with an I2C module. So what exactly an I2C is?

A sample diagram illustrating I2C communication.

I2C (I-squared-C) stands for Inter-Integrated Circuit. According to randomnerdtutorials.com, it is a synchronous, multi-master, multi-slaves communication protocol. With I2C, we can connect multiple slaves to one master, or the other way around. Put it simply, this is one of the communication protocols that we can use with the ESP32 so that it can “communicate” with external devices like sensors and displays. The I2C protocol uses 2 wires, namely SCL for sending the clock signal and SDA to receive and transmit data, aside from the GND (ground) wire and the VCC (voltage) wire. That’s a total of 4 wires in each I2C device.

As I’ve previously mentioned, using the devices that I’ve already owned, I’ll create a circuit connecting the ESP32 board, the BMP180 sensor, and the LCD. The goal is to output the BMP180 sensor readings to the LCD screen.

1. The Ingredients

The ingredients.

To create this project, I’ll be using my laptop, a 38 pins ESP32 board, a breadboard, a MicroUSB to USB cable, a few male-to-female dan male-to-male jumper wires, a 16x2 I2C LCD, and a BMP180 sensor.

2. Getting the device address

You’ve probably thought at one point after reading about the I2C protocol: “How is the one device suppose to communicate with more than one devices without confusing which is which???”

Because same; I thought that too.

That’s where the device address comes to the rescue! *heroic sfx, please*

The device address is 8 bits long and is written in hexadecimal form. It should be different for every kind of device so it’ll be easy for the master devices to know which slave devices is which when communicating with them. The randomnerdtutorials.com website that I’ve linked before provided a nice, easy and clean code to get the device address via the serial monitor.

I run this code twice for both the I2C LCD and the BMP180 sensor. You need to wire each of the devices separately. Simply plug in the ESP32 board into the computer and uploaded the code. Then open the serial monitor at 115200 baud rate to get the result.

BMP180 address (left) and LCD address (right).

I get my LCD address at 0x3F and my BMP180 address at 0x77. This is the address that I’ll be using in the project code.

3. Wiring it out

To be honest, it was a bit of a daunting task for me at first. I’ve never wired more than 1 external device to the ESP32 board. The randomnerdtutorials.com website only provides me with an example on how to get sensor readings from a BME280 sensor (via I2C) and displays the results on an I2C OLED display (read here). But since all devices in the example and my own devices use I2C communication protocols, the wirings should be exactly the same. Kudos to my project partner

for helping me out!

Wiring layout for connecting 30 pins ESP32 board, OLED display, and BME280 sensor (left) and the wiring table for connecting general I2C device (right).

Basically, the only thing that I changed from the wiring layout is the VCC pin wiring (the red coloured cable on the left picture). The LCD needs to be connected to the 5V pin on the ESP32 and the BMP180 to the 3.3V pin. And so, we’re good to go!

Wire, wire, wire!

4. Displaying the BMP180 readings on LCD

Did I say the wiring was daunting?

The coding was even more daunting 😈😈😈

BME280 sensor and the OLED display are totally different entities from BMP180 sensor and LCD display, which means that the coding will look much different from the one provided in the randomnerdtutorials.com. BUT! No worries! After googling around for a good 30 minutes and studying the code from the previous projects, I was able to produce my own code for this project! (yaaay 👏👏👏)

Basically I’ll set up both the devices using their respective addresses and make sure that they are properly connected. Then I’ll proceed to print the readings to the screen. The readings will cycle from the temperature reading on the top row followed by the pressure reading on the bottom row, to the altitude reading on the top row followed by the sea level pressure reading on the bottom row. Each reading will be displayed for one second in a continuous loop.

Upload the code to the board (and be extremely patient with uploading, as usual), ignore the warning that appears, and then you’ll see the readings on the display!

Readings on the screen!!!

5. Lessons learnt

  • When the code had done uploading for the first time, I was under the impression that it didn’t work because the screen displays nothing. My project partner who sat across me noticed, from a different angle, that the screen actually displays the reading. We borrowed a key (yes, a door key 😅) to turn up the contrast of the screen using the built-in potentiometer at the back of the screen. You can guess: the readings appeared before our very eyes! I speculate that voltage was the cause of the low screen contrast (because it was divided among the devices in the circuit and hence became low). Lesson learnt: sometimes, it wasn’t the code’s mistakes! Aside from the major elements of the circuit, you have to pay attention to the subtle elements as well.

--

--