Mettre à jour dynamiquement l'échelle du widget Tkinter à partir des ports Arduino en utilisant python et firmata

10

J'ai du mal à obtenir les valeurs des ports numériques Arduino et à définir ces valeurs dans une échelle de widget Python Tkinter.

J'utilise Python et Arduino avec Firmata. Je peux accéder à ma carte Arduino avec du code Python. Par exemple, dans un widget d'étiquette, j'obtiens et définit la valeur du port analogique Arduino en temps réel sur une étiquette comme dans le code suivant sans aucun problème:

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

Jusqu'à présent, tout va bien et l'interface graphique me montre quelque chose comme:

Interface Python Gui lisant la valeur en temps réel de l'analogique 0

Mais ce que j'essaie de faire et de ne pas obtenir, c'est:

Ce que j'essaie de mettre à jour Scale avec des broches numériques

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

Pour résumer: j'ai des commutateurs reed dans chaque port numérique déclaré dans le code. Ces interrupteurs à lames sont normalement ouverts, lorsque je mets un champ magnétique près d'eux, ils se tournent pour se fermer et j'obtiens un changement de cette valeur comme de Faux à Vrai. Ce que j'essaie de faire, c'est de mettre à jour le widget d'échelle Tkinter en temps réel en tant qu'étiquettes, mais je ne l'obtiens pas.

Y a-t-il une astuce dans le code python qui peut résoudre mon problème? Parce que j'ai fait beaucoup de recherches sur Internet et que je n'ai pas pu le faire, comme vous pouvez le voir sur l'image 2 lorsque l'état de la deuxième broche numérique change, une étiquette devient True, et dans le code d'échelle, cela correspond à la valeur 100, mais il est toujours sur la marque 0.

Je ne suis pas à l'aise également avec l'utilisation de la commande et des paramètres variables du widget d'échelle.

En bref, je veux mettre à jour en temps réel le widget d'échelle Tkinter python en fonction des valeurs des ports numériques d'arduino en utilisant firmata.

J'utilise Python 2.7

PS: pour être complet:

Ceci est mon code arduino (Sketch) sans firmata, qui fonctionne comme prévu.

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

}

Ce que je pourrais aussi faire ici, c'est obtenir ces valeurs via série en python et les utiliser pour mettre à jour l'échelle de cette manière, mais je ne sais pas si dans cette méthode ça marchera aussi!

Et ce que je pensais en Python: Mais j'ai encore beaucoup à apprendre dans les algorithmes et les structures de données. Juste le pseudo code:

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
la source
votre troisième fichier est mal formé, def setScaleValue (): n'est pas défini correctement, vous avez besoin d'un changement de niveau de retrait après une définition de fonction.
esoterik
Lorsque votre code s'exécute, pouvez-vous être en mesure de cliquer sur le bouton d'arrêt?
Mert Gülsoy

Réponses:

-1

dans votre 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

En ajoutant la ligne d'impression, vous pouvez garantir la valeur et le type de variable.
Ensuite, vous devrez peut-être adapter votre instruction if en conséquence.
Méfiez-vous de ce que vous faites alors avec ces 2 lignes réaffectant posX, ce n'est probablement pas ce que vous voulez faire avant de mettre à jour la balance.

SMFSW
la source