GPIO Ansteuerung

Python auf Einplatinencomputer wie Raspberry Pi, Banana Pi / Python für Micro-Controller
Antworten
lachi457
User
Beiträge: 9
Registriert: Mittwoch 12. Juli 2017, 10:36

Moin,
ich muss gleich zu Beginn sagen dass mein Problem eher einfacher Natur ist und ich mich nicht wirklich mit Python auskenne. Ich hoffe dennoch hier Hilfe zu beokmmen.
Ich habe ein USB zu GPIO Controller gekauft (https://docs.numato.com/doc/8-channel-u ... og-inputs/) und möchte jetzt zunächst nur einen GPIO PIN auf high bzw low setzen um ein kontrolliertes 5V Signal zu erhalten. Ich habe mich hierfür für PYVisa entschieden. Das Modul ist über COM4 verbunden und ich bin mittlerweile so weit gekommen:

Code: Alles auswählen

import visa
Rm = visa.ResourceManager()
Rm.list_resources()
('ASRL1::INSTR', 'ASRL3::INSTR', 'ASRL4::INSTR')
my_instrument = rm.open_resource('ASRL4::INSTR')
Wie kann ich jetzt einen der PINS auf high bzw low setzen? Ich habe vorher HyperTerminal genutzt, dort habe ich einfach GPIO Set 0 gemacht und der 0te Pin wurde auf 5V gesetzt. Zum zurücksetzen dann GPIO Clear 0. Leider komme ich hier mit PYVisa nicht wirklich weiter, bei Tutorials bin ich auch eher überfordert da ich mir erstmal alle Grundlagen anlesen müsste...
Zuletzt geändert von Anonymous am Mittwoch 12. Juli 2017, 11:09, insgesamt 1-mal geändert.
Grund: Quelltext in Python-Codebox-Tags gesetzt.
BlackJack

@lachi457: Ich sehe da jetzt nach kurzem überfliegen der Dokumentation nichts was darauf hindeutet das die Hardware über VISA benutzbar ist. Das benutzt ein einfaches serielles Protokoll was Du ja auch schon manuell per HyperTerm verwendet hast. Das müsstest Du mit `PySerial` per Programm machen. Also beispielsweise die serielle Verbindung öffnen und 'GPIO Set 0\n' darüber schreiben.

Edit: Aus der Dokumentation im Abschnitt „Controlling the module using custom programs and scripts“:
Here is the list of steps that you may need to follow while writing your own program.
  • Open the serial port for communication.
  • Set port parameters. Most of the parameters can be left to defaults except Flow Control, which needs to be set to “none”.
  • To send a command to the module, use an API equivalent to write/writefile and pass the buffer/string containing the command. It is important to append Carriage Return (ASCII 13) to emulate the ENTER key.
  • If return data is expected (Eg: “ver” command), try to read the characters from the serial port input buffer. APIs equivalent to Read/ReadFile can be used to read data from the module. Please note that the return data will include the command itself (since the module echoes everything back), the result, carriage return and the “>” symbol.
lachi457
User
Beiträge: 9
Registriert: Mittwoch 12. Juli 2017, 10:36

Danke für die Antwort,ich werde mich damit mal beschäftigen!
lachi457
User
Beiträge: 9
Registriert: Mittwoch 12. Juli 2017, 10:36

Ich habe es jetzt so weit geschafft:

Code: Alles auswählen

import serial
 
port = "COM4"
baud = 19200
 
ser = serial.Serial(port, baud, timeout=1)

if ser.isOpen():
     print(ser.name + ' is open...')
 
while True:
    cmd = input("Enter command or 'exit':")

    if cmd == 'exit':
        ser.close()
        exit()
    else:
        ser.write(cmd.encode('ascii')+'\r\n')
        out = ser.read()
        print('Receiving...'+out)
Wenn ich es ausführe passiert folgendes

Code: Alles auswählen

COM4 is open...

Enter command or 'exit':
Wenn ich jetzt allerdings mein Befehl "GPIO set 0" eingebe kommt die Meldung

Code: Alles auswählen

Traceback (most recent call last):

  File "<ipython-input-1-24b56f4e4210>", line 1, in <module>
    runfile('C:/Users/Pfad/ashyperterminal.py', wdir='C:/Users/Pfad')

  File "C:\ProgramData\Anaconda3\lib\site-packages\spyder\utils\site\sitecustomize.py", line 866, in runfile
    execfile(filename, namespace)

  File "C:\ProgramData\Anaconda3\lib\site-packages\spyder\utils\site\sitecustomize.py", line 102, in execfile
    exec(compile(f.read(), filename, 'exec'), namespace)

  File "C:/Users/Pfad/ashyperterminal.py", line 25, in <module>
    ser.write(cmd.encode('ascii')+'\r\n')

TypeError: can't concat bytes to str
Kann mir da jemand weiterhelfen?
Zuletzt geändert von Anonymous am Mittwoch 12. Juli 2017, 18:05, insgesamt 1-mal geändert.
Grund: Quelltext in Python-Codebox-Tags gesetzt.
__deets__
User
Beiträge: 14480
Registriert: Mittwoch 14. Oktober 2015, 14:29

Die serielle Schnittstelle kann nur Bytes verarbeiten. Das machst du auch richtig mit cmd.encode("ascii"), welches einen String (der zB auch japanische Zeichen enthalten kann) in reine Bytes umwandelt (wobei ASCII kein japanisch enthaelt, aber das ist ja fuer dich egal).

Aber dann versuchst du, dass mit einem String (der wieder alles sein kann) einfach zu verbinden. Das geht natuerlich nicht. Du musst eines von zwei Dingen tun:

- zuerst die zwei Strings zusammenbasteln, und dann encodieren
- aus dem '\n\r'-String stattdessen eine Byte-Sequenz machen. Theoretisch kann man das mit '\n\r'.encode('ascii') machen, das waere aber etwas wahnsinnig. Stattdessen einfach b'\n\r' schreiben, und das sollte es gewesen sein.
lachi457
User
Beiträge: 9
Registriert: Mittwoch 12. Juli 2017, 10:36

Danke für die Antwort, leider kriege ich es trotzdem nicht hin. Ich habe es so angepasst

Code: Alles auswählen

    else:
        ser.write(cmd.encode('ascii')+'b\n\r')
        out = ser.read()
        print('Receiving...'+out)
bzw. auch mit b'\n\r',hat beides nicht geklappt. Muss ich hier noch etwas anderes ändern?
Sirius3
User
Beiträge: 17703
Registriert: Sonntag 21. Oktober 2012, 17:20

@lachi457: das sollte aber funktionieren

Code: Alles auswählen

ser.write(cmd.encode('ascii')+b'\n\r')
Welche Fehlermeldung bekommst Du jetzt?
lachi457
User
Beiträge: 9
Registriert: Mittwoch 12. Juli 2017, 10:36

Ich kriege leider immernoch diesen Fehler:

Code: Alles auswählen

COM4 is open...

Enter command or 'exit':gpio set 0
Traceback (most recent call last):

  File "<ipython-input-1-24b56f4e4210>", line 1, in <module>
    runfile('C:/Users/Pfad/ashyperterminal.py', wdir='C:/Users/Pfad')

  File "C:\ProgramData\Anaconda3\lib\site-packages\spyder\utils\site\sitecustomize.py", line 866, in runfile
    execfile(filename, namespace)

  File "C:\ProgramData\Anaconda3\lib\site-packages\spyder\utils\site\sitecustomize.py", line 102, in execfile
    exec(compile(f.read(), filename, 'exec'), namespace)

  File "C:/Users/Pfad/ashyperterminal.py", line 27, in <module>
    print('Receiving...'+out)

TypeError: must be str, not bytes
__deets__
User
Beiträge: 14480
Registriert: Mittwoch 14. Oktober 2015, 14:29

Dir ist schon klar, dass das eine andere Zeile ist als der Fehler vorher?
lachi457
User
Beiträge: 9
Registriert: Mittwoch 12. Juli 2017, 10:36

Ja das ist mir klar, dass immernoch bezog sich allgemein darauf dass ein Fehler da ist
__deets__
User
Beiträge: 14480
Registriert: Mittwoch 14. Oktober 2015, 14:29

Wenn du den gleichen Fehler bekommst, und einen Hinweis, wie du den Fehler an anderer Stelle beheben kannst - warum versuchst du nicht das gleiche da auch vorzunehmen?
lachi457
User
Beiträge: 9
Registriert: Mittwoch 12. Juli 2017, 10:36

Ich dachte dass

Code: Alles auswählen

must be str, not bytes
fuer einen anderen Fehler steht als der vorherige. In Zeile 27 passiert doch eigentlich garnichts bis auf das print,verstehe nicht so ganz wo da der Fehler liegt.
__deets__
User
Beiträge: 14480
Registriert: Mittwoch 14. Oktober 2015, 14:29

Es ist schon mehr oder minder dasselbe. Es werden wieder zwei Dinge mit + verbunden, und die sind nicht vom gleichen Typ - nur die Reihenfolge ist unterschiedlich, einmal bytes + string, dann string + bytes.

Darum kann man das auch gleich loesen - man muss beides zu bytes machen. Und das macht man wie gezeigt mit dem kleinen b vor dem Literal.
lachi457
User
Beiträge: 9
Registriert: Mittwoch 12. Juli 2017, 10:36

Danke dir erstmal fuer deine Geduld mit mir! Ich werde es gleich mal ausprobieren
lachi457
User
Beiträge: 9
Registriert: Mittwoch 12. Juli 2017, 10:36

Funktioniert erstmal so,danke!
BlackJack

@lachi457: Das ``if ser.isOpen():`` ist überflüssig, den die serielle Schnittstelle ist an der Stelle ganz sicher offen — andernfalls hätte Zeile 6 eine Ausnahme ausgelöst.

Ich würde dem Objekt auch einen besseren Namen geben. `gpio_connection` zum Beispiel, damit man auch weiss womit man da eine Verbindung hat.

`serial.Serial`-Objekte kann man mit der ``with``-Anweisung verwenden. Das ist sicherer als selbst irgendwo ein `close()` aufzurufen.

Die `exit()`-Funktion muss man aus `sys` importieren. Das die einfach so da ist, ist undokumentiert.
Sirius3
User
Beiträge: 17703
Registriert: Sonntag 21. Oktober 2012, 17:20

@lachi457: »exit« ist an dieser Stelle sowieso nicht gut, da reicht ein »break«.
Antworten