简体   繁体   中英

Writing serial data to Arduino using pyserial on Windows

I am having some trouble writing serial data to an Arduino Uno using pyserial on a 64 bit Windows 10 machine with Python 3.7.

Here is the stripped down version of the code I am testing:

SerialEcho.ino

void setup() {
    pinMode(LED_BUILTIN, OUTPUT);
    digitalWrite(LED_BUILTIN, LOW);

    Serial.begin(9600);
    Serial.println("Serial connected");
}

void loop() {
    int c = Serial.read();
    if (c < 0) return;
    digitalWrite(LED_BUILTIN, HIGH);
    Serial.write(c);
}

SerialEcho.py

from sys import stdout
import serial
import time

port = "COM14"
baud_rate = 9600

com = serial.Serial()
com.port = port
com.baudrate = baud_rate

# Doesn't effect write issues
com.timeout = 0.1

# 0 = no exception but no echo, anything else = instant SerialTimeoutException
com.writeTimeout = 0

# setDTR works as expected but doesn't help the issue
# True = Arduino resets on open, False = Arduino doesn't reset on open
com.setDTR(True)

# EDIT: This doesn't seem to do anything
#com.setRTS(False)

com.open()

# Adding a sleep here has no effect because I am already waiting for a character to come through from the Arduino
time.sleep(1)

# Wait for a character to come through to ensure there is no issue with auto resetting
while not com.read():
    pass

print("Connected")

# This should be echoed back but it isn't
# EDIT: adding a new line character doesn't fix the issue
com.write(b'55555555555555555555555555555555555\n')

# Neither of these lines have any effect on the issue
#com.flush()
#com.flushOutput()

# This is always 0
#print(com.outWaiting())
print(com.out_waiting)

while True:
    c = com.read()
    if c:
        print(c, end=" ")
        com.write(b'6')
        stdout.flush()

The issue I have when I run the above code is that I don't get an echo back from the Arduino. I do see the Connected print statement as well as the characters of erial connected come through (as expected) but no 5 s or 6 s and the built in LED does not turn on.

I know there isn't an issue with the Arduino or its connection to the computer because it works just fine using the Arduino Serial monitor (all characters echo back just fine and the built in led turns on after receiving the first character).

If I use a non-zero value for writeTimeout I get the following traceback as soon as the com.write runs (even if I set writeTimeout to 1000 ):

Traceback (most recent call last):
File "SerialEcho/SerialEcho.py", line 30, in <module>
    com.write(b'55555555555555555555555555555555555')
File "C:\Users\James\AppData\Local\Programs\Python\Python37-32\lib\site-packages\serial\serialwin32.py", line 323, in write
    raise writeTimeoutError
serial.serialutil.SerialTimeoutException: Write timeout

I also get the same traceback if I attempt to send a character to the arduino program using miniterm .

I have commented in SerialEcho.py a couple of other changes I have tried which haven't solved the issue.

I have come across some posts suggesting issues with different versions of pyserial on windows. I have tried the above on most combinations of Python 3.7 32bit and 64bit along with pyserial 3.4, 2.7 and 2.6 but none work for me.

I have come across many different posts here on Stack Overflow as well as on the Arduino forums while trying to solve this issue but either there is no answer or the answer doesn't work for me. I have tried my best to cover all the answers I have found.

Thanks

Edit

I have modified the above test code to include more changes that haven't fixed the issue.

I had issue with arduino and python too, I just give you some tips, first add a delay after arduino connection, So:

com.open()
time.sleep(1)

This is my send function which will send with a new line character:

def ArduinoSend(data):
    arduino.write(format(('{}\n').format(data)).encode())

and These are my read and read line functions:

def ArduinoRead():
    if Serial.in_waiting:
        data = arduino.read().decode('ascii').strip()
    return data

def ArduinoReadLine():
    if Serial.in_waiting:
        data = arduino.readline().decode('ascii').strip()
        return data

And this is my loop:

while arduino.is_open:
        info = ArduinoRead()
        time.sleep(0.2)

Hope this will help.

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