2016-11-18 4 views
1

Итак, я пытаюсь установить связь с модулем zigbee, подключенным к последовательному порту, с помощью команд AT (иногда называемых Hayes).проблемы при чтении с помощью pyserial

Моя проблема: я не могу понять, как правильно читать ответы с помощью pyserial модуля Python (я использую Python 2.7 на встроенном устройстве).

Иногда скрипту удается отлично читать ответы модуля, а иногда он просто возвращает набор символов «А».

Вот пример вывода:

серийный Открытие/DEV/ttyS2 ... /DEV/ttyS2 открыт ...

Введите команду или 'выход': AT

------------- ------------- Response

AT OK

Введите команду или 'выход': ATI

------------- ------------- Response aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaAaaaaaaaaaaaaaaaaaaaaaAaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaAaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaAaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaAaaaaaaaaaaaaaaaaaaaaaaaaAaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaAaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaAaAaaaAaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa

Введите команду или ' выход ':

Я действительно не понимаю, что здесь происходит, но я думаю, что это, вероятно, из-за неправильного использования pyserial модуля. Я уже пытался использовать команду inWaiting() для чтения только байтов, содержащихся во входном буфере, но эта функция всегда возвращает ноль, и команда readline(), похоже, не работает, поэтому я просто читаю пакеты размером 1024 байта.

Вот код, который я написал до сих пор:

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

Вы пробовали управления устройством с помощью последовательного порта терминала как minicom (или экран), чтобы отправлять команды, набирая их напрямую, и непосредственно показывать ответы устройства zignee? Это поможет решить, является ли проблема вашей программой, настройкой последовательного порта или устройством (или комбинацией). – barny

+0

Более подробно см., Например, http://unix.stackexchange.com/questions/22545/how-to-connect-to-a-serial-port-as-simple-as-using-ssh – barny

+1

Похож на битрейт и/или стоп-бит-матчи. – Olaf

ответ

0

ИТАК первый, спасибо всем за ответы. Наконец, я выяснил, как решить эту проблему.

Я не знаю, почему, но проблема в том, что я включил плату zigbee для тележки, используя ее штырь UART vcc (подключенный к контакту Linkit 7688 3v3).

Теперь я просто подключаю GND, Tx и Rx обеих плат и использую внешний источник питания, и он отлично работает. Пожалуйста, обратитесь к рисунку ниже, если у вас есть одна и та же проблема с тем же материалом.

Не используйте штырь VCC в красном цвете, вы должны подключить плату с помощью внешнего источника питания через разъем x2.

(К сожалению все для низкого качества мой английский)

Telegesis ETRX357-DVK development kit

EDIT:

Ах, и теперь я не читаю случайные пакеты 1024 байт больше, я использую отдельный поток для этого, как вы можете увидеть ниже:

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)) 

Тогда просто положить

readThread = readSerial(ser) 

в вашей основной программе после того, как вы открыли свое последовательное соединение.

Я надеюсь, что это может быть полезным для кого-то, даже если я хорошо знаю, он не совершенен программирования (не перехватывать исключения, как я ...)

Смежные вопросы