Showing posts with label Humidity. Show all posts
Showing posts with label Humidity. Show all posts

Saturday, 13 June 2020

Pimoroni Envirobit

Pimoroni Envirobit


The Pimoroni Envirobit is a set of sensors for the BBC Micro:Bit .


As you can see, it is equipped with a slot to take the Micro:Bit, so no soldering is required.

The Envirobit is fitted with the following sensors:

  • BME280 environmental sensor - which measures temperature, pressure, humidity and can calculate the altitude based on a supplied base pressure level (discuss).
  • tcs3472 RGB sensor - which measures Red Green and Blue light levels as well as “white” light levels. Also includes two illuminating (white) LEDs,
  • Sound - a small microphone allows the sound level to be measured on one of the Micro:Bit’s analogue pins

Assembly

Assembly is simple. Take the Envirobit board with the sensors facing forward, and insert the Micro:Bit with the LEDs also facing forward.
Due to the nature of the connection, you can swap the Microbits if the colour scheme does not match your needs.

Software

The main software support for the Envirobit is orientated towards the Microsoft MakeCode block based system.
There is some support for MicroPython. There is a GitHub link here: https://github.com/pimoroni/micropython-envirobit

There are three python files in the Library.
  • sound.py
  • bme280.py
  • tcs3472.py

The files can be transferred to your Micro:Bit using the Files function in Mu.

Sound

Contrary to the description on GitHub, this is not a class, just three methods.

  • sound.read() - This takes a reading of the sound level and returns a value between 0 and 440. There is an offset value in the code to set the minimum sensitivity.
  • sound.wait_for_double_clap() - listen for two high level sound events in a second, returns True if detected
  • sound.wait_for_clap() - listen for a single high sound level event in a second, returns True if detected

tcs3472

This uses a class to access the TCS3472 sensor via I2C.
To use the sensor, import the module (having transferred it to the Micro:Bit) and instantiate an instance.
import tcs3472
light_sensor = tcs3472.tcs3472() 
Methods:

  • r, g, b = light_sensor.rgb() - returns a tuple of the corrected levels of red, green and blue out of 255
  • r, g, b = light_sensor.scaled() - return a tuple of the amounts of red, green and blue on a scale of 0-1
  • level = light_sensor.light() - return a raw reading of light level on a scale of 0-65535
  • light_sensor.set_leds(0) - Turn the LEDs off
  • light_sensor.set_leds(1) - Turn the LEDs on

BME280

This uses a class to access the BME280 sensor via I2C.
The instructions on GitHub are incorrect, there is a missing () on the end of the class instantiation. Python can be very unforgiving if you make a mistake of this kind.
import bme280
bme = bme280.bme280()

The bme280 class has the following methods:

  • temp = bme.temperature() - return the temperature in degrees C
  • pressure = bme.pressure() - return the pressure in hectopascals
  • humidity = bme.humidity() - return the relative humidity in %
  • alt = bme.altitude() - return the altitude in feet, calculated against the current QNH value
  • bme.set_qnh(value) - set the QNH value for calculating altitude

QNH is the atmospheric pressure adjusted to sea level (what the pressure sensor should read at sea level).
https://en.wikipedia.org/wiki/QNH

References

https://github.com/pimoroni/micropython-envirobit
https://en.wikipedia.org/wiki/QNH


Sunday, 5 April 2020

Pimoroni BME680 Environment sensor

So, having a display is all well and good, but now you need something to display.

The Pimoroni BME680 breakout board has a Bosch BME680 temperature, pressure, humidity and air quality sensor.

The following code assumes you have the BME680 and the SH1106 OLED display on the default I2C addresses.

import os
import time
import datetime
import sys

from PIL import Image

from PIL import ImageFont
from PIL import ImageDraw

import bme680

from luma.core.interface.serial import i2c
from luma.oled.device import sh1106
from luma.core.render import canvas

TEMPERATURE_UPDATE_INTERVAL = 0.1  # in seconds


# Temperature offset 

TEMP_OFFSET = 0.0

print("Temperature/pressure monitor - OLED")

print("Initialising")

# Instantiate object for SH1106 OLED display

oled = sh1106(i2c(port=1, address=0x3C), rotate=2, height=128, width=128)

# Instantiate object to read  BME680 sensor

sensor = bme680.BME680()

# Set up the sensors

sensor.set_humidity_oversample(bme680.OS_2X)
sensor.set_pressure_oversample(bme680.OS_4X)
sensor.set_temperature_oversample(bme680.OS_8X)
sensor.set_filter(bme680.FILTER_SIZE_3)
sensor.set_temp_offset(TEMP_OFFSET)

# Build the fonts

rr_path = os.path.abspath(os.path.join(os.path.dirname(__file__), 'fonts',
                                       'Roboto-Regular.ttf'))
rb_path = os.path.abspath(os.path.join(os.path.dirname(__file__), 'fonts',
                                       'Roboto-Black.ttf'))
rr_24 = ImageFont.truetype(rr_path, 24)
rb_20 = ImageFont.truetype(rb_path, 20)
rr_15 = ImageFont.truetype(rr_path, 15)
rr_40 = ImageFont.truetype(rr_path, 40)

# Get sensor data first so that device settings take effect

sensor.get_sensor_data()
# Get the initial date/time and max/min temperature
low_temp = sensor.data.temperature
high_temp = sensor.data.temperature
curr_date = datetime.date.today().day

last_checked = time.time()


# Main loop

while True:
    if sensor.get_sensor_data():
        temp = sensor.data.temperature
        press = sensor.data.pressure
        humidity =sensor.data.humidity
        if datetime.datetime.today().day == curr_date:
            if temp < low_temp:
                low_temp = temp
            elif temp > high_temp:
                high_temp = temp
        else:
            curr_date = datetime.datetime.today().day
            low_temp = temp
            high_temp = temp

        # Write data to canvas

        with canvas(oled) as draw:
            draw.text((65, 55), u"{0:4.0f}".format(press), fill="white", font=rb_20)
            draw.text((1, 55), u"{0:2.1f}%".format(humidity), fill="white", font=rb_20)
            draw.text((1, 1), u"{0:2.0f}°".format(temp), fill="white", font=rr_40)

            draw.text((65, 4), u"max: {0:2.0f}°".format(high_temp), fill="white", font=rr_15)

            draw.text((65, 30), u"min: {0:2.0f}°".format(low_temp), fill="white", font=rr_15)

            if int(time.time()) % 2 == 0:

                draw.text((14, 78), datetime.datetime.now().strftime("%H:%M"),
                          fill="white", font=rr_40)
            else:
                draw.text((14, 78), datetime.datetime.now().strftime("%H %M"),
                          fill="white", font=rr_40)

    time.sleep(TEMPERATURE_UPDATE_INTERVAL)


And this is the result.

There is a potential issue with the temperature. The temperature sensor is directly above the Raspberry Pi Zero, and more importantly close to being above the processor. This does mean that the heat from the processor may well be affecting the temperature being sensed and hence displayed.

Dealing with that is for the next instalment.