Seite 1 von 1

Probleme mit pyserial

Verfasst: Dienstag 8. Dezember 2015, 19:40
von holgie
Hallo zusammen,
ich möchte mit Python Daten an die serielle Schnittstelle eines Atmega8 schicken und von dort empfangen. Dafür verwende ich untenstehenden Code. Das Versenden funktioniert einwandfrei aber leider bekomme ich keine Daten eingelesen. Die globale Variable Werte ist immer leer. Das lesen läuft in einem extra thread weil ich ja nicht weiß wann der Atmega etwas verschickt. Der PC muss ständig lesebereit sein.
Ich hatte zuerst ser.readline() gewählt und vom Atmega \n als Abschluss senden lassen, was auch nicht funktionierte.
Die Übertragung vom Atmega funktioniert, dies habe ich mit hterm getestet.
Wäre nett wenn mir jemand weiterhelfen würde. Ich komme leider nicht auf die Lösung.
Gruß
Holger

Code: Alles auswählen

import serial
import time, _thread

def empfang():
    global werte
    id = _thread.get_ident()
    print("Empfangstherad lauft, id={0}.".format(id))
    while 1:
            try:
                werte = ser.read(5).decode('ascii')
            except:
                print("Lesefehler im Thread",id)
                ser.close()

ser = serial.Serial('COM1', 9600, timeout=0, parity=serial.PARITY_NONE, rtscts=0)
werte = 0
_thread.start_new_thread(empfang,())
time.sleep(0.5)

while 1:


    print ("Gebe den Befehl ein")
    text = input()
    ser.write(format(text).encode('ascii')+b'\r\n')
    print(werte)
    print (len(werte))

Re: Probleme mit pyserial

Verfasst: Dienstag 8. Dezember 2015, 20:17
von holgie
Hallo,
bei timeout=3 funktioniert es manchmal. Es ist aber kein sicherer Empfang möglich.
Gruß
Holger

Re: Probleme mit pyserial

Verfasst: Dienstag 8. Dezember 2015, 20:34
von pillmuncher
Namen, die mit einem Unterstrich beginnen, bedeuten: das ist ein Implementationsdetail und sollte nicht von außen verwendet werden. Wenn man das Inhaltsverzeichnis zur Dokumentation der Standardbibliothek von uben nach unten liest, stößt man zuerst auf das threading-Modul, welches man verwenden sollte, anstatt _thread. Ich wundere mich ja schon seit Jahren darüber, dass Anfänger immer von unten nach oben zu lesen scheinen...

So, wie du das programmiert hast, wird es nicht funktionieren. Wenn man aus verschiedenen Threads auf dieselben Daten zugreift, wickelt man das normalerweise in einen Monitor, oder verwendet wenigstens ein Lock. Es ist aber alles andere als trivial, das fehlerfrei hinzubekommen. Deswegen verwendet man in Python gerne eine Queue, die einem das Locking abnimmt. queue.Queue aus der Standardbibliothek ist genau dafür gemacht. Außerdem bedeutet der ser.read(5) Aufruf "lies bis zu fünf Bytes". Ggf. musst du mehr als einen Aufruf durchführen und die empfangenen Bytes konkatenieren.

Globale Variablen sollte es in einem vernünftig geschriebenen Programm nicht geben. Werte betreten Funktionen als Argumente und verlassen sie als Rückgabewerte. Alles andere ist Mist.

Ach ja: Python hat einen eingebauten bool Datentyp mit den Konstanten True und False. Statt while 1: solltest du while True: verwenden. Python ist nicht C.