Seite 1 von 1

Argumente an Script übergeben und über serielle Schnittstelle weiterleiten

Verfasst: Dienstag 12. Juli 2016, 08:57
von phischmi
Hallo zusammen,

da ich neu hier bin, zunächst zu mir :D
Ich heiße Philipp und bin bei Python gelandet, da ich mich aktuell näher mit dem Arduino auseinander setze.
Mein Ziel ist es, zwei Motoren - einen 12V Lüfter und einen Schrittmotor - vom Mac aus zu steuern.
Die Kommunikation zwischen Mac und Arduino soll per Python erfolgen, da mir dies die am weitesten verbreite Lösung zu sein scheint. Das Python-Script wiederum wird aus einem anderen Programm heraus aufgerufen und mit Argumenten gefüttert, welche angeben, welcher der beiden Motoren angesprochen werden soll und was dieser tun soll (Lüfter: Geschwindigkeit ändern / Schrittmotor: Anzahl der Schritte und Richtung).
Meine Erfahrungen in der Programmierung beschränken sich in erster Regel auf kleinere PHP-Skripte, welche ich vor einiger Zeit geschrieben habe (v.a. einfache Front-Ends für Datenbanken). OOP ist mir also zumindest nicht völlig unbekannt ;)

Da sowohl Python als auch der Arduino nun eben noch völlig neu für mich sind, taste ich mich nun langsam voran.
Der folgende Code macht grundsätzlich schon einmal, was er soll :)
Es wird ein fester Wert zwischen 0 und 255 (im Beispiel '100') über die serielle Schnittstelle an den Arduino gesendet, welcher die Geschwindigkeit des Lüfters entsprechend anpasst.

Code: Alles auswählen

#!/usr/bin/python

import sys
import serial
import struct
import time

port = '/dev/tty.usbmodemFA131'

arduino = serial.Serial(port, 9600)

arduino.open

time.sleep(2)

arduino.write(b'100')

print(arduino.readline())

arduino.close
Zur Kontrolle lasse ich mir den übergebenen Wert vom Arduino zurück geben.

Nun will ich im nächsten Schritt keine statischen Werte im Script definieren, sondern den Wert flexibel als Argument an das Script übergeben (z.B. "Arduino.py 100").
Soweit ich bisher verstanden habe, geht dies über das Array sys-argv[].
Das erste Argument bekomme ich also über sys.argv[1].

Nun würde ich das erste Argument in eine Variable einlesen und an die serielle Schnittstelle übergeben.
Mein Problem liegt nun jedoch darin, dass ich nicht weiß, wie ich den o.g. Code abwandeln muss, damit der Inhalt der Variable in gleicher Form übertragen wird wie durch

Code: Alles auswählen

arduino.write(b'100')
Das vorangestellte 'b' funktioniert ja nur mit Strings, nicht jedoch mit Variablen :K

Viele Dank für eure Unterstützung!

Philipp

Re: Argumente an Script übergeben und über serielle Schnittstelle weiterleiten

Verfasst: Dienstag 12. Juli 2016, 09:28
von Sirius3
@phischmi: Da Du mit Python2 arbeitest, gibt es keinen Unterschied zwischen Byte-Strings und den Strings, die Du in sys.argv bekommst. Du kannst sie also ohne weiteres als Argument übergeben:

Code: Alles auswählen

#!/usr/bin/python
import sys
import serial
import time

PORT = '/dev/tty.usbmodemFA131'

arduino = serial.Serial(PORT, 9600)
time.sleep(2)
arduino.write(sys.argv[1])
print arduino.readline()
arduino.close()
Übrigens muß man Funktionen auch aufrufen, damit sie abgearbeitet werden und nicht nur referenzieren, also "close()".

Re: Argumente an Script übergeben und über serielle Schnittstelle weiterleiten

Verfasst: Dienstag 12. Juli 2016, 09:42
von phischmi
@Sirius3
Danke für die schnelle Antwort!

Ich habe leider vergessen zu erwähnen, dass ich mit Python 3 arbeite :?

Die Shebang-Zeile ist entsprechend natürlich falsch und muss heissen

Code: Alles auswählen

#!/usr/bin/env python3
Da ich ohnehin bei Null anfange, wollte ich auch mit der Version starten, die in ihrer Syntax fortgeführt wird.

Des Weiteren ist das arduino.open() nicht notwendig, wie ich aus deinem Code lese?


Grüße

Philipp

Re: Argumente an Script übergeben und über serielle Schnittstelle weiterleiten

Verfasst: Dienstag 12. Juli 2016, 10:02
von Sirius3
@phischmi: Da Du anscheinend ohne "open" erfolgreich warst, ist das open überflüssig. Wenn Du mit Python 3 arbeitest, dann ist die erste Zeile irreführend.

Für Python3 mußt Du die Unicode-Strings, die Du in sys.argv erhältst, encodieren:

Code: Alles auswählen

#!/usr/bin/python3
import sys
import serial
import time

PORT = '/dev/tty.usbmodemFA131'

arduino = serial.Serial(PORT, 9600)
time.sleep(2)
arduino.write(sys.argv[1].encode("ASCII"))
print(arduino.readline())
arduino.close()

Re: Argumente an Script übergeben und über serielle Schnittstelle weiterleiten

Verfasst: Dienstag 12. Juli 2016, 10:08
von BlackJack
Den expliziten `close()`-Aufruf kann man sich auch noch sparen wenn man die ``with``-Anweisung verwendet:

Code: Alles auswählen

#!/usr/bin/env python3
import sys
import time

import serial
 
PORT = '/dev/tty.usbmodemFA131'
 
with serial.Serial(PORT, 9600) as arduino:
    time.sleep(2)
    arduino.write(sys.argv[1].encode('ASCII'))
    print(arduino.readline())

Re: Argumente an Script übergeben und über serielle Schnittstelle weiterleiten

Verfasst: Dienstag 12. Juli 2016, 11:00
von phischmi
Vielen Dank für eure Antworten! :D
Werde das Script heute Abend anpassen und ausprobieren!

Re: Argumente an Script übergeben und über serielle Schnittstelle weiterleiten

Verfasst: Dienstag 12. Juli 2016, 20:04
von phischmi
Der Code funktioniert so wie er soll. Nochmal Danke dafür :)

Eine Frage habe ich jedoch noch.

Die Rückgabe vom Arduino lautet...

Code: Alles auswählen

Last login: Tue Jul 12 19:57:12 on ttys000
Philipps-Air:~ philipp$ ./arduino.py 100
b'100\r\n'
Philipps-Air:~ philipp$ ./arduino.py 0
b'0\r\n'
Philipps-Air:~ philipp$ 
Ich hätte nun aber z.B. 100 statt b'100\r\n' erwartet. Woran liegt das?


Viele Grüße

Philipp

Re: Argumente an Script übergeben und über serielle Schnittstelle weiterleiten

Verfasst: Dienstag 12. Juli 2016, 20:08
von BlackJack
@phischmi: Woran das liegt das Du falsche Erwartungen hast? Keine Ahnung. ;-)

So sieht halt die Zeichenkettedarstellung eine `bytes`-Objektes aus das die Zeichen '1', '0', '0', und ein ”carriage return” und ein ”line feed” enthält.

Re: Argumente an Script übergeben und über serielle Schnittstelle weiterleiten

Verfasst: Dienstag 12. Juli 2016, 20:13
von phischmi
BlackJack hat geschrieben:@phischmi: Woran das liegt das Du falsche Erwartungen hast? Keine Ahnung. ;-)
Das frag ich mich auch so oft :mrgreen:

Danke für die kurze Aufklärung!

Re: Argumente an Script übergeben und über serielle Schnittstelle weiterleiten

Verfasst: Dienstag 12. Juli 2016, 20:30
von snafu
@phischmi:
Damit wird das Zeilenende signalisiert. Anders weiß das angeschlossene Gerät nicht, ob noch Eingaben kommen.