Seite 1 von 1
Serielle Schnittstelle - write hängt
Verfasst: Donnerstag 1. August 2013, 14:01
von wilhelmO
Hallo an alle Leser meines Problems.
Ich möchte einen Motorcontroller über die "serielle Schnittstelle" ansteuern. Hierbei wird ein usb/seriel-converter verwendet.
Dieser scheint auch nicht mein Problem zu sein. Nach Auslösen des write-befehls verabschiedet sich mein Programm. Keine
Rückmeldung mehr.
Bin in MotorOn wird nicht mehr ausgedruckt.
Bei erneutem Starten des Programms kommt die Fehlermeldung auf port kann nicht zugegriffen werden, was ja auch korrekt ist,
denn bis zum Schliessen kommt es ja nicht.
Code: Alles auswählen
import usb.core
import usb.util
import serial
class Oriental(object):
def __init__(self):
self.dev = usb.core.find(idVendor=0x403,idProduct=0x6001)
print 'dev is named :',self.dev
if self.dev is None:
raise ValueError('USB - Port not found !')
else:
#print'ELSE'
self.available = []
for i in range(256):
try:
print'tryNr =',i
self.serial = serial.Serial(i)
#print'1'
self.available.append((i,self.serial.portstr))
print'available =',self.available
self.serial.close()
print type(self.available)
#return self.available
if self.available is not None:
break
except serial.SerialException:
#print'Exception'
pass
def Port(self):
p = self.available[0]
port = list(p)
self.port = port[1]
print self.port
return self.port
def MotorOn(self,port):
self.port = port
self.serial = serial.Serial(self.port,9600,8,'N',1,timeout=5)
self.open = self.serial.isOpen()
print 'self.serial is open ?',self.open
self.serial.flushOutput()
self.serial.write("CURRENT=1")
print 'bin in MotorOn'
def Move(self,motion):
self.motion = motion
print 'motion is :',self.motion
self.serial.flushOutput()
self.serial.write(self.motion)
def Close(self,port):
self.port = port
self.serial.Serial.close(self.port)
if __name__ =="__main__" :
motion=("VS=10.0;TA=1.0;TD=1.0;VR=2.0;MI")
a = Oriental()
p=a.Port()
a.MotorOn(p)
a.Move(motion)
a.Close(p)
Folgende Meldungen erscheinen in der Konsole :
dev is named : <usb.core.Device object at 0x00000000025F7A20>
tryNr = 0
tryNr = 1
tryNr = 2
tryNr = 3
tryNr = 4
available = [(4, 'COM5')]
<type 'list'>
COM5
self.serial is open ? True
Re: Serielle Schnittstelle - write hängt
Verfasst: Donnerstag 1. August 2013, 14:41
von BlackJack
@wilhelmO: Stimmen denn die Verbindungsdaten? Kannst Du mit diesen Parametern mit dem Motor über andere Software kommuniziern, also zum Beispiel über ein serielles Terminal?
Das Programm ist stilistisch übrigens extrem schlecht. Das was Du da mit der Klasse veranstaltest ist keine ordentliche objektorientierte Programmierung. In der `__init__()` sollten zum Beispiel alle Attribute definiert werden, die den Zustand des Objekts beschreiben und das Objekt in einen benutzbaren Zustand versetzt werden. Es sollten nicht mehr Attribute existieren als nötig sind um dieses eine Objekt ausreichend zu beschreiben. Also nicht einfach irgendwelche Werte an das Objekt binden, die genau so gut einfach nur lokale Namen in Methoden sein könnten.
Re: Serielle Schnittstelle - write hängt
Verfasst: Freitag 2. August 2013, 13:11
von wilhelmO
Mit dem vom Hersteller geliefertem terminal-programm läßt sich der Motor steuern.
Wenn ich jedoch die 'gleichen strings oder auch hex-werte' sende hängt sich das
programm auf. Es wird nicht bin in MotorOn gedruckt.
Re: Serielle Schnittstelle - write hängt
Verfasst: Freitag 2. August 2013, 13:35
von BlackJack
@wilhelmO: Verwendet das Programm denn die gleichen Verbindungseinstellungen? Stehen die irgendwo so in der Dokumentation?
Ausserdem wird man bei dem Terminalprogramm wohl die Eingabetaste betätigen müssen, also solltest Du auch die dadurch entstehenden Zeilenendenzeichen senden. Daran wird der Empfänger sehr wahrscheinlich erkennen wann er anfangen muss die Daten zu verarbeiten.
Re: Serielle Schnittstelle - write hängt
Verfasst: Montag 5. August 2013, 09:36
von wilhelmO
Guten Morgen Black Jack,
vielen Dank für die Antwort. Ich habe in idle folgendes eingegeben :
import seriel
rs = serial.Serial("COM5",9600,8,'N',1,timeout=20)
rs.isOpen
>>>True # Antwort
rs.getPort
'COM5' # Antwort
rs.write('')
>>>0 # Antwort
So weit so gut, die obigen Schnittstellenparameter sind die default-werte des Interfaces
Sobald ich irgendeinen sinnvollen parameter sende, egal ob als hex-wert oder ascii-zeichen in "" ,
hängt das Programm, soll heißen keine Rückmeldung. Abbruch nur noch mit dem Taskmanager.
Selbst wenn ich irgendeinen "Müll" sende, sollte doch das Programm nicht hängen sonder lediglich keine
Reaktion vom Motor die Folge sein.
Bin ein wenig ratlos.
Re: Serielle Schnittstelle - write hängt
Verfasst: Montag 5. August 2013, 10:21
von BlackJack
@wilhelmO: Du hast jetzt immer noch nicht definitiv beantwortet ob die Verbindungsparameter stimmen. Und wenn ja, woher Du das weisst. Stehen die in der Dokumentation? Hast Du die geraten?
Kannst Du mit anderer Software ausser der vom Hersteller auf die Schnittstelle zugreifen? Einfaches serielles Terminal zum Beispiel? Also beispielsweise HyperTerminal unter Windows? (Weiss gar nicht ob das bei aktuellen Windows-Versionen noch zum Lieferumfang gehört.)
Re: Serielle Schnittstelle - write hängt
Verfasst: Montag 5. August 2013, 10:46
von wilhelmO
Völlig korrekt ! hole ich hiermit nach
Die Schnittstellenparameter habe ich aus Handbuch und Software des Herstellers. Hiermit funktioniert auch die Kommunikation und das Steuern des Motor.
Die Schnittstelle ist von der hardware eine usb. Diese wird durch einen chip des Herstellers Future Technology Devices auf controllerseite auf rs232 konvertiert.
Deshalb ist im obigen program auch die Abfrage auf idVendor und idProduct zu sehen. Es sollen später mehrere Motoren über usb - Ausgänge angesteuert werden.
Die Software des Herstellers des Motorinterfaces ( oriental ) arbeitet allerdings über dieselbe Wandlerschnittstelle.
Re: Serielle Schnittstelle - write hängt
Verfasst: Montag 5. August 2013, 11:15
von BlackJack
@wilhelmO: Funktioniert es denn über eine Terminalsoftware die nicht vom Hersteller ist?
Re: Serielle Schnittstelle - write hängt
Verfasst: Montag 5. August 2013, 14:33
von wilhelmO
Bin etwas weiter. Ein Kollege hatte eine Verbindung für sein handy über bluetooth auf meinem laptop eingerichtet. Zufällig habe ich dies jetzt in der Systemsteuerung entdeckt.
COM3 und COM5 waren hier "belegt".
Offensichtlich wurden die Steuerbefehle nicht an den oriental-controller gesandt. Leider haben die mir zur Verfügung stehenden laptops keine serielle Schnittstelle mehr - nur noch usb.
Ein terminal-programm zum testen habe ich nicht zur Verfügung.
Jedenfalls stürzt das Skript nicht mehr ab.
Hier das aktuelle skript :
Code: Alles auswählen
import usb
import usb.core
import usb.util
import usb.control
import time
import sys
import Tkinter as tk
class Window(object):
def __init__(self,root):
self.root = root
self.canvas = tk.Canvas(self.root)
self.canvas.pack()
self.canvas.config(bg='black')
self.canvas.config(width=400)
self.canvas.config(height=200)
class Oriental(object):
VENDOR = 0x0403
PRODUCT= 0x6001
CONFIGURATION= 0x01
INTERFACE = 0
ENDPOINT_IN= 0x02
ENDPOINT_OUT=0x81
device = None
handle = None
def __init__(self):
for bus in usb.busses():
for dev in bus.devices:
if dev.idVendor == self.VENDOR and dev.idProduct == self.PRODUCT :
self.device = dev
print 'self.device =',self.device
print 'search done'
return None
def open(self):
if not self.device:
print >>sys.stderr,"Unable to find device"
return None
try:
self.handle = self.device.open()
self.handle.setConfiguration(self.CONFIGURATION)
self.handle.claimInterface(self.INTERFACE)
print "self.handle =",self.handle
except usb.USBError,err:
print >> sys.stderr,err
self.handle = None
return self.handle
def close(self):
try:
self.handle.releaseInterface()
except Exception,err:
print >> sys.stderr,err
self.handle, self.device = None,None
def read(self,length,timeout=0):
return self.handle.bulkRead(self.ENDPOINT_OUT,length,timeout)
def write(self,buffer,timeout=0):
return self.handle.bulkWrite(self.ENDPOINT_IN,buffer,timeout)
if __name__ == "__main__" :
root = tk.Tk()
root.title('Oriental Motors USB - Connection')
O = Window(root)
o = Oriental()
o.open()
b=o.write(chr(0x43)+chr(0x55)+chr(0x52)+chr(0x52)+chr(0x45)+chr(0x4E)+chr(0x54)+chr(0x3D)+chr(0x31)+chr(0x0D),10)
a=o.read(8,20)
print'answerone=',a
#a=o.write('TD=1.0;TA=1.0;VS=1.0;VR=4.0;DIS=10;MI',10)
a=o.write(chr(0x56)+chr(0x53)+chr(0x3d)+chr(0x31)+chr(0x30)+chr(0x54)+chr(0x41)+chr(0x3d)+chr(0x31)+chr(0x54)+chr(0x44)+chr(0x3d)+chr(0x31)+chr(0x56)+chr(0x52)+chr(0x3d)+chr(0x32)+chr(0x4d)+chr(0x49)+chr(0x43)+chr(0x52))
antwort2=o.read(8,20)
print'answertwo =',antwort2
o.close()
root.mainloop()
Der printout lautet dann wie folgt :
self.device = <usb.legacy.Device object at 0x00000000025AA8D0>
search done
self.handle = <usb.legacy.DeviceHandle object at 0x0000000002557080>
answerone= array('B', [1, 96])
answertwo = array('B', [1, 96])
Re: Serielle Schnittstelle - write hängt
Verfasst: Montag 5. August 2013, 15:49
von Sirius3
warum Du 'CURRENT=1\r' und 'VS=10TA=1TD=1VR=2MICR' so kompliziert schreibst, bleibt wohl Dein Geheimnis??
Re: Serielle Schnittstelle - write hängt
Verfasst: Montag 5. August 2013, 16:24
von BlackJack
Und zusätzlich sollte das 'CR' bei der zweiten Übertragung wohl auch eher ein '\r' sein.
Re: Serielle Schnittstelle - write hängt
Verfasst: Dienstag 6. August 2013, 08:13
von wilhelmO
Guten Morgen und vielen Dank für eure Beiträge.
Wenn ich im terminalprogramm des Herstellers "CURRENT=1" eintippe und mit carriage return abschliesse, dann ist die Endstufe eingeschaltet.
Daraufhin kann ich "VS=1.0;TA=1.0;TD=1.0,VR=2.0;MI" eingeben und ebenfalls mit carriage return abschliessen.
Dann läuft der Motor mit diesen Parametern los.
Ich habe keine Ahnung was wirklich an den controller gesandt wird.
Allerdings hatte ich erwartet ser.write(chr(64)) oder ser.write(chr(0x40)) oder ser.write("\x40") sendet immer "@" über die Schnittstelle.
Daher habe ich erwartet mit rs.write("CURRENT=1") und einem 'Enter/carriage return' als rs.write('CR') den gleichen Erfolg zu haben.
Habe inzwischen rs.write("CURRENT=1"+"\r" oder rs.write("CURRENT=1") und rs.write('\r')
ohne positives Ergebnis probiert.
Re: Serielle Schnittstelle - write hängt
Verfasst: Dienstag 6. August 2013, 08:20
von wilhelmO
Sorry ! muss natürlich o.write lauten - hatte ich auch gemeint aber nicht geschrieben.
Re: Serielle Schnittstelle - write hängt
Verfasst: Dienstag 6. August 2013, 08:48
von Sirius3
@wilhelmO: gibt es denn keine Beschreibung des Protokolls, das Dein Controller versteht? Werden die Befehle wirklich mit '\r' oder mit '\n' oder '\n\r' oder einem sonstigen Steuerzeichen abgeschlossen? Oder werden die Befehle vom Terminalprogramm in irgendein Binärformat übersetzt?
Vielleicht solltest Du mal am USB-Port lauschen, was tatsächlich gesendet wird.
Re: Serielle Schnittstelle - write hängt
Verfasst: Dienstag 6. August 2013, 09:13
von wilhelmO
Guten Morgen Sirius3 ,
werde alle \r , \n , \n\r testen. Habe mit der Vetretung von oriental Kontakt aufgenommen. Evtl. sendet das kleine "terminal - programm" doch nocht etwas
für den Bediener nicht sichtbares.
Im Handbuch der software steht : 8 data, 1 stop , parity None , fix frame: 10 bytes , binary transmission , half duplex.
Hier macht mir 10 bytes Bauchschmerzen. Passt denn o.write("TD=1.0;TA=1.0;VS=1.0;VR=4.0;DIS=10.0;MI\n") in 10 bytes ?
Oder ist dies eh egal, da der Controller die Übertragung steuert/proportioniert ?
Ich hoffe oriental hat hierfür Antworten.
Re: Serielle Schnittstelle - write hängt
Verfasst: Dienstag 6. August 2013, 09:23
von BlackJack
@wilhelmO: Nö, das passt ganz offensichtlich nicht in 10 Bytes:
Code: Alles auswählen
In [3]: len("TD=1.0;TA=1.0;VS=1.0;VR=4.0;DIS=10.0;MI\n")
Out[3]: 40
Aber was ist denn das jetzt mit dem Controller? Hängt da noch ein Gerät zwischen dem Rechner und dem Motor? Falls ja macht es erst einmal mehr Sinn zu schauen was *das* Gerät denn als Protokoll erwartet. Denn mit *dem* kommuniziert man ja.
Re: Serielle Schnittstelle - write hängt
Verfasst: Dienstag 6. August 2013, 14:02
von wilhelmO
Hallo BlackJack , Danke für den Beitrag
Habe inzwischen vom Controller/Motorenlieferanten Oriental ein kleines Programm von Fa. Deutschmann ( Nockenschaltwerk und businterface - Hersteller ) erhalten.
Und siehe da -- gleicher Effekt ! Motor reagiert nicht. Controller liefert aber anscheinend für jedes gesandte byte den Wert 0x07 zurück.
Warte auf Rückmeldung von Oriental - melde mich dann wieder.
Meiner Ansicht nach wird vom original Oriental - Konsolenprogramm doch noch etwas mehr an den controller gesandt , echo -Funktion zeigt es aber evtl. nicht an.
Re: Serielle Schnittstelle - write hängt
Verfasst: Mittwoch 7. August 2013, 15:28
von wilhelmO
Nochmals vielen Dank an alle Beteiligten
das Problem bestand im abschliessenden Steuerzeichen.
Strom einschalten :
o.write("CURREN=1"+chr(0x0A))
Motor fahren lassen :
o.write("TD=0.1;TA=0.5;VS=1.0;VR=4.0;DIS=14;MI"+chr(0x0D))
wobei es gleichgültig ist ob man als abschliessendes Steuerzeichen ein linefeed (0x0A) oder carriage return (0x0D) sendet
Nochmals vielen Dank für die Beteiligung.
Re: Serielle Schnittstelle - write hängt
Verfasst: Mittwoch 7. August 2013, 18:44
von BlackJack
@wilhelmO: Das kann jetzt aber irgendwie nicht sein, denn das kann man einfacher schreiben und das hatten wir doch schon:
Code: Alles auswählen
In [1]: chr(0x0A)
Out[1]: '\n'
In [2]: chr(0x0D)
Out[2]: '\r'
Re: Serielle Schnittstelle - write hängt
Verfasst: Donnerstag 8. August 2013, 12:31
von wilhelmO
Korrekt - hatten wir schon
Kann nicht mehr nachvollziehen warum es nicht funktionierte.
o.write("MI"+'\n') funktioniert
o.write("MI\n") funktioniert
o.write("MI\r") funktioniert
Sicherlich habe ich irgendetwas anderes übersehen.
Ich kann den Motor steuern und bin weiter.