如何将值从Arduino发送到Python并使用该值
我正在制作一个机器人,这个机器人可以通过Python远程控制,控制信息是通过简单的图形界面(GUI)在互联网上发送的。
我已经把部分代码搞得不错了,图形界面和控制系统都能正常工作,但现在遇到了一些问题。我想用一个叫做parallax ping传感器的东西来获取与物体的距离信息,这个传感器是通过Arduino Mega连接的,然后把这个值发送到我的Python控制脚本中,以便在远程图形界面上显示。
我遇到的主要问题是,如何把Python代码和已经建立好的Arduino的COM端口结合起来,发送一个消息给Arduino,让它去读取ping传感器的数据,然后把这个值发送给Python程序,最后让我把这个值放到我的图形界面上。
我已经有了控制Arduino的代码,并且它能正常工作,和我的简单图形界面配合得很好。
import serial
ser = serial.Serial('/dev/ttyUSB0', 9600)
from PythonCard import model
class MainWindow(model.Background):
def on_SpdBtn_mouseClick(self, event):
spd = self.components.SpdSpin.value
def on_FBtn_mouseClick(self, event):
spd = self.components.SpdSpin.value
ser.write('@')
ser.write('F')
ser.write(chr(spd))
def on_BBtn_mouseClick(self, event):
spd = self.components.SpdSpin.value
ser.write('@')
ser.write('B')
ser.write(chr(spd))
def on_LBtn_mouseClick(self, event):
spd = self.components.SpdSpin.value
ser.write('@')
ser.write('L')
ser.write(chr(spd))
def on_RBtn_mouseClick(self, event):
spd = self.components.SpdSpin.value
ser.write('@')
ser.write('R')
ser.write(chr(spd))
def on_SBtn_mouseClick(self, event):
spd = self.components.SpdSpin.value
ser.write('@')
ser.write('S')
ser.write('0')
def on_PngDisBtn_mouseClick(self, event):
ser.write('~')
ser.write('P1')
ser.write('p2')
app = model.Application(MainWindow)
app.MainLoop()
我其实想做的就是改进上面的代码,添加一个按钮,点击这个按钮后,Python会发送一个消息给Arduino,让它去检查ping传感器并返回值。我对Arduino的代码很熟悉,但我最近两周才开始接触Python。
3 个回答
首先,我想说之前的回答都很好,帮助也很大,直接相关。我的评论更为一般,适用于任何想要实现与Arduino之间双向数据流的人。基本的想法是设计你的数据流,使得发送到Arduino程序的数据可以被人输入,而从Arduino程序返回的数据可以被人理解。虽然这并不总是可能,但很多时候是可以做到的。
关键的想法是多次运行你的Arduino程序,并使用串口监视器。你可以在IDE菜单的工具中找到串口监视器。你也可以按Ctrl-Shift-M来打开串口监视器。
串口监视器会显示Arduino程序发送回来的信息。同时,它也允许你输入数据,这些数据会发送到Arduino程序。换句话说,你可以通过串口监视器测试和调试数据流的两个方向。
看看显示的内容。通常这会很有帮助,前提是你的程序尝试通过Serial.print()发送数据。这里有几点需要注意。一定要确保串口监视器中的波特率和你的程序中的波特率完全一致(在几乎所有情况下,9600是个不错的选择)。
第二点非常重要。打开串口监视器会强制重置Arduino板子。你的程序会重新开始(总是如此)。这其实是件好事,因为每次都能给你一个新的运行环境。需要注意的是,即使波特率已经是9600,你也可以通过设置波特率为9600来强制重置。这让你可以在串口监视器中进行多次测试,而不需要每次都重新启动串口监视器。
基本上,你只需要给Arduino发送一个合适的指令,就像你现在正在做的那样,然后等待Arduino给你回传一些信息;在Python这边,代码可能看起来像这样:
ser.write('foo')
retval = ser.readline() # read a complete line (\r\n or \n terminated),
#or you could use read(n) where n is the number of bytes you want (default=1)
ping_data = retval.strip() # strip out the newline, if you read an entire line
当然,这样你会得到一个字符串,你可能想把它转换成整数(int)或浮点数(float),这样才能在后面的计算中使用(如果是字符串,可以用int(ping_data)或float(ping_data)来转换;如果是字节序列,需要先用struct.unpack解包成可用的格式,这一切都取决于你如何表示传感器的数据)。
也许可以看看Pyduino项目:
pyduino是一个库,它可以让你用Python和装有Firmata协议的Arduino板进行交流。现在它支持Firmata协议的第2个版本。