我在尝试获取Arduino数字端口值并将这些值设置为Python Tkinter Widget Scale时遇到麻烦。
我正在将Python和Arduino与Firmata一起使用。我可以使用python代码访问arduino板。例如在标签小部件中,我可以像以下代码一样实时获取并设置Arduino模拟端口值到标签,而没有任何问题:
importTkinterimportpyfirmatadefonStartButtonPress():whileTrue:ifflag.get():analogReadLabel.config(text=str(a0.read()))analogReadLabel.update_idletasks()top.update()else:breakboard.exit()top.destroy()defonExitButtonPress():flag.set(False)port='COM7'board=pyfirmata.Arduino(port)it=pyfirmata.util.Iterator(board)it.start()a0=board.get_pin('a:0:i')top=Tkinter.Tk()top.title("Reading Analog pins")descriptionLabel=Tkinter.Label(top,text="Potentiometer input:- ")descriptionLabel.grid(column=1,row=1)analogReadLabel=Tkinter.Label(top,text="Press Start..")analogReadLabel.grid(column=2,row=1)flag=Tkinter.BooleanVar(top)flag.set(True)startButton=Tkinter.Button(top,text="Start",command=onStartButtonPress)startButton.grid(column=1,row=2)exitButton=Tkinter.Button(top,text="Exit",command=onExitButtonPress)exitButton.grid(column=2,row=2)top.mainloop()
到现在为止还可以,GUI会显示类似以下内容:
但是我想做但没有得到的是:
这是代码:
importTkinterimportpyfirmataimportserial;defonStartButtonPress():whileTrue:ifflag.get():analogReadLabel.config(text=str(d8.read()))analogReadLabel1.config(text=str(d9.read()))analogReadLabel2.config(text=str(d10.read()))analogReadLabel.update_idletasks()pos1=d8.read()ifpos1==True:pos1=int(pos1)pos1=0brightnessScale.set(pos1)pos2=d9.read()ifpos2==True:pos2=int(pos2)pos2=100brightnessScale.set(pos2)''' and so on '''brightnessScale.update_idletasks()top.update()else:breakboard.exit()top.destroy()defonExitButtonPress():flag.set(False)port='COM7'board=pyfirmata.Arduino(port)it=pyfirmata.util.Iterator(board)it.start()a0=board.get_pin('a:0:i')d4=board.get_pin('d:4:i')d5=board.get_pin('d:5:i')d6=board.get_pin('d:6:i')d7=board.get_pin('d:7:i')d8=board.get_pin('d:8:i')d9=board.get_pin('d:9:i')d10=board.get_pin('d:10:i')top=Tkinter.Tk()top.geometry("800x600")top.title("Reading Analog pins")descriptionLabel=Tkinter.Label(top,text="Potentiometer input:- ")descriptionLabel.grid(column=1,row=1)analogReadLabel=Tkinter.Label(top,text="Level 1")analogReadLabel.grid(column=2,row=1)analogReadLabel1=Tkinter.Label(top,text="Level 2")analogReadLabel1.grid(column=3,row=1)analogReadLabel2=Tkinter.Label(top,text="Level 3")analogReadLabel2.grid(column=4,row=1)brightnessScale=Tkinter.Scale(top,from_=500,to=0,length=500,width="30",tickinterval=50,bg="lightskyblue",highlightcolor="darkblue",highlightbackground="royalblue",troughcolor="darkblue",state=Tkinter.DISABLED,sliderlength=50,relief="sunken",label="Volume do Reservatorio em %",orient=Tkinter.VERTICAL)brightnessScale.grid(column=1,row=5)Tkinter.Label(top,text="Volume da Caixa em (%)").grid(column=1,row=6)flag=Tkinter.BooleanVar(top)flag.set(True)startButton=Tkinter.Button(top,text="Start",command=onStartButtonPress)startButton.grid(column=1,row=2)exitButton=Tkinter.Button(top,text="Exit",command=onExitButtonPress)exitButton.grid(column=2,row=2)top.mainloop()
总结一下:我在代码中声明的每个数字端口中都装有磁簧开关。这些簧片开关通常处于打开状态,当我在它们附近施加磁场时,它会关闭,并且该值会从False变为True发生变化。我想做的是实时更新Tkinter Scale Widget作为标签,但我不明白。
python代码中有什么技巧可以解决我的问题?因为我在互联网上进行了大量研究,但无法完成,如您在图2中看到的那样,当第二个数字引脚的状态更改时,标签更改为True,并且在标尺代码中,它对应于该值100,但仍在0标记上。
我对命令和scale小部件的可变参数的用法也不满意。
简而言之,我想使用Firmata根据来自arduino的数字端口的值实时更新python Tkinter规模小部件。
我正在使用Python 2.7
PS:出于完整性考虑:
这是我的没有固件的arduino代码(Sketch),可以正常运行。
intlevel;intposition;voidsetup(){pinMode(8,INPUT);pinMode(9,INPUT);pinMode(10,INPUT);pinMode(11,INPUT);pinMode(12,INPUT);Serial.begin(9600);// ativa a porta serialvoidloop(){digitalWrite(8,LOW);digitalWrite(9,LOW);digitalWrite(10,LOW);digitalWrite(11,LOW);digitalWrite(12,LOW);position=digitalRead(8);if(position==HIGH){level=0;}position=digitalRead(9);if(position==HIGH){Level=100;}position=digitalRead(10);if(position==HIGH){level=200;}position=digitalRead(11);if(position==HIGH){level=300;}position=digitalRead(12);if(position==HIGH){level=400;}Serial.println(level);delay(500);}
我在这里还能做的是通过python中的serial获取这些值,并以这种方式使用它们来更新刻度,但是我不知道这种方法是否还能工作!
我在Python中的想法:但是我在算法和数据结构方面仍有很多知识要学习。只是伪代码:
defsetScaleValue():whileTrue:ifflag.get():pos1=d4.read()ifpos1==True:#or 1#Here is the problem i don't know for sure what comes in my digital port#If is a True bool or a 1 as HIGH value from arduino#And probably i don't know if it's possible to change the values of a scale in this way !!!#or if i'm mistaken the Cast stuff in Pythonpos1=int(pos1)pos1=0brightnessScale.set(pos1)pos2=d8.read()ifpos2==True:pos2=int(pos2)pos2=100brightnessScale.set(pos2)brightnessScale.update_idletasks()top.update()else:breakboard.exit()top.destroy()returnd4=board.get_pin('d:4:i')d5=board.get_pin('d:5:i')d6=board.get_pin('d:6:i')d7=board.get_pin('d:7:i')d8=board.get_pin('d:8:i')brightnessScale=Tkinter.Scale(top,from_=500,to=0,length=500,width="30",tickinterval=50,bg="lightskyblue",highlightcolor="darkblue",highlightbackground="royalblue",troughcolor="darkblue",state=Tkinter.DISABLED,sliderlength=50,relief="sunken",label="Volume do Reservatorio em %",orient=Tkinter.VERTICAL)brightnessScale.grid(column=1,row=5)Tkinter.Label(top,text="Volume da Caixa em (%)").grid(column=1,row=6)