Author Topic: BMP280 Minimum Working Hardware  (Read 256 times)

0 Members and 1 Guest are viewing this topic.

Offline AndyP

  • Member
  • *
  • Posts: 3
BMP280 Minimum Working Hardware
« on: January 26, 2022, 03:00:14 PM »
Hi,

I'm wondering what the minimum working hardware would be to get BMP280 pressure readings into weewx.

I have a Davis Vantage Vue just installed and guess what - no one mentioned you needed a proprietary data logger so the current set up is:

Old laptop with a clean install of Ubuntu 20.04LTS hosting weewx 4.5.1 installed using the Debian  method. Luc's RTLDavis software and driver allows me to get the data from the weather station into weewx via an SDR dongle and push it out to Wunderground (IOSWES10) and WOW (Starling Castle). But no pressure readings as this is in the console not the outdoor ISS.

I could use USB, WiFi or ethernet to get the data into the laptop but what's the neatest solution to mounting the BMP280?  A Raspberry Pi 4 seems like overkill as the weewx is already hosted on the laptop.

I hope this isn't off topic.

AndyP


Offline davidmc36

  • He who dies with the most toys wins!
  • Forecaster
  • *****
  • Posts: 996
  • FN25ie61jw
    • MorewoodW34
Re: BMP280 Minimum Working Hardware
« Reply #1 on: January 26, 2022, 05:36:22 PM »
ESP 32 running a web server should make data available.

I have one that I check wirelessly with very basic web page. Surely some server that your other device can access would be simple.

Maybe even Mini Arduino passing the day into a comm port would work too.

Offline AndyP

  • Member
  • *
  • Posts: 3
Re: BMP280 Minimum Working Hardware
« Reply #2 on: January 27, 2022, 12:42:47 AM »
Thanks David,

I'll look in to the ESP32-DevKitC V4 board. I haven't come across this before but there are plenty of articles on hooking one up to a BMP280.

AndyP

Offline zoomx

  • Contributor
  • ***
  • Posts: 141
Re: BMP280 Minimum Working Hardware
« Reply #3 on: January 27, 2022, 02:12:24 PM »
Bosh BMP280 and BME280 are very common sensor on Arduino world.
Maybe you can be interested on the new BMP390

BMP388 sensor has a relative accuracy of 8 Pascals, which translates to about 0.5 meter of altitude
BMP390 sensor has a relative accuracy of 3 Pascals, which translates to about 0.25 meter of altitude

https://learn.adafruit.com/adafruit-bmp388-bmp390-bmp3xx

Offline davidmc36

  • He who dies with the most toys wins!
  • Forecaster
  • *****
  • Posts: 996
  • FN25ie61jw
    • MorewoodW34
Re: BMP280 Minimum Working Hardware
« Reply #4 on: January 27, 2022, 03:18:01 PM »
Nice. Always looking for better sensors.  [tup]

Offline AndyP

  • Member
  • *
  • Posts: 3
BMP280 Minimum Working Hardware Eventual solution
« Reply #5 on: February 05, 2022, 12:48:33 PM »
After a good deal of thought I went for:

Hardware
A Raspberry Pi Pico  https://shop.pimoroni.com/products/raspberry-pi-pico?variant=32402092326995       
Breakout Garden https://shop.pimoroni.com/products/pico-breakout-garden-pack
A BMP280 temperature & pressure sensor https://shop.pimoroni.com/products/bmp280-breakout-temperature-pressure-altitude-sensor
A USB C-A data cable to connect the Pico to the laptop.

Soldering iron not required. Assembled in 2 minutes. Micropython loaded in another 5 minutes.

Software:
Micropython from here: https://github.com/pimoroni/pimoroni-pico/releases/tag/v1.18.0   
Starter script from here: https://github.com/pimoroni/pimoroni-pico/blob/v1.18.0/micropython/examples/breakout_bmp280/demo_bmp280.py                             

The starter script ended up as this:

Code: [Select]
# Imports ##################################################################################

import time
from machine import Pin, UART # removed  Timer,
from breakout_bmp280 import BreakoutBMP280
from pimoroni_i2c import PimoroniI2C

# Setup ####################################################################################

PINS_BREAKOUT_GARDEN = {"sda": 4, "scl": 5}
# PINS_PICO_EXPLORER = {"sda": 20, "scl": 21}
led = Pin(25, Pin.OUT)
i2c = PimoroniI2C(**PINS_BREAKOUT_GARDEN)
bmp = BreakoutBMP280(i2c) # Pimoroni only provide read() and configure() methods so you might want to use your own driver for the BMP280
sR = 2.5 # Sample rate which matches that of weather station

# Initialize a UART object  ###############################################################

uart = UART(0, baudrate=9600, rx=Pin(17), tx=Pin(16, Pin.OUT ),timeout=10)

# Run #####################################################################################

while True:
    reading = bmp.read() # returns temperature (deg C), pressure (Pa)
   
    # just send the digits eg 12.34, 10142.45
    print(reading)
   
    # send a fancier feed over the link
    # print("temperature ,",reading[0],"\n")
    # eg temperature , 12.34
    # print("pressure ,",reading[1]/100, "\n") #  for sensor used at home giving raw output converted from Pa to hPa
    # eg pressure , 1014.245
    # print("Pressure = ",(reading[1]/100)+43.4489, "hPa @ Sea Level\n") # corrected  for altitude of 365M
    # eg Pressure = 1057.693 hPa @ Sea Level
    # print(time.gmtime()[3], ".", time.gmtime()[4], ":", time.gmtime()[5], " ", time.gmtime()[2], "/", time.gmtime()[1], "/", time.gmtime()[0], "\n\n", sep = '')
    # eg a timestamp 9.45:26 4/2/2022
 
    # flash the led on the pico to show the script is running
    led.toggle()
 
    # run loop again
    time.sleep(sR)

On the laptop I can receive the data and parse it as follows:

Code: [Select]
import serial
ser = serial.Serial('/dev/ttyACM0')
ser.flushInput()

while True:
    ser_bytes = ser.readline()
    b = ser_bytes.decode('UTF-8')
    b2 = b.rsplit("(")
    b3 = b2[1]
    b4 = b3.rsplit(")")
    results = b4[0].rsplit(", ")
    temperature = float(results[0])
    pressure = float(results[1])
    corPress = (pressure/100)+44
    print("temperature = ", temperature)
    print("pressure = ", pressure)
    print("Corrected pressure = ", corPress)

But the next step is to somehow merge it into the rtldavis.py feed into weewx so I have barometric pressure. I bet this will be challenging for a novice python programmer  ](*,) so if anyone has succeeded please let me know!

After 9 days, a lot of trial and error and a bit of grief from the other half I ended up with something that works and incorporates the pressure and indoor temperature into the weewx report. I suspect it is not very robust code as I am new to this but it's a start.

Code: [Select]
import sys
import syslog
import serial
import time
path_to_module = "/home/weewx/bin"
sys.path.append(path_to_module)
import weewx
from weewx.wxengine import StdService

class Add_temp_and_press(StdService):
    def __init__(self, engine, config_dict):
        super(Add_temp_and_press, self).__init__(engine, config_dict)
        # d = config_dict.get('Add_temp_and_press', {})
        # Use the loop packet event as that allows data to still get into the WeeWX database
        self.bind(weewx.NEW_LOOP_PACKET, self.load_data)

    def load_data(self, event):

        self.get_BMPpress(event)
        self.get_BMPtemp(event)
        self.get_BMPbaro(event)

            # Get inTemp data
    def get_BMPtemp(self, event):
        ser = serial.Serial('/dev/ttyACM0')
        ser.flushInput()
        ser_bytes = ser.readline()
        b = ser_bytes.decode('UTF-8')
        b2 = b.rsplit("(")
        b3 = b2[1]
        b4 = b3.rsplit(")")
        results = b4[0].rsplit(", ")
        inTemp = float(results[0])
        # NOTE: stores as degC
        event.packet['inTemp'] = float(inTemp)
        syslog.syslog(syslog.LOG_DEBUG, "Add_temp_and_press: found temperature value of %s C" % inTemp)

    # Get pressure data
    def get_BMPbaro(self, event):
        ser = serial.Serial('/dev/ttyACM0')
        ser.flushInput()
        ser_bytes = ser.readline()
        b = ser_bytes.decode('UTF-8')
        b2 = b.rsplit("(")
        b3 = b2[1]
        b4 = b3.rsplit(")")
        results = b4[0].rsplit(", ")
        barometer = (float(results[1])/100)+44
        event.packet['barometer'] = float(barometer)
        syslog.syslog(syslog.LOG_DEBUG, "Add_temp_and_press: found barometer value of %s hPa" % barometer)

    # Get absolute pressure data
    def get_BMPpress(self, event):
        ser = serial.Serial('/dev/ttyACM0')
        ser.flushInput()
        ser_bytes = ser.readline()
        b = ser_bytes.decode('UTF-8')
        b2 = b.rsplit("(")
        b3 = b2[1]
        b4 = b3.rsplit(")")
        results = b4[0].rsplit(", ")
        pressure = (float(results[1])/100)
        event.packet['pressure'] = float(pressure)
        syslog.syslog(syslog.LOG_DEBUG, "Add_temp_and_press: found pressure value of %s hPa" % pressure)
« Last Edit: February 14, 2022, 12:04:41 PM by AndyP »

 

anything