2016-11-18 4 views
1

So versuche ich mit einem Zigbee-Modul mit einem seriellen Anschluss mit Hilfe von AT (manchmal als Hayes bezeichnet) Befehle zu kommunizieren.Probleme beim Lesen mit pyserial

Mein Problem ist, dass ich nicht herausfinden kann, wie man seine Antworten mit dem pyserial Modul von Python richtig liest (ich benutze Python 2.7 auf einem eingebetteten Gerät).

Manchmal gelingt es dem Skript, die Antworten des Moduls perfekt zu lesen, und manchmal gibt es nur eine Folge von 'A'-Zeichen zurück.

Hier ist ein Beispiel für die Ausgabe:

Eröffnung seriell/dev/ttyS2 ... /dev/ttyS2 ist offen ...

Befehl eingeben oder 'exit': AT

------------- ------------- Antwort

AT OK

Geben Sie den Befehl oder 'exit': ATI

------------- ------------- Antwort aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaAaaaaaaaaaaaaaaaaaaaaaAaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaAaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaAaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaAaaaaaaaaaaaaaaaaaaaaaaaaAaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaAaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaAaAaaaAaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa

Geben Sie den Befehl oder ' Ausgang ':

Ich verstehe wirklich nicht, was hier passiert, aber ich denke, es ist wahrscheinlich, weil ich das Pyserial-Modul falsch verwende. Ich habe bereits versucht, den Befehl inWaiting() zu verwenden, um nur die Bytes im Eingangspuffer zu lesen, aber diese Funktion gibt immer Null zurück und der readline() Befehl scheint nicht zu funktionieren, also lese ich nur Pakete von 1024 Bytes.

Hier ist der Code, den ich bisher geschrieben habe:

import serial, time, os 

def sendAtCommand(command): 

    # responseArray = [] 
    # i = 0 

    try: 
     # print('Number of bytes waiting in input buffer before write : '+str(ser.inWaiting())) -> always zero... 

     if ser.inWaiting(): 
      # flush input buffer, discarding all its contents 
      print('flushing input buffer ...') 
      ser.flushInput() 
      # flush output buffer, aborting current output 
      # ser.flushOutput() 

     try: 
      ser.write(command.encode('ascii')+'\r') 
      #ser.write(command+'\r') 
      #time.sleep(5) 
     except SerialTimeoutException as e: 
      print(repr(e)) 

     response = ser.read(size=1024) 
     # print('Number of bytes waiting in input buffer after write : '+str(ser.inWaiting())) -> always zero 
     # while ser.inWaiting(): 
      # print('Reading response ... '+str(i)) 
      # responseArray.append(ser.readline(eol='\r\n')) 
      # i += 1 
      # time.sleep(0.2) 

     print('------------------------------------') 
     print('------------- Response -------------') 
     print('------------------------------------') 
     print(response) 
     # for line in responseArray: 
      # print(line)   
     print('------------------------------------') 

     time.sleep(1) 

    except KeyboardInterrupt as e: 
     print('Closing serial '+port+' before interrupting ...') 
     ser.close() 
     exit() 

VERSION = '0.02' 
firstStart = True 

port = '/dev/ttyS2' 
baudrate = 19200 
bytesize = 8 
parity = 'N' 
stopbits = 1 
timeout = 1 
xonxoff = False 
rtscts = False 
dsrdtr = False 
write_timeout = None 
inter_byte_timeout = None 

try: 
    os.system('cls' if os.name == 'nt' else 'clear') 
    print('') 
    print('PySerial version : '+serial.VERSION) 
    firstStart = False 

    print('') 
    print('Opening serial '+port+' ...') 
    ser = serial.Serial(port, baudrate, bytesize, parity, stopbits, timeout, 
    xonxoff, rtscts, write_timeout, dsrdtr, inter_byte_timeout) 
except ValueError as e: 
    print(repr(e)) 
except SerialException as e: 
    print(repr(e)) 

if ser.isOpen(): 
    print(ser.name + ' is open...') 
    print('') 

while True: 

    try: 
     cmd = raw_input('Enter command or \'exit\' : ') 

     if cmd == 'exit': 
      ser.close() 
      exit() 
     else: 
      sendAtCommand(cmd) 
    except KeyboardInterrupt as e: 
     print('Closing serial '+port+' before interrupting ...') 
     ser.close() 
     exit() 
+0

Haben Sie versucht, das Gerät zu steuern einen seriellen Port Terminal Programm wie Minicom (oder Bildschirm), um Befehle zu senden, indem Sie sie direkt eingeben, und zeigen Sie direkt die Zignee-Geräte-Antworten? Dies wird helfen herauszufinden, ob das Problem Ihr Programm, die Einrichtung des seriellen Ports oder das Gerät (oder eine Kombination) ist. – barny

+0

Für weitere Einzelheiten siehe z. http://unix.stackexchange.com/questions/22545/how-to-connect-to-a-serial-port-as-simple-as-using-ssh – barny

+1

Sieht aus wie eine Bitrate und/oder stopbit-missmatch. – Olaf

Antwort

0

Ok so zuerst, ich danke Ihnen allen für Ihre Antworten. Endlich habe ich herausgefunden, wie ich dieses Problem lösen kann.

Ich weiß nicht warum, aber das Problem war, dass ich die Telegesis Zigbee-Board mit seinem UART VCC Pin (verbunden mit dem Linkit 7688 3v3 Pin) angetrieben.

Jetzt verbinden Sie einfach die GND, Tx und Rx der beiden Platine und verwenden Sie eine externe Quelle für die Stromversorgung und es funktioniert perfekt. Bitte beachten Sie das Bild unten, wenn Sie das gleiche Problem mit dem gleichen Material haben.

Verwenden Sie nicht den rot markierten VCC-Pin. Sie müssen die Karte mit einer externen Stromquelle über die x2-Buchse mit Strom versorgen.

(Leider alle für die schlechte Qualität meines Englisch)

Telegesis ETRX357-DVK development kit

EDIT:

Ah, und jetzt lese ich nicht zufällig Pakete von 1024 Bytes mehr, verwende ich ein separaten Thread für diese so können Sie weiter unten sehen:

class readSerial(Thread): 
    """This thread waits for data in the serial input buffer""" 
    """This is a new subclass of the Thread class (cf. Python 2.4+ threading module"""  

    def __init__(self, serialObject): 
     """Overrides the __init__(self [,args]) method to add additional arguments""" 
     Thread.__init__(self) 
     self.serialObject = serialObject 
     self.daemon = True 
     self.start() 

    def run(self): 

     ser = self.serialObject 

     data = '' 

     ser.reset_input_buffer() 
     ser.reset_output_buffer() 

     while True: 
      try: 
       if ser.in_waiting > 0: 
        data = ser.read(ser.in_waiting) 

        print('msg received : ') 
        print('') 
        print(data.decode('ascii')) 

       if 'UCAST' in data.decode('ascii'): 
        zigbeeRequest(data.decode('ascii')[26:], ser) 

        ser.reset_input_buffer() 

        data = '' 
       if 'BCAST' in data.decode('ascii'): 
        zigbeeRequest(data.decode('ascii')[26:], ser) 

        ser.reset_input_buffer() 

        data = '' 

       time.sleep(1)      
      except Exception as e: 
       print(repr(e)) 

Dann legte nur

readThread = readSerial(ser) 

in Ihrem Hauptprogramm, nachdem Sie Ihre serielle Verbindung geöffnet haben.

Ich hoffe, dass dies auch für jemanden nützlich sein kann, wenn ich gut kenne es nicht perfekt Programmierung ist (nicht fangen Ausnahmen wie ich ...)

Verwandte Themen