pySerial 与 python 2.7 和 3.4 的区别
pySerial differences with python 2.7 and 3.4
我正在做一个项目,需要通过串行端口将 windows 10 中的 python 中的一些数字发送到 arduino uno。作为一个简单的测试,我只想通过从命令提示符发送“2”来打开 LED,并通过发送“4”来关闭 LED,尽管我希望最终能够将 0-99 中的任何数字用于不同的目的。这是我的 arduino 代码:
const int ledPin = 13;
byte b1, b2;
int val;
void setup() {
Serial.begin(9600);
pinMode(ledPin, OUTPUT);
}
void loop() {
if (Serial.available() > 1) {
b1 = Serial.read();
b2 = Serial.read();
val = ((b1-48)*10) + (b2-48);
if (val == 2) {
digitalWrite(ledPin, HIGH);
}
if (val == 4) {
digitalWrite(ledPin, LOW);
}
}
这感觉有点像 hack,但有效,因为“0”在 ASCII table 上从 48 开始(所以 2 = 50,等等),这是我使用时 arduino 实际接收到的以下 python 代码发送一些号码:
import serial
ser = serial.Serial('COM4',9600)
n = 2
s = str(n)
t = s.rjust(2,'0')
ser.write(t.encode())
所以我发现当我在桌面上使用 python 3.4 时,这确实会打开我的 LED,而使用 n = 4 会关闭它。这总是 returns '2' 无论我为 n 选择的数字如何,如“2 个字节已发送”,这正是我想要的。我遇到的问题是,这在 python 3.4 中一切都很好,但当我尝试使用 python 2.7 在我的笔记本电脑上加载这个项目时,我得到一个 '2L' [=35=]而不仅仅是“2”,LED 不再亮起。
我的笔记本电脑和台式机都在使用 pySerial 3.3,我已经确认当我在台式机上使用 python 2.7 时会发生同样的事情(不起作用),而当我使用它时它确实有效在我的笔记本电脑上使用 python 3.4。
我需要为这个项目使用python 2.7,因为一些额外的hardware/API我想稍后添加,那么这个'L'被附加到序列号上有什么意义return 为什么这不适用于 python 2.7?
所以对于将来遇到这个问题的任何人,我终于在所有地方的 Arduino 网站上找到了答案:http://playground.arduino.cc/interfacing/python
简而言之,python 3 个字符串是 Unicode,python 2 个字符串不是。
我在我的问题中提到的 "L" 我认为代表 "Literal," 意味着字符串已以其文字字符串形式发送,而不是 0-255 值的 ASCII 字节。因此,使用 python 2 解释 Arduino 上的串行数据要简单得多。对于此应用程序,您可以使用 serial.parseInt() 而不是使用 serial.Read() 来读取单个字节将您的字符串转换为 int。默认情况下,此函数有 1 秒超时,但您可以在设置块中添加 Serial.setTimeout(n),其中 n 是您想要等待的毫秒数(这对我的特定情况很重要 - 我已经发现 5 个有效)。
至于 python 部分,ser.write('2') 使用 python 2 执行与我在问题中使用 python 显示的功能相同的功能3 - 不需要用 0 或编码来证明。
我正在做一个项目,需要通过串行端口将 windows 10 中的 python 中的一些数字发送到 arduino uno。作为一个简单的测试,我只想通过从命令提示符发送“2”来打开 LED,并通过发送“4”来关闭 LED,尽管我希望最终能够将 0-99 中的任何数字用于不同的目的。这是我的 arduino 代码:
const int ledPin = 13;
byte b1, b2;
int val;
void setup() {
Serial.begin(9600);
pinMode(ledPin, OUTPUT);
}
void loop() {
if (Serial.available() > 1) {
b1 = Serial.read();
b2 = Serial.read();
val = ((b1-48)*10) + (b2-48);
if (val == 2) {
digitalWrite(ledPin, HIGH);
}
if (val == 4) {
digitalWrite(ledPin, LOW);
}
}
这感觉有点像 hack,但有效,因为“0”在 ASCII table 上从 48 开始(所以 2 = 50,等等),这是我使用时 arduino 实际接收到的以下 python 代码发送一些号码:
import serial
ser = serial.Serial('COM4',9600)
n = 2
s = str(n)
t = s.rjust(2,'0')
ser.write(t.encode())
所以我发现当我在桌面上使用 python 3.4 时,这确实会打开我的 LED,而使用 n = 4 会关闭它。这总是 returns '2' 无论我为 n 选择的数字如何,如“2 个字节已发送”,这正是我想要的。我遇到的问题是,这在 python 3.4 中一切都很好,但当我尝试使用 python 2.7 在我的笔记本电脑上加载这个项目时,我得到一个 '2L' [=35=]而不仅仅是“2”,LED 不再亮起。
我的笔记本电脑和台式机都在使用 pySerial 3.3,我已经确认当我在台式机上使用 python 2.7 时会发生同样的事情(不起作用),而当我使用它时它确实有效在我的笔记本电脑上使用 python 3.4。
我需要为这个项目使用python 2.7,因为一些额外的hardware/API我想稍后添加,那么这个'L'被附加到序列号上有什么意义return 为什么这不适用于 python 2.7?
所以对于将来遇到这个问题的任何人,我终于在所有地方的 Arduino 网站上找到了答案:http://playground.arduino.cc/interfacing/python
简而言之,python 3 个字符串是 Unicode,python 2 个字符串不是。
我在我的问题中提到的 "L" 我认为代表 "Literal," 意味着字符串已以其文字字符串形式发送,而不是 0-255 值的 ASCII 字节。因此,使用 python 2 解释 Arduino 上的串行数据要简单得多。对于此应用程序,您可以使用 serial.parseInt() 而不是使用 serial.Read() 来读取单个字节将您的字符串转换为 int。默认情况下,此函数有 1 秒超时,但您可以在设置块中添加 Serial.setTimeout(n),其中 n 是您想要等待的毫秒数(这对我的特定情况很重要 - 我已经发现 5 个有效)。
至于 python 部分,ser.write('2') 使用 python 2 执行与我在问题中使用 python 显示的功能相同的功能3 - 不需要用 0 或编码来证明。