关于Arduino的基于Tkinter()的GUI

时间:2018-08-14 20:50:07

标签: python tkinter arduino

我正在尝试为arduino编写python GUI,其思想是计算机将通过串行端口与arduino进行通信。

我认为arduino代码本身太复杂,无法尝试像Matlab一样直接控制事物,因此我想通过串行发送命令来控制它。除此之外,我还试图现场绘制一些数据。

我很难在不将连接端口硬编码到脚本中的情况下运行实时绘图。

def connectArduino():
    global e1
    serial_port = e1.get()
    baud_rate = 9600
    path = "data.txt"
    ser = serial.Serial(serial_port, baud_rate, timeout=0, writeTimeout=0)

def setTunings():
    global entries
    kp = entries[0][1].get()
    ki = entries[1][1].get()
    kd = entries[2][1].get()
    print(kp + ki + kd)

def animate(i):
    ser.reset_input_buffer()
    data = ser.readline()
    data_array = data.split('\t')
    xvalue = float(data_array[0])/1000
    yvalue = float(data_array[1])
    yar.append(yvalue)
    xar.append(xvalue)
    line.set_data(xar, yar)
    ax1.set_xlim(0, i+1)
    print(data_array[0] + '\t' + data_array[1])


import serial
from Tkinter import *
from matplotlib import pyplot as plt
import matplotlib.animation as animation
from matplotlib import style
from matplotlib.backends.backend_tkagg import FigureCanvasTkAgg

root = Tk()
#root.geometry('1200x700+200+100')
root.title('Temperature Control')
root.config(background='#fafafa')

frame = Frame(root)
frame.pack(side=LEFT)

l1 = Label(frame, text = "Connection Port:", anchor ='w')
l1.pack()
e1 = Entry(frame)
e1.pack()
b1 = Button(frame, text = "Connect", command = connectArduino)
b1.pack()

fields = 'Kp', 'Ki', 'Kd'
entries = []
for field in fields:
    row = Frame(frame)
    lab = Label(row, width=15, text=field, anchor='w')
    ent = Entry(row)
    row.pack(side=TOP, fill=X, padx=5, pady=5)
    lab.pack(side=LEFT)
    ent.pack(side=RIGHT, expand=YES, fill=X)
    entries.append((field, ent))

b2 = Button(frame, text = 'Set Tunings')
b2.pack()

b3 = Button(frame, text = 'Start')
b3.pack(side=LEFT, padx=5, pady=5)
#b2.pack(side = LEFT, padx=5, pady=5)

b4 = Button(frame, text = 'Stop')
b4.pack(side=RIGHT, padx=5, pady=5)
#b3.pack(side = LEFT, padx=5, pady=5)


xar = []
yar = []

style.use('ggplot')
fig = plt.figure(figsize=(8, 8), dpi=100)
ax1 = fig.add_subplot(1, 1, 1)
ax1.set_ylim(0, 35)
line, = ax1.plot(xar, yar, 'r', marker='o')

plotcanvas = FigureCanvasTkAgg(fig, root)
plotcanvas.get_tk_widget().pack(side = RIGHT)
ani = animation.FuncAnimation(fig, animate, interval=100, blit=False)

root.mainloop()

我必须承认,我比python更习惯于C和cpp,所以我一直在阅读的有关gui的很多东西都让我有些头疼。

TLDR:尝试从串行提示符下写入/读取,以及在实时绘图中显示一些数据,全部使用GUI和按钮/文本输入用户输入。

1 个答案:

答案 0 :(得分:0)

根据您在评论中的描述:

  

错误是动画没有定义就调用了“ ser”对象……

对,ser不作为全局变量存在,因为您定义的唯一位置是connectArduino内的局部变量:

def connectArduino():
    global e1
    serial_port = e1.get()
    baud_rate = 9600
    path = "data.txt"
    ser = serial.Serial(serial_port, baud_rate, timeout=0, writeTimeout=0)

解决方案很简单:就像您添加global e1来使e1是全局变量而不是局部变量一样,您需要添加global ser来使ser全局变量而不是局部变量。

然后,在调用connectArduino之后,将定义ser,以便animate可以使用它。