Guten Tag,
ich habe mir nun auch ein kleines Pico zugelegt und schon das erste fast brauchbare Programm dafür geschrieben.
Meine erste Frage wäre:
- Wie kann man den STRING speziell in der Zeile für die Luftfeuchtigkeit so formatieren, damit auch das "%" Zeichen mit angezeigt wird ?
Ich nachfolgenden Schritt würde ich gern noch eine Funktion via eines angeschlossenen Tasters ergänzen, damit mir auf dem Display nicht nur die aktuellen Werte angezeigt werden, sondern auch zwei Graphen angezeigt werden, wie der Temperaturverlauf und der Verlauf der Luftfeuchtigkeit der letzten 24 Stunden angezeigt wird. Um auf den Display mit einer Breite von 128 Pixeln einen vollständigen Tagesgraphen darzustellen, müßte ich somit wenn meine Berechnungen stimmen aller 11 1/4 Minuten eine Messung durchführen.
Dazu meine zweite Frage:
- Wie kann man am geschicktesten 2 x 128 Meßwerte zwischenspeichern ?
Hierzu dann auch die nächste Frage:
- Wie bewerkstelligt man es, damit diese Speicherliste immer die Größe von maximal 128 Meßwerten beibehält ? Somit am zweiten Tag oder nach 24 Stunden nicht mehr Meßwerte beinhaltet als dargestellt werden können.
Im Weiteren:
- Wie setzt man eine Tasterabfrage so um, dass diese erst dann zu einem Unterprogramm- / Funktionsaufruf führt, wenn auch schon genügend Meßwerteinträge vorhanden sind ?
- Wie kann man erreichen, dass die grafische Darstellung nur für eine gewisse Zeit z.B. 30 Sekunden Bestand hat, und dann wieder auf die ursprüngliche Anzeige mit den zuletzt gemessenen Werte zurückgeschaltet wird ?
Und als letzte Frage:
- Wie skaliert man die gespeicherten Meßwerte für die grafische Meßwertdarstellung so, dass diese für die Displayhöhe passend sind ?
from machine import Pin, I2C
from hdy21 import HTU21D
from utime import sleep
import ssd1306
display_witdh = 128
display_height = 64
button_pin = 3
sda_pin = 0
scl_pin = 1
i2c_bus = I2C(0, sda=Pin(sda_pin), scl=Pin(scl_pin))
display = ssd1306.SSD1306_I2C(display_witdh, display_height, i2c_bus)
sensor = HTU21D(i2c_bus)
button = Pin(button_pin, Pin.IN)
while True:
temp = str(sensor.temperature)
humi = str(sensor.humidity)
display.fill(0)
display.text(temp, 0,0)
display.text(humi, 0,16)
display.show()
sleep(10)
Display More
from machine import I2C, Pin
import time
class HTU21D(object):
ADDRESS = 0x40
ISSUE_TEMP_ADDRESS = 0xE3
ISSUE_HU_ADDRESS = 0xE5
def __init__(self, I2C_bus):
"""Initiate the HUT21D
Args:
scl (int): Pin id where the sdl pin is connected to
sda (int): Pin id where the sda pin is connected to
"""
self.i2c = I2C_bus
def _crc_check(self, value):
"""CRC check data
Notes:
stolen from https://github.com/sparkfun/HTU21D_Breakout
Args:
value (bytearray): data to be checked for validity
Returns:
True if valid, False otherwise
"""
remainder = ((value[0] << 8) + value[1]) << 8
remainder |= value[2]
divsor = 0x988000
for i in range(0, 16):
if remainder & 1 << (23 - i):
remainder ^= divsor
divsor >>= 1
if remainder == 0:
return True
else:
return False
def _issue_measurement(self, write_address):
"""Issue a measurement.
Args:
write_address (int): address to write to
:return:
"""
#self.i2c.start()
self.i2c.writeto_mem(int(self.ADDRESS), int(write_address), '')
#self.i2c.stop()
time.sleep_ms(50)
data = bytearray(3)
self.i2c.readfrom_into(self.ADDRESS, data)
if not self._crc_check(data):
raise ValueError()
raw = (data[0] << 8) + data[1]
raw &= 0xFFFC
return raw
@property
def temperature(self):
"""Calculate temperature"""
raw = self._issue_measurement(self.ISSUE_TEMP_ADDRESS)
return -46.85 + (175.72 * raw / 65536)
@property
def humidity(self):
"""Calculate humidity"""
raw = self._issue_measurement(self.ISSUE_HU_ADDRESS)
return -6 + (125.0 * raw / 65536)
def test(self):
print("estoy dentro")
'''
lectura = HTU21D(22,21)
hum = lectura.humidity
temp = lectura.temperature
print('Humedad: ', + hum)
print('Temperatura: ', + temp)
'''
Display More
# MicroPython SSD1306 OLED driver, I2C and SPI interfaces
from micropython import const
import framebuf
# register definitions
SET_CONTRAST = const(0x81)
SET_ENTIRE_ON = const(0xA4)
SET_NORM_INV = const(0xA6)
SET_DISP = const(0xAE)
SET_MEM_ADDR = const(0x20)
SET_COL_ADDR = const(0x21)
SET_PAGE_ADDR = const(0x22)
SET_DISP_START_LINE = const(0x40)
SET_SEG_REMAP = const(0xA0)
SET_MUX_RATIO = const(0xA8)
SET_IREF_SELECT = const(0xAD)
SET_COM_OUT_DIR = const(0xC0)
SET_DISP_OFFSET = const(0xD3)
SET_COM_PIN_CFG = const(0xDA)
SET_DISP_CLK_DIV = const(0xD5)
SET_PRECHARGE = const(0xD9)
SET_VCOM_DESEL = const(0xDB)
SET_CHARGE_PUMP = const(0x8D)
# Subclassing FrameBuffer provides support for graphics primitives
# http://docs.micropython.org/en/latest/pyboard/library/framebuf.html
class SSD1306(framebuf.FrameBuffer):
def __init__(self, width, height, external_vcc):
self.width = width
self.height = height
self.external_vcc = external_vcc
self.pages = self.height // 8
self.buffer = bytearray(self.pages * self.width)
super().__init__(self.buffer, self.width, self.height, framebuf.MONO_VLSB)
self.init_display()
def init_display(self):
for cmd in (
SET_DISP, # display off
# address setting
SET_MEM_ADDR,
0x00, # horizontal
# resolution and layout
SET_DISP_START_LINE, # start at line 0
SET_SEG_REMAP | 0x01, # column addr 127 mapped to SEG0
SET_MUX_RATIO,
self.height - 1,
SET_COM_OUT_DIR | 0x08, # scan from COM[N] to COM0
SET_DISP_OFFSET,
0x00,
SET_COM_PIN_CFG,
0x02 if self.width > 2 * self.height else 0x12,
# timing and driving scheme
SET_DISP_CLK_DIV,
0x80,
SET_PRECHARGE,
0x22 if self.external_vcc else 0xF1,
SET_VCOM_DESEL,
0x30, # 0.83*Vcc
# display
SET_CONTRAST,
0xFF, # maximum
SET_ENTIRE_ON, # output follows RAM contents
SET_NORM_INV, # not inverted
SET_IREF_SELECT,
0x30, # enable internal IREF during display on
# charge pump
SET_CHARGE_PUMP,
0x10 if self.external_vcc else 0x14,
SET_DISP | 0x01, # display on
): # on
self.write_cmd(cmd)
self.fill(0)
self.show()
def poweroff(self):
self.write_cmd(SET_DISP)
def poweron(self):
self.write_cmd(SET_DISP | 0x01)
def contrast(self, contrast):
self.write_cmd(SET_CONTRAST)
self.write_cmd(contrast)
def invert(self, invert):
self.write_cmd(SET_NORM_INV | (invert & 1))
def rotate(self, rotate):
self.write_cmd(SET_COM_OUT_DIR | ((rotate & 1) << 3))
self.write_cmd(SET_SEG_REMAP | (rotate & 1))
def show(self):
x0 = 0
x1 = self.width - 1
if self.width != 128:
# narrow displays use centred columns
col_offset = (128 - self.width) // 2
x0 += col_offset
x1 += col_offset
self.write_cmd(SET_COL_ADDR)
self.write_cmd(x0)
self.write_cmd(x1)
self.write_cmd(SET_PAGE_ADDR)
self.write_cmd(0)
self.write_cmd(self.pages - 1)
self.write_data(self.buffer)
class SSD1306_I2C(SSD1306):
def __init__(self, width, height, i2c, addr=0x3C, external_vcc=False):
self.i2c = i2c
self.addr = addr
self.temp = bytearray(2)
self.write_list = [b"\x40", None] # Co=0, D/C#=1
super().__init__(width, height, external_vcc)
def write_cmd(self, cmd):
self.temp[0] = 0x80 # Co=1, D/C#=0
self.temp[1] = cmd
self.i2c.writeto(self.addr, self.temp)
def write_data(self, buf):
self.write_list[1] = buf
self.i2c.writevto(self.addr, self.write_list)
class SSD1306_SPI(SSD1306):
def __init__(self, width, height, spi, dc, res, cs, external_vcc=False):
self.rate = 10 * 1024 * 1024
dc.init(dc.OUT, value=0)
res.init(res.OUT, value=0)
cs.init(cs.OUT, value=1)
self.spi = spi
self.dc = dc
self.res = res
self.cs = cs
import time
self.res(1)
time.sleep_ms(1)
self.res(0)
time.sleep_ms(10)
self.res(1)
super().__init__(width, height, external_vcc)
def write_cmd(self, cmd):
self.spi.init(baudrate=self.rate, polarity=0, phase=0)
self.cs(1)
self.dc(0)
self.cs(0)
self.spi.write(bytearray([cmd]))
self.cs(1)
def write_data(self, buf):
self.spi.init(baudrate=self.rate, polarity=0, phase=0)
self.cs(1)
self.dc(1)
self.cs(0)
self.spi.write(buf)
self.cs(1)
Display More
Die beiden Library habe ich mir aus dem Internet besorgt. Das Grundprogramm noch ohne Wertformatierung funktioniert auch schon soweit.