Ich kann nicht mehr als 34 serielle Ports gleichzeitig auf dem Raspberry Pi 4B öffnen

Python auf Einplatinencomputer wie Raspberry Pi, Banana Pi / Python für Micro-Controller
Antworten
ibidreli
User
Beiträge: 1
Registriert: Donnerstag 15. Oktober 2020, 07:16

Zuerst möchte ich mich für den schlecht geschribenen Code entschuldigen. Ich bin noch ein Anfänger :wink: .

Ich habe ein Debug Gerät entwickelt um nun die Performance des Gerätes zu testen, möchte ich alle Ports öffnen und mit einer Schleife alle Ports miteinander verbinden.

Mit folgendem Code probierte ich die 48 seriellen Ports gleichzeitig zu öffnen:

Code: Alles auswählen

# performance.py

#import der Libarys 
import serial                                                       
import time 
import sys                                                      


serialInterfaces = [] 

basicpath = "/dev/ttyUSB"
portnum = 47

def close():
    for serialIf in serialInterfaces:
        serialIf["if"].close()

def Init():
    portnumbers = range(portnum)
    for port in portnumbers:
        serialIf = {
            "path": basicpath + str(port),
        }
        serialIf["if"] = serial.Serial(serialIf.get("path"), baudrate=1200, timeout=1)

        serialInterfaces.append(serialIf)
        print(str(serialIf))


Init()
close()
Nach 34 Ports bricht das Raspberry Pi dann zusammen.

Weiss jemand was ich falsch gemacht habe oder ist die Performance des RPI einfach zu schlecht?
Benutzeravatar
sparrow
User
Beiträge: 4538
Registriert: Freitag 17. April 2009, 10:28

Was heißt denn "er bricht zusammen". So richtig physisch? Mit Chips die über den Boden rollern? Oder stürzt das Programm ab? Mit welcher Fehlermeldung?
Sirius3
User
Beiträge: 18270
Registriert: Sonntag 21. Oktober 2012, 17:20

@ibidreli: niemand muß sich als Anfänger entschuldigen. Es gibt nur ein paar Regeln, an die man sich ganz einfach halten kann. Variablennamen werden generell klein geschrieben, Konstanten dagegen komplett gross. Funktionen werden ebenfalls komplett klein geschrieben.
`serialInterfaces` (aka `serial_interfaces`) sollte keine globale Variable sein.
Die Funktion `close` macht so wenig, dass man sie fast nicht braucht.
Benutze keine Abkürzungen. if ist etwas anderes als interface.
Benutzeravatar
__blackjack__
User
Beiträge: 14047
Registriert: Samstag 2. Juni 2018, 10:21
Wohnort: 127.0.0.1
Kontaktdaten:

@ibidreli: Noch Anmerkungen zum Quelltext:

Die Module `sys` und `time` werden importiert, aber nirgends verwendet.

Was ist denn an dem Pfad `basic`? Das sollte wohl eher `base` heissen.

Die `serialIf`-Struktur macht hier keinen Sinn. Das `Serial`-Objekt kennt ja seinen Pfad, den kann man da auch wieder abfragen. Damit wird der Code schon mal deutlich vereinfacht.

`Serial`-Objekte sind genau wie Dateiobjekte Kontextmanager die man mit ``with`` zusammen verwenden kann und sollte. Das geht hier nicht direkt, aber über einen `contextlib.ExitStack`.

Da der Code in der Schleife massiv einfacher geworden ist, lässt sich der Aufbau der Liste auch als „list comprehension“ ausdrücken.

Ungetestet:

Code: Alles auswählen

#!/usr/bin/env python3
from contextlib import ExitStack

from serial import Serial

SERIAL_BASE_PATH = "/dev/ttyUSB"
PORT_COUNT = 47


def main():
    with ExitStack() as stack:
        serial_interfaces = [
            stack.enter_context(
                Serial(
                    f"{SERIAL_BASE_PATH}{port_number}",
                    baudrate=1200,
                    timeout=1,
                )
            )
            for port_number in range(PORT_COUNT)
        ]
        #
        # TODO Do something with `serial_interfaces`.
        #


if __name__ == "__main__":
    main()
“Vir, intelligence has nothing to do with politics!” — Londo Mollari
__deets__
User
Beiträge: 14545
Registriert: Mittwoch 14. Oktober 2015, 14:29

Ich vermute da kommt der USB Stack an seine Grenzen. Auch wenn der Bus für 128 Geräte konzipiert ist (Hubs inklusive) ist das eine absolute Ausnahmesituation die du da hast. Was sagt der Kernel in diesem Moment?
Benutzeravatar
DeaD_EyE
User
Beiträge: 1239
Registriert: Sonntag 19. September 2010, 13:45
Wohnort: Hagen
Kontaktdaten:

Ich stelle mir gerade einen USB-Igel vor. Am besten den Code von __blackjack__ verwenden und ggf. noch ein time.sleep(1) einbauen.
Dann kannst du z.B. nebenbei mit `dmseg` Kernel-Meldungen ausgeben.

Gemein wäre es, wenn durch den sleep der Fehler nicht auftreten würde.
sourceserver.info - sourceserver.info/wiki/ - ausgestorbener Support für HL2-Server
Antworten