Hm dann müsste der Thread von IRQ eine Exception geworfen haben, damit der Rest aber noch weiterläuft? Aber da antwortet bestimmt noch jemand mit mehr Erfahrung.
Sonst müsstest du das Ganze am PC laufen lassen und schauen ob du Fehler bekommst? Ansonsten gibt es auch eine kleine Platine mit SD-Karten-Slot , darauf könnte man eventuell Fehler loggen. Aber vielleicht sieht auch einer noch den Fehler.
Ich hatte gerade ein paar Minuten Zeit und habe dein Code mal etwas umstrukturiert(in der Hoffnung, mir würde etwas unlogisches auffallen), ich hoffe die Funktion ist noch gleich.
Das hat sich leider etwas länger gezogen als gedacht, daher poste ich jetzt einfach mal meinen Zwischenstand, der sicherlich noch optimiert werden kann und ganz ungetestet ist:
Code: Alles auswählen
from time import sleep, sleep_ms, ticks_diff, ticks_ms
import machine
import sev2seg32
import urtc
import writer
from ds18x20 import DS18X20
from machine import Pin, SoftI2C
from onewire import OneWire
from SH1106 import SH1106_I2C
KUELWASSER_PIN = 10
AUSSEN_TEMPERATUR_PIN = 8
LED_PIN = 25
BUTTON_PIN = 7
SDA_PIN = 0
SCL_PIN = 1
# In millisecond
BOUNCE_TIME = 100
class InfoSystem:
def __init__(self, display, rtc, led, kuelwasser_sensor, aussen_temperatur_sensor):
self.display = display
self.clock = rtc
self.led = led
self.kuehlwasser_sensor = kuelwasser_sensor
self.aussen_temperatur_sensor = aussen_temperatur_sensor
self.button_state = 0
self.change_infosystem = None
self.timestamp = ticks_ms()
def update_button_state(self):
while not ticks_diff(ticks_ms(), self.timestamp) >= BOUNCE_TIME:
pass
self.timestamp = ticks_ms()
self.led.toggle()
self.button_state += 1 if self.button_state < 3 else 0
self.change_infosystem = True
def show_date_time(self):
while True:
self.display.fill(0)
datetime = self.clock.datetime()
font_writer = writer.Writer(self.display, sev2seg32)
font_writer.set_textpos(20, 30)
font_writer.printstring("{:02d}".format(datetime.hour))
font_writer.set_textpos(73, 30)
font_writer.printstring("{:02d}".format(datetime.minute))
font_writer.set_textpos(60, 23)
font_writer.printstring(":")
self.display.text(
"{:02d} / {:02d} / {}".format(
datetime.day, datetime.month, datetime.year
),
14,
7,
)
self.display.text("{:02d}".format(datetime.second), 112, 52)
self.display.text(str(datetime.second), 112, 52)
self.display.show()
if self.change_infosystem:
self.change_infosystem = False
break
sleep(1)
def show_cooling_water(self):
while True:
self.update_display(self.kuehlwasser_sensor, "Kuehlwassertemperatur")
if self.change_infosystem:
self.change_infosystem = False
break
def show_outside_temperature(self):
while True:
self.update_display(self.aussen_temperatur_sensor, "Aussentemperatur")
if self.change_infosystem:
self.change_infosystem = False
break
def update_display(self, sensor, description):
sensor.convert_temp()
sleep_ms(750)
for rom in sensor.scan():
self.display.fill(0)
self.display.text(description, 0, 10)
font_writer = writer.Writer(self.display, sev2seg32)
font_writer.set_textpos(24, 33)
font_writer.printstring("{:.3f}".format(sensor.read_temp(rom)))
font_writer.set_textpos(90, 33)
font_writer.printstring("C")
self.display.text("O", 82, 38)
self.display.show()
sleep(3)
def main():
kuehlwasser_sensor = DS18X20(OneWire(machine.Pin(KUELWASSER_PIN)))
aussen_temperatur_sensor = DS18X20(OneWire(machine.Pin(AUSSEN_TEMPERATUR_PIN)))
builtin_led = machine.Pin(LED_PIN, Pin.OUT)
i2c = SoftI2C(sda=Pin(SDA_PIN), scl=Pin(SCL_PIN))
rtc = urtc.DS3231(i2c)
oled = SH1106_I2C(128, 64, i2c, res=None, addr=0x3C)
oled.rotate(180)
oled.fill(0)
info_system = InfoSystem(
oled, rtc, builtin_led, kuehlwasser_sensor, aussen_temperatur_sensor
)
button = machine.Pin(BUTTON_PIN, machine.Pin.IN, machine.Pin.PULL_UP)
button.irq(trigger=machine.Pin.IRQ_RAISING, handler=info_system.update_button_state)
while True:
if info_system.button_state == 0:
info_system.show_date_time()
elif info_system.button_state == 1:
info_system.show_cooling_water()
elif info_system.button_state == 2:
info_system.show_outside_temperature()
if __name__ == "__main__":
main()
Ich hab mit dem Sensor leider keine Erfahrung, und habe fast über all deine 'sleep' 's mal drin gelassen. Die Entprellzeit kannst du jetzt über eine Konstante einstellen. Ich will den IRQ nicht durch ein 'sleep' unterbrechen, sondern ich will das alles registriert wird, aber in einem bestimmten Zeitraum nichts passiert.
Mal zusammen gefasst, man will keine keine globalen Variabeln, das macht ein Programm sehr unübersichtlich, schlecht wartbar und bei größeren Programmen wird man bei der Fehlersuche verrückt. Wenn man sich einen Zustand merken will, dann braucht man eine Klasse.
Code wiederholt man nicht gern, sondern steckt den lieber in Funktionen und ruft die mit passenden Argumenten auf.
Strings puzzelt man nicht mit '+' zusammen, MP hat die 'format'-Methode, da kann man die Ausgabe gleich mit führender 0 formatieren, dann fällt deine Abfrage weg. Ich bin mir nicht sicher, aber ich glaube aktuelle MP-Versionen haben sogar 'f'-Strings.
Wenn du Namen sprechend wählst, dann sparst du dir die Kommentare, die den Namen erklären.
Grüße
Dennis