简体   繁体   中英

Python pySerial on Raspberry Pi Zero W: detecting a disconnected serial device

In my project, there's a Raspberry Pi Zero W, linked with Arduino Pro Micro over the serial TX/RX lines (through 5 - 3.3V logic level converter). At power-on, the Arduino starts sending "are you there" command over the serial, until Pi has finished booting and launched a python program that listens on serial port, and it replies with "yes". Then Arduino proceeds with sending regular updates with sensor data.

For some reason not yet understood, the Arduino can disconnect and reboot, while the Pi is still running. And, for some reason, the connection on the Python end is severed in a way that does not raise exception if connection.in_waiting is read.

import serial
import time
ser = serial.Serial('/dev/serial0')
ser.baudrate = 9600
cmd = b''
while True:
  time.sleep(1)
  print(ser.is_open)
  while ser.in_waiting:
    ch = ser.read()
    if ch == b'\n':
      print('New command:', cmd)
      cmd = b''
      ser.write(b'OK\n')
      continue
    else:
      cmd = cmd + ch

I have tested with this simple code, but in my tests, if I disconnect the Arduino and connect it back, the ser.is_open never is False , and the old connection works just fine also with reconnected Arduino. So, unfortunately I can not exactly replicate the loss of connection scenario when the data stop coming after disconnection. However, in order to investigate further, I'd like to add some monitoring code that would log serial disconnection incidents in file. But is there a way? If connection.is_open is always true, even without Arduino connected, then how one can detect if there is no connection?

The port remains open if there's a disconnection so your example code will loop continuously.

import serial

def connect(port):
    return serial.Serial(port, baudrate=9600, timeout=1)

ser = connect('/dev/serial0')
buf = bytearray()
while True:
    i = buf.find(b'\n')
    if i >= 0:
        buf = buf[i + 1:]
        ser.write('OK\n')

    num_bytes = max(1, min(1024, ser.in_waiting))
    data = ser.read(num_bytes)
    if data:
        buf.extend(data)
    else:
        # no data to read aka disconnection has occurred
        ser = connect('/dev/serial0')
        if ser.isOpen():
            continue
        else:
            # could not reconnect
            break

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM