Thank you Tonygo2, I appreciate the code, but alphanumeric is right. I am investigating the graphs on the Enviro+ (python scripts).
My code is pretty much what you have alphanumeric,we had the discussion about displaying the info on multiple screens before, and I have implemented that successfully. Since then I did notice the graphs behavior and I wasn’t happy,but always busy with something else.
I read your idea to slow down the readings for pressure and I will probably try to do that as well,but I don’t think that helps with the color issue.
My script for two 2.2" displays showing Temperature and Humidity :
import time
import colorsys
import sys
import os
import ST7789
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
import logging
logging.basicConfig(
format='%(asctime)s.%(msecs)03d %(levelname)-8s %(message)s',
level=logging.INFO,
datefmt='%Y-%m-%d %H:%M:%S')
logging.info("""2Left_Center_Temp_Hum.py - Displays readings temperature and humidity sensors
Press Ctrl+C to exit!
""")
# BME280 temperature/pressure/humidity sensor
bme280 = BME280()
#Left screen . Displays temperature
disp0 = ST7789.ST7789(
port=1,
cs=0,
dc=25,
backlight=13,
rotation=180,
spi_speed_hz=50000000
)
#Center screen. Displays humidity
disp1 = ST7789.ST7789(
port=1,
cs=2,
dc=25,
backlight=13,
rotation=180,
spi_speed_hz=50000000
)
WIDTH = 320
HEIGHT = 240
disp0.begin()
WIDTH0 = disp0.width
HEIGHT0 = disp0.height
disp1.begin()
WIDTH1 = disp1.width
HEIGHT1 = disp1.height
# Set up canvas and font
img = Image.new('RGB', (WIDTH, HEIGHT), color=(0, 0, 0))
draw = ImageDraw.Draw(img)
font_size_small = 20 # was 10
font_size_large = 30 # was 20
font = ImageFont.truetype(UserFont, font_size_large)
smallfont = ImageFont.truetype(UserFont, font_size_small)
x_offset = 2
y_offset = 2
message = ""
# The position of the top bar
top_pos = 30 # was 25
# Create a values dict to store the data
variables = ["Temperature",
"Humidity"]
units = ["C" ,
"%"]
# Define your own warning limits
# The limits definition follows the order of the variables array
# Example limits explanation for temperature:
# [4,18,28,35] means
# [-273.15 .. 4] -> Dangerously Low
# (4 .. 18] -> Low
# (18 .. 28] -> Normal
# (28 .. 35] -> High
# (35 .. MAX] -> Dangerously High
# DISCLAIMER: The limits provided here are just examples and come
# with NO WARRANTY. The authors of this example code claim
# NO RESPONSIBILITY if reliance on the following values or this
# code in general leads to ANY DAMAGES or DEATH.
limits = [[4, 18, 28, 35],
[20, 40, 60, 70]]
# RGB palette for values on the combined screen
palette = [(0, 0, 255), # Dangerously Low
(0, 255, 255), # Low
(0, 255, 0), # Normal
(255, 255, 0), # High
(255, 0, 0)] # Dangerously High
values = {}
# Displays data on Left Display.Temperature
def display_text0(variable, data, unit):
# Maintain length of list
values[variable] = values[variable][1:] + [data]
# Scale the values for the variable between 0 and 1
vmin = min(values[variable])
vmax = max(values[variable])
colours = [(v - vmin + 1) / (vmax - vmin + 1) for v in values[variable]]
# Format the variable name and value
message = "{}:{:.1f} {}".format(variable[:11], data, unit)
logging.info(message)
draw.rectangle((0, 0, WIDTH, HEIGHT), (255, 255, 255))
for i in range(len(colours)):
# Convert the values to colours from red to blue
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 a 1-pixel wide rectangle of colour
draw.rectangle((i, top_pos, i + 1, HEIGHT), (r, g, b))
# Draw a line graph in black
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))
# Write the text at the top in black
draw.text((10, 0), message, font=font, fill=(0, 0, 0))
disp0.display(img)
#Display data on Center Display.Humidity
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, WIDTH1, HEIGHT1), (255, 255, 255))
for i in range(len(colours)):
# Convert the values to colours from red to blue
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, HEIGHT1), (r, g, b))
line_y = HEIGHT1 - (top_pos + (colours[i] * (HEIGHT1 - top_pos))) + top_pos
draw.rectangle((i, line_y, i + 1, line_y + 1), (0, 0, 0))
draw.text((10, 0), message, font=font, fill=(0, 0, 0))
disp1.display(img)
# Saves the data to be used in the graphs later and prints to the log
def save_data(idx, data):
variable = variables[idx]
# Maintain length of list
values[variable] = values[variable][1:] + [data]
unit = units[idx]
message = "{}: {:.1f} {}".format(variable[:11], data, unit)
logging.info(message)
# Get the temperature of the CPU for compensation
def get_cpu_temperature():
process = Popen(['vcgencmd', 'measure_temp'], stdout=PIPE, universal_newlines=True)
output, _error = process.communicate()
return float(output[output.index('=') + 1:output.rindex("'")])
def main():
# Tuning factor for compensation. Decrease this number to adjust the
# temperature down, and increase to adjust up
# Measured with external thermometer and adjusted
factor = 22.0 # was 2.25
cpu_temps = [get_cpu_temperature()] * 5
# keep mode to display different parameters on different displays
# mode is colled below for each display
mode = 0 # The starting mode
last_page = 0
for v in variables:
values[v] = [1] * WIDTH
# The main loop
try:
while True:
# One mode for each variable
if mode == 0:
# variable = "temperature"
unit = "C"
cpu_temp = get_cpu_temperature()
# Smooth out with some averaging to decrease jitter
cpu_temps = cpu_temps[1:] + [cpu_temp]
avg_cpu_temp = sum(cpu_temps) / float(len(cpu_temps))
raw_temp = bme280.get_temperature()
data = raw_temp - ((avg_cpu_temp - raw_temp) / factor)
display_text0(variables [mode], data, unit)
mode = 1
if mode == 1:
# variable = "humidity"
unit = "%"
data = bme280.get_humidity()
display_text1(variables[mode], data, unit)
mode = 0
# Exit cleanly
except KeyboardInterrupt:
sys.exit(0)
if __name__ == "__main__":
main()
I have added back on the above script the default color values for graphs,but even without them I was getting the same result.
I will look at Tonygo2’s code and see if I can come up with some idea for python. I will also try your idea to switch red and green around.
The thing is, I was expecting to see green values when parameters are within limits established and changing colors when drifting one way or the other. In my case, it never happened. I never had any blue displayed (for lower than normal values) in normal operation. Again, when I touch the bme 280 sensor, briefly graphs work as they should ( going blue or green,etc) but very soon after,everything kinda defaults to red and the follow up like stays always high on the screen.