我正在尝试为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和按钮/文本输入用户输入。
答案 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
可以使用它。