Cập nhật quy mô widget động Tkinter từ cổng Arduino bằng python và Firmata


10

Tôi gặp khó khăn khi cố lấy các giá trị cổng kỹ thuật số Arduino và đặt các giá trị này thành Thang đo tiện ích Python Tkinter.

Tôi đang sử dụng Python và Arduino với Firmata. Tôi có thể truy cập bảng arduino của mình bằng mã python. Ví dụ: trong tiện ích nhãn tôi nhận và đặt giá trị cổng tương tự Arduino theo thời gian thực thành nhãn như trong mã sau mà không gặp sự cố nào:

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

Cho đến thời điểm này, nó ổn và GUI hiển thị cho tôi một cái gì đó như:

Giao diện Python Gui đọc giá trị thời gian thực từ analog 0

Nhưng những gì tôi đang cố gắng làm và không nhận được là:

Những gì tôi đang cố gắng cập nhật Scale với các chân kỹ thuật số

Đây là mã:

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

Để tóm tắt: Tôi có các công tắc sậy trong mỗi cổng kỹ thuật số được khai báo trong mã. Các công tắc sậy này thường ở trạng thái mở, khi tôi đặt một từ trường gần chúng, nó sẽ chuyển sang đóng và tôi nhận được một sự thay đổi trong giá trị đó như từ Sai thành Đúng. Những gì tôi đang cố gắng làm là cập nhật Widget Tkinter Scale trong thời gian thực dưới dạng nhãn nhưng tôi không nhận được nó.

Có mẹo nào trong mã python có thể giải quyết vấn đề của tôi không? Bởi vì tôi đã nghiên cứu rất nhiều trên internet và tôi không thể thực hiện được, như bạn có thể thấy trong hình 2 khi trạng thái của pin kỹ thuật số thứ hai thay đổi, nhãn thay đổi thành True và trong mã tỷ lệ này tương ứng với giá trị 100, nhưng nó vẫn ở mốc 0.

Tôi cũng không thoải mái với việc sử dụng lệnh và các tham số biến đổi của tiện ích tỷ lệ.

Nói tóm lại, tôi muốn cập nhật trong widget quy mô Tthonnter python thời gian thực theo các giá trị từ các cổng kỹ thuật số từ arduino bằng cách sử dụng Firmata.

Tôi đang sử dụng Python 2.7

PS: cho đầy đủ:

Đây là mã arduino của tôi (Phác thảo) không có Firmata, đang hoạt động như mong đợi.

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

}

Những gì tôi có thể làm ở đây là lấy các giá trị này qua serial trong python và sử dụng chúng để cập nhật thang đo theo cách này nhưng tôi không biết nếu trong phương pháp này nó cũng sẽ hoạt động!

Và những gì tôi nghĩ trong Python: Nhưng tôi vẫn còn nhiều điều phải học về thuật toán và Cấu trúc dữ liệu. Chỉ là Mã giả:

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)

tệp thứ ba của bạn không đúng định dạng, def setScaleValue (): không được xác định đúng, bạn cần thay đổi mức thụt lề sau khi xác định hàm.
esoterik ngày

Khi mã của bạn chạy, bạn có thể nhấp vào nút dừng không?
Mert Gülsoy

Câu trả lời:


-1

trong mã của bạn:

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

Bằng cách thêm dòng in, bạn có thể đảm bảo giá trị và loại biến.
Sau đó, bạn có thể phải điều chỉnh câu lệnh if của mình cho phù hợp.
Cẩn thận với những gì bạn đang làm sau đó với 2 dòng đó khẳng định lại posX, đây có lẽ không phải là điều bạn muốn làm trước khi cập nhật thang đo.

Khi sử dụng trang web của chúng tôi, bạn xác nhận rằng bạn đã đọc và hiểu Chính sách cookieChính sách bảo mật của chúng tôi.
Licensed under cc by-sa 3.0 with attribution required.