Serial Com Port Werte senden

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
error404
User
Beiträge: 18
Registriert: Montag 24. Oktober 2016, 09:14

Hallo,

ich möchte über die Serielle schnittstelle Werte an ein BLE-Dongel senden. Hierbei werden aber die Werte die ich sende nicht übernommen. Weiß jemand wie ich das mit der übergabe des Strings machen muss?

Code: Alles auswählen


#! /bin/python3
import serial
import time

port = "/dev/ttyUSB0"
baud = 115200
i = 0
ser = serial.Serial(port, baud)


if ser.isOpen():
     print(ser.name + ' is open...')
     time.sleep(1)
     print('Please wait a few seconds')

while i < 1:
        ser.write("\r\nSET NAME TEST123 ")
        time.sleep(2)
        i = 1
        
cmd = raw_input("successful!\npress any key to exit...")
ser.close()
exit()
Ich bedanke mich im voraus schon mal für jede Hilfe.
Zuletzt geändert von Anonymous am Donnerstag 10. August 2017, 12:30, insgesamt 1-mal geändert.
Grund: Quelltext in Python-Codebox-Tags gesetzt.
BlackJack

@error404: Vielleicht die Steuerzeichen für Wagenrücklauf und Zeilenvorschub *nach* den Daten senden und nicht *davor*? Oder zumindest sollte/müsste man ohne abschliessende Steuerzeichen den Ausgabepuffer ”flush”en.

Die „she-bang“-Zeile ist fehlerhaft. Zwischen '!' und '/' darf kein Leerzeichen stehen. Ausserdem ist es besser `env` zu verwenden und den Pfad zum Python-Interpreter nicht hart vorzugeben. ``/bin/python3`` ist wahrscheinlich auch nicht sooo häufig. Zumindest nicht unter den meisten Linuxdistributionen.

Allerdings ist Python 3 eh falsch wenn der Code `raw_input()` verwendet! Andererseits schreibst Du die ``print``-Anweisung als wäre es eine Funktion. Sehr verwirrend.

Zudem sind da einige Merkwürdigkeiten in dem Code.

Das ``if`` mit `ser.isOpen()` macht keinen Sinn weil die Verbindung an der Stelle offen *ist*, denn sonst hätte das erstellen des `Serial`-Exemplars eine Ausnahme ausgelöst.

Wie ``while``-Schleife macht so gar keinen Sinn weil sie grundsätzlich *genau* einmal durchlaufen wird. Damit ist das aber Schleife.

`exit()` braucht man am Ende des normalen Programmflusses nicht aufrufen und vor allem sollte man das nicht tun ohne die Funktion explizit aus dem `sys`-Modul zu importieren. Das die einfach so existiert ist ”Zufall”. Grundsätzlich sollte man die Funktion sowieso nur aufrufen wenn man einen Rückgabecode an den aufrufenden Prozess übermitteln möchte, und nicht einfach nur um das Programm zu beenden.

`Serial`-Objekt sind übrigens Kontextmanager und können mit ``with`` verwendet werden.

Die Ausgabe am Programmende stimmt nicht: Nicht irgendeine Taste beendet das Programm, sondern die Eingabetaste. `cmd` wird nicht verwendet, braucht also auch nicht definiert zu werden. Wobei so etwas sehr nervig ist wenn man das Konsolenprogramm in der Konsole startet. Da enden Programme einfach und gut ist.

Eingerückt wird per Konvention vier Leerzeichen pro Ebene. Nicht fünf und auch nicht acht.

Ungetestet:

Code: Alles auswählen

#!/usr/bin/env python
# coding: utf-8
from __future__ import absolute_import, division, print_function
import time
from serial import Serial


def main():
    port = '/dev/ttyUSB0'
    baud = 115200

    with Serial(port, baud) as connection:
        print(connection.name, 'is open...')
        time.sleep(1)
        print('Please wait a few seconds')

        connection.write(b'SET NAME TEST123\r\n')
        time.sleep(2)
    
    raw_input('successful!\npress enter to exit...')


if __name__ == '__main__':
    main()
error404
User
Beiträge: 18
Registriert: Montag 24. Oktober 2016, 09:14

Danke. Ein paar Sachen habe ich so übernommen.

Code: Alles auswählen

#!/usr/bin/env python
# coding: utf-8
from __future__ import absolute_import, division, print_function
import serial
import time
x = 0

for i in range(5):     
  port = "/dev/ttyUSB"+str(x)
  baud = 115200
  ser = serial.Serial(port, baud)
    
  if ser.isOpen():
     print(ser.name + ' is open...')
     time.sleep(1)
     print('Please wait a few seconds')
     
     ser.write("\r\nSET NAME TEST123\r\n")
     ser.write("SET DB 1332\r\n")
     x = x + 1

cmd = raw_input("successful!\npress any key to exit...")
ser.close()
exit()

ich nutze hier nun eine for Schleife um mehrere Ports zu errechen. Ich werde nochmal versuchen, das ganze mit Exceptions hin zu bekommen, damit es auch läuft sollte mal ein Port nicht belegt sein.
Nochmals herzlichen Danke für die Hilfe.
Zuletzt geändert von Anonymous am Donnerstag 10. August 2017, 16:55, insgesamt 1-mal geändert.
Grund: Quelltext in Python-Codebox-Tags gesetzt.
BlackJack

@error404: Jetzt schliesst Du keine seriellen Verbindungen mehr, ausser der letzten. Die ``with``-Anweisung ist da echt ein Freund.

Und wie gesagt ist die Verbindung garantiert offen! Das ``if`` ist überflüssig. Wäre es das *nicht* dann hättest Du auch ein Problem, denn dann würde `x` nicht hochgezählt und versucht eine Verbindung auf dem gleichen Port zu öffnen bei dem es ja gerade schon nicht funktioniert hätte.

Kann es sein dass Du `x` ganz weglassen möchtest und stattdessen gleich `i` verwenden wolltest?

Du könntest Dir auch mal `comports()` oder `grep()` aus `serial.tools.list_ports` anschauen. Es gibt da ja noch mehr Möglichkeiten als ``/dev/ttyUSB*`` und das liefert auch mehr Informationen nach denen man filtern könnte.
error404
User
Beiträge: 18
Registriert: Montag 24. Oktober 2016, 09:14

Ok, ich habe das mit "with" wohl nicht so recht verstanden. Das problem ist halt, er geht ja die einzelnen Ports ab und es kann halt sein, das dann z.b. Port 1 belegt ist, Port 2 und 3 nicht. Trotzdem soll er dann aber versuchen die weiteren Ports also 4, 5 ,6 ... zu öffnen und dort die Werte zu übermitteln. Das wollte ich halt nun irgendwie mit Try und Exceptions lösen. Ich werde hierzu nochmal `serial.tools.list_ports` anschauen und im Internet recherchieren. An sich funktioniert das Script aber wenn halt alle Ports belegt sind die er öffnen soll. Den zähler x habe ich nun auch durch i ersetzt.
Nochmals recht herzlichen Dank.
Antworten