Aktualisieren Sie die dynamische Tkinter-Widget-Skalierung von Arduino-Ports mithilfe von Python und Firmata


10

Ich habe Probleme beim Abrufen der Werte für die digitalen Arduino-Ports und beim Festlegen dieser Werte in einer Python Tkinter-Widget-Skala.

Ich benutze Python und Arduino mit Firmata. Ich kann mit Python-Code auf mein Arduino-Board zugreifen. Zum Beispiel erhalte und setze ich in einem Label-Widget den Wert des analogen Arduino-Ports in Echtzeit ohne Probleme auf ein Label wie im folgenden Code:

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

Bis zu diesem Punkt ist es okay und die GUI zeigt mir so etwas wie:

Python Gui-Schnittstelle liest Echtzeitwert von analog 0

Aber was ich versuche zu tun und nicht zu bekommen ist:

Was ich versuche, Scale mit digitalen Pins zu aktualisieren

Hier ist der Code:

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

Zusammenfassend: Ich habe Reed-Schalter in jedem im Code deklarierten digitalen Port. Diese Reed-Schalter sind normalerweise geöffnet. Wenn ich ein Magnetfeld in ihre Nähe lege, wird es geschlossen und ich erhalte eine Änderung dieses Wertes wie von Falsch zu Wahr. Ich versuche, das Tkinter Scale Widget in Echtzeit als Labels zu aktualisieren, aber ich verstehe es nicht.

Gibt es einen Trick im Python-Code, der mein Problem lösen kann? Da ich im Internet viel recherchiert habe und nicht fertig werden konnte, wie Sie in Bild 2 sehen können, wenn sich der Status des zweiten digitalen Pins ändert, ändert sich eine Bezeichnung in True, und im Skalierungscode entspricht dies dem Wert 100, aber es ist immer noch auf der 0-Marke.

Ich bin auch mit der Verwendung von Befehlen und variablen Parametern des Skalierungs-Widgets nicht vertraut.

Kurz gesagt, ich möchte das Python-Tkinter-Widget in Echtzeit gemäß den Werten von digitalen Ports von Arduino unter Verwendung von Firmata aktualisieren.

Ich benutze Python 2.7

PS: der Vollständigkeit halber:

Dies ist mein Arduino-Code (Sketch) ohne Firmata, der wie erwartet funktioniert.

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

}

Was ich auch hier tun könnte, ist, diese Werte über seriell in Python abzurufen und sie zu verwenden, um die Skala auf diese Weise zu aktualisieren, aber ich weiß nicht, ob es bei dieser Methode auch funktionieren wird!

Und was ich in Python gedacht habe: Aber ich muss noch viel in Algorithmen und Datenstrukturen lernen. Nur der Pseudocode:

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)

Ihre dritte Datei ist fehlerhaft, def setScaleValue (): ist nicht richtig definiert, Sie benötigen nach einer Funktionsdefinition eine Änderung der Einrückungsstufe.
Esoterik

Können Sie, wenn Ihr Code ausgeführt wird, auf die Schaltfläche Stopp klicken?
Mert Gülsoy

Antworten:


-1

in Ihrem Code:

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

Durch Hinzufügen der Druckzeile können Sie den Variablenwert und -typ sicherstellen.
Dann müssen Sie möglicherweise Ihre if-Anweisung entsprechend anpassen.
Passen Sie auf, was Sie dann mit diesen 2 Zeilen tun, die posX erneut beeinflussen. Dies ist wahrscheinlich nicht das, was Sie tun möchten, bevor Sie die Skala aktualisieren.

Durch die Nutzung unserer Website bestätigen Sie, dass Sie unsere Cookie-Richtlinie und Datenschutzrichtlinie gelesen und verstanden haben.
Licensed under cc by-sa 3.0 with attribution required.