032 - MicroPython TechNotes: BMP280 Sensor

Introduction

In this article, we will learn to use the BMP280 sensor with ESP32 using MicroPython.

Pinout

  1. GND – for the ground pin.
  2. VCC – for the supply voltage.
  3. SDA – for the i2c serial data pin.
  4. SCL – for the i2c serial clock pin.

Bill Of Materials

  1. ESP32 development board.
  2. ESP32 shield from Gorillacell ESP32 development kit.
  3. 4-pin female-female dupont wires.
  4. BMP280 temperature, pressure, and altitude sensor module.

Hardware Instruction

  1. First, attach the ESP32 board on top of the ESP32 shield making sure that both USB port are on the same side.
  2. Next, attach the dupont wires to the BMP280 sensor by following a color coding which is black for the ground, red for the VCC, yellow for the SDA pin, and white for the SCL pin.
  3. Next, attach the other end of the dupont wires to the ESP32 shield by matching the colors of the wires to the colors of the pin headers which is black to black, red to red, yellow and the following colors to the yellow pin headers. For this, I choose GPIO 21 for the SDA pin and GPIO 22 for the SCL pin.
  4. Next, power the ESP32 shield with an external power supply with a type-C USB connector and make sure that the power switch is set to ON state.
  5. Lastly, connect the ESP32 to the computer through the micro USB cable.

Software Instruction

  1. Copy and paste the bmp280.py to Thonny IDE and save it to ESP32 MicroPython device root directory by clicking the File menu and select Save As. Click MicroPython Device and save it as bmp280.py.
  2. Copy and paste the examples to Thonny IDE. You may modify it according to your needs.
  3. Happy tinkering.

Video Demonstration

Call To Action

For any concern, write your message in the comment section.

You might also like to support my journey on Youtube by Subscribing. Click this to Subscribe to TechToTinker.

Thank you and have a good days ahead.

See you,

– George Bantique | tech.to.tinker@gmail.com

Source Code

1. Example # 1, exploring the basics of BMP280 sensor:

 1# More details can be found in TechToTinker.blogspot.com 
 2# George Bantique | tech.to.tinker@gmail.com
 3
 4from machine import Pin
 5from machine import I2C
 6from bmp280 import BMP280
 7
 8i2c_bus = I2C(0, sda=Pin(21), scl=Pin(22))
 9bmp = BMP280(i2c_bus)
10
11# The following lines of code should be tested in the REPL:
12# 1. To get envirment temperature (^C):
13# bmp.getTemp()
14#
15# 2. To get Pressure (hPa):
16# bmp.getPress()
17#
18# 3. To calculate absolute altitude (m):
19# bmp.getAlti()

2. Example # 2, displaying the BMP280 sensor readings in the OLED display:

 1# More details can be found in TechToTinker.blogspot.com 
 2# George Bantique | tech.to.tinker@gmail.com
 3
 4from machine import Pin
 5from machine import I2C
 6from bmp280 import BMP280
 7from ssd1306 import SSD1306_I2C
 8import freesans20
 9from writer_minimal import Writer
10from time import sleep_ms
11
12oled_i2c = I2C(0, scl=Pin(22), sda=Pin(21), freq=400000) 
13oled = SSD1306_I2C(128, 64, oled_i2c, addr=0x3C)
14font_writer = Writer(oled, freesans20)
15
16bmp_bus = I2C(0, sda=Pin(21), scl=Pin(22))
17bmp = BMP280(bmp_bus)
18
19while True:
20    # Get the current readings
21    temp = bmp.getTemp()
22    press = bmp.getPress()
23    alti = bmp.getAlti()
24
25    # Update the OLED with current readings
26    oled.fill(0)
27    font_writer.set_textpos(0, 0)
28    font_writer.printstring('T:{:.2f}^C'.format(temp))
29    font_writer.set_textpos(20, 0)
30    font_writer.printstring('P:{:.0f}hPa'.format(press))
31    font_writer.set_textpos(40, 0)
32    font_writer.printstring('A:{:.2f}m'.format(alti))
33    oled.show()
34    
35    # Also send to the REPL the current readings
36    print('T:{:.2f}^C'.format(temp),
37          'P:{:.0f}hPa'.format(press),
38          'A:{:.2f}m'.format(alti))
39    
40    # Read and update only every 1000 ms
41    sleep_ms(1000)

3. bmp280.py driver library for BMP280:

 1 '''  
 2   mpy drive for BMP280 Digital Pressure Sensor  
 3   Author: shaoziyang  
 4   Date:  2018.2  
 5   http://www.micropython.org.cn  
 6 '''  
 7 from micropython import const  
 8 from machine import I2C  
 9 BMP280_I2C_ADDR = const(0x76)  
10 class BMP280():  
11   def __init__(self, i2c):  
12     self.i2c = i2c  
13     self.tb = bytearray(1)  
14     self.rb = bytearray(1)  
15     self.dig_T1 = self.get2Reg(0x88)  
16     self.dig_T2 = self.short(self.get2Reg(0x8A))  
17     self.dig_T3 = self.short(self.get2Reg(0x8C))  
18     self.dig_P1 = self.get2Reg(0x8E)  
19     self.dig_P2 = self.short(self.get2Reg(0x90))  
20     self.dig_P3 = self.short(self.get2Reg(0x92))  
21     self.dig_P4 = self.short(self.get2Reg(0x94))  
22     self.dig_P5 = self.short(self.get2Reg(0x96))  
23     self.dig_P6 = self.short(self.get2Reg(0x98))  
24     self.dig_P7 = self.short(self.get2Reg(0x9A))  
25     self.dig_P8 = self.short(self.get2Reg(0x9C))  
26     self.dig_P9 = self.short(self.get2Reg(0x9E))  
27     self.mode = 3  
28     self.osrs_p = 3  
29     self.osrs_t = 1  
30     self.setReg(0xF4, 0x2F)  
31     self.setReg(0xF5, 0x0C)  
32     self.filter = 3  
33     self.T = 0  
34     self.P = 0  
35     self.version = '1.0'  
36   def     short(self,     dat):  
37     if dat > 32767:  
38       return dat - 65536  
39     else:  
40       return dat  
41   # set reg  
42   def     setReg(self, reg, dat):  
43     self.tb[0] = dat  
44     self.i2c.writeto_mem(BMP280_I2C_ADDR, reg, self.tb)  
45   # get reg  
46   def     getReg(self, reg):  
47     self.i2c.readfrom_mem_into(BMP280_I2C_ADDR, reg, self.rb)  
48     return self.rb[0]  
49   # get two reg  
50   def     get2Reg(self, reg):  
51     return self.getReg(reg) + self.getReg(reg+1) * 256  
52   def get(self):  
53     adc_T = (self.getReg(0xFA)<<12) + (self.getReg(0xFB)<<4) + (self.getReg(0xFC)>>4)  
54     var1 = (((adc_T>>3)-(self.dig_T1<<1))*self.dig_T2)>>11  
55     var2 = (((((adc_T>>4)-self.dig_T1)*((adc_T>>4) - self.dig_T1))>>12)*self.dig_T3)>>14  
56     t = var1+var2  
57     self.T = ((t * 5 + 128) >> 8)/100  
58     var1 = (t>>1) - 64000  
59     var2 = (((var1>>2) * (var1>>2)) >> 11 ) * self.dig_P6  
60     var2 = var2 + ((var1*self.dig_P5)<<1)  
61     var2 = (var2>>2)+(self.dig_P4<<16)  
62     var1 = (((self.dig_P3*((var1>>2)*(var1>>2))>>13)>>3) + (((self.dig_P2) * var1)>>1))>>18  
63     var1 = ((32768+var1)*self.dig_P1)>>15  
64     if var1 == 0:  
65       return # avoid exception caused by division by zero  
66     adc_P = (self.getReg(0xF7)<<12) + (self.getReg(0xF8)<<4) + (self.getReg(0xF9)>>4)  
67     p=((1048576-adc_P)-(var2>>12))*3125  
68     if p < 0x80000000:  
69       p = (p << 1) // var1  
70     else:  
71       p = (p // var1) * 2  
72     var1 = (self.dig_P9 * (((p>>3)*(p>>3))>>13))>>12  
73     var2 = (((p>>2)) * self.dig_P8)>>13  
74     self.P = p + ((var1 + var2 + self.dig_P7) >> 4)  
75     return [self.T, self.P]  
76   # get Temperature in Celsius  
77   def getTemp(self):  
78     self.get()  
79     return self.T  
80   # get Pressure in Pa  
81   def getPress(self):  
82     self.get()  
83     return self.P  
84   # Calculating absolute altitude  
85   def     getAlti(self):  
86     return 44330*(1-(self.getPress()/101325)**(1/5.255))  
87   # sleep mode  
88   def poweroff(self):  
89     self.setReg(0xF4, 0)  
90   # normal mode  
91   def poweron(self):  
92     self.setReg(0xF4, 0x2F)  

4. Copy ssd1306.py from:

https://techtotinker.com/010-micropython-technotes-0-96-oled-display/

5. Copy the custom fonts, writer_minimal.py, and freesans20.py from:

https://techtotinker.com/011-micropython-technotes-1-3-oled-display/

References And Credits

  1. Purchase your Gorillacell ESP32 development kit at: https://gorillacell.kr

  2. Zhaoziyang BMP280 driver library: https://github.com/micropython-Chinese-Community/mpy-lib/tree/master/sensor/bmp280



Posts in this series



No comments yet!

GitHub-flavored Markdown & a sane subset of HTML is supported.