Enviro+++ sort of kind of. =)

I’ve been working on this for a while and finally got it all working on a solderless breadboard setup.
I have three of the 0.96" SPI Color LCD (160x80) Breakouts wired up on SPI1, CE0, CE1, CE2. This is the display the Enviro+ uses. I also have a BME280 wired up to i2c.
I’m running a modified all-in-one-enviro-mini python example file. Instead of showing the Temperature “or” Humidity “or” Barometric Pressure graph, I show all three at the same time, one on each display. I striped out the proximity detection cycle the display parts.
Also played around with the sampling rates. Temp and humidity get get plotted every 9 seconds. That gets me about 13 minutes of data across the screen. Pressure is plotted every 45 seconds for 2 hours of data across the screen. The Barometric pressure changes so slowly that unless I plot over a long time I just can’t see a trend up or down.
On the other side of the coin, temp and especially humidity often change at a much faster rate. Long delays between samples gives me a jerky plot. Basically this is what works for “me”.
I also did a quick fill with no delay in the first 160 plots. This gets a graph up on screen quickly on boot up.
My python skills are average. There is likely code in there I could have removed or changed or simplified. It is what it is though and works for me.

#!/usr/bin/env python3

import time
import colorsys
import os
import sys
import ST7735
import RPi.GPIO as GPIO
import logging

from sys import exit
from bme280 import BME280
from subprocess import PIPE, Popen
from PIL import Image
from PIL import ImageDraw
from PIL import ImageFont
from fonts.ttf import RobotoMedium as UserFont

def Shutdown(channel):  
    os.system("sudo shutdown now -P")
    time.sleep(30)

GPIO.setmode(GPIO.BCM)  
GPIO.setwarnings(False)
GPIO.setup(26, GPIO.IN, pull_up_down = GPIO.PUD_UP)

GPIO.add_event_detect(26, GPIO.FALLING, callback = Shutdown, bouncetime = 2000)

logging.basicConfig(
    format='%(asctime)s.%(msecs)03d %(levelname)-8s %(message)s',
    level=logging.INFO,
    datefmt='%Y-%m-%d %H:%M:%S')

logging.info("""Displays readings from BME280 sensor
Press Ctrl+C to exit!
""")

# BME280 temperature/pressure/humidity sensor
bme280 = BME280()

# Create ST7735 LCD display class

disp1 = ST7735.ST7735(
    port=1,
    cs=0, 
    dc=19,
    backlight=5, 
    rotation=90,
    spi_speed_hz=10000000
)

disp2 = ST7735.ST7735(
    port=1,
    cs=1, 
    dc=19,
    backlight=6, 
    rotation=90,
    spi_speed_hz=10000000
)

disp3 = ST7735.ST7735(
    port=1,
    cs=2, 
    dc=19,
    backlight=13, 
    rotation=90,
    spi_speed_hz=10000000
)

# Initialize display

disp1.begin()
WIDTH = disp1.width
HEIGHT = disp1.height

disp2.begin()
WIDTH = disp2.width
HEIGHT = disp2.height

disp3.begin()
WIDTH = disp2.width
HEIGHT = disp2.height

# Set up canvas and font
img = Image.new('RGB', (WIDTH, HEIGHT), color=(0, 0, 0))
draw = ImageDraw.Draw(img)
path = os.path.dirname(os.path.realpath(__file__))
font_size = 20
font = ImageFont.truetype(UserFont, font_size)

message = ""

# The position of the top bar
top_pos = 25


# Displays data and text on the 0.96" LCD
def display_text1(variable, data, unit):
    values[variable] = values[variable][1:] + [data]
    vmin = min(values[variable])
    vmax = max(values[variable])
    colours = [(v - vmin + 1) / (vmax - vmin + 1) for v in values[variable]]
    message = "{}:{:.0f}{}".format(variable[:11],data,unit)
    logging.info(message)
    draw.rectangle((0, 0, WIDTH, HEIGHT), (255, 255, 255))
    for i in range(len(colours)):
        colour = (1.0 - colours[i]) * 0.6
        r, g, b = [int(x * 255.0) for x in colorsys.hsv_to_rgb(colour, 1.0, 1.0)]
        draw.rectangle((i, top_pos, i + 1, HEIGHT), (r, g, b))
        line_y = HEIGHT - (top_pos + (colours[i] * (HEIGHT - top_pos))) + top_pos
        draw.rectangle((i, line_y, i + 1, line_y + 1), (0, 0, 0))

    draw.text((0, 0), message, font=font, fill=(0, 0, 0))
    disp1.display(img)

def display_text2(variable, data, unit):
    values[variable] = values[variable][1:] + [data]
    vmin = min(values[variable])
    vmax = max(values[variable])
    colours = [(v - vmin + 1) / (vmax - vmin + 1) for v in values[variable]]
    message = "{}:{:.0f}{}".format(variable[:11],data,unit)
    logging.info(message)
    draw.rectangle((0, 0, WIDTH, HEIGHT), (255, 255, 255))
    for i in range(len(colours)):
        colour = (1.0 - colours[i]) * 0.6
        r, g, b = [int(x * 255.0) for x in colorsys.hsv_to_rgb(colour, 1.0, 1.0)]
        draw.rectangle((i, top_pos, i + 1, HEIGHT), (r, g, b))
        line_y = HEIGHT - (top_pos + (colours[i] * (HEIGHT - top_pos))) + top_pos
        draw.rectangle((i, line_y, i + 1, line_y + 1), (0, 0, 0))

    draw.text((0, 0), message, font=font, fill=(0, 0, 0))
    disp2.display(img)

# Displays data and text on the 0.96" LCD
def display_text3(variable, data, unit):
    values[variable] = values[variable][1:] + [data]
    vmin = min(values[variable])
    vmax = max(values[variable])
    colours = [(v - vmin + 1) / (vmax - vmin + 1) for v in values[variable]]
    message = "{}:{:.0f}{}".format(variable[:11],data,unit)
    logging.info(message)
    draw.rectangle((0, 0, WIDTH, HEIGHT), (255, 255, 255))
    for i in range(len(colours)):
        colour = (1.0 - colours[i]) * 0.6
        g, r, b = [int(x * 255.0) for x in colorsys.hsv_to_rgb(colour, 1.0, 1.0)]
        draw.rectangle((i, top_pos, i + 1, HEIGHT), (r, g, b))
        line_y = HEIGHT - (top_pos + (colours[i] * (HEIGHT - top_pos))) + top_pos
        draw.rectangle((i, line_y, i + 1, line_y + 1), (0, 0, 0))

    draw.text((0, 0), message, font=font, fill=(0, 0, 0))
    disp3.display(img)    
    

last_page = 0
light = 1

# Create a values dict to store the data
variables = ["Temperature",
             "Humidity",
             "Pressure"]

values = {}

for v in variables:
    values[v] = [1] * WIDTH

# The main loop

mode = 0
F = 0
D = 0

while True:

    
    if F < 161:
        F = F + 1 
    elif F >= 161:
        time.sleep(9)
        D = D + 1 
            
    if mode == 0:
        mode %= len(variables)
        last_page = time.time()
        # variable = "Temperature"
        unit = "C"
        data = bme280.get_temperature()
        display_text1(variables[mode], data, unit)
        mode = 1

    if mode == 1:
        mode %= len(variables)
        last_page = time.time()
        # variable = "Humidity"
        unit = "%"
        data = bme280.get_humidity()
        display_text2(variables[mode], data, unit)
        
    if D == 0:        
        mode = 2
    elif D > 0 and D < 5:
        mode = 0
    elif D == 5:
        mode = 2
        D = 0
    
    if mode == 2:
        mode %= len(variables)
        last_page = time.time()
        # variable = "Pressure"
        unit = "mb"
        data = bme280.get_pressure()
        display_text3(variables[mode], data, unit)
        mode = 0
1 Like

Just a heads up if you try to use my python code, you will need to install the needed fonts or you will get an error.
sudo pip3 install fonts
sudo pip3 install font-roboto