Hi, I've been testing arduino communication with serial.
during running it always connected , buy sometime the read is incorrect
python in run in version 3.9 in Debian 11
I'm using aioserial which is a asyncio wrapper for pyserial
This is the python code
import serial
import aioserial
import asyncio
import time
import sys
import logging
class SerialListener:
def __init__(self, port="/dev/ttyUSB0", baudrate=9600):
self._port = port
self._baud_rate = baudrate
self._run = True
self._serial = None
self._logger = logging.getLogger()
def disconnect(self):
self._logger.info("Cleanup serial {}".format(self._port))
if self._serial is not None:
try:
self._serial.close()
except:
self._logger.info(sys.exc_info())
self._serial = None
def reconnect(self):
self.disconnect()
while self._serial is None:
try:
self._serial = aioserial.AioSerial(
port=self._port, baudrate=self._baud_rate,
)
self._logger.info("Connected to {}".format(self._port))
except serial.serialutil.SerialException:
self._logger.info("{} not ready".format(self._port))
except:
self._logger.info(sys.exc_info())
time.sleep(1)
async def listen(self):
while self._run:
try:
data = await self._serial.read_until_async()
code = data.decode(errors="ignore").strip()
self._logger.info("Receive {}".format(code))
except asyncio.CancelledError:
break
except serial.serialutil.SerialException:
# Blocking call
self.reconnect()
except AttributeError:
self.reconnect()
except:
self._logger.info(sys.exc_info())
await asyncio.sleep(0.1)
async def shutdown(self):
self._run = False
await asyncio.sleep(1)
def main():
logging.basicConfig(
level=logging.DEBUG,
format="%(asctime)s %(levelname)s %(name)s : %(message)s",
handlers=[logging.StreamHandler(sys.stdout)],
)
logger = logging.getLogger()
serial_listener = SerialListener(port="/dev/ttyUSB0", baudrate=9600)
loop = asyncio.get_event_loop()
try:
asyncio.ensure_future(serial_listener.listen())
loop.run_forever()
except asyncio.CancelledError:
logger.info("Receive Cancel")
except KeyboardInterrupt:
logger.info("Receive Keyboard Interrupt")
except:
logger.info("Unknown Error")
logger.info(sys.exc_info())
finally:
logger.info("Stop application")
asyncio.ensure_future(serial_listener.shutdown())
serial_listener.disconnect()
if __name__ == "__main__":
main()
This is arduino part
const int buttonPin = 4;
int buttonState = 0;
int value = 0;
void setup() {
Serial.begin(9600);
pinMode(buttonPin, INPUT_PULLUP);
}
void loop() {
buttonState = digitalRead(4);
if (buttonState == HIGH)
{
value = 0x01;
} else if (buttonState == LOW)
{
value = 0x00;
}
if (Serial.available()) {
// Sending value to python
Serial.println(value);
}
delay(500);
}
It is very simple code, basically the arduino will send a value 0x01 when button is press and 0x00 when not every .5 second
When starting the python script, if the delay is .5 second ( set in arduino ) then all communication is responsive. But if the delay around .1s ( python kept printing without delay ) all the command from arduino are not sent correctly.
Testing using this method , all not consistent
- Unplug the usb, start the python script , then plug the usb.
- start the python script , replug the usb
- usb kept plug, start and stop ( ctrl+c ) the script
- running on separate terminal
- rerun after
fuser kill -TERM /dev/ttyUSB0
Testing same script in windows 10 with port COM3 ( using pyserial ) the problem doesn't seem to occur
Any idea what the cause ?