aioserial.py
aioserial.py copied to clipboard
Communication with arduino sometime error
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
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()
async def stop(self):
self._run = False
async def start(self):
await self.reconnect()
await self.listen()
async 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
async def reconnect(self):
await 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())
await asyncio.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
await self.reconnect()
except:
self._logger.info(sys.exc_info())
await asyncio.sleep(0.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.start())
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")
loop.run_until_complete(asyncio.wait([serial_listener.stop()]))
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, sometime the delay is lower then .5 second, and any button press in the arduino will not send the correct value , it kept sending the default value.
On re-connection either by repluging the usb cable or restarting the script might cause the same problem. The most visible is when I clear the terminal. Testing same script in windows 10 with port COM3 ( using pyserial ) the problem doesn't seem to occur
Any idea what the cause ?