The BME280 sensor
Introduction
The BEM280 is a small sensor which measures Temperature, Humidity and Pressure. It is easy to use by microcontrollers since it implements two different standard bus interfaces: I2C and SPI. Which interface is used depends on the state of the CSB line. If the line is high the I2C interface is active. If it is driven low at any point in time the chip switches to SPI mode and stays in this mode until the next power cycle. The datasheet which is required for this exercise can be downloaded here [1].
In this course we use the chip in I2C mode. We use a development board from Adafruit. The photo and the circuit diagram of this board follows here [2]:
First step
Download the data sheet and study the contents. Try to find the essential chapters which you need to study in order to read out the sensor. Identify the sections which you do not understand and discuss them with your co-students. Ask questions if you get stuck. You should be able to find out how, in principle, you would have to write a program to read out the sensor data.
In case you want to concentrate on the essentials in the datasheet:
- Look at the Key Features (2nd line) on the first page: The sensor chip supports SPI AND I2C Interfaces. We want to use the I2C interface in the exercise. You can see on the circuit diagram of the sensor module a remark, which shows you what you need to do to choose the sensor in I2C mode. Chapter 6.1 gives a more detailed explanation how the interface selection is done.
- In chapter 3 you can learn a lot about the sensor so that you can use it optimally.
- Chapter 5 is the most important chapter for using the sensor. The memory map shows all registers and their addresses which need to be used for operating the sensor. There is a table with an overview followed by a short description of how to use the registers. More detailed explanations can be found in the previous chapters.
- Chapter 4 describes how to read out the sensor and how to interpret of the values read from the sensor. Calibration data (also contained in the sensor) needs to be used to convert the retrieved values to units which we use in everyday life (degree Celsius, millibar, percent of relative humidity...). The formulas for these conversions are given in form of a C program code.
- Chapter 6 describes the digital interfaces of the sensor. It is not very interesting since it essentially describes how I2C (or SPI) works. But if you know these interfaces there is not much relevant information here. (For SPI you need to know the supported operation modes.)
Second step: Setup the hardware
It is always important to get the powering of hardware components right. Reversing the power polarity or using the wrong voltages can easily destroy the components you want to use. Therefore make sure you understand the power requirements of the components you use.
Study the circuit diagram of the Sensor board. Compare it to the datasheet of the BME280 chip where you should be able to find the power requirements of the sensor.
In the next step study the pinout of the Microcontroller board. You should be sure that you understand all power pins of the board. Look at the circuit diagram of the board if not completely sure about the meaning of the various power pins.
With this information make a sketch of how you want to wire up the power of the sensor and the Microcontroller board on your bread board.
Next you need to make a wiring plan for the I2C communication. Also here you need the pinout of the Microcontroller board and the sensor board. The ESP32 has 2 I2C interfaces on board. To which pins the I2C lines are routed is programmable with software. Any accessible GPIO which is not used for other purposes can be used. You might have seen that the development board is quite wide so that if you plug it on the bread-board only pins on one side are accessible for wire connections. Choose the pin row close to the LED (if you hold the board in front of you with the USB connector on the top and the components facing to your it is the right pin row). Now with help of the pin out diagram find some free pins. Most of the GPIO pins are indeed free to use, however there are 6 GPIO pins at the extremity of the board where the USB connector is situated which have a red exclamation mark on the pinout drawing. These pins are used internally in the WROOM module to access the flash chip and they cannot be used for normal purposes. (In special cases users might want to access these pins and this is why they have been connected also to external pins.).
Once you chose the pins you want to use, note them down for later and enter the necessary connections in your sketch and then wire up the components.
Verify your plan and wiring with somebody before powering if you are not 100% sure that everything is correct. Wrong cabling can easily destroy either the controller or the sensor.
When everything is connected correctly and you plug the USB cable in your computer you should see a red LED on the microcontroller and a green LED on the sensor board lighting up. If this is not the case quickly remove the USB cable to detach the power and check you wiring.
The first I2C access
We start modestly: We just want to read out the chip ID which is stored in a register of the BME280. Once we have done this we know that we have understood how to program the I2C communication and we can move on to read out and convert the measurements of the sensor.
In the first exercise we use the REPL.
Start your terminal emulation program and type the following commands (this example assumes you have connected the scl pin to GPIO 32 and the sda pin to GPIO 33. You can adapt the example according to your wiring.)
>>> from machine import I2C
>>> from machine import Pin
>>> i2c = I2C( 0, scl=Pin(32), sda=Pin(33), freq=100000)
>>> i2c.scan()
[119]
>>>
A mini program to read the chip ID
In this step we will use the REPL environment to execute a program which we write in a file on the host computer. The computer should read out the chip ID and print it on the console. The register with the chipID is easily found by inspecting the memory map. Write down the address of the register. Note: the address is given in hexadecimal notation (starting with 0x). But fortunately python understand hexadecimal notation...
From the previous exercise you know how to instantiate a I2C interface in python. To read a register there is the method "readfrom_mem" which you can call on your i2c device. Details of the API (i.e. the function you can call on your I2C device) can be found in the micropython documentation. (Best open it in another tab of your browser and bookmark it... you will need it over and over again.)
If you are completely lost with writing the program you can cheat and look at an example program under the "Code examples" section. However, I really recommend you to try yourself or discuss with your co-students first. (Your program just needs 4 lines if written very compact. The first two lines you know from the previous exercise...)
Once you have written your program we use the mpremote utility to start it. If your program is called readId.py then use the following command.
(Usempremote --help
to explore the functionality of this utility. More extensive documentation you find on the micropython web page.)
The chipId should be 0x60.
As we discussed in the general section about microcontrollers, usually there is only one application running on the microcontroller and it should start automatically when you power the device. If you name your program main.py
and transfer it to root of the filesystem then it will be automatically executed whenever the microcontroller starts:
Note that 'mpremote fs {something}' executes filesystem related commands on the microcontroller. Linux commands like cp, mv, ls, rm, mkdir, rmdir can be used fro example. If you have to specify files or destinations on the target system you have to put a colon (:) in front of the path. In our example ":/" means the root directory of the microcontroller.
Then make sure your terminal emulator is connected to your board. If you now reset the controller (using the reset button) or power cycle the board you will find the output of your program on the terminal output (there will be also some debugging information from the micropython environment). You can remove your main.py program with the command:
Finally write a program to read out temperature, humidity and pressure
This requires that you study a bit more the datasheet of the sensor where it is described what you need to do in order to trigger a single measurement and how to calculate the values in human friendly units. The sensor has been calibrated at the factory and the calibration constants necessary for the calculation are stored in the sensor itself (they are slightly different for each sensor). The data sheet also contains the code for the calculations. It is convenient to copy this code and adapt it to the python language.
Try to write a program which reads out the sensor data once every 5 seconds and print it on the terminal.
We will use the Sensor also in other examples later. Hence I suggest you write a re-usable python Class which you put into a class library. This library can then be re-used in other programs.
The time we have for the exercises will not allow you to write this class during the course. Hence you have two options: If you have time and if you are motivated you can try on your own at home to write this class. However, in the code example you find a template class: this is a pre-written code with some question marks for sections you have to fill in. Use this in case you cannot spend so much time on an implementation/debugging cycle.
You probably know that you have to import the classes which you want to use in your program before usage. By default python searches specific directories for the libraries you specify in the "import" statement. In micropython the directories which are searched for libraries by default are the root directory and the subdirectory "lib/". Hence you can copy all libraries you want to use in your microcontroller in one of these directories. They are stored persistently since the filesystem is implemented in the flash of the ESP32. Do not forget to copy them to the microcontroller each time you do a modification!
References
[1] The datasheet of the BME280 sensor
[2] Circuit diagram of the BME280 board
[3] Micropython_I2C_Documentation