Perbarui Skala Widget Tkinter Secara Dinamis dari Pelabuhan Arduino menggunakan python dan firmata

10

Saya mengalami masalah saat mencoba mendapatkan nilai port digital Arduino dan mengatur nilai-nilai ini ke dalam Skala Widget Python Tkinter.

Saya menggunakan Python dan Arduino dengan Firmata. Saya dapat mengakses papan Arduino saya dengan kode python. Sebagai contoh dalam widget label saya mendapatkan dan mengatur nilai port analog Arduino secara real-time ke label seperti dalam kode berikut tanpa masalah:

import Tkinter
import pyfirmata

def onStartButtonPress():
    while True:
        if flag.get():
            analogReadLabel.config(text=str(a0.read()))
            analogReadLabel.update_idletasks()
            top.update()
        else:
            break
    board.exit()
    top.destroy()

def onExitButtonPress():
    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()

Hingga saat ini tidak apa-apa dan GUI menunjukkan sesuatu seperti:

Antarmuka Python Gui membaca nilai waktu-nyata dari analog 0

Tetapi yang saya coba lakukan dan tidak saya dapatkan adalah:

Apa yang saya coba perbarui Skala dengan pin digital

Ini kodenya:

import Tkinter
import pyfirmata
import serial; 

def onStartButtonPress():
    while True:
        if flag.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()
        if pos1 == True:
            pos1 = int(pos1)
            pos1 = 0
            brightnessScale.set(pos1)

        pos2 = d9.read()
        if pos2 == True:
            pos2 = int(pos2)
            pos2 = 100
            brightnessScale.set(pos2)

       ''' and so on '''

        brightnessScale.update_idletasks()
        top.update()
    else:
        break
board.exit()
top.destroy()


def onExitButtonPress():
    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()

Untuk meringkas: Saya memiliki buluh switch di setiap port digital yang dinyatakan dalam kode. Sakelar buluh ini biasanya keadaan terbuka, ketika saya meletakkan medan magnet di dekat mereka itu berubah menjadi tertutup dan saya mendapatkan perubahan nilai seperti dari False ke True. Apa yang saya coba lakukan adalah memperbarui Widget Skala Tkinter secara real time sebagai label tapi saya tidak mengerti.

Apakah ada trik dalam kode python yang dapat menyelesaikan masalah saya? Karena saya melakukan banyak penelitian di internet dan saya tidak bisa menyelesaikannya, seperti yang Anda lihat pada gambar 2 ketika keadaan pin digital kedua berubah, label berubah menjadi True, dan dalam kode skala ini sesuai dengan nilainya. 100, tapi masih di tanda 0.

Saya tidak nyaman juga dengan penggunaan perintah, dan parameter variabel widget skala.

Singkatnya, saya ingin memperbarui widget skala Tkinter python waktu nyata menurut nilai dari port digital dari arduino menggunakan firmata.

Saya menggunakan Python 2.7

PS: untuk kelengkapan:

Ini adalah kode Arduino saya (Sketsa) tanpa firmata, yang berfungsi seperti yang diharapkan.

int level; 
int position; 

void setup() {

pinMode(8, INPUT); 
pinMode(9, INPUT);
pinMode(10, INPUT);
pinMode(11, INPUT);
pinMode(12, INPUT);

Serial.begin(9600); // ativa a porta serial

void loop() {
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);

}

Apa yang bisa saya lakukan juga di sini adalah mendapatkan nilai-nilai ini melalui serial dalam python dan menggunakannya untuk memperbarui skala dengan cara ini, tetapi saya tidak tahu apakah dalam metode ini akan bekerja juga!

Dan apa yang saya pikirkan dengan Python: Tapi saya masih harus banyak belajar dalam algoritma dan Struktur Data. Hanya Kode Pseudo:

def setScaleValue():
while True:
    if flag.get():
         pos1 = d4.read()
        if pos1 == 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 Python
            pos1 = int(pos1)
            pos1 = 0
            brightnessScale.set(pos1)

        pos2 = d8.read()
        if pos2 == True:
            pos2 = int(pos2)
            pos2 = 100
            brightnessScale.set(pos2)

        brightnessScale.update_idletasks()
        top.update()
    else:
        break
board.exit()
top.destroy()

return


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')

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)
Vinicius Biscolla
sumber
file ketiga Anda salah format, def setScaleValue (): tidak didefinisikan dengan benar, Anda perlu perubahan tingkat indentasi setelah definisi fungsi.
esoterik
Ketika kode Anda berjalan, dapatkah Anda mengklik tombol stop?
Mert Gülsoy

Jawaban:

-1

dalam kode Anda:

pos2 = d8.read()
print("pos2 is {} type {}".format(pos2, type(pos2)))  # This way, you'll know the var type you're getting on the console
    if posX == True:
        posX = int(posX)          # You then cast to an integer
        posX = 100                # You discard pos2 value by setting it to 100
        brightnessScale.set(posX) # You set the scale always to value 100

Dengan menambahkan garis cetak, Anda dapat memastikan nilai dan jenis variabel.
Kemudian, Anda mungkin harus menyesuaikan pernyataan if Anda sesuai.
Waspadalah dengan apa yang Anda lakukan dengan 2 jalur reaffecting posX, ini mungkin bukan yang ingin Anda lakukan sebelum memperbarui skala.

SMFSW
sumber