超簡單做出低功耗藍牙温度計-Part 3(nRF52840 Dongle + BME280 + CircuitPython)

 之前用TMP102, 只有温度值可以看, 若加上溼度值, 會更具實用性! 那就要改用別顆感測器了, 具温溼度感測功能的sensor有很多選擇, 之前試了DHT11, AM2320, BME280, 覺得BOSCH BME280比較好用, 晶片本身具有I2C, SPI界面, 有些模塊二個界面都有把pin腳引出, 有些模塊只引出I2C, 這種的價錢便宜許多。這裡, 只使用I2C, 所以寫程式方式和之前(TMP102)文章相似, 也可以使用便宜的模塊就好。

同Part 2的文章, 使用CircuitPython來實作BLE低功耗藍牙傳輸資料, 可以使用Adafruit寫好的Bluefruit Connect App, 我們只要在nRF52840 Dongle上面透過現成的BLE UART服務, 把温度和溼度的數值傳送出去給App就可以了。先看一下完成的樣子:


送出來的資料格式就是温度值接著是逗號, 然後是溼度值再接著換行符號。這樣在Plotter就會出現2條線, 一條代表温度, 一條代表溼度。

因為BLE UART服務的寫法, 之前的文章已經看過, 我們現在只要克服讀取BME280這個問題就好了。之前在使用TMP102的時候, 提過可以使用別人現成寫好的驅動, 但為了更深入掌握TMP102, 之前的文章有去了解驅動的寫法, 而且我們自己也動手寫了一支適合自己的TMP102驅動。但這其實很花時間! 在這裡, 我們直接使用現成的BME280驅動。一樣去CircuitPython Librarys (adafruit cricuitpython bundle)找就有 (adafruit_bme280), 如下圖, 把這個目錄複製到開發板上的lib目錄下面:


我買的BME280, 如下圖, 只用到左邊4支接腳(VCC, GND, SCL, SDA)。
同樣接到nRF52840 Dongle的(VDD OUT, GND, 0.31, 0.29), 如下圖圈起處:

把下面程式存入至Dongle上面的code.py, Ctr-D, 同樣由終端機來觀察看看, 如果都成功取得數值, 那麼就成功連通BME280了。
import time
import board
import busio
from adafruit_bme280 import basic as adafruit_bme280

i2c = busio.I2C(board.P0_31, board.P0_29)
bme280 = adafruit_bme280.Adafruit_BME280_I2C(i2c, 0x76)

# change this to match the location's pressure (hPa) at sea level
bme280.sea_level_pressure = 1013.25

while True:
    print("\nTemperature: %0.1f C" % bme280.temperature)
    print("Humidity: %0.1f %%" % bme280.relative_humidity)
    print("Pressure: %0.1f hPa" % bme280.pressure)
    print("Altitude = %0.2f meters" % bme280.altitude)
    time.sleep(2)
這段程式裡, BME280的I2C設備位址必須指明為0x76, 如果不指定, 預設為0x77。我買的這顆BME280模塊可以由SDO腳位來決定其I2C設備位址, SDO為high時位址為0x77, 否則為0x76。為了線路簡化, 就使用0x76位址吧!

接著把以下程式放到Dongle的code.py, 同樣重開機, 就可以打開手機Bluefruit connect App來查看温溼度的數值了。
簡單吧! 只要接對線, 複製現成的驅動, 加上以下現成程式, 就完成了。

# CircuitPython Bluefruit LE Connect Plotter Example

import time
import board
import busio
from adafruit_ble import BLERadio
from adafruit_ble.advertising.standard import ProvideServicesAdvertisement
from adafruit_ble.services.nordic import UARTService

from adafruit_bme280 import basic as adafruit_bme280
i2c = busio.I2C(board.P0_31, board.P0_29)
bme280 = adafruit_bme280.Adafruit_BME280_I2C(i2c, 0x76)

ble = BLERadio()
uart_server = UARTService()
advertisement = ProvideServicesAdvertisement(uart_server)


while True:
    # Advertise when not connected.
    ble.start_advertising(advertisement)
    while not ble.connected:
        pass
    ble.stop_advertising()

    while ble.connected:
        tempc = bme280.temperature
        humidity = bme280.relative_humidity
        print("{}, {}".format(tempc, humidity))
        uart_server.write("{}, {}\n".format(tempc, humidity))
        time.sleep(2.0) 

留言

這個網誌中的熱門文章

D-BUS學習筆記

Cisco Switch學習筆記: EtherChannel

Cisco Switch學習筆記: interface的封包錯誤統計