使用GUI从Arduino控制串行数据传输

时间:2019-06-27 08:14:17

标签: python tkinter arduino

我正在尝试创建一个Python GUI,当按下1时使Arduino开始传输,而在按下其他任何东西(例如0)时停止传输。我编写的代码(如下)在第一次启动和停止时都可以正常工作,但是在我下次单击启动时却无法工作。 我的Python代码:

import tkinter as tk
from time import time

import serial
import serial.tools.list_ports
ports = list(serial.tools.list_ports.comports())
for p in ports:
    print (p)
    if "Serial Device" in str(p):
        print("Connect here!")
        wor=str(p)
        w=wor[:4]
        print(w)

ser = serial.Serial(w, 9600)


ser.write('0'.encode())


def start1():
    ser.write('1'.encode())
    global count_flag1
    count_flag1 = True
    count = str(ser.readline())
    while True:
        if count_flag1 == False:
            break
        s=count.split(",")
        p=s[0].split("'")
        s[0]=p[1]
        # put the count value into the label
        label1['text'] = "A0:"+s[0]+" A1:"+s[1]+" A2:"+s[2]
        # wait for 0.1 seconds
        #time.sleep(1)
        # needed with time.sleep()
        root.update()
        # increase count
        count = str(ser.readline())

def stop1():
    global count_flag1
    count_flag1 = False
    ser.write('0'.encode())



# create a Tkinter window
root = tk.Tk()
# this will be a global flag
count_flag1 = True


# create needed widgets
label1 = tk.Label(root, text='l1')
btn_start1 = tk.Button(root, text='start all', command=start1)
btn_stop1 = tk.Button(root, text='stop all', command=stop1)
# use a grid to place the widgets
label1.grid(row=0, column=0, columnspan=2)
btn_start1.grid(row=1, column=0, padx=5, pady=5)
btn_stop1.grid(row=1, column=1, padx=5)

我的Arduino代码:

int oldv;
int newv;
void setup() {
  // put your setup code here, to run once:
Serial.begin(9600);
}

void loop() {
  // put your main code here, to run repeatedly:
  if(Serial.available()>0){
    newv=(Serial.read());
    if(newv=='1'){
      //newv=1;
      Serial.print(analogRead(A0));
      Serial.print(",");
      Serial.print(analogRead(A1));
      Serial.print(",");
      Serial.print(analogRead(A2));
      Serial.println(",");
      oldv=1;}
    else{
       oldv=0;
    }
    delay(500);
  }
   else{
    newv=oldv;
        if(newv==1){
          Serial.print(analogRead(A0));
          Serial.print(",");
          Serial.print(analogRead(A1));
          Serial.print(",");
          Serial.print(analogRead(A2));
          Serial.println(",");
          oldv=1;}
        else{
           oldv=0;
        }
        delay(500);
    }
  }

2 个答案:

答案 0 :(得分:0)

在Ture与Tkinter一起使用时是一个大的红旗。并使用更新的经验法则;) 刷新tkinter的最好方法是after()

import tkinter as tk
from time import time

import serial
import serial.tools.list_ports
ports = list(serial.tools.list_ports.comports())
for p in ports:
    print (p)
    if "Serial Device" in str(p):
        print("Connect here!")
        wor=str(p)
        w=wor[:4]
        print(w)

ser = serial.Serial(w, 9600)


ser.write('0'.encode())


def start1():
    ser.write('1'.encode())
    ref = root.after(100, refresh) #runs function refresh every 100ms


def stop1():
    if ref != None:
       root.cancle(ref)
       ser.write('0'.encode())

def refresh():
    # increase count
    count = str(ser.readline())
    s=count.split(",")
    p=s[0].split("'")
    s[0]=p[1]
    # put the count value into the label
    label1['text'] = "A0:"+s[0]+" A1:"+s[1]+" A2:"+s[2]
    # wait for 0.1 seconds

# create a Tkinter window
root = tk.Tk()

#global va, prepared for after function
ref =None

# create needed widgets
label1 = tk.Label(root, text='l1')
btn_start1 = tk.Button(root, text='start all', command=start1)
btn_stop1 = tk.Button(root, text='stop all', command=stop1)
# use a grid to place the widgets
label1.grid(row=0, column=0, columnspan=2)
btn_start1.grid(row=1, column=0, padx=5, pady=5)
btn_stop1.grid(row=1, column=1, padx=5)

#mainloop() is better way of running tkinter GUI. It is similar to function   .update() in while
root.mainloop()

答案 1 :(得分:0)

我终于明白了。看来我也需要更新根目录以获取停止功能!

import tkinter as tk
from time import time

import serial
import serial.tools.list_ports
ports = list(serial.tools.list_ports.comports())
for p in ports:
    print (p)
    if "Serial Device" in str(p):
        print("Connect here!")
        wor=str(p)
        w=wor[:4]
        print(w)

ser = serial.Serial(w, 9600)

ser.write('0'.encode())



def start1():
    ser.write('1'.encode())
    global count_flag1
    count_flag1 = True
    count = str(ser.readline())
    #print("started")
    while True:
        if count_flag1 == False:
            break
        s=count.split(",")
        p=s[0].split("'")
        s[0]=p[1]
        # put the count value into the label
        label1['text'] = "A0:"+s[0]+" A1:"+s[1]+" A2:"+s[2]
        # wait for 0.1 seconds
        #time.sleep(1)
        # needed with time.sleep()
        root.update()
        # increase count
        count = str(ser.readline())

def stop1():
    ser.write('0'.encode())
    global count_flag1
    count_flag1 = False
    while True:
        if count_flag1 == True:
            break
        root.update()






# create a Tkinter window
root = tk.Tk()
# this will be a global flag
count_flag1 = True


# create needed widgets
label1 = tk.Label(root, text='Display')
btn_start1 = tk.Button(root, text='start all', command=start1)
btn_stop1 = tk.Button(root, text='stop all', command=stop1)
# use a grid to place the widgets
label1.grid(row=0, column=0, columnspan=2)
btn_start1.grid(row=1, column=0, padx=5, pady=5)
btn_stop1.grid(row=1, column=1, padx=5)