如何通过Python 3和模块序列号向Arduino UNO发送数字


9

我是Arduino新手(通常是计算机编程人员),因此,如果这个问题看起来很傻,我深表歉意。

设置基本的arduino-LED连接后,我将无法通过串行端口将INTEGERS发送到arduino。我可以轻松地发送诸如“ m”,“ o”等字符。.但是,如果我发送一个数字,看起来它根本无法接收。

这是Arduino代码,理想情况下,它应该通过python或串行监视器从usb端口获取一个值,然后根据该值调整LED的亮度。(值必须在[0,255]范围内)。

注意:我使用的是ARDUINO UNO和PYTHON 3

// --------------------------

int LED = 10;
int number;

void setup(){

pinMode(LED,OUTPUT);
Serial.begin(9600);
}

void loop(){

number = Serial.read();
Serial.print(number);
Serial.print('\n');
if(number == -1){
number = 0;
}

else if(number > 255){

number = 255;

}

else if(number < 0){

number = 0;
}

analogWrite(LED,number);
delay(1000);
}

但是,当我向串行端口或通过Python输入一个值时,例如0,它给了我48个答案(有趣的是,它是0的ASCII码!)并点亮了LED,这是不应该的,因为在0,LED应该熄灭!!我错过了一些东西,但我找不到什么。

这是我在Python中使用的代码:

import serial
import time
try:
    arduino = serial.Serial(port,speed)
    time.sleep(2)
    print("Connection to " + port + " established succesfully!\n")
except Exception as e:
    print(e)

#Note: for characters such as 'a' I set data = b'a' to convert the data in bytes
#However the same thing does not work with numbers...
data = 0
data = arduino.write(valueToWrite)
time.sleep(2)
arduino.close()

我在做什么错或误解?谢谢。


1
试试arduino.write(chr(valueToWrite))
Gerben

此解决方案甚至对于字符也不起作用。此外,就字符而言,仅将它们作为字节发送,例如b'm',效果很好。无论如何,谢谢您的回答。
mickkk 2014年

Answers:


6

在Arduino上进行解析可能会很慢且耗时(如果您使用时钟预缩放或有时间紧迫的任务,这是很糟糕的),所以让我们在Python中进行解析。

问题是您将数字作为ASCII发送,而您需要将它们作为原始二进制发送。这是struct进来的地方。

3>> import struct
3>> print(struct.pack('>B', 0))
b'\x00'
3>> print(struct.pack('>B', 255))
b'\xff'
3>> print(struct.pack('>2B', 255, 0))
b'\xff\x00'
3>> print(struct.pack('>H', 9000))
b'#('

因此,您真正想要的是:

data = arduino.write(struct.pack('>B', valueToWrite))

或类似的东西。


非常感谢你!这正是我想要的!
mickkk 2014年

尽管空白的注释框为灰色,但我要说声谢谢!试图使用Teensy 3.2并将Arduino作为PC->闪存接口,将位流(FPGA .bin程序文件)写入SPI闪存芯片,这是使其在PC端工作的关键。
KyranF

1

Serial.read()从串行端口仅读取一个字符并返回其ASCII值,这说明了48您所得到的。

要读取完整的数字,您有2个选项:

  1. 使用Serial.parseInt(),它会根据需要读取尽可能多的字符并执行转换,然后以形式返回读取的数字int。请在此处进一步检查参考
  2. 循环读取每个字符(带有Serial.read()),直到最后一个字符为止,然后将每个读取的字符放入缓冲区(char数组)中,然后使用标准C函数将结果字符串转换为数字atoi

当然,第一个选项是最简单的选项,但0如果在1秒的超时后仍未读取任何内容(可通过设置Serial.setTimeout()),它将返回。


这个答案并不是我所要的,但是它非常有用,我将继续使用它!非常感谢你的帮助!
mickkk 2014年
By using our site, you acknowledge that you have read and understand our Cookie Policy and Privacy Policy.
Licensed under cc by-sa 3.0 with attribution required.