Multithreading Verzweiflung (Bitte um Bsp in meinem Programm)

Wenn du dir nicht sicher bist, in welchem der anderen Foren du die Frage stellen sollst, dann bist du hier im Forum für allgemeine Fragen sicher richtig.
Antworten
Kiwi_gamer01
User
Beiträge: 17
Registriert: Freitag 2. November 2018, 21:55

Ich habe hier ein Python Programm für einen Schritmotor Robter (tut nichts zur Sache) und ich möchte das die befehle R1.vor(), R2.vor(), ... gleichzeitig ausgeführt werden und nicht nach einander. Alle Tutorials und Anleitungen sind an mir gescheitert (ich bin gescheitert und bitte um den Korrekten Programmcode um mir Multithreading zu erschließen.)

Code: Alles auswählen

import time
from RPi import GPIO


GPIO.setmode(GPIO.BOARD)
GPIO.setwarnings(False)

control_pins_1 = [12, 15, 13, 11]   #   rv
control_pins_2 = [37, 35, 33, 31]   #   rh
control_pins_3 = [18, 22, 24, 26]   #   lv
control_pins_4 = [40, 38, 36, 32]   #   lh

for pin in control_pins_1:
    GPIO.setup(pin, GPIO.OUT)
    GPIO.output(pin, 0)
for pin in control_pins_2:
    GPIO.setup(pin, GPIO.OUT)
    GPIO.output(pin, 0)
for pin in control_pins_3:
    GPIO.setup(pin, GPIO.OUT)
    GPIO.output(pin, 0)
for pin in control_pins_4:
    GPIO.setup(pin, GPIO.OUT)
    GPIO.output(pin, 0)

vorstep_seq = [
  [1,0,0,0],
  [1,1,0,0],
  [0,1,0,0],
  [0,1,1,0],
  [0,0,1,0],
  [0,0,1,1],
  [0,0,0,1],
  [1,0,0,1]
]   
rueckstep_seq = [
  [0,0,0,1],
  [0,0,1,1],
  [0,0,1,0],
  [0,1,1,0],
  [0,1,0,0],
  [1,1,0,0],
  [1,0,0,0],
  [1,0,0,1]
]
class Rad():
    def __init__(self, controlpins, seg, speed):
        self.speed = speed
        self.controlpins = controlpins
        self.seg = seg

    def vor(self):
        for i in range(200):
            for vorstep in range(8):
                for pin in range(4):
                    GPIO.output(self.controlpins[pin], self.seg[vorstep][pin])
                time.sleep(0.0009)
    def rueck(self):
        for i in range(200):
            for rueckstep in range(8):
                for pin in range(4):
                    GPIO.output(self.controlpins[pin], self.seg[rueckstep][pin])
                time.scleep(0.0009)
    def getdata(self):
        print('Speed : ', self.speed , ', Pins : ', self.controlpins , ', Seq : ', self.seg)


if __name__ == "__main__":
    R1 = Rad(control_pins_1, vorstep_seq, 100)
    R2 = Rad(control_pins_2, vorstep_seq, 100)
    R3 = Rad(control_pins_3, vorstep_seq, 100)
    R4 = Rad(control_pins_4, vorstep_seq, 100)

    R1.getdata()

    R1.vor()
    R2.vor()
    R3.vor()
    R4.cor()

    GPIO.cleanup()

#### Es müsste egal sein was das Programm macht ## möchte nur das R1,R2,... mit den argumenten gleichzeitg ausgeführt werden ####
Sirius3
User
Beiträge: 17754
Registriert: Sonntag 21. Oktober 2012, 17:20

Warnungen sind dazu da, dass man sie behebt und nicht, dass man sie ignoriert. Dazu muß aber cleanup auch verlässlich ausgeführt werden, z.b. in einem finally-Block.
GPIO.setup kann auch mit Listen umgehen, so dass die 4 for-Schleifen unnötig sind.
Konstanten schreibt man KOMPLETT_GROSS, Variablen, wie R1 aber klein, also rad1.
Das beste wäre, eine Schleife zu haben, die alle Räder gleichzeitig ansprechen kann.
Geht ja ganz einfach, indem man die Listen mit Pins zusammenstückelt.
Apropos. for-Schleifen über einen Index sind ein Antipattern. Statt dessen benutzt man zip, wenn man über zwei Listen gleichzeitig iterieren will.
__deets__
User
Beiträge: 14545
Registriert: Mittwoch 14. Oktober 2015, 14:29

Du wirst das nicht hören wollen - aber das wird nichts. Threads sind so gut wie nie die Lösung, erst recht nicht mehrere davon. Ja, da draußen gibt es jede Menge von stümpern zusammengekloppten Code der die benutzt - aber die wissen nicht, wie schwer zu beherrschen und gleichzeitig unzureichend die wirklich sind.

Selbst wenn wir dir den Code hinschreiben würden - er würde nicht tun was du willst. Gerade für schrittmotoren brauchst du gutes Timing. Da in Python eh nur ein Thread läuft (ja, auch wenn du 100 startest - die wechseln sich ab!) kommt alleine das schon nicht hin.

Doch du brauchst die nicht, du kannst mit nur einem einzigen thread arbeiten, und stattdessen so Vorgehen, das du ausrechnest, wann du etwas schalten musst, und das dann tun. Aber selbst das ist nur so mittelgeil. Denn auch ein Thread unterliegt scheduling jitter, sprich sein timing ist nicht präzise. Darum funktioniert es am besten mit pigpio und seinem DMA basierten Waves Feature. Beschrieben hier: viewtopic.php?t=42436 - Diskussion der hier angerissenen Probleme inklusive!
Antworten