【问题标题】:Have to use sleep with pyserial when opening com port for arduino nano为arduino nano打开com端口时必须使用pyserial睡眠
【发布时间】:2016-08-15 07:00:03
【问题描述】:

我正在使用 python 2.7 在 Windows 10 上运行 pyserial (3.1.1)

更新 - 在 Xubuntu 16 和 Windows 上运行相同的问题。

我正在通过 USB/串行接口通过串行向 arduino nano 写入数据。

我正在编写一个简单的字符串(例如“2+”)并读取 arduino 中的输出。如果我在打开 com 端口后将 first time.sleep 保持在 2 秒,它就可以工作。如果我将其更改为 1 或将其删除,arduino 似乎会收到不同的字符/编码并且它不起作用。

理想情况下,我不想要任何睡眠,以便更快地工作。我做错了什么还是有更好的方法来做到这一点,以便我可以消除睡眠或至少减少睡眠?

Python 代码:

import sys, getopt
import time
import serial
ser = serial.Serial(
    port='COM3',
    baudrate=9600,
    parity=serial.PARITY_ODD,
    stopbits=serial.STOPBITS_TWO,
    bytesize=serial.SEVENBITS
)
time.sleep(1)  #change this to 2 and it works
ser.write('2+')
out = ''
time.sleep(1)
while ser.inWaiting() > 0:
    out += ser.read(1)
if out != '':
    print ">>" + out
else:
    print ">> nothing!"
time.sleep(1)   
ser.close()

Arduino 代码(我对 ASCII 字符数也有一些小问题 - 我认为这是字节的签名,但这是我目前最少的问题)

String inString = ""; 
int pinNumber = 0;

void setup() {
    // initialize serial communication at 9600 bits per second:
Serial.begin(9600);
}

void loop() {
    // expected input:    1+   //to change the digital pin to on
    // expected input:    2-   //to change the digital pin to off  
    while (Serial.available() > 0) {
        //char inChar = char(int(Serial.read()));
        char inChar = Serial.read();
        Serial.println(inChar);
        if (isDigit(inChar)) {
            inString += inChar;
            Serial.println(inString);
        }
        else {
            pinNumber = inString.toInt();
            Serial.println(pinNumber);
            pinMode(pinNumber, OUTPUT);
        if (inChar == -85) {
            Serial.println("set high");
            digitalWrite(pinNumber, HIGH);  
        } else if (inChar == -83) {
            Serial.println("set low");
            digitalWrite(pinNumber, LOW);  
        } else {
            Serial.println("NO MATCH!!!");
        }
        inString = "";
    }
}

}

【问题讨论】:

  • 你有没有试过在你的 python 代码中紧跟ser.write('2+') 之后添加一个ser.flush()
  • 感谢您的帮助。我尝试了 ser.flush() 并没有改变任何东西 - 由于某种原因我仍然需要睡眠。

标签: python arduino pyserial


【解决方案1】:

您假设如果有数据,它将是完整的数据。如果在发送部分处理串口的方式有缓冲,则只能得到部分数据。

您可以尝试在您的 python 代码中添加ser.flush(),但您还应该检查您收到的数据是否完整。您可以通过确保您的数据以已知字符结尾并检查它来做到这一点。

请记住,您还应该有某种超时,这样您就不会陷入某个阅读循环。

另一个问题是您正在读取char 类型,但根据the documentationSerial.read() 实际上返回intchar 数据类型的大小为 1 字节,而 int 的大小为 2 字节,所以这可能就是为什么你会得到奇怪的东西(有一个参考 here)。

它还说read 将只返回数据的第一个字节。所以,如果你想要第二个字节,你需要读两次。

【讨论】:

  • 谢谢 - serial 没有工作,但感谢 arduino 上 serial.read() 的帮助以及 char / int 之间的区别
【解决方案2】:

您的 Arduino 是否有可能在打开串行连接时自动重置?

在 Arduino Nano 中,RESET 引脚通过 C4 连接到 FTDI USB 到串行转换器的 DTR。见Arduino Nano Schematic

也许如果您删除 C4 或禁用 DTR,您的问题就会消失。

您可以通过在设置函数中放置一个短的 LED 脉冲来检查这一点,看看它是否在从 Python 程序打开串行端口后发生。

【讨论】:

    【解决方案3】:

    我无法找到解决此睡眠问题的任何方法。只有在允许至少 1.5 秒的情况下,才能在 arduino 上正确接收字节 - 大概是为了初始化串行连接。

    作为一种解决方法,我必须在启动时打开串行端口一次,然后通过套接字服务器接受和写入数据。这按预期工作。看来问题出在串口的打开上。

    import os, os.path
    import time
    import serial
    import socket
    import re
    
    def sendData(msg):
        if not ser.is_open:
            ser.open()
        ser.write(msg)
        ser.flush()
        out = ''
        time.sleep(0.5)
        while ser.inWaiting() > 0:
            out += ser.read(1)
        if out != '':
            print ">>" + out
        else:
            print ">> nothing!"
        time.sleep(0.5) 
    
    port='/dev/ttyUSB1',
    
    serversocket = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
    serversocket.bind(('localhost', 9000))
    serversocket.listen(1) # become a server socket, maximum 5 connections
    
    ser = serial.Serial(
        port=port,
        baudrate=9600,
        parity=serial.PARITY_ODD,
        stopbits=serial.STOPBITS_TWO,
        bytesize=serial.SEVENBITS
    )
    
    while True:
        connection, address = serversocket.accept()
        buf = connection.recv(64)
        if len(buf) > 0:
            print buf
            sendData(buf)
    

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2012-07-27
      • 1970-01-01
      相关资源
      最近更新 更多