Обновление динамического масштаба виджета Tkinter из портов Arduino с использованием python и firmata

У меня возникли проблемы с попыткой получить значения цифровых портов Arduino и установить эти значения в шкалу виджета Python Tkinter.

Я использую Python и Arduino с Firmata. Я могу получить доступ к моей плате arduino с кодом python. Например, в виджетах ярлыков я получаю и устанавливаю значение аналогового порта Arduino в режиме реального времени на метку, как в следующем коде, без каких-либо проблем:

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

До этого момента все в порядке, и GUI показывает мне что-то вроде:

Интерфейс Python Gui, считывающий значение в реальном времени из аналогового 0

Но я пытаюсь сделать это и не получаю:

Я пытаюсь обновить масштаб с помощью цифровых контактов

Вот код:

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

Подводя итог: у меня есть герконы в каждом цифровом порту, объявленном в коде. Эти герконовые переключатели обычно открываются, когда я помещаю рядом с ними магнитное поле, он поворачивается, закрываясь, и я получаю изменение в этом значении, например, от False до True. То, что я пытаюсь сделать, это обновить виджет масштабирования Tkinter в режиме реального времени в качестве ярлыков, но я не получаю его.

Есть ли какой-либо трюк в коде python, который можетрешить мою проблему? Потому что я провел много исследований в Интернете, и я не мог сделать это, как вы можете видеть на изображении 2, когда состояние второго цифрового пальца меняется, метка меняется на True, а в шкале это соответствует значению 100, но он все еще находится на отметке 0.

Мне не удобно также использовать команду и переменные параметры виджета масштаба.

Короче говоря, я хочу обновить виджет шкалы Tkinter реального времени в режиме реального времени в соответствии с значениями из цифровых портов от arduino, используя firmata.

Я использую Python 2.7

PS: для полноты:

Это мой код arduino (Sketch) без firmata, который работает как ожидалось.

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

}

Что я мог бы здесь сделать получает эти значения через serial в python и использует их для обновления масштаба таким образом, но я не знаю, будет ли в этом методе работать!

И что я подумал в Python: Но мне еще многое предстоит узнать в алгоритмах и структурах данных. Только псевдо-код:

 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)
10 голосов | спросил Vinny Biscolla 22 72015vEurope/Moscow11bEurope/MoscowSun, 22 Nov 2015 18:16:25 +0300 2015, 18:16:25

1 ответ


-1

в вашем коде:

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

Добавив строку печати, вы можете обеспечить значение переменной и тип.
Затем вам, возможно, придется адаптировать ваше утверждение if.
Остерегайтесь того, что вы делаете, затем с этими двумя линиями, повторно использующими posX, это, вероятно, не то, что вы хотите сделать, прежде чем обновлять масштаб.

ответил SMFSW 16 MaramThu, 16 Mar 2017 09:19:19 +03002017-03-16T09:19:19+03:0009 2017, 09:19:19

Похожие вопросы

Популярные теги

security × 330linux × 316macos × 2827 × 268performance × 244command-line × 241sql-server × 235joomla-3.x × 222java × 189c++ × 186windows × 180cisco × 168bash × 158c# × 142gmail × 139arduino-uno × 139javascript × 134ssh × 133seo × 132mysql × 132