Seite 1 von 1
MicroPython Threads
Verfasst: Sonntag 4. Juli 2021, 13:25
von T4m4go
Hallo, liebes Forum!
Ich bin ein Python Einsteiger, habe mich mit dem Raspberry Pi Pico und MicroPython befasst und bin jetzt auf ein Problem gestoßen, an dem ich nicht weiter komme.
Ich wollte mithilfe Threads 2 Sachen (messung() und giessen()) parallel laufen lassen, damit ich bei giessen() höhere sleep Zeiten einstellen kann , ohne dass messung() unterbrochen wird.
Leider hat das nicht so geklappt, wie ich mir das vorgestellt habe.
Wie gesagt bin ich ein Einsteiger...
from machine import I2C, Pin, ADC
from time import sleep, sleep_ms
from machine_i2c_lcd import I2cLcd
from dht import DHT11, InvalidChecksum
import _thread
i2c = I2C(1, sda=Pin(2), scl=Pin(3), freq=400000)
i2c_scan=i2c.scan()[0]
i2c_scan_hex=hex(i2c_scan)
I2C_ADDR = i2c_scan
lcd = I2cLcd(i2c, I2C_ADDR, 2, 16)
DHTpin = Pin(15, Pin.OUT, Pin.PULL_DOWN)
led = Pin(11, Pin.OUT)
motor = Pin(9, Pin.OUT)
adc = ADC(Pin(28))
lock = _thread.allocate_lock()
def error():
print("Error")
led.value(1)
sleep(1)
led.value(0)
sleep(1)
led.value(1)
sleep(1)
led.value(0)
sleep(1)
def messung():
while True:
sensor = DHT11(DHTpin)
t = (sensor.temperature)
h = (sensor.humidity)
feuchte = (float(-adc.read_u16()/655+100))#
lcd.hide_cursor()
lcd.move_to(0,0)
lcd.putstr("Temp: " + str(t) + " C")
lcd.move_to(0,1)
lcd.putstr("Luftf.: " + str(h) + " %")
sleep(5)
lcd.hide_cursor()
lcd.move_to(0,0)
lcd.putstr("Temp: " + str(t) + " C")
lcd.move_to(0,1)
lcd.putstr("Giessen: " + str("%.1f" % (feuchte)) + " ")
sleep(5)
def giessen():
while True:
print(int(-adc.read_u16()/655.35+100))
led.value(0)
feuchte = (int(-adc.read_u16()/655.35+100))
if 1 < feuchte < 20:
sleep(5)
motor.value(1)
sleep(7)
motor.value(0)
elif feuchte < 1:
motor.value(0)
error()
else:
motor.value(0)
_thread.start_new_thread(messung,())
_thread.start_new_thread(giessen,())
Ich wäre wirklich sehr dankbar, wenn man mir helfen könnte.
MfG Fabi
Re: MicroPython Threads
Verfasst: Sonntag 4. Juli 2021, 13:38
von __deets__
Statt das mit dem experimentellen und nicht wirklich gut unterstuetzten Thread-Modul zu machen, musst du dein Programm einfach so umschreiben, dass es keine sleeps mehr enthaelt, und einfach beide Aufgaben bestaendig nacheinander macht. Alternativ kannst du uasyncio verwenden, damit bleibst du bei deinem quasi-parallelen Design. Aber ohne eben echte und schlechte Threads.
https://docs.micropython.org/en/latest/ ... yncio.html
Re: MicroPython Threads
Verfasst: Sonntag 4. Juli 2021, 14:55
von Sirius3
Eingerückt wird immer mit 4 Leerzeichen pro Ebene, nicht mal 4 und mal 6 oder 8.
Variablennamen werden komplett klein geschrieben.
Das Lesen der Feuchte steht drei mal im Code, das sollte es nur einmal geben.
Microprozessor-Programmierung ist ganz anders, als bei großen Maschinen.
Man hat meist einen Loop, aus dem heraus alles gesteuert wird:
Code: Alles auswählen
from time sleep_ms, ticks_ms, ticks_add, ticks_diff
from machine import I2C, Pin, ADC
from machine_i2c_lcd import I2cLcd
from dht import DHT11, InvalidChecksum
def initialize():
i2c = I2C(1, sda=Pin(2), scl=Pin(3), freq=400000)
i2c_addr = i2c.scan()[0]
lcd = I2cLcd(i2c, i2c_addr, 2, 16)
sensor = DHT11(Pin(15, Pin.OUT, Pin.PULL_DOWN))
led = Pin(11, Pin.OUT)
motor = Pin(9, Pin.OUT)
adc = ADC(Pin(28))
led.value(0)
return lcd, sensor, led, motor, adc
def get_feuchte(adc):
return 100 - adc.read_u16() / 655.
def update_display(display_state, lcd, feuchte):
if display_state == 0 or display_state == 5
temperature = sensor.temperature
humidity = sensor.humidity
lcd.hide_cursor()
lcd.move_to(0,0)
lcd.putstr("Temp: %s C" % temperature)
lcd.move_to(0,1)
if display_state == 0:
lcd.putstr("Luftf.: %s %" % humidity)
else:
lcd.putstr("Giessen: %.1f" % feuchte)
return (display_state + 1) % 10
def update_motor(motor_state, motor, led, feuchte):
if motor_state == 0:
if 1 < feuchte < 20:
# start motor
return 1
elif feuchte < 1:
# special error state
led.value(1)
return 100
return 0
elif motor_state < 5:
return motor_state + 1
elif motor_state == 5:
motor.value(1)
return motor_state + 1
elif motor_state < 11:
return motor_state + 1
elif motor_state == 12:
motor.value(0)
return 0
elif motor_state >= 100:
# error
led.value(motor_state % 2)
if motor_state == 104:
return 0
return motor_state + 1
def main():
lcd, sensor, led, motor, adc = initialize()
clock = ticks_ms()
motor_state = 0
display_state = 0
while True:
feuchte = get_feuchte(adc)
display_state = update_display(display_state, lcd, feuchte)
motor_state = update_motor(motor_state, motor, led, feuchte)
clock = ticks_add(clock, 1000)
diff = ticks_diff(clock, time.ticks_ms())
if diff > 0:
sleep_ms(diff)
main()
Re: MicroPython Threads
Verfasst: Sonntag 4. Juli 2021, 17:10
von T4m4go
Sirius3 hat geschrieben: Sonntag 4. Juli 2021, 14:55
Eingerückt wird immer mit 4 Leerzeichen pro Ebene, nicht mal 4 und mal 6 oder 8.
Variablennamen werden komplett klein geschrieben.
Das Lesen der Feuchte steht drei mal im Code, das sollte es nur einmal geben.
Microprozessor-Programmierung ist ganz anders, als bei großen Maschinen.
Man hat meist einen Loop, aus dem heraus alles gesteuert wird.
Vielen Dank, dass sie mir den kompletten Code verbessert geschickt haben(!), nur kann ich leider nicht viel damit anfangen und funktionieren tut es leider auch nicht.
Ich habe es einfach copy/paste übertragen, deshalb sind die Einrückungen anscheinend verloren gegangen aber danke für den Hinweis!
Re: MicroPython Threads
Verfasst: Sonntag 4. Juli 2021, 17:12
von T4m4go
__deets__ hat geschrieben: Sonntag 4. Juli 2021, 13:38
Statt das mit dem experimentellen und nicht wirklich gut unterstuetzten Thread-Modul zu machen, musst du dein Programm einfach so umschreiben, dass es keine sleeps mehr enthaelt, und einfach beide Aufgaben bestaendig nacheinander macht. Alternativ kannst du uasyncio verwenden, damit bleibst du bei deinem quasi-parallelen Design. Aber ohne eben echte und schlechte Threads.
https://docs.micropython.org/en/latest/ ... yncio.html
Werde mich wohl mal daran orientieren und versuchen etwas auf die Beine zu stellen:
Danke für die schnelle Antwort!
Re: MicroPython Threads
Verfasst: Sonntag 4. Juli 2021, 17:14
von Sirius3
Ich habe ja Deine Hardware nicht hier. Also wäre es schon hilfreich, nicht einfach zu schrieben, dass es nicht geht, sondern was nicht geht.
Re: MicroPython Threads
Verfasst: Sonntag 4. Juli 2021, 17:53
von T4m4go
....def update_display(display_state, lcd, feuchte):
........ if display_state == 0 or display_state == 5
24 .......temperature = sensor.temperature
............humidity = sensor.humidity
............lcd.hide_cursor()
............lcd.move_to(0,0)
............lcd.putstr("Temp: %s C" % temperature)
............lcd.move_to(0,1)
............if display_state == 0:
................lcd.putstr("Luftf.: %s %" % humidity)
............else:
................lcd.putstr("Giessen: %.1f" % feuchte)
........return (display_state + 1) % 10
Traceback (most recent call last):
File "<stdin>", line 24
SyntaxError: invalid syntax
also das ist der Fehler.
Ich habe leider keine Ahnung.
Hardware ist der Raspberry Pi Pico mit einem DHT11, einem LCD Display und einem Feuchtigkeitssensor.
Re: MicroPython Threads
Verfasst: Sonntag 4. Juli 2021, 17:59
von Sirius3
Was sollen denn die vielen Punkte? Code steckt man hier im Forum in Code-Tags, so ist Dein Code erst recht nicht mehr lesbar.
In der Zeile davor fehlt ein Doppelpunkt.
Und 7 Zeilen später fehlt ein %:
Code: Alles auswählen
def update_display(display_state, lcd, feuchte):
if display_state == 0 or display_state == 5:
temperature = sensor.temperature
humidity = sensor.humidity
lcd.hide_cursor()
lcd.move_to(0,0)
lcd.putstr("Temp: %s C" % temperature)
lcd.move_to(0,1)
if display_state == 0:
lcd.putstr("Luftf.: %s %%" % humidity)
else:
lcd.putstr("Giessen: %.1f" % feuchte)
return (display_state + 1) % 10
Re: MicroPython Threads
Verfasst: Sonntag 4. Juli 2021, 18:03
von T4m4go
Sirius3 hat geschrieben: Sonntag 4. Juli 2021, 17:59
Was sollen denn die vielen Punkte? Code steckt man hier im Forum in Code-Tags, so ist Dein Code erst recht nicht mehr lesbar.
In der Zeile davor fehlt ein Doppelpunkt.
Und 7 Zeilen später fehlt ein %:
Die Punkte hab ich nur gemacht, dass Sie sich nicht mehr über das Einrücken beschweren, da ich nicht weiss wie man code importiert, sonst habe ich bis auf das import in der 1. Zeile alles von Ihnen übernommen.
Re: MicroPython Threads
Verfasst: Sonntag 4. Juli 2021, 18:08
von T4m4go
Traceback (most recent call last):
File "<stdin>", line 81, in <module>
File "<stdin>", line 73, in main
File "<stdin>", line 24, in update_display
NameError: name 'sensor' isn't defined
Habe schon etwas versucht aber ich bekomme es nicht hin.
Wie gesagt komme ich mit Ihrer Version nicht so gut zurecht.
Re: MicroPython Threads
Verfasst: Sonntag 4. Juli 2021, 18:13
von Sirius3
Das sind wirklich triviale Fehler, Du mußt `sensor` einfach als zusützlichen Parameter an `update_display` übergeben.
Re: MicroPython Threads
Verfasst: Sonntag 4. Juli 2021, 18:21
von T4m4go
Sirius3 hat geschrieben: Sonntag 4. Juli 2021, 18:13
Das sind wirklich triviale Fehler, Du mußt `sensor` einfach als zusützlichen Parameter an `update_display` übergeben.
Ok ich habe davor nur sensor = DHT11(DHTpin) übergeben und jetzt komplett und es funktioniert!
Vielen Dank!
Sleep kann ich jetzt beim Motor nicht einbauen, oder?(ohne, dass die Messung anhält)
Re: MicroPython Threads
Verfasst: Sonntag 4. Juli 2021, 18:25
von T4m4go
Was ich Ihnen vorhin blöderweise noch verschwiegen habe ist , dass es sich um eine Pflanze und eine Pumpe handelt und bis das Wasser den Fühler erreicht, die Pumpe die Pflanze ersäuft,
Deswegen brauch ich eine bestimmte Laufzeit der Pumpe und am besten noch eine Sperrzeit von ein paar Stunden/Minuten.
Dafür wollte ich einen Thread benutzen um die Messung bei der Sperrzeit der Pumpe weiterlaufen zu lassen.
Kann ich das mit Ihrem verbesserten Code auch erreichen?
Re: MicroPython Threads
Verfasst: Sonntag 4. Juli 2021, 18:45
von Sirius3
Natürlich geht das. Dafür gibt es ja die Counter, motor_state. Das könnte man noch entkoppeln, in einen wait-Counter und einen getrennten State.
Re: MicroPython Threads
Verfasst: Sonntag 4. Juli 2021, 18:47
von T4m4go
Sirius3 hat geschrieben: Sonntag 4. Juli 2021, 18:45
Natürlich geht das. Dafür gibt es ja die Counter, motor_state. Das könnte man noch entkoppeln, in einen wait-Counter und einen getrennten State.
Wie würde das ungefähr ausschauen?
Re: MicroPython Threads
Verfasst: Sonntag 4. Juli 2021, 19:27
von Sirius3
Wo kommst Du konkret nicht weiter?
Re: MicroPython Threads
Verfasst: Sonntag 4. Juli 2021, 20:04
von T4m4go
Sirius3 hat geschrieben: Sonntag 4. Juli 2021, 18:45
Natürlich geht das. Dafür gibt es ja die Counter, motor_state. Das könnte man noch entkoppeln, in einen wait-Counter und einen getrennten State.
Wie das funktioniert, was Sie geschrieben haben.
Ich habe jetzt ewig auf die Antwort gewartet, ohne zu merken, dass sie auf der 2. Seite ist. :' D
Ich bin sehr dankbar für Ihre schnellen Antworten!
Re: MicroPython Threads
Verfasst: Sonntag 4. Juli 2021, 20:19
von Dennis89
Hallo,
@T4m4go hast du den Code mal erfolgreich laufen lassen? Hast du gesehen das in Zeile 1 noch ein 'import' fehlt?
Wenn du die Laufzeit verändern willst, zeigst du hier am besten was du versucht hast oder was du genau nicht verstehst.
Grüße
Dennis
Re: MicroPython Threads
Verfasst: Freitag 23. Juli 2021, 17:56
von T4m4go
Dennis89 hat geschrieben: Sonntag 4. Juli 2021, 20:19
Hallo,
@T4m4go hast du den Code mal erfolgreich laufen lassen? Hast du gesehen das in Zeile 1 noch ein 'import' fehlt?
Wenn du die Laufzeit verändern willst, zeigst du hier am besten was du versucht hast oder was du genau nicht verstehst.
Grüße
Dennis
Hab ich schon beim 1. mal ausgebessert.