Liebe Community Ich experimentiere hier mit einer Gorba LCD Anzeige (Fahrzielazeige in einem Bus) herum. Diese wird per Alpha-Bus angesteuert. Was ich weiss, ist dass die Datenleitung bidirektional ist und mit 19200 Baud, 8N2 angesteuert wird. Ich kann auch schon erste Erfolge mit einem Python Script erzielen. Nun die Krux: Die Datenleitung ist idle auf 24V. Ich habe mir nun einen Schaltung zusammengebastelt, die via Optokoppler und Transistor die 5V vom FTDI Chip an die 24V der Anzeige anpasst. Das funktioniert soweit. Um die Antwort der Anzeige zu empfangen habe ich das Signal via Optokoppler an die 5V angeglichen. Achtung, es ist ein Gebastel funktioniert soweit für erste Kommunikation. Nun das Problem: Sende ich auf TX, so kommt das gleich im RX wieder an (da ja die Anzeige nur eine Datenleitung hat). Ich muss also beim Senden das TX Signal auf der RX Leitung unterdrücken. Ich dachte, ich könne dies mit einem 7400 NAND erledigen (den habe ich rumliegend und verwende diesen bereits im RX Pfad um das Signal nach dem Optokoppler zu invertieren). Doch der 7400 erzeugt auch ein Delay, somit geht das nicht. Ich weiss, 7400 ist keine schlaue Wahl. Was gäbe es hier für einfachere Lösungen? Ev. Kann ich dies auch softwaremöäsig lösen, doch dafür sind meine Python Kenntnisse wohl zu mager. Und die Telegramme der Kommunikation sind unterschiedlich lange und haben als Start- und Stopbyte jeweils 0x7E.
:
Bearbeitet durch User
das lokale echo von der datenleitung ist eigentlich sogar zu bevorzugen, einfach vor jeder erwarteten antwort den rx fifo flushen und ggf später die integrität der selbst gesendeten signale prüfen. eine empfangsunterdrückung klappt dann ggf mit höherer kabelkapazität nicht mehr richtig bzw unterdrückt auch korrekte signale.
Man könnte ja über die Steuersignale des FTDI vor Sendebeginn den zweiten Eingang des 7400 auf low ziehen und nach dem Stopbit letzten Zeichens wieder auf high legen.
Du kannst doch die Antwort entsprechend in deinem Programm einfach "verschlucken" ? Du weisst ja, was du gesendet hast. Überspring diesen Teil der Antwort.
:
Bearbeitet durch User
Simon S. schrieb: > Ev. Kann ich dies auch softwaremöäsig lösen, doch dafür sind meine > Python Kenntnisse wohl zu mager. Einfach nach jedem gesendeten Paket die gleiche Anzahl Bytes empfangen. Tritt dabei ein Timeout auf oder weichen die Daten ab, wirfst Du eine Fehlermeldung aus, dass etwas mit dem Bus nicht stimmt.
Danke für die bisherigen Antworten, dieses Forum ist einfach so toll. Auch wenn ich mich nur alle Schaltjahre hierbewege, die werstschätzende Unterstützung und Lösungsideen aus der Community kommen sofort. Herzliche Dank. Fürs erste möchte ich die Idee von Schorsch X. weiterverfolgen. Schorsch X. schrieb: > Du kannst doch die Antwort entsprechend in deinem Programm einfach > "verschlucken" ? Du weisst ja, was du gesendet hast. Überspring diesen > Teil der Antwort. Da ich wirklich Python Beginner bin, stelle ich hier mal meinen Code ein. Wie könnte ich das anpassen, dass bei der Antwort, die gesendeten Pakete "verschluckt" werden?
1 | import serial |
2 | import time |
3 | |
4 | ser = serial.Serial('/dev/cu.usbserial-A400C24C', |
5 | baudrate=19200, |
6 | parity=serial.PARITY_NONE, |
7 | stopbits=serial.STOPBITS_TWO, |
8 | bytesize=serial.EIGHTBITS, |
9 | timeout=0 |
10 | ) |
11 | |
12 | tx_1 = [0x7E, 0x81, 0x7D, 0x5E, 0x7E] |
13 | tx_2 = [0x7E, 0x91, 0x04, 0x02, 0x68, 0x7E] |
14 | |
15 | # Initialisierung senden |
16 | print ("Sende Initialisierung " + ''.join(format(x, '02x') for x in tx_1)) |
17 | ser.write(serial.to_bytes(tx_1)) |
18 | |
19 | print ("\nWarte auf Antwort ...") |
20 | time.sleep(0.007) |
21 | ser.flushInput() |
22 | |
23 | while 1: |
24 | # Bytes einlesen |
25 | hexData= ser.read(50).hex() |
26 | #Auf Antwort warten |
27 | if (hexData): |
28 | print("Empfange: " + hexData) |
29 | |
30 | if (hexData == "7e817d5e7e7e014c4d01563135ac7e"): |
31 | print (" rx_1") |
32 | print (" Sende Antwort " + ''.join(format(x, '02x') for x in tx_2)) |
33 | ser.write(serial.to_bytes(tx_2)) |
34 | else: |
35 | print (" Daten unbekannt") |
36 | |
37 | print ("\nWarte auf Antwort ...") |
38 | |
39 | ser.close() |
Obiger COde funktionert so weit. Unschön daran ist, dass ich den String
1 | "hexData == "7e817d5e7e7e014c4d01563135ac7e" |
manuell generiert habe. Die Variable tx_1 würde "7e817d5e7e" enthalten. Wie müsste ich das anpassen, damit dies von hexData "subtrahiert" wird?
:
Bearbeitet durch User
Flip B. schrieb: > das lokale echo von der datenleitung ist eigentlich sogar zu bevorzugen, > einfach vor jeder erwarteten antwort den rx fifo flushen und ggf später > die integrität der selbst gesendeten signale prüfen. eine > empfangsunterdrückung klappt dann ggf mit höherer kabelkapazität nicht > mehr richtig bzw unterdrückt auch korrekte signale. Kannst du mir beim Code oben helfen, wie ich diese umsetzen könnte? Das mit dem ser.flushInput() direkt nach dem Senden habe ich bereits probiert. Das hat leider nichts genützt.
Hurrah, ich konnte den Code wie von euch empfohlen anpassen. Dabei kann ich mit dem Python Befehl "replace()" die gesendeten Bytes von den Empfangenen abziehen:
1 | # Bytes einlesen |
2 | hexData = ser.read(100).hex() |
3 | # Antwort bereinigen |
4 | rxData = hexData.replace(''.join(format(x, '02x') for x in txData), "", 1) |
Nun kann ich auch die Anzeige ansteuern mit den Befehlen, die ich gesnifft habe. Ich mache mich nun daran, die Bytes den einzelnen Pixeln der Anzeige zuzuordnen. Nun muss ich aber erst mal herausfinden, wie die Checksumme berechnet wird. Was ich soweit sehe: Startbyte und Endbyte sind jeweils "0x7E". Kann mir jemand anhand der Daten helfen, wie die Checksumme berechnet wird? Hier ein paar Telegramme:
1 | tx_301 = [0x7E,0x82,0x7D,0x5D,0x7E] |
2 | tx_302 = [0x7E,0x83,0x7C,0x7E] |
3 | tx_303 = [0x7E,0x84,0x7B,0x7E] |
4 | tx_304 = [0x7E,0x85,0x7A,0x7E] |
5 | tx_305 = [0x7E,0x86,0x79,0x7E] |
6 | tx_306 = [0x7E,0x87,0x78,0x7E] |
7 | tx_307 = [0x7E,0x88,0x77,0x7E] |
8 | tx_308 = [0x7E,0x89,0x76,0x7E] |
9 | tx_309 = [0x7E,0x8A,0x75,0x7E] |
10 | tx_310 = [0x7E,0x8B,0x74,0x7E] |
11 | tx_311 = [0x7E,0x8C,0x73,0x7E] |
12 | tx_312 = [0x7E,0x8D,0x72,0x7E] |
13 | tx_313 = [0x7E,0x8E,0x7D,0x5E,0x7E,0x00,0x00] |
14 | tx_314 = [0x7E,0x81,0x7D,0x5E,0x7E] |
15 | row_24 = [0x7E,0xA1,0x24,0x90,0x00,0x00,0x00,0x00,0x00,0x90,0x00,0x00,0x00,0x00,0x00,0x90,0x00,0x00,0x00,0x00,0x00,0x90,0x00,0x00,0x00,0x00,0x00,0x90,0x00,0x00,0x00,0x00,0x00,0xEA,0x7E] |
16 | row_23 = [0x7E,0xA1,0x23,0x90,0x00,0x00,0x00,0x00,0x00,0x90,0x00,0x00,0x00,0x00,0x00,0x90,0x00,0x00,0x00,0x00,0x00,0x90,0x00,0x00,0x00,0x00,0x00,0x90,0x00,0x00,0x00,0x00,0x00,0xED,0x7E] |
17 | row_22 = [0x7E,0xA1,0x22,0x90,0x00,0x00,0x00,0x00,0x00,0x90,0x00,0x00,0x00,0x00,0x00,0x90,0x00,0x00,0x00,0x00,0x00,0x90,0x00,0x00,0x00,0x00,0x00,0x90,0x00,0x00,0x00,0x00,0x00,0xEC,0x7E] |
Die Checksumme ist gefunden: Es ist XORen der einzelnen Bytes (ohne Startbyte) und dann von 0xFF abziehen. In Python habe ich das mit folgender Funktion lösen können:
1 | def checksum(data): |
2 | xorval = 0 |
3 | for el in data: |
4 | xorval ^= el |
5 | return 255 - xorval |
Die Bitmaps können nun verändert werden. Nächste Hürde wird nun sein, die Pixel eines Bildes den Pixeln auf der Anzeige zuordnen zu können. Dies wird spannend, da in zwei Halbbildern übertragen wird.
:
Bearbeitet durch User
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
Mit Google-Account einloggen
Noch kein Account? Hier anmelden.