Pyserial & RS485 ist nicht RS485

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
richardcz
User
Beiträge: 5
Registriert: Dienstag 5. August 2014, 19:50

Hallo,

Methode "serial.write" schreibt nicht alle Daten. Vor paar Wochen hat alles prima funktioniert.
Ich habe python 2.7 und serial 2.7 und W7Pro. Wie kann ich das wieder laufbar kriegen?
Ich benutze ein USB-COM485-PLUS-2.

G.

r.
EyDu
User
Beiträge: 4881
Registriert: Donnerstag 20. Juli 2006, 23:06
Wohnort: Berlin

Hallo und willkommen im Forum!

Stelle dir zu deinem Beitrag doch bitte folgende Frage: Kann ein Außenstehender, welcher dein Programm nicht kennt, dir mit den gelieferten Information irgendwie helfen?

"Funktioniert nicht" ist eine äußerst schlechte Fehlerbeschreibung. *Was* funktioniert denn nicht? Wie hat sich das Programm vorher vehalten, was erwartest du für ein Verhalten und was macht es jetzt? Gibt es eine Fehlermeldung und wenn ja, welche? Läuft dein Programm einfach weiter? Fängt dein PC Feuer? Wie startest du das Programm und was hast du in der Zwischenzeit verändert? Wie sieht der Code aus?
Das Leben ist wie ein Tennisball.
BlackJack

Ich rate trotzdem mal: Fehlt vielleicht ein `flush()`-Aufruf?
EyDu
User
Beiträge: 4881
Registriert: Donnerstag 20. Juli 2006, 23:06
Wohnort: Berlin

Ich bleibe bei der Vermutung mit dem Feuer :mrgreen:
Das Leben ist wie ein Tennisball.
richardcz
User
Beiträge: 5
Registriert: Dienstag 5. August 2014, 19:50

Code: Alles auswählen

import serial
import time

s = serial.Serial(
    port='COM17',
    baudrate=9600,
    parity=serial.PARITY_EVEN,
    timeout=0.7,
    xonxoff =False, 
    rtscts=False,
    dsrdtr  =False,
    writeTimeout = 0.2
)

...
cmd = [104, 21, 21, 104, 0, 80, 0, 2, 2, 1, 4, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 90, 22]
#s.setDTR(0)
        #s.setRTS(True)
        s.write(cmd)
        time.sleep(0.2)
        #s.flush()
        #s.setRTS(False)
        #s.setDTR(1)

...
Ich habe alles probiert. Un die Ereigniss ist, dass ein Empäger kriegt etwas als

104, 21, 21, 104, 0, 80, 0, 2, 2, 1, 4, 0, 0, 0, 1

Manchmal zwei Bytes mehr, manchmal zwei weniger. Deshalb habe ich geschrieben : "nicht alle"

Interresant ist, wenn ich nochmal schreibe, dann kommen die übrigen Bytes und einen Anfang von dem nächsten und so weiter.

Ich habe das auch mit einem anderem Modul probiert und das gleiche.
BlackJack

@richardcz: Du kannst `write()` tatsächlich eine Liste mit Zahlen übergeben!?
richardcz
User
Beiträge: 5
Registriert: Dienstag 5. August 2014, 19:50

Ok, das habe ich verbessert:

Code: Alles auswählen

s.write(bytes(cmd))
Aber keine Auswirkungen.

Mit dem Frame = [104, 11, 11, 104, 1, 11, 0, 2, 2, 1, 0, 0, 0, 0, 1, 18, 22] fehlt nur der letzte Byte. Es scheint so, dass etwas 16 Byte Puffer hat.
BlackJack

@richardcz: Wenn gepuffert wird, darf man halt das `flush()`\en nicht vergessen.
richardcz
User
Beiträge: 5
Registriert: Dienstag 5. August 2014, 19:50

Code: Alles auswählen

        time.sleep(0.2)
        s.write(bytes(cmd))
        s.flush()
        #s.drainOutput()
        #s.setRTS(False)
        #s.setDTR(1)
        print(s.outWaiting())
Es hilft nicht.
Benutzeravatar
pillmuncher
User
Beiträge: 1484
Registriert: Samstag 21. März 2009, 22:59
Wohnort: Pfaffenwinkel

@richardcz: Nur mal so als Denkanstoß:

Code: Alles auswählen

>>> cmd = [104, 21, 21, 104, 0, 80, 0, 2, 2, 1, 4, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 90, 22]
>>> cmd
[104, 21, 21, 104, 0, 80, 0, 2, 2, 1, 4, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 90,22]
>>> bytes(cmd)
'[104, 21, 21, 104, 0, 80, 0, 2, 2, 1, 4, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 90, 22]'
>>> len(cmd)
27
>>> len(bytes(cmd))
90
>>> ''.join(chr(each) for each in cmd)
'h\x15\x15h\x00P\x00\x02\x02\x01\x04\x00\x00\x00\x01\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00Z\x16'
>>> len(''.join(chr(each) for each in cmd))
27
In specifications, Murphy's Law supersedes Ohm's.
BlackJack

@richardcz: Dann liegt's beim Empfänger in einem Puffer. (Oder die Bits machen im Kabel eine kleine Verschnaufpause :mrgreen:)

Edit: `bytearray()` wäre unter Python 2.7 vielleicht noch eine Alternative:

Code: Alles auswählen

In [3]: bytearray(cmd)
Out[3]: bytearray(b'h\x15\x15h\x00P\x00\x02\x02\x01\x04\x00\x00\x00\x01\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00Z\x16')

In [4]: len(bytearray(cmd))
Out[4]: 27
richardcz
User
Beiträge: 5
Registriert: Dienstag 5. August 2014, 19:50

Ja stimmt, ich habe neuer MCU, mit paar konfig. Bits mehr und die haben 'default' Werte:)

Übrigens:

Code: Alles auswählen

cmd = [104, 21, 21, 104, 0, 80, 0, 2, 2, 1, 4, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 90, 22]
        print(cmd, len(cmd), len(bytes(cmd)))
und die Ereignis sieht so aus:

Code: Alles auswählen

[104, 21, 21, 104, 0, 80, 0, 2, 2, 1, 4, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 90, 22] 27 90
P.S. len(bytes(cmd)) ist wirklich 90, ich habe das erste mal nicht richtig gespeichert.

Ich habe 32bit Version

Danke BlackJack
Antworten