通过 pySerial 通过 Python 控制 Arduino
Posted
技术标签:
【中文标题】通过 pySerial 通过 Python 控制 Arduino【英文标题】:Controlling Adruino through Python via pySerial 【发布时间】:2015-07-09 18:12:34 【问题描述】:您好,提前感谢您的宝贵时间,
我正在尝试使用 pySerial 和 Tkinter 通过 python 脚本控制连接到我的 Arduino 的一系列继电器。问题是,虽然我知道我的代码正在连接到我的 Arduino(我听到与使用 Arduino 软件上传代码时相同的继电器颤动),但我无法让继电器响应从我的Tkinter 图形用户界面。这是我的python代码:
ser = Serial(port=3, timeout=1, writeTimeout=1, baudrate=9600) # ensure non-blocking
class Application(Frame):
print("Arduino Dish Control Ready")
def __init__(self, parent): # create constructor
Frame.__init__(self, parent) # define parent
self.parent = parent # save reference of parent widget
self.initUI() # delegate creation of the initUI() method
def initUI(self):
self.parent.title("Dish Control") # title of window
Style().configure("TButton", padding=(0, 5, 0, 5), font='serif 10')
self.columnconfigure(0, pad=4)
self.columnconfigure(1, pad=4)
self.columnconfigure(2, pad=4)
self.columnconfigure(3, pad=4)
self.columnconfigure(4, pad=4)
self.rowconfigure(0, pad=3)
self.rowconfigure(1, pad=3)
self.rowconfigure(2, pad=3)
self.rowconfigure(3, pad=3)
def UP(): # define the UP command.
ser.write(str(32)) # convert "32" to ASCII and send it via serial port (USB) to arduino.
print ser.write(str(64))
# sleep(0.1)
up = Button(self, text="Up", command=UP) # create button UP and set the command.
up.grid(row=0, column=1) # define position of UP button.
self.pack()
这里是相关的 Arduino 代码:
void loop()
if(Serial.available() > 0)
Serial.begin(9600);
int inByte = Serial.read(); //read the incoming data
Serial.print("I received: ");
Serial.println(inByte, DEC);
if(Serial.read() == 32)//If the serial reads 32...
digitalWrite(8, LOW); //Motor Select Low
digitalWrite(9, LOW);
digitalWrite(10, LOW); //Motor 1 Low
digitalWrite(11, LOW);
digitalWrite(12, LOW); // Motor 2 Low
digitalWrite(13, LOW);
digitalWrite(6, HIGH); //Motor Power High
digitalWrite(7, HIGH);
抱歉包含这么多,但我不确定我的错误在哪里。
编辑:有人要求我在 python 代码中包含 ser.write(32) 而不是 ser.write(str(32)) 时给出的错误的回溯:
Traceback (most recent call last):
File "C:\Python27\lib\lib-tk\Tkinter.py", line 1536, in __call__
return self.func(*args)
File "C:/Users/Radio Astro 4/PycharmProjects/untitled/DishControl.py", line 46, in UP
ser.write(32) # convert "1" to ASCII and send it via serial port (USB) to arduino.
File "C:\Python27\lib\site-packages\serial\serialwin32.py", line 283, in write
data = to_bytes(data)
File "C:\Python27\lib\site-packages\serial\serialutil.py", line 75, in to_bytes
for item in seq:
TypeError: 'int' object is not iterable
【问题讨论】:
您不应该使用“ser”,类实例而不是void_loop()中的“Serial” 对串行端口一无所知,但“Serial”不知道哪个端口读/写等。 你是否应该在 python 代码中有一个 ser.begin()。 我在上面代码的第一行定义了使用哪个端口“Serial”。将其定义为“ser”是否会使该信息无效?如果是这样,我必须每次都输入整行吗?另外,我应该在哪里包含 ser.begin()?在查找类似示例时,例如:instructables.com/id/Interface-Python-and-Arduino-with-pySerial/… 我没有看到它被使用。 好吧,我调查了你的第一个建议,但我仍然必须使用类似这样的东西:Serial.write(ser, 32),它的工作原理与 ser.write(32) 相同,只要“ ser" 已定义。我不能从 Serial.write(ser, 32) 中省略“ser”,因为此处需要“IronSerial”和“数据”输入。 【参考方案1】:Arduino documentation 表示Serial.read()
命令:
返回
传入串行数据的第一个字节可用(如果没有数据可用,则为 -1)-
int
您正在向微控制器发送字符串“32”,这实际上是发送了两个字节[51, 50]
。检查if(Serial.read() == 32)
时,您会检查字节值 32,但永远不会发送字节值32(ASCII 空间)。
更改您的发送命令以直接传输字节值:
ser.write(32) # without str()
编辑:
Serial.write()
将(字节)字符串作为参数,因此您必须执行以下操作:
ser.write(bytes([32])) # convert the list `[32]` to a bytestring
【讨论】:
抱歉,我应该提到这样做会给我一个错误:“TypeError: 'int' object is not iterable” 是否有另一种可行的解决方法? 您的错误和回溯到底是什么?请将此包含在您的主要问题中,回溯对于解决您的问题是不可避免的 抱歉耽搁了 - 我周末不在城里。我已更新问题以包含回溯。 @Matt:如果这解决了您的问题,请将答案勾选为“已接受” 它确实有帮助,但还没有完全解决问题。整理好所有内容后,我将为遇到此问题的其他人发布摘要并接受您的回答!以上是关于通过 pySerial 通过 Python 控制 Arduino的主要内容,如果未能解决你的问题,请参考以下文章
GNU/Linux - Python3 - PySerial:如何通过 USB 连接发送数据?
未找到 windows 10 python 串行模块,但 pip install pyserial 已通过
如何通过 pySerial 从 Python 发送 int 或 string 并在 C 中转换为 int 或 String