Forum: PC-Programmierung Raspberry Pi Prozesse parallel ablaufen lassen.


von Dominik L. (dominikl774)


Lesenswert?

Hallo zusammen,

erstmal zum Anfang, bin neu hier im Forum und ein Anfänger im Thema 
Raspberry Pi und Pyhton.

Zu meiner Frage habe ich bisher keine Lösung gefunden, weshalb ich hier 
jetzt meine Frage Stelle.

Mein Plan ist es ein Modellblaulichtbalken zu bauen und mit einem 
Raspberry Pi 3b+ zu betreiben. Der Balken soll über ein echtes 
Bedienteil ansteuerbar sein, welches nicht das Problem sein sollte.

Mein Problem liegt hier an den Prozessen die parallel ablaufen müssen.
1. Blaulicht mit bestimmter Frequenz
2. Gelblicht mit bestimmter Frequenz
3. Lautsprecher mit unterschiedlichen Tönen (Martinshorn)
4. ggf noch eine Matrixanzeige

Bisher habe ich es mit Threads hinbekommen. Leider macht das Raspberry 
bei mehr als 2 Threads nicht mehr sauber seine Arbeit und lässt 
unkontrolliert das Blaulicht blinken. Ich denke er ist damit 
überfordert.


Gibt es von Eurer Seite Lösungsvorschläge? Soll ich vielleicht mit einer 
anderen Programmiersprache anfangen oder ist ein anderes Board von 
Vorteilen?

Danke schon Mal für die Hilfe. Grüße Dominik

: Verschoben durch Moderator
von Dave (Gast)


Lesenswert?

Wie üblich: Schaltung und Programm posten.
Ich kann dir aber schonmal sagen, dass wenn der Pi mit dieser Aufgabe 
überlastet ist dann stimmt etwas mit dem aktuellen Aufbau (Software, 
Hardware oder beides) nicht.

von Oliver S. (oliverso)


Lesenswert?

Dominik L. schrieb:
> Leider macht das Raspberry
> bei mehr als 2 Threads nicht mehr sauber seine Arbeit

Wenn das so wäre, wäre das sehr unschön, denn da laufen im Hintergrund 
doch sehr viel mehr Threads.

Echtzeit geht mit dem Raspi zwar nicht, aber so ein bisschen Blinken und 
Hupen sollte der nebenbei schon schaffen.

Also wird das Problem an deinen Threads liegen, und nicht am Raspi.

Oliver

von Programmierer (Gast)


Lesenswert?

Dominik L. schrieb:
> Bisher habe ich es mit Threads hinbekommen. Leider macht das Raspberry
> bei mehr als 2 Threads nicht mehr sauber seine Arbeit und lässt
> unkontrolliert das Blaulicht blinken.

Das ist Quatsch. Der Pi 3b+ hat 4 Cores und kann somit 4 Threads echt 
parallel ausführen. Mit dem üblichen Multithreading des Linux Kernels 
kann er locker Hunderte Threads präemptiv gleichzeitig ausführen. Der 
Kernel alleine startet schon ein paar Dutzend Threads, der Rest vom 
Linux System noch viele weitere. Deine paar Threads fallen da überhaupt 
nicht ins Gewicht. Du hast höchstwahrscheinlich Fehler im Programm. Mit 
mehreren Threads zu programmieren ist nämlich sehr kompliziert und es 
gibt unzählige Fallstricke. Leider wird in den meisten Kursen 
Multithreading als einfach dargestellt und ein paar Werkzeuge 
angerissen, aber tatsächlich ist es eine Wissenschaft wenn es über 
triviale Fälle hinaus geht. Weil deine Blinkerei ja keine Rechenleistung 
braucht, kann es durchaus eine Lösung sein, auf Threads zu verzichten 
und clever mit Timern zu arbeiten, also z.B. immer die Zeit bis zur 
nächsten Operation zu berechnen und abzuwarten.

von Andreas B. (bitverdreher)


Lesenswert?

Ein Raspi ist für so etwas völliger Overkill. Dazu reicht ein simpler 
8-Bit Controller mit genügend Eingängen und der wird ich dabei noch 
langweilen.
Stichwort zur Programmierung: Statemachine

von Tilo R. (joey5337) Benutzerseite


Lesenswert?

Ich weiß nicht, woran es liegt. Dass es gehen müsste (4 Cores) ist 
eigentlich klar.

Aber zur Fehlereingrenzung wäre mein erster Verdächtiger das 
Multithreading in Python.
Ich bin mir nicht sicher wie das heute da implementiert ist. Früher war 
es jedenfalls so, dass nur ein Thread innerhalb Python gleichzeitig 
aktiv sein konnte.
(Technische Ursache war das GIL, das global interpreter lock. Wodurch 
Multithreading nur dann Vorteile hatte, wenn Threads auf irgendwas, z.B. 
IO, warten mussten.)

Wie gesagt - obs daran liegt weiß ich nicht. Aber da würde ich zu suchen 
anfangen.

von Tom (Gast)


Lesenswert?

Ein Blaulicht (egal welcher Größe,Stärke usw.) anzusteuern ist einfach 
über Transistor oder MOSFET zu machen. Eine Sirene wie bei der Feuerwehr 
besteht aus 2 Grundtönen, die da 440HZ und 585Hz wären. Hier könnte man 
einen Piezo oder für lauteres ein Signalhorn aus der Gebäudesicherheit 
o.ä. ansteuern. Das Ganze hatte ich mal mit einem kleinen ATtiny85 
vollkommen problemlos gemacht. Blinkfrequenz und die Frequenzen für das 
Signal können einfach über die internen Timer gemacht werden. Sollte für 
jeden der sich mit den Atmel MCs auskennt absolut kein Problem sein!
Ein Raspi dafür zu verwenden, wie es "Andreas B." schrieb, ist wirklich 
vollkommen Overkill!!!

von Christof R. (prediger)


Lesenswert?

Da bin ich echt mal auf den Code gespannt. Wo da wohl der Hase im 
Pfeffer liegt.

von Frank (Gast)


Lesenswert?

Mit sicherheit sind das WS2812B LEDs und deren Timing haut vorne und 
hinten nicht mehr hin. Falls das so ist, würde ich einen kleinen µC 
dazwischen packen, auf den die Echtzeit-Sachen ausgelagert werden.

Gruß

von Äxl (Gast)


Lesenswert?

> ...besteht aus 2 Grundtönen, die da 440HZ und 585Hz wären.

Hella RTK5E
1
Allgemeine Technische Daten
2
....
3
Schalldruckpegel: Frequenzbereich 
4
410 Hz (tief), 547 Hz (hoch)
5
362 Hz (tief), 483 Hz (hoch) (umfangreiche länderspezifische Frequenzen sind programmiert)
6
....

410 und 547 wären also okay ... 😎

von Äxl (Gast)


Lesenswert?

Edit
410 und 547 wären also AUCH okay ... 😎

von DPA (Gast)


Lesenswert?

Ein paar leds blinken lassen, ein paar mal pro Sekunde? Für sowas 
braucht man doch noch nicht einmal threads. Einfach die Zeit nehmen, und 
dann in ner schleife schauen, was kommt als nächstes, wie lang muss man 
den Thread schlafen legen.

Eventuell muss man sich nicht einmal um die Blinkerei kümmern. Linux hat 
Treiber für leds. Ich weiss gerade nicht, ob man aus einem GPIO zur 
Laufzeit eine LED machen kann, aber sowas braucht höchstens einen 
kleinen device tree change. Da kann man auch PWM Zeugs einrichten, womit 
man dann einfach die Helligkeit setzen kann, und der Kernel kümmert sich 
um den rest. Für gewisse einfachere Sachen kann man auch direkt im 
Kernel einen trigger setzen, dann braucht man nicht einmal ein Programm 
im Userspace.

Und ich glaube für blink muster zeug könnte man eventuell feedbackd 
nehmen. Hab das zwar noch nie ausprobiert, aber theoretisch müsste man 
da dan einfach per dbus sagen können, event X, und es startet blink und 
sound themen für X.

von Dominik L. (dominikl774)


Angehängte Dateien:

Lesenswert?

Dave schrieb:
> Wie üblich: Schaltung und Programm posten.
> Ich kann dir aber schonmal sagen, dass wenn der Pi mit dieser Aufgabe
> überlastet ist dann stimmt etwas mit dem aktuellen Aufbau (Software,
> Hardware oder beides) nicht.

Danke für die Antwort. Hier im Anhang das Programm. Ich bin Anfänger, 
ich gehe davon aus, das es viel einfacher geht, bzw. das was ich gemacht 
habe, völliger Müll ist xD

Zur Verständniss vielleicht:
Pin 13 - Blaulicht An/Aus
Pin 26 - Horn An/Aus
Pin 22 - Horn wechsel (Stadt/Land)

Pin 23 - Blaulicht Rechts
Pin 24 - Blaulicht Links

Das ganze mit der Abfrage musste ich machen, da das Bedienteil nur 
Taster besitzt, und ich die Funktionen mit einem einmaligen Tasten Ein 
bzw. Aus schalten möchte.

Grüße

von Dominik L. (dominikl774)


Lesenswert?

Andreas B. schrieb:
> Ein Raspi ist für so etwas völliger Overkill. Dazu reicht ein simpler
> 8-Bit Controller mit genügend Eingängen und der wird ich dabei noch
> langweilen.
> Stichwort zur Programmierung: Statemachine

Danke für die Antwort! Klar ist der Overkillt, da ich aber evtl. 
vorhabe, das ganze über ein Webserver zu steuern und etvl. sonstige 
spielerein, habe ich ein Raspi gewählt.

Grüße

von Dominik L. (dominikl774)


Lesenswert?

Christof R. schrieb:
> Da bin ich echt mal auf den Code gespannt. Wo da wohl der Hase im
> Pfeffer liegt.

Den Code hab ich hier in einem Kommentar gepostet. Guck dir den gerne 
mal an - bitte nicht weinen xD -! Grüße

von Thomas W. (twust)


Lesenswert?

Dominik L. schrieb:
> Bisher habe ich es mit Threads hinbekommen. Leider macht das Raspberry
> bei mehr als 2 Threads nicht mehr sauber seine Arbeit und lässt
> unkontrolliert das Blaulicht blinken. Ich denke er ist damit
> überfordert.

Ich denke Du bist überfordert, denn der Programmcode für diese 2 Threads 
muss ja schon saumäßig verbeutelt sein um damit einen Raspberry 
auszulasten. Auch mit deinem gewählten Python kann man so etwas auch auf 
viel kleineren Controllern spielend umsetzen.

: Bearbeitet durch User
von Dominik L. (dominikl774)


Lesenswert?

Thomas W. schrieb:
> Dominik L. schrieb:
>
>> Bisher habe ich es mit Threads hinbekommen. Leider macht das Raspberry
>> bei mehr als 2 Threads nicht mehr sauber seine Arbeit und lässt
>> unkontrolliert das Blaulicht blinken. Ich denke er ist damit
>> überfordert.
>
> Ich denke Du bist überfordert, denn der Programmcode für diese 2 Threads
> muss ja schon saumäßig verbeutelt sein um damit einen Raspberry
> auszulasten. Auch mit deinem gewählten Python kann man so etwas auch auf
> viel kleineren Controllern spielend umsetzen.



Das denk ich Mal auch... Der Programmcode ist hier in einem Kommentar 
angehangen, vielleicht schaust du Mal rüber?

Grüße

: Bearbeitet durch User
von Nee, Du (Gast)


Lesenswert?

Guck dir deine while loops und auch True vs. "True" an. Test im REPL mit 
True == "True" usw. sowie type <object>.

Fang mit einem thread an.

von chef (Gast)


Lesenswert?

Python Threads werden nicht echt parallel ausgeführt, dazu braucht man 
multiprocessing... Keine Ahnung wer sich das so ausgedacht hat...

Beitrag #6954072 wurde vom Autor gelöscht.
Beitrag #6954077 wurde vom Autor gelöscht.
von Christof R. (prediger)


Lesenswert?

Das mit dem Taster ein/ausschalten wird so nicht gehen. Schmeiß den def 
Abfrage raus und probiere für Blaulicht das. Das mit dem Martinhorn muss 
du ggf. ähnlich umbauen.
1
def Blaulicht():
2
    abfrage_blaulicht = True
3
    while True:
4
        if GPIO.input(13) == 1:
5
            GPIO.output(23, GPIO.LOW)
6
            GPIO.output(24, GPIO.LOW)
7
            abfrage_blaulicht = not abfrage_blaulicht
8
            while GPIO.input(13) == 1:
9
                time.sleep(0.1)          
10
        if abfrage_blaulicht:
11
            GPIO.output(23, GPIO.HIGH)
12
            time.sleep(0.04)
13
            GPIO.output(23, GPIO.LOW)
14
            time.sleep(0.04)
15
            GPIO.output(23, GPIO.HIGH)
16
            time.sleep(0.04)
17
            GPIO.output(23, GPIO.LOW)
18
            time.sleep(0.4)
19
            GPIO.output(24, GPIO.HIGH)
20
            time.sleep(0.04)
21
            GPIO.output(24, GPIO.LOW)
22
            time.sleep(0.04)
23
            GPIO.output(24, GPIO.HIGH)
24
            time.sleep(0.04)
25
            GPIO.output(24, GPIO.LOW)
26
        else:
27
            time.sleep(0.1)

von N. M. (mani)


Lesenswert?

Ich kenne mich jetzt mit Python und Threads nicht sonderlich aus, aber 
wenn deine If Bedingung nicht zutrifft, hast du kein wait in deiner 
while(true).
Sie werden also wahrscheinlich so schnell wie es geht ausgeführt.
Das führt vermutlich zu einer hohen Systemlast.

Also schau Mal dass du in jedem Zweig ein wait hast oder auf ein anderes 
Event wartest.

: Bearbeitet durch User
von Sascha W. (sascha-w)


Lesenswert?

Noch besser währe es den Blaulicht Thread zu starten wenn's blinken soll 
und sonst wieder zu beenden.
Die Eingangsabfrage braucht auch nicht in einen Thread, im Hauptprogramm 
kann man ja schließlich auch noch was machen.

Sascha

Bitte melde dich an um einen Beitrag zu schreiben. Anmeldung ist kostenlos und dauert nur eine Minute.
Bestehender Account
Schon ein Account bei Google/GoogleMail? Keine Anmeldung erforderlich!
Mit Google-Account einloggen
Noch kein Account? Hier anmelden.