我需要联系一个连接USB端口的Arduino Pro Micro控制器。上传到它的草图应该响应带有调试响应的标准C#字符串:
> #NAME
>>> ARDUINO
(请求字符串没有换行终止符。)Arduino IDE中的串口监视器从连接的Arduino获得正确的响应。
我写了一个C#程序来自己测试通信,它也得到了正确的响应:
using System;
using System.IO.Ports;
using System.Threading;
class Program {
static SerialPort port;
// static void port_DataReceived(object sender, SerialDataReceivedEventArgs e) {
// // Show all the incoming data in the port's buffer
// Console.WriteLine(port.ReadExisting());
//}
static void Main(string[] args) {
port = new SerialPort("COM5", 115200, Parity.None, 8, StopBits.One);
// port.DataReceived += port_DataReceived;
Console.WriteLine("Port: " + port.PortName);
port.Open();
if (!port.IsOpen) {
Console.WriteLine("Can't open port.");
return;
}
Console.WriteLine("Writing '#NAME' to port...");
port.Write("#NAME");
Thread.Sleep(500);
string ans = port.ReadExisting();
Console.WriteLine("Response: " + ans + "| " + ans.Length);
port.Close();
}
}
输出:
Port: COM5
Writing '#NAME' to port...
Response: ARDUINO | 9
我尝试使用Python和pySerial模块与控制器交谈:
import serial
from time import sleep
# msg = b'\x00\x23\x00\x4e\x00\x41\x00\x4d\x00\x45\n'
# msg = b'\x23\x4e\x41\x4d\x45\n'
# msg = b'#NAME\n'
# msg = b'\xff\xfe\x00\x00#\x00\x00\x00N\x00\x00\x00A\x00\x00\x00M\x00\x00\x00E\x00\x00\x00'
# msg = b'\xff\xfe#\x00N\x00A\x00M\x00E\x00'
# msg = bytes('#NAME', encoding="utf-8")
# msg = bytes('#NAME', encoding="utf-16")
# msg = bytearray([0x23, 0x4E, 0x41, 0x4D, 0x45])
# msg = bytearray(b"#NAME")
msg = "#NAME".encode("utf-16")
port = serial.Serial("COM5", baudrate=115200, parity=serial.PARITY_NONE, bytesize=8, stopbits=serial.STOPBITS_ONE, timeout=2)
print("Port:", port.name)
print("Is open?:", port.is_open)
print("Writing:", msg)
# port.writelines([msg])
port.write(msg)
sleep(1)
output = port.read_until(size=len(msg))
# output = port.read_all()
print("Reading:", output)
port.close()
但我无法正确回应:
Port: COM5
Is open? True
Writing: b'\xff\xfe#\x00N\x00A\x00M\x00E\x00'
Reading: b''
pySerial的写入方法不能用于字符串,只接受字节序列,所以我尝试用不同的方法转换字符串。
由于端口和控制器都正常工作,我认为这可能是我的Python或pySerial安装的问题,所以我尝试测试它们。我有另一个控制器,它简单地回应它得到的任何输入字节序列。使用相同的Python程序进行测试运行:
Port: COM5
Is open? True
Writing: b'\xff\xfe#\x00N\x00A\x00M\x00E\x00'
Reading: b'\xff\xfe#\x00N\x00A\x00M\x00E\x00'
有人可以解释一下,发生了什么以及如何使用Python与第一个控制器交谈?
更新:
我使用串口监控程序来监控数据流:
Arduino IDE串行监视器数据交换日志('#NAME',无终点字节,波特率= 115200):
Port opened by process "javaw.exe" (PID: 2792)
Request: 27.12.2017 16:24:37.38864
23 4E 41 4D 45 #NAME
Answer: 27.12.2017 16:24:37.58964 (+0.2010 seconds)
41 52 44 55 49 4E 4F 0D 0A ARDUINO..
Port closed
C#程序交换日志('#NAME',没有终点字节,波士率= 115200):
Port opened by process "ConsoleApplication1.exe" (PID: 7004)
Request: 27.12.2017 16:31:24.69564 (+26.5445 seconds)
23 4E 41 4D 45 #NAME
Answer: 27.12.2017 16:31:26.72564 (+2.0291 seconds)
41 52 44 55 49 4E 4F 0D 0A ARDUINO..
Port closed
Python程序交换日志(b'#NAME',没有终点字节,baudrate = 115200):
Port opened by process "python.exe" (PID: 2416)
Request: 27.12.2017 16:39:32.00464 (+139.8020 seconds)
23 4E 41 4D 45 #NAME
Port closed
所有三个程序都编写相同的字节序列,我不明白,为什么Python程序没有得到响应。
答案 0 :(得分:2)
您正在使用带有BOM的UTF16编码,这很可能是不正确的。通常,这些协议期望带有换行符的ASCII:
import serial
from time import sleep
msg = "#NAME\r\n".encode('ascii')
port = serial.Serial("COM5", baudrate=115200, parity=serial.PARITY_NONE, bytesize=8, stopbits=serial.STOPBITS_ONE, timeout=2)
print("Port:", port.name)
print("Is open?:", port.is_open)
print("Writing:", msg)
port.write(msg)
sleep(1)
output = port.read_until(size=len(msg))
print("Reading:", output)
port.close()
答案 1 :(得分:0)
在打印结果之前,请尝试msg = msg.decode('ascii')
或msg = msg.decode('utf-16')
。那是在print("Writing:", msg)
行之前。
我遇到了类似的问题并试了一下这对我有用。
答案 2 :(得分:0)
原来,我的控制器设备有问题。我仍然不知道为什么它没有响应使用Python发送的请求,而它确实使用C#和Arduino IDE做出响应,但在用新设备替换它之后,我在所有环境中得到了所需的响应