通过 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

使用 pySerial 控制发酵罐

我应该为使用 Pyserial 通过串口传输的数据实现校验和过程吗?

为啥pyserial填充USB数据包?