<gh_stars>0
#!/usr/bin/python
# -*- coding: UTF-8 -*-
# File name   : controller.py
# Description : Controller PC  
# Website     : www.adeept.com
# E-mail      : <EMAIL>
# Author      : William
# Date        : 2018/08/22
# Modified    : seb3n
# Mod date    : 2021/08/15

from socket import *
import time
import threading as thread
import tkinter as tk


stat=0          #A status value,ensure the mainloop() runs only once
tcpClicSock=''  #A global variable,for future socket connection
BUFSIZ=1024     #Set a buffer size
ip_stu=1        #Shows connection status

#Global variables of input status
BtnIP=''
ipaddr=''
ipcon=0
send_pwm_conf = 1

def replace_num(initial,new_num):   #Call this function to replace data in '.txt' file
    newline=""
    str_num=str(new_num)
    with open("ip.txt","r") as f:
        for line in f.readlines():
            if(line.find(initial) == 0):
                line = initial+"%s" %(str_num)
            newline += line
    with open("ip.txt","w") as f:
        f.writelines(newline)    #Call this function to replace data in '.txt' file

def num_import(initial):            #Call this function to import data from '.txt' file
    with open("ip.txt") as f:
        for line in f.readlines():
            if(line.find(initial) == 0):
                r=line
    begin=len(list(initial))
    snum=r[begin:]
    n=snum
    return n    

def call_forward(event):         #When this function is called, controller commands the car to move forward
    tcpClicSock.send(('add').encode())

def call_back(event):            #When this function is called, controller commands the car to move backward
    tcpClicSock.send(('sub').encode())

def normal_state():
    Btn_L0.config(fg=color_text,bg=color_btn)
    Btn_L1.config(fg=color_text,bg=color_btn)
    Btn_L2.config(fg=color_text,bg=color_btn)
    Btn_L3.config(fg=color_text,bg=color_btn)
    Btn_L4.config(fg=color_text,bg=color_btn)
    Btn_L5.config(fg=color_text,bg=color_btn)
    Btn_L6.config(fg=color_text,bg=color_btn)
    Btn_L7.config(fg=color_text,bg=color_btn)
    Btn_L8.config(fg=color_text,bg=color_btn)
    Btn_L9.config(fg=color_text,bg=color_btn)
    Btn_L10.config(fg=color_text,bg=color_btn)
    Btn_L11.config(fg=color_text,bg=color_btn)
    Btn_L12.config(fg=color_text,bg=color_btn)
    Btn_L13.config(fg=color_text,bg=color_btn)
    Btn_L14.config(fg=color_text,bg=color_btn)
    Btn_L15.config(fg=color_text,bg=color_btn)



def set_L0():
    print('L0')
    tcpClicSock.send(('L0').encode())
    normal_state()
    Btn_L0.config(fg='#0277BD',bg='#BBDEFB')

def set_L1():
    print('L1')
    tcpClicSock.send(('L1').encode())
    normal_state()
    Btn_L1.config(fg='#0277BD',bg='#BBDEFB')

def set_L2():
    tcpClicSock.send(('L2').encode())
    normal_state()
    Btn_L2.config(fg='#0277BD',bg='#BBDEFB')

def set_L3():
    tcpClicSock.send(('L3').encode())
    normal_state()
    Btn_L3.config(fg='#0277BD',bg='#BBDEFB')

def set_L4():
    tcpClicSock.send(('L4').encode())
    normal_state()
    Btn_L4.config(fg='#0277BD',bg='#BBDEFB')

def set_L5():
    tcpClicSock.send(('L5').encode())
    normal_state()
    Btn_L5.config(fg='#0277BD',bg='#BBDEFB')

def set_L6():
    tcpClicSock.send(('L6').encode())
    normal_state()
    Btn_L6.config(fg='#0277BD',bg='#BBDEFB')

def set_L7():
    tcpClicSock.send(('L7').encode())
    normal_state()
    Btn_L7.config(fg='#0277BD',bg='#BBDEFB')

def set_L8():
    tcpClicSock.send(('L8').encode())
    normal_state()
    Btn_L8.config(fg='#0277BD',bg='#BBDEFB')

def set_L9():
    tcpClicSock.send(('L9').encode())
    normal_state()
    Btn_L9.config(fg='#0277BD',bg='#BBDEFB')

def set_L10():
    tcpClicSock.send(('L10').encode())
    normal_state()
    Btn_L10.config(fg='#0277BD',bg='#BBDEFB')

def set_L11():
    tcpClicSock.send(('L11').encode())
    normal_state()
    Btn_L11.config(fg='#0277BD',bg='#BBDEFB')

def set_L12():
    tcpClicSock.send(('L12').encode())
    normal_state()
    Btn_L12.config(fg='#0277BD',bg='#BBDEFB')

def set_L13():
    tcpClicSock.send(('L13').encode())
    normal_state()
    Btn_L13.config(fg='#0277BD',bg='#BBDEFB')

def set_L14():
    tcpClicSock.send(('L14').encode())
    normal_state()
    Btn_L14.config(fg='#0277BD',bg='#BBDEFB')

def set_L15():
    tcpClicSock.send(('L15').encode())
    normal_state()
    Btn_L15.config(fg='#0277BD',bg='#BBDEFB')



def normal_st():
    Btn_ST1.config(fg=color_text,bg=color_btn)
    Btn_ST2.config(fg=color_text,bg=color_btn)
    Btn_ST3.config(fg=color_text,bg=color_btn)
    Btn_ST4.config(fg=color_text,bg=color_btn)
    Btn_ST5.config(fg=color_text,bg=color_btn)
    Btn_ST6.config(fg=color_text,bg=color_btn)
    Btn_ST7.config(fg=color_text,bg=color_btn)
    Btn_ST8.config(fg=color_text,bg=color_btn)
    Btn_ST9.config(fg=color_text,bg=color_btn)
    Btn_ST10.config(fg=color_text,bg=color_btn)
    Btn_ST11.config(fg=color_text,bg=color_btn)
    Btn_ST12.config(fg=color_text,bg=color_btn)
    Btn_ST13.config(fg=color_text,bg=color_btn)
    Btn_ST14.config(fg=color_text,bg=color_btn)
    Btn_MAX.config(fg=color_text,bg=color_btn)
    Btn_MIN.config(fg=color_text,bg=color_btn)



def set_ST1():
    tcpClicSock.send(('ST1').encode())
    normal_st()
    Btn_ST1.config(fg='#0277BD',bg='#BBDEFB')

def set_ST2():
    tcpClicSock.send(('ST2').encode())
    normal_st()
    Btn_ST2.config(fg='#0277BD',bg='#BBDEFB')

def set_ST3():
    tcpClicSock.send(('ST3').encode())
    normal_st()
    Btn_ST3.config(fg='#0277BD',bg='#BBDEFB')

def set_ST4():
    tcpClicSock.send(('ST4').encode())
    normal_st()
    Btn_ST4.config(fg='#0277BD',bg='#BBDEFB')

def set_ST5():
    tcpClicSock.send(('ST5').encode())
    normal_st()
    Btn_ST5.config(fg='#0277BD',bg='#BBDEFB')

def set_ST6():
    tcpClicSock.send(('ST6').encode())
    normal_st()
    Btn_ST6.config(fg='#0277BD',bg='#BBDEFB')

def set_ST7():
    tcpClicSock.send(('ST7').encode())
    normal_st()
    Btn_ST7.config(fg='#0277BD',bg='#BBDEFB')

def set_ST8():
    tcpClicSock.send(('ST8').encode())
    normal_st()
    Btn_ST8.config(fg='#0277BD',bg='#BBDEFB')

def set_ST9():
    tcpClicSock.send(('ST9').encode())
    normal_st()
    Btn_ST9.config(fg='#0277BD',bg='#BBDEFB')

def set_ST10():
    tcpClicSock.send(('ST10').encode())
    normal_st()
    Btn_ST10.config(fg='#0277BD',bg='#BBDEFB')

def set_ST11():
    tcpClicSock.send(('ST11').encode())
    normal_st()
    Btn_ST10.config(fg='#0277BD',bg='#BBDEFB')

def set_ST12():
    tcpClicSock.send(('ST12').encode())
    normal_st()
    Btn_ST10.config(fg='#0277BD',bg='#BBDEFB')

def set_ST13():
    tcpClicSock.send(('ST13').encode())
    normal_st()
    Btn_ST10.config(fg='#0277BD',bg='#BBDEFB')

def set_ST14():
    tcpClicSock.send(('ST14').encode())
    normal_st()
    Btn_ST10.config(fg='#0277BD',bg='#BBDEFB')

def set_MIN():
    tcpClicSock.send(('MIN').encode())
    normal_st()
    Btn_ST2.config(fg='#0277BD',bg='#BBDEFB')

def set_MAX():
    tcpClicSock.send(('MAX').encode())
    normal_st()
    Btn_ST2.config(fg='#0277BD',bg='#BBDEFB')

def set_config():
    tcpClicSock.send(('config').encode())

def set_reset():
    tcpClicSock.send(('reset').encode())

def set_save():
    tcpClicSock.send(('save').encode())

def set_run():
    setp_send = var_setps.get()
    time_send = var_time.get()
    tcpClicSock.send(('run %s %s'%(setp_send,time_send)).encode())

def set_stop():
    tcpClicSock.send(('stop').encode())

def set_all():
    setp_send = var_setps.get()
    time_send = var_time.get()
    tcpClicSock.send(('all %s %s'%(setp_send,time_send)).encode())

def set_stepall():
    tcpClicSock.send(('frame').encode())

def set_pwm_thread():
    global send_pwm_conf
    while 1:
        if send_pwm_conf == 0:
            time.sleep(0.3)
            tcpClicSock.send((var_pwm.get()).encode())
            send_pwm_conf = 1
        time.sleep(0.2)
            


def set_pwm(event):
    global send_pwm_conf
    if send_pwm_conf == 1:
        #tcpClicSock.send((var_pwm.get()).encode())
        send_pwm_conf = 0

def loop():                       #GUI
    global tcpClicSock,BtnIP,led_status,color_text,color_btn,Btn_L0,Btn_L1,Btn_L2,Btn_L3,Btn_L4,Btn_L5,Btn_L6,Btn_L7,Btn_L8,Btn_L9,Btn_L10,Btn_L11,Btn_L12,Btn_L13,Btn_L14,Btn_L15,Btn_ST1, Btn_ST2,Btn_ST3,Btn_ST4,Btn_ST5,Btn_ST6,Btn_ST7,Btn_ST8,Btn_ST9,Btn_ST10,Btn_ST11,Btn_ST12,Btn_ST13,Btn_ST14,Btn_MIN,Btn_MAX,var_setps,var_time,var_pwm     #The value of tcpClicSock changes in the function loop(),would also changes in global so the other functions could use it.
    while True:
        color_bg='#000000'        #Set background color
        color_text='#E1F5FE'      #Set text color
        color_btn='#0277BD'       #Set button color
        color_line='#01579B'      #Set line color
        color_can='#212121'       #Set canvas color
        color_oval='#2196F3'      #Set oval color
        target_color='#FF6D00'

        root = tk.Tk()            #Define a window named root
        root.title('Adeept')      #Main window title
        root.geometry('800x630')  #Main window size, middle of the English letter x.
        root.config(bg=color_bg)  #Set the background color of root window
    
        var_pwm = tk.StringVar()  #Speed value saved in a StringVar
        var_pwm.set(425)            #Set a default speed,but change it would not change the default speed value in the car,you need to click button'Set' to send the value to the car

        var_setps = tk.StringVar()
        var_setps.set(5)

        var_time = tk.StringVar()
        var_time.set(0.2)

        logo =tk.PhotoImage(file = 'logo.png')         #Define the picture of logo,but only supports '.png' and '.gif'
        l_logo=tk.Label(root,image = logo,bg=color_bg) #Set a label to show the logo picture
        l_logo.place(x=30,y=13)                        #Place the Label in a right position

        def connect(event):       #Call this function to connect with the server
            if ip_stu == 1:
                sc=thread.Thread(target=socket_connect) #Define a thread for connection
                sc.setDaemon(True)                      #'True' means it is a front thread,it would close when the mainloop() closes
                sc.start()                              #Thread starts

        def connect_2():          #Call this function to connect with the server
            if ip_stu == 1:
                sc=thread.Thread(target=socket_connect) #Define a thread for connection
                sc.setDaemon(True)                      #'True' means it is a front thread,it would close when the mainloop() closes
                sc.start()                              #Thread starts

        def socket_connect():     #Call this function to connect with the server
            global ADDR,tcpClicSock,BUFSIZ,ip_stu,ipaddr
            ip_adr=E1.get()       #Get the IP address from Entry

            if ip_adr == '':      #If no input IP address in Entry,import a default IP
                ip_adr=num_import('IP:')
                l_ip_4.config(text='Connecting')
                l_ip_4.config(bg='#FF8F00')
                l_ip_5.config(text='Default:%s'%ip_adr)
                pass
            
            SERVER_IP = ip_adr
            SERVER_PORT = 10223   #Define port serial 
            BUFSIZ = 1024         #Define buffer size
            ADDR = (SERVER_IP, SERVER_PORT)
            tcpClicSock = socket(AF_INET, SOCK_STREAM) #Set connection value for socket

            for i in range (1,6): #Try 5 times if disconnected
                try:
                    if ip_stu == 1:
                        print("Connecting to server @ %s:%d..." %(SERVER_IP, SERVER_PORT))
                        print("Connecting")
                        tcpClicSock.connect(ADDR)        #Connection with the server
                    
                        print("Connected")
                    
                        l_ip_5.config(text='IP:%s'%ip_adr)
                        l_ip_4.config(text='Connected')
                        l_ip_4.config(bg='#558B2F')

                        replace_num('IP:',ip_adr)
                        E1.config(state='disabled')      #Disable the Entry
                        Btn14.config(state='disabled',bg='#212121')   #Disable the Entry
                    
                        ip_stu=0                         #'0' means connected
                    
                        at=thread.Thread(target=code_receive) #Define a thread for data receiving
                        at.setDaemon(True)                    #'True' means it is a front thread,it would close when the mainloop() closes
                        at.start()                            #Thread starts
                        break
                    else:
                        break
                except Exception:
                    print("Cannot connecting to server,try it latter!")
                    l_ip_4.config(text='Try %d/5 time(s)'%i)
                    l_ip_4.config(bg='#EF6C00')
                    print('Try %d/5 time(s)'%i)
                    ip_stu=1
                    time.sleep(1)
                    continue
            if ip_stu == 1:
                l_ip_4.config(text='Disconnected')
                l_ip_4.config(bg='#F44336')

        def code_receive():     #A function for data receiving
            global led_status,ipcon,findline_status,auto_status,opencv_status,speech_status
            while True:
                code_car = tcpClicSock.recv(BUFSIZ) #Listening,and save the data in 'code_car'
                l_ip.config(text=code_car)          #Put the data on the label
                #print(code_car)
                data = code_car.decode()
                if not code_car:
                    continue
                elif 'L0' == data:
                    l_ip_L.config(text='L0')
                elif 'L1' == data:
                    l_ip_L.config(text='L1')
                elif 'L2' == data:
                    l_ip_L.config(text='L2')
                elif 'L3' == data:
                    l_ip_L.config(text='L3')
                elif 'L4' == data:
                    l_ip_L.config(text='L4')
                elif 'L5' == data:
                    l_ip_L.config(text='L5')
                elif 'L6' == data:
                    l_ip_L.config(text='L6')
                elif 'L7' == data:
                    l_ip_L.config(text='L7')
                elif 'L8' == data:
                    l_ip_L.config(text='L8')
                elif 'L9' == data:
                    l_ip_L.config(text='L9')
                elif 'L10' == data:
                    l_ip_L.config(text='L10')
                elif 'L11' == data:
                    l_ip_L.config(text='L11')
                elif 'L12' == data:
                    l_ip_L.config(text='L12')
                elif 'L13' == data:
                    l_ip_L.config(text='L13')
                elif 'L14' == data:
                    l_ip_L.config(text='L14')
                elif 'L15' == data:
                    l_ip_L.config(text='L15')



                elif 'ST1' == data:
                    l_ip_SET.config(text='ST1')
                elif 'ST2' == data:
                    l_ip_SET.config(text='ST2')
                elif 'ST3' == data:
                    l_ip_SET.config(text='ST3')
                elif 'ST4' == data:
                    l_ip_SET.config(text='ST4')
                elif 'ST5' == data:
                    l_ip_SET.config(text='ST5')
                elif 'ST6' == data:
                    l_ip_SET.config(text='ST6')
                elif 'ST7' == data:
                    l_ip_SET.config(text='ST7')
                elif 'ST8' == data:
                    l_ip_SET.config(text='ST8')
                elif 'ST9' == data:
                    l_ip_SET.config(text='ST9')
                elif 'ST10' == data:
                    l_ip_SET.config(text='ST10')
                elif 'ST11' == data:
                    l_ip_SET.config(text='ST11')
                elif 'ST12' == data:
                    l_ip_SET.config(text='ST12')
                elif 'ST13' == data:
                    l_ip_SET.config(text='ST13')
                elif 'ST14' == data:
                    l_ip_SET.config(text='ST14')
                elif 'MAX' == data:
                    l_ip_SET.config(text='MAX')
                elif 'MIN' == data:
                    l_ip_SET.config(text='MIN')

                else:
                    try:
                        org = int(data)
                        var_pwm.set(org)
                    except:
                        pass

        s1 = tk.Scale(root,label="PWM",
        from_=100,to=700,orient=tk.HORIZONTAL,length=740,
        showvalue=1,tickinterval=100,resolution=1,variable=var_pwm,troughcolor='#42A5F5',fg=color_text,command=set_pwm,bg=color_bg,highlightthickness=0)
        s1.place(x=30,y=270)                            #Define a Scale and put it in position

        s2 = tk.Scale(root,label="SETPS",
        from_=1,to=14,orient=tk.HORIZONTAL,length=440,
        showvalue=1,tickinterval=1,resolution=1,variable=var_setps,troughcolor='#42A5F5',fg=color_text,bg=color_bg,highlightthickness=0)
        s2.place(x=330,y=350)                            #Define a Scale and put it in position

        s3 = tk.Scale(root,label="TIME",
        from_=0.1,to=1,orient=tk.HORIZONTAL,length=440,
        showvalue=0.1,tickinterval=0.2,resolution=0.1,variable=var_time,troughcolor='#42A5F5',fg=color_text,bg=color_bg,highlightthickness=0)
        s3.place(x=330,y=450)                            #Define a Scale and put it in position

        Btn_RUN = tk.Button(root, width=18, text='RUN',bd=0,fg=color_text,bg=color_btn,relief='ridge',command=set_run)
        Btn_RUN.place(x=187,y=388)

        Btn_ALL = tk.Button(root, width=18, text='RUN ALL',bd=0,fg=color_text,bg=color_btn,relief='ridge',command=set_all)
        Btn_ALL.place(x=187,y=428)

        Btn_STOP = tk.Button(root, width=18, text='STOP',bd=0,fg=color_text,bg=color_btn,relief='ridge',command=set_stop)
        Btn_STOP.place(x=187,y=488)

        Btn_STEPALL = tk.Button(root, width=18, text='STEP ALL',bd=0,fg=color_text,bg=color_btn,relief='ridge',command=set_stepall)
        Btn_STEPALL.place(x=30,y=488)

        l_ip=tk.Label(root,width=18,text='Status',fg=color_text,bg=color_btn)
        l_ip.place(x=30,y=110)                           #Define a Label and put it in position

        l_ip_2=tk.Label(root,width=18,text='pwm:%s'%(var_pwm.get()),fg=color_text,bg=color_btn)
        l_ip_2.place(x=30,y=145)                         #Define a Label and put it in position

        l_ip_L=tk.Label(root,width=18,text='choose L',fg=color_text,bg=color_btn)
        l_ip_L.place(x=230,y=145) 

        l_ip_SET=tk.Label(root,width=18,text='pos set',fg=color_text,bg=color_btn)
        l_ip_SET.place(x=430,y=145) 

        l_ip_4=tk.Label(root,width=18,text='Disconnected',fg=color_text,bg='#F44336')
        l_ip_4.place(x=637,y=110)                         #Define a Label and put it in position

        l_ip_5=tk.Label(root,width=18,text='Use default IP',fg=color_text,bg=color_btn)
        l_ip_5.place(x=637,y=145)                         #Define a Label and put it in position

        E1 = tk.Entry(root,show=None,width=16,bg="#37474F",fg='#eceff1')
        E1.place(x=170,y=40)                             #Define a Entry and put it in position

        l_ip_3=tk.Label(root,width=10,text='IP Address:',fg=color_text,bg='#000000')
        l_ip_3.place(x=165,y=15)                         #Define a Label and put it in position

        Btn14= tk.Button(root, width=8, text='Connect',fg=color_text,bg=color_btn,command=connect_2,relief='ridge')
        Btn14.place(x=300,y=35)                          #Define a Button and put it in position

        #Define buttons and put these in position
        Btn0 = tk.Button(root, width=3, text='+',bd=0,fg=color_text,bg=color_btn,relief='ridge')
        Btn1 = tk.Button(root, width=3, text='-',bd=0,fg=color_text,bg=color_btn,relief='ridge')

        Btn0.place(x=30,y=195)
        Btn1.place(x=30,y=230)

        Btn_L0 = tk.Button(root, width=3, text='L0',bd=0,fg=color_text,bg=color_btn,relief='ridge',command=set_L0)
        Btn_L0.place(x=65,y=195)

        Btn_L1 = tk.Button(root, width=3, text='L1',bd=0,fg=color_text,bg=color_btn,relief='ridge',command=set_L1)
        Btn_L1.place(x=100,y=195)
        
        Btn_L2 = tk.Button(root, width=3, text='L2',bd=0,fg=color_text,bg=color_btn,relief='ridge',command=set_L2)
        Btn_L2.place(x=135,y=195)

        Btn_L3 = tk.Button(root, width=3, text='L3',bd=0,fg=color_text,bg=color_btn,relief='ridge',command=set_L3)
        Btn_L3.place(x=170,y=195)

        Btn_L4 = tk.Button(root, width=3, text='L4',bd=0,fg=color_text,bg=color_btn,relief='ridge',command=set_L4)
        Btn_L4.place(x=205,y=195)

        Btn_L5 = tk.Button(root, width=3, text='L5',bd=0,fg=color_text,bg=color_btn,relief='ridge',command=set_L5)
        Btn_L5.place(x=240,y=195)

        Btn_L6 = tk.Button(root, width=3, text='L6',bd=0,fg=color_text,bg=color_btn,relief='ridge',command=set_L6)
        Btn_L6.place(x=275,y=195)

        Btn_L7 = tk.Button(root, width=3, text='L7',bd=0,fg=color_text,bg=color_btn,relief='ridge',command=set_L7)
        Btn_L7.place(x=310,y=195)

        Btn_L8 = tk.Button(root, width=3, text='L8',bd=0,fg=color_text,bg=color_btn,relief='ridge',command=set_L8)
        Btn_L8.place(x=345,y=195)

        Btn_L9 = tk.Button(root, width=3, text='L9',bd=0,fg=color_text,bg=color_btn,relief='ridge',command=set_L9)
        Btn_L9.place(x=380,y=195)

        Btn_L10 = tk.Button(root, width=3, text='L10',bd=0,fg=color_text,bg=color_btn,relief='ridge',command=set_L10)
        Btn_L10.place(x=415,y=195)

        Btn_L11 = tk.Button(root, width=3, text='L11',bd=0,fg=color_text,bg=color_btn,relief='ridge',command=set_L11)
        Btn_L11.place(x=450,y=195)

        Btn_L12 = tk.Button(root, width=3, text='L12',bd=0,fg=color_text,bg=color_btn,relief='ridge',command=set_L12)
        Btn_L12.place(x=485,y=195)

        Btn_L13 = tk.Button(root, width=3, text='L13',bd=0,fg=color_text,bg=color_btn,relief='ridge',command=set_L13)
        Btn_L13.place(x=520,y=195)

        Btn_L14 = tk.Button(root, width=3, text='L14',bd=0,fg=color_text,bg=color_btn,relief='ridge',command=set_L14)
        Btn_L14.place(x=555,y=195)

        Btn_L15 = tk.Button(root, width=3, text='L15',bd=0,fg=color_text,bg=color_btn,relief='ridge',command=set_L15)
        Btn_L15.place(x=590,y=195)

        Btn_CONFIG = tk.Button(root, width=18, text='CONFIG',bd=0,fg=color_text,bg=color_btn,relief='ridge',command=set_config)
        Btn_CONFIG.place(x=637,y=195)

        Btn_SAVE = tk.Button(root, width=8, text='SAVE',bd=0,fg=color_text,bg=color_btn,relief='ridge',command=set_save)
        Btn_SAVE.place(x=637,y=230)

        Btn_RESET = tk.Button(root, width=8, text='RESET',bd=0,fg=color_text,bg=color_btn,relief='ridge',command=set_reset)
        Btn_RESET.place(x=707,y=230)


        Btn_ST1 = tk.Button(root, width=3, text='ST1',bd=0,fg=color_text,bg=color_btn,relief='ridge',command=set_ST1)
        Btn_ST1.place(x=65,y=230)
        
        Btn_ST2 = tk.Button(root, width=3, text='ST2',bd=0,fg=color_text,bg=color_btn,relief='ridge',command=set_ST2)
        Btn_ST2.place(x=100,y=230)

        Btn_ST3 = tk.Button(root, width=3, text='ST3',bd=0,fg=color_text,bg=color_btn,relief='ridge',command=set_ST3)
        Btn_ST3.place(x=135,y=230)

        Btn_ST4 = tk.Button(root, width=3, text='ST4',bd=0,fg=color_text,bg=color_btn,relief='ridge',command=set_ST4)
        Btn_ST4.place(x=170,y=230)

        Btn_ST5 = tk.Button(root, width=3, text='ST5',bd=0,fg=color_text,bg=color_btn,relief='ridge',command=set_ST5)
        Btn_ST5.place(x=205,y=230)

        Btn_ST6 = tk.Button(root, width=3, text='ST6',bd=0,fg=color_text,bg=color_btn,relief='ridge',command=set_ST6)
        Btn_ST6.place(x=240,y=230)

        Btn_ST7 = tk.Button(root, width=3, text='ST7',bd=0,fg=color_text,bg=color_btn,relief='ridge',command=set_ST7)
        Btn_ST7.place(x=275,y=230)

        Btn_ST8 = tk.Button(root, width=3, text='ST8',bd=0,fg=color_text,bg=color_btn,relief='ridge',command=set_ST8)
        Btn_ST8.place(x=310,y=230)

        Btn_ST9 = tk.Button(root, width=3, text='ST9',bd=0,fg=color_text,bg=color_btn,relief='ridge',command=set_ST9)
        Btn_ST9.place(x=345,y=230)

        Btn_ST10 = tk.Button(root, width=3, text='ST10',bd=0,fg=color_text,bg=color_btn,relief='ridge',command=set_ST10)
        Btn_ST10.place(x=380,y=230)

        Btn_ST11 = tk.Button(root, width=3, text='ST11',bd=0,fg=color_text,bg=color_btn,relief='ridge',command=set_ST11)
        Btn_ST11.place(x=415,y=230)

        Btn_ST12 = tk.Button(root, width=3, text='ST12',bd=0,fg=color_text,bg=color_btn,relief='ridge',command=set_ST12)
        Btn_ST12.place(x=450,y=230)

        Btn_ST13 = tk.Button(root, width=3, text='ST13',bd=0,fg=color_text,bg=color_btn,relief='ridge',command=set_ST13)
        Btn_ST13.place(x=485,y=230)

        Btn_ST14 = tk.Button(root, width=3, text='ST14',bd=0,fg=color_text,bg=color_btn,relief='ridge',command=set_ST14)
        Btn_ST14.place(x=520,y=230)

        Btn_MIN = tk.Button(root, width=3, text='MIN',bd=0,fg=color_text,bg=color_btn,relief='ridge',command=set_MIN)
        Btn_MIN.place(x=555,y=230)

        Btn_MAX = tk.Button(root, width=3, text='MAX',bd=0,fg=color_text,bg=color_btn,relief='ridge',command=set_MAX)
        Btn_MAX.place(x=590,y=230)


        # Bind the buttons with the corresponding callback function
        Btn0.bind('<ButtonPress-1>', call_forward)
        Btn1.bind('<ButtonPress-1>', call_back)

        # Bind the keys with the corresponding callback function
        root.bind('<KeyPress-w>', call_forward) 
        root.bind('<KeyPress-s>', call_back)

        # When these keys is released,call the function call_stop()


        # Press these keyss to call the corresponding function()
        root.bind('<Return>', connect)

        
        global stat
        if stat==0:              # Ensure the mainloop runs only once
                root.mainloop()  # Run the mainloop()
                stat=1           # Change the value to '1' so the mainloop() would not run again.

if __name__ == '__main__':
    setPWM_threading=thread.Thread(target=set_pwm_thread)      #Define a thread for FPV and OpenCV
    setPWM_threading.setDaemon(True)                             #'True' means it is a front thread,it would close when the mainloop() closes
    setPWM_threading.start()                                     #Thread starts
    try:
        loop()                   # Load GUI
    except KeyboardInterrupt:
        tcpClicSock.close()          # Close socket or it may not connect with the server again


#!/usr/bin/python
# -*- coding: UTF-8 -*-
# File name   : controller.py
# Description : Controller PC  
# Website     : www.adeept.com
# E-mail      : <EMAIL>
# Author      : William
# Date        : 2018/08/22
# Modified    : seb3n
# Mod date    : 2021/08/15

from socket import *
import time
import threading as thread
import tkinter as tk


stat=0          #A status value,ensure the mainloop() runs only once
tcpClicSock=''  #A global variable,for future socket connection
BUFSIZ=1024     #Set a buffer size
ip_stu=1        #Shows connection status

#Global variables of input status
BtnIP=''
ipaddr=''
ipcon=0
send_pwm_conf = 1

def replace_num(initial,new_num):   #Call this function to replace data in '.txt' file
    newline=""
    str_num=str(new_num)
    with open("ip.txt","r") as f:
        for line in f.readlines():
            if(line.find(initial) == 0):
                line = initial+"%s" %(str_num)
            newline += line
    with open("ip.txt","w") as f:
        f.writelines(newline)    #Call this function to replace data in '.txt' file

def num_import(initial):            #Call this function to import data from '.txt' file
    with open("ip.txt") as f:
        for line in f.readlines():
            if(line.find(initial) == 0):
                r=line
    begin=len(list(initial))
    snum=r[begin:]
    n=snum
    return n    

def call_forward(event):         #When this function is called, controller commands the car to move forward
    tcpClicSock.send(('add').encode())

def call_back(event):            #When this function is called, controller commands the car to move backward
    tcpClicSock.send(('sub').encode())

def normal_state():
    Btn_L0.config(fg=color_text,bg=color_btn)
    Btn_L1.config(fg=color_text,bg=color_btn)
    Btn_L2.config(fg=color_text,bg=color_btn)
    Btn_L3.config(fg=color_text,bg=color_btn)
    Btn_L4.config(fg=color_text,bg=color_btn)
    Btn_L5.config(fg=color_text,bg=color_btn)
    Btn_L6.config(fg=color_text,bg=color_btn)
    Btn_L7.config(fg=color_text,bg=color_btn)
    Btn_L8.config(fg=color_text,bg=color_btn)
    Btn_L9.config(fg=color_text,bg=color_btn)
    Btn_L10.config(fg=color_text,bg=color_btn)
    Btn_L11.config(fg=color_text,bg=color_btn)
    Btn_L12.config(fg=color_text,bg=color_btn)
    Btn_L13.config(fg=color_text,bg=color_btn)
    Btn_L14.config(fg=color_text,bg=color_btn)
    Btn_L15.config(fg=color_text,bg=color_btn)



def set_L0():
    print('L0')
    tcpClicSock.send(('L0').encode())
    normal_state()
    Btn_L0.config(fg='#0277BD',bg='#BBDEFB')

def set_L1():
    print('L1')
    tcpClicSock.send(('L1').encode())
    normal_state()
    Btn_L1.config(fg='#0277BD',bg='#BBDEFB')

def set_L2():
    tcpClicSock.send(('L2').encode())
    normal_state()
    Btn_L2.config(fg='#0277BD',bg='#BBDEFB')

def set_L3():
    tcpClicSock.send(('L3').encode())
    normal_state()
    Btn_L3.config(fg='#0277BD',bg='#BBDEFB')

def set_L4():
    tcpClicSock.send(('L4').encode())
    normal_state()
    Btn_L4.config(fg='#0277BD',bg='#BBDEFB')

def set_L5():
    tcpClicSock.send(('L5').encode())
    normal_state()
    Btn_L5.config(fg='#0277BD',bg='#BBDEFB')

def set_L6():
    tcpClicSock.send(('L6').encode())
    normal_state()
    Btn_L6.config(fg='#0277BD',bg='#BBDEFB')

def set_L7():
    tcpClicSock.send(('L7').encode())
    normal_state()
    Btn_L7.config(fg='#0277BD',bg='#BBDEFB')

def set_L8():
    tcpClicSock.send(('L8').encode())
    normal_state()
    Btn_L8.config(fg='#0277BD',bg='#BBDEFB')

def set_L9():
    tcpClicSock.send(('L9').encode())
    normal_state()
    Btn_L9.config(fg='#0277BD',bg='#BBDEFB')

def set_L10():
    tcpClicSock.send(('L10').encode())
    normal_state()
    Btn_L10.config(fg='#0277BD',bg='#BBDEFB')

def set_L11():
    tcpClicSock.send(('L11').encode())
    normal_state()
    Btn_L11.config(fg='#0277BD',bg='#BBDEFB')

def set_L12():
    tcpClicSock.send(('L12').encode())
    normal_state()
    Btn_L12.config(fg='#0277BD',bg='#BBDEFB')

def set_L13():
    tcpClicSock.send(('L13').encode())
    normal_state()
    Btn_L13.config(fg='#0277BD',bg='#BBDEFB')

def set_L14():
    tcpClicSock.send(('L14').encode())
    normal_state()
    Btn_L14.config(fg='#0277BD',bg='#BBDEFB')

def set_L15():
    tcpClicSock.send(('L15').encode())
    normal_state()
    Btn_L15.config(fg='#0277BD',bg='#BBDEFB')



def normal_st():
    Btn_ST1.config(fg=color_text,bg=color_btn)
    Btn_ST2.config(fg=color_text,bg=color_btn)
    Btn_ST3.config(fg=color_text,bg=color_btn)
    Btn_ST4.config(fg=color_text,bg=color_btn)
    Btn_ST5.config(fg=color_text,bg=color_btn)
    Btn_ST6.config(fg=color_text,bg=color_btn)
    Btn_ST7.config(fg=color_text,bg=color_btn)
    Btn_ST8.config(fg=color_text,bg=color_btn)
    Btn_ST9.config(fg=color_text,bg=color_btn)
    Btn_ST10.config(fg=color_text,bg=color_btn)
    Btn_ST11.config(fg=color_text,bg=color_btn)
    Btn_ST12.config(fg=color_text,bg=color_btn)
    Btn_ST13.config(fg=color_text,bg=color_btn)
    Btn_ST14.config(fg=color_text,bg=color_btn)
    Btn_MAX.config(fg=color_text,bg=color_btn)
    Btn_MIN.config(fg=color_text,bg=color_btn)



def set_ST1():
    tcpClicSock.send(('ST1').encode())
    normal_st()
    Btn_ST1.config(fg='#0277BD',bg='#BBDEFB')

def set_ST2():
    tcpClicSock.send(('ST2').encode())
    normal_st()
    Btn_ST2.config(fg='#0277BD',bg='#BBDEFB')

def set_ST3():
    tcpClicSock.send(('ST3').encode())
    normal_st()
    Btn_ST3.config(fg='#0277BD',bg='#BBDEFB')

def set_ST4():
    tcpClicSock.send(('ST4').encode())
    normal_st()
    Btn_ST4.config(fg='#0277BD',bg='#BBDEFB')

def set_ST5():
    tcpClicSock.send(('ST5').encode())
    normal_st()
    Btn_ST5.config(fg='#0277BD',bg='#BBDEFB')

def set_ST6():
    tcpClicSock.send(('ST6').encode())
    normal_st()
    Btn_ST6.config(fg='#0277BD',bg='#BBDEFB')

def set_ST7():
    tcpClicSock.send(('ST7').encode())
    normal_st()
    Btn_ST7.config(fg='#0277BD',bg='#BBDEFB')

def set_ST8():
    tcpClicSock.send(('ST8').encode())
    normal_st()
    Btn_ST8.config(fg='#0277BD',bg='#BBDEFB')

def set_ST9():
    tcpClicSock.send(('ST9').encode())
    normal_st()
    Btn_ST9.config(fg='#0277BD',bg='#BBDEFB')

def set_ST10():
    tcpClicSock.send(('ST10').encode())
    normal_st()
    Btn_ST10.config(fg='#0277BD',bg='#BBDEFB')

def set_ST11():
    tcpClicSock.send(('ST11').encode())
    normal_st()
    Btn_ST10.config(fg='#0277BD',bg='#BBDEFB')

def set_ST12():
    tcpClicSock.send(('ST12').encode())
    normal_st()
    Btn_ST10.config(fg='#0277BD',bg='#BBDEFB')

def set_ST13():
    tcpClicSock.send(('ST13').encode())
    normal_st()
    Btn_ST10.config(fg='#0277BD',bg='#BBDEFB')

def set_ST14():
    tcpClicSock.send(('ST14').encode())
    normal_st()
    Btn_ST10.config(fg='#0277BD',bg='#BBDEFB')

def set_MIN():
    tcpClicSock.send(('MIN').encode())
    normal_st()
    Btn_ST2.config(fg='#0277BD',bg='#BBDEFB')

def set_MAX():
    tcpClicSock.send(('MAX').encode())
    normal_st()
    Btn_ST2.config(fg='#0277BD',bg='#BBDEFB')

def set_config():
    tcpClicSock.send(('config').encode())

def set_reset():
    tcpClicSock.send(('reset').encode())

def set_save():
    tcpClicSock.send(('save').encode())

def set_run():
    setp_send = var_setps.get()
    time_send = var_time.get()
    tcpClicSock.send(('run %s %s'%(setp_send,time_send)).encode())

def set_stop():
    tcpClicSock.send(('stop').encode())

def set_all():
    setp_send = var_setps.get()
    time_send = var_time.get()
    tcpClicSock.send(('all %s %s'%(setp_send,time_send)).encode())

def set_stepall():
    tcpClicSock.send(('frame').encode())

def set_pwm_thread():
    global send_pwm_conf
    while 1:
        if send_pwm_conf == 0:
            time.sleep(0.3)
            tcpClicSock.send((var_pwm.get()).encode())
            send_pwm_conf = 1
        time.sleep(0.2)
            


def set_pwm(event):
    global send_pwm_conf
    if send_pwm_conf == 1:
        #tcpClicSock.send((var_pwm.get()).encode())
        send_pwm_conf = 0

def loop():                       #GUI
    global tcpClicSock,BtnIP,led_status,color_text,color_btn,Btn_L0,Btn_L1,Btn_L2,Btn_L3,Btn_L4,Btn_L5,Btn_L6,Btn_L7,Btn_L8,Btn_L9,Btn_L10,Btn_L11,Btn_L12,Btn_L13,Btn_L14,Btn_L15,Btn_ST1, Btn_ST2,Btn_ST3,Btn_ST4,Btn_ST5,Btn_ST6,Btn_ST7,Btn_ST8,Btn_ST9,Btn_ST10,Btn_ST11,Btn_ST12,Btn_ST13,Btn_ST14,Btn_MIN,Btn_MAX,var_setps,var_time,var_pwm     #The value of tcpClicSock changes in the function loop(),would also changes in global so the other functions could use it.
    while True:
        color_bg='#000000'        #Set background color
        color_text='#E1F5FE'      #Set text color
        color_btn='#0277BD'       #Set button color
        color_line='#01579B'      #Set line color
        color_can='#212121'       #Set canvas color
        color_oval='#2196F3'      #Set oval color
        target_color='#FF6D00'

        root = tk.Tk()            #Define a window named root
        root.title('Adeept')      #Main window title
        root.geometry('800x630')  #Main window size, middle of the English letter x.
        root.config(bg=color_bg)  #Set the background color of root window
    
        var_pwm = tk.StringVar()  #Speed value saved in a StringVar
        var_pwm.set(425)            #Set a default speed,but change it would not change the default speed value in the car,you need to click button'Set' to send the value to the car

        var_setps = tk.StringVar()
        var_setps.set(5)

        var_time = tk.StringVar()
        var_time.set(0.2)

        logo =tk.PhotoImage(file = 'logo.png')         #Define the picture of logo,but only supports '.png' and '.gif'
        l_logo=tk.Label(root,image = logo,bg=color_bg) #Set a label to show the logo picture
        l_logo.place(x=30,y=13)                        #Place the Label in a right position

        def connect(event):       #Call this function to connect with the server
            if ip_stu == 1:
                sc=thread.Thread(target=socket_connect) #Define a thread for connection
                sc.setDaemon(True)                      #'True' means it is a front thread,it would close when the mainloop() closes
                sc.start()                              #Thread starts

        def connect_2():          #Call this function to connect with the server
            if ip_stu == 1:
                sc=thread.Thread(target=socket_connect) #Define a thread for connection
                sc.setDaemon(True)                      #'True' means it is a front thread,it would close when the mainloop() closes
                sc.start()                              #Thread starts

        def socket_connect():     #Call this function to connect with the server
            global ADDR,tcpClicSock,BUFSIZ,ip_stu,ipaddr
            ip_adr=E1.get()       #Get the IP address from Entry

            if ip_adr == '':      #If no input IP address in Entry,import a default IP
                ip_adr=num_import('IP:')
                l_ip_4.config(text='Connecting')
                l_ip_4.config(bg='#FF8F00')
                l_ip_5.config(text='Default:%s'%ip_adr)
                pass
            
            SERVER_IP = ip_adr
            SERVER_PORT = 10223   #Define port serial 
            BUFSIZ = 1024         #Define buffer size
            ADDR = (SERVER_IP, SERVER_PORT)
            tcpClicSock = socket(AF_INET, SOCK_STREAM) #Set connection value for socket

            for i in range (1,6): #Try 5 times if disconnected
                try:
                    if ip_stu == 1:
                        print("Connecting to server @ %s:%d..." %(SERVER_IP, SERVER_PORT))
                        print("Connecting")
                        tcpClicSock.connect(ADDR)        #Connection with the server
                    
                        print("Connected")
                    
                        l_ip_5.config(text='IP:%s'%ip_adr)
                        l_ip_4.config(text='Connected')
                        l_ip_4.config(bg='#558B2F')

                        replace_num('IP:',ip_adr)
                        E1.config(state='disabled')      #Disable the Entry
                        Btn14.config(state='disabled',bg='#212121')   #Disable the Entry
                    
                        ip_stu=0                         #'0' means connected
                    
                        at=thread.Thread(target=code_receive) #Define a thread for data receiving
                        at.setDaemon(True)                    #'True' means it is a front thread,it would close when the mainloop() closes
                        at.start()                            #Thread starts
                        break
                    else:
                        break
                except Exception:
                    print("Cannot connecting to server,try it latter!")
                    l_ip_4.config(text='Try %d/5 time(s)'%i)
                    l_ip_4.config(bg='#EF6C00')
                    print('Try %d/5 time(s)'%i)
                    ip_stu=1
                    time.sleep(1)
                    continue
            if ip_stu == 1:
                l_ip_4.config(text='Disconnected')
                l_ip_4.config(bg='#F44336')

        def code_receive():     #A function for data receiving
            global led_status,ipcon,findline_status,auto_status,opencv_status,speech_status
            while True:
                code_car = tcpClicSock.recv(BUFSIZ) #Listening,and save the data in 'code_car'
                l_ip.config(text=code_car)          #Put the data on the label
                #print(code_car)
                data = code_car.decode()
                if not code_car:
                    continue
                elif 'L0' == data:
                    l_ip_L.config(text='L0')
                elif 'L1' == data:
                    l_ip_L.config(text='L1')
                elif 'L2' == data:
                    l_ip_L.config(text='L2')
                elif 'L3' == data:
                    l_ip_L.config(text='L3')
                elif 'L4' == data:
                    l_ip_L.config(text='L4')
                elif 'L5' == data:
                    l_ip_L.config(text='L5')
                elif 'L6' == data:
                    l_ip_L.config(text='L6')
                elif 'L7' == data:
                    l_ip_L.config(text='L7')
                elif 'L8' == data:
                    l_ip_L.config(text='L8')
                elif 'L9' == data:
                    l_ip_L.config(text='L9')
                elif 'L10' == data:
                    l_ip_L.config(text='L10')
                elif 'L11' == data:
                    l_ip_L.config(text='L11')
                elif 'L12' == data:
                    l_ip_L.config(text='L12')
                elif 'L13' == data:
                    l_ip_L.config(text='L13')
                elif 'L14' == data:
                    l_ip_L.config(text='L14')
                elif 'L15' == data:
                    l_ip_L.config(text='L15')



                elif 'ST1' == data:
                    l_ip_SET.config(text='ST1')
                elif 'ST2' == data:
                    l_ip_SET.config(text='ST2')
                elif 'ST3' == data:
                    l_ip_SET.config(text='ST3')
                elif 'ST4' == data:
                    l_ip_SET.config(text='ST4')
                elif 'ST5' == data:
                    l_ip_SET.config(text='ST5')
                elif 'ST6' == data:
                    l_ip_SET.config(text='ST6')
                elif 'ST7' == data:
                    l_ip_SET.config(text='ST7')
                elif 'ST8' == data:
                    l_ip_SET.config(text='ST8')
                elif 'ST9' == data:
                    l_ip_SET.config(text='ST9')
                elif 'ST10' == data:
                    l_ip_SET.config(text='ST10')
                elif 'ST11' == data:
                    l_ip_SET.config(text='ST11')
                elif 'ST12' == data:
                    l_ip_SET.config(text='ST12')
                elif 'ST13' == data:
                    l_ip_SET.config(text='ST13')
                elif 'ST14' == data:
                    l_ip_SET.config(text='ST14')
                elif 'MAX' == data:
                    l_ip_SET.config(text='MAX')
                elif 'MIN' == data:
                    l_ip_SET.config(text='MIN')

                else:
                    try:
                        org = int(data)
                        var_pwm.set(org)
                    except:
                        pass

        s1 = tk.Scale(root,label="PWM",
        from_=100,to=700,orient=tk.HORIZONTAL,length=740,
        showvalue=1,tickinterval=100,resolution=1,variable=var_pwm,troughcolor='#42A5F5',fg=color_text,command=set_pwm,bg=color_bg,highlightthickness=0)
        s1.place(x=30,y=270)                            #Define a Scale and put it in position

        s2 = tk.Scale(root,label="SETPS",
        from_=1,to=14,orient=tk.HORIZONTAL,length=440,
        showvalue=1,tickinterval=1,resolution=1,variable=var_setps,troughcolor='#42A5F5',fg=color_text,bg=color_bg,highlightthickness=0)
        s2.place(x=330,y=350)                            #Define a Scale and put it in position

        s3 = tk.Scale(root,label="TIME",
        from_=0.1,to=1,orient=tk.HORIZONTAL,length=440,
        showvalue=0.1,tickinterval=0.2,resolution=0.1,variable=var_time,troughcolor='#42A5F5',fg=color_text,bg=color_bg,highlightthickness=0)
        s3.place(x=330,y=450)                            #Define a Scale and put it in position

        Btn_RUN = tk.Button(root, width=18, text='RUN',bd=0,fg=color_text,bg=color_btn,relief='ridge',command=set_run)
        Btn_RUN.place(x=187,y=388)

        Btn_ALL = tk.Button(root, width=18, text='RUN ALL',bd=0,fg=color_text,bg=color_btn,relief='ridge',command=set_all)
        Btn_ALL.place(x=187,y=428)

        Btn_STOP = tk.Button(root, width=18, text='STOP',bd=0,fg=color_text,bg=color_btn,relief='ridge',command=set_stop)
        Btn_STOP.place(x=187,y=488)

        Btn_STEPALL = tk.Button(root, width=18, text='STEP ALL',bd=0,fg=color_text,bg=color_btn,relief='ridge',command=set_stepall)
        Btn_STEPALL.place(x=30,y=488)

        l_ip=tk.Label(root,width=18,text='Status',fg=color_text,bg=color_btn)
        l_ip.place(x=30,y=110)                           #Define a Label and put it in position

        l_ip_2=tk.Label(root,width=18,text='pwm:%s'%(var_pwm.get()),fg=color_text,bg=color_btn)
        l_ip_2.place(x=30,y=145)                         #Define a Label and put it in position

        l_ip_L=tk.Label(root,width=18,text='choose L',fg=color_text,bg=color_btn)
        l_ip_L.place(x=230,y=145) 

        l_ip_SET=tk.Label(root,width=18,text='pos set',fg=color_text,bg=color_btn)
        l_ip_SET.place(x=430,y=145) 

        l_ip_4=tk.Label(root,width=18,text='Disconnected',fg=color_text,bg='#F44336')
        l_ip_4.place(x=637,y=110)                         #Define a Label and put it in position

        l_ip_5=tk.Label(root,width=18,text='Use default IP',fg=color_text,bg=color_btn)
        l_ip_5.place(x=637,y=145)                         #Define a Label and put it in position

        E1 = tk.Entry(root,show=None,width=16,bg="#37474F",fg='#eceff1')
        E1.place(x=170,y=40)                             #Define a Entry and put it in position

        l_ip_3=tk.Label(root,width=10,text='IP Address:',fg=color_text,bg='#000000')
        l_ip_3.place(x=165,y=15)                         #Define a Label and put it in position

        Btn14= tk.Button(root, width=8, text='Connect',fg=color_text,bg=color_btn,command=connect_2,relief='ridge')
        Btn14.place(x=300,y=35)                          #Define a Button and put it in position

        #Define buttons and put these in position
        Btn0 = tk.Button(root, width=3, text='+',bd=0,fg=color_text,bg=color_btn,relief='ridge')
        Btn1 = tk.Button(root, width=3, text='-',bd=0,fg=color_text,bg=color_btn,relief='ridge')

        Btn0.place(x=30,y=195)
        Btn1.place(x=30,y=230)

        Btn_L0 = tk.Button(root, width=3, text='L0',bd=0,fg=color_text,bg=color_btn,relief='ridge',command=set_L0)
        Btn_L0.place(x=65,y=195)

        Btn_L1 = tk.Button(root, width=3, text='L1',bd=0,fg=color_text,bg=color_btn,relief='ridge',command=set_L1)
        Btn_L1.place(x=100,y=195)
        
        Btn_L2 = tk.Button(root, width=3, text='L2',bd=0,fg=color_text,bg=color_btn,relief='ridge',command=set_L2)
        Btn_L2.place(x=135,y=195)

        Btn_L3 = tk.Button(root, width=3, text='L3',bd=0,fg=color_text,bg=color_btn,relief='ridge',command=set_L3)
        Btn_L3.place(x=170,y=195)

        Btn_L4 = tk.Button(root, width=3, text='L4',bd=0,fg=color_text,bg=color_btn,relief='ridge',command=set_L4)
        Btn_L4.place(x=205,y=195)

        Btn_L5 = tk.Button(root, width=3, text='L5',bd=0,fg=color_text,bg=color_btn,relief='ridge',command=set_L5)
        Btn_L5.place(x=240,y=195)

        Btn_L6 = tk.Button(root, width=3, text='L6',bd=0,fg=color_text,bg=color_btn,relief='ridge',command=set_L6)
        Btn_L6.place(x=275,y=195)

        Btn_L7 = tk.Button(root, width=3, text='L7',bd=0,fg=color_text,bg=color_btn,relief='ridge',command=set_L7)
        Btn_L7.place(x=310,y=195)

        Btn_L8 = tk.Button(root, width=3, text='L8',bd=0,fg=color_text,bg=color_btn,relief='ridge',command=set_L8)
        Btn_L8.place(x=345,y=195)

        Btn_L9 = tk.Button(root, width=3, text='L9',bd=0,fg=color_text,bg=color_btn,relief='ridge',command=set_L9)
        Btn_L9.place(x=380,y=195)

        Btn_L10 = tk.Button(root, width=3, text='L10',bd=0,fg=color_text,bg=color_btn,relief='ridge',command=set_L10)
        Btn_L10.place(x=415,y=195)

        Btn_L11 = tk.Button(root, width=3, text='L11',bd=0,fg=color_text,bg=color_btn,relief='ridge',command=set_L11)
        Btn_L11.place(x=450,y=195)

        Btn_L12 = tk.Button(root, width=3, text='L12',bd=0,fg=color_text,bg=color_btn,relief='ridge',command=set_L12)
        Btn_L12.place(x=485,y=195)

        Btn_L13 = tk.Button(root, width=3, text='L13',bd=0,fg=color_text,bg=color_btn,relief='ridge',command=set_L13)
        Btn_L13.place(x=520,y=195)

        Btn_L14 = tk.Button(root, width=3, text='L14',bd=0,fg=color_text,bg=color_btn,relief='ridge',command=set_L14)
        Btn_L14.place(x=555,y=195)

        Btn_L15 = tk.Button(root, width=3, text='L15',bd=0,fg=color_text,bg=color_btn,relief='ridge',command=set_L15)
        Btn_L15.place(x=590,y=195)

        Btn_CONFIG = tk.Button(root, width=18, text='CONFIG',bd=0,fg=color_text,bg=color_btn,relief='ridge',command=set_config)
        Btn_CONFIG.place(x=637,y=195)

        Btn_SAVE = tk.Button(root, width=8, text='SAVE',bd=0,fg=color_text,bg=color_btn,relief='ridge',command=set_save)
        Btn_SAVE.place(x=637,y=230)

        Btn_RESET = tk.Button(root, width=8, text='RESET',bd=0,fg=color_text,bg=color_btn,relief='ridge',command=set_reset)
        Btn_RESET.place(x=707,y=230)


        Btn_ST1 = tk.Button(root, width=3, text='ST1',bd=0,fg=color_text,bg=color_btn,relief='ridge',command=set_ST1)
        Btn_ST1.place(x=65,y=230)
        
        Btn_ST2 = tk.Button(root, width=3, text='ST2',bd=0,fg=color_text,bg=color_btn,relief='ridge',command=set_ST2)
        Btn_ST2.place(x=100,y=230)

        Btn_ST3 = tk.Button(root, width=3, text='ST3',bd=0,fg=color_text,bg=color_btn,relief='ridge',command=set_ST3)
        Btn_ST3.place(x=135,y=230)

        Btn_ST4 = tk.Button(root, width=3, text='ST4',bd=0,fg=color_text,bg=color_btn,relief='ridge',command=set_ST4)
        Btn_ST4.place(x=170,y=230)

        Btn_ST5 = tk.Button(root, width=3, text='ST5',bd=0,fg=color_text,bg=color_btn,relief='ridge',command=set_ST5)
        Btn_ST5.place(x=205,y=230)

        Btn_ST6 = tk.Button(root, width=3, text='ST6',bd=0,fg=color_text,bg=color_btn,relief='ridge',command=set_ST6)
        Btn_ST6.place(x=240,y=230)

        Btn_ST7 = tk.Button(root, width=3, text='ST7',bd=0,fg=color_text,bg=color_btn,relief='ridge',command=set_ST7)
        Btn_ST7.place(x=275,y=230)

        Btn_ST8 = tk.Button(root, width=3, text='ST8',bd=0,fg=color_text,bg=color_btn,relief='ridge',command=set_ST8)
        Btn_ST8.place(x=310,y=230)

        Btn_ST9 = tk.Button(root, width=3, text='ST9',bd=0,fg=color_text,bg=color_btn,relief='ridge',command=set_ST9)
        Btn_ST9.place(x=345,y=230)

        Btn_ST10 = tk.Button(root, width=3, text='ST10',bd=0,fg=color_text,bg=color_btn,relief='ridge',command=set_ST10)
        Btn_ST10.place(x=380,y=230)

        Btn_ST11 = tk.Button(root, width=3, text='ST11',bd=0,fg=color_text,bg=color_btn,relief='ridge',command=set_ST11)
        Btn_ST11.place(x=415,y=230)

        Btn_ST12 = tk.Button(root, width=3, text='ST12',bd=0,fg=color_text,bg=color_btn,relief='ridge',command=set_ST12)
        Btn_ST12.place(x=450,y=230)

        Btn_ST13 = tk.Button(root, width=3, text='ST13',bd=0,fg=color_text,bg=color_btn,relief='ridge',command=set_ST13)
        Btn_ST13.place(x=485,y=230)

        Btn_ST14 = tk.Button(root, width=3, text='ST14',bd=0,fg=color_text,bg=color_btn,relief='ridge',command=set_ST14)
        Btn_ST14.place(x=520,y=230)

        Btn_MIN = tk.Button(root, width=3, text='MIN',bd=0,fg=color_text,bg=color_btn,relief='ridge',command=set_MIN)
        Btn_MIN.place(x=555,y=230)

        Btn_MAX = tk.Button(root, width=3, text='MAX',bd=0,fg=color_text,bg=color_btn,relief='ridge',command=set_MAX)
        Btn_MAX.place(x=590,y=230)


        # Bind the buttons with the corresponding callback function
        Btn0.bind('<ButtonPress-1>', call_forward)
        Btn1.bind('<ButtonPress-1>', call_back)

        # Bind the keys with the corresponding callback function
        root.bind('<KeyPress-w>', call_forward) 
        root.bind('<KeyPress-s>', call_back)

        # When these keys is released,call the function call_stop()


        # Press these keyss to call the corresponding function()
        root.bind('<Return>', connect)

        
        global stat
        if stat==0:              # Ensure the mainloop runs only once
                root.mainloop()  # Run the mainloop()
                stat=1           # Change the value to '1' so the mainloop() would not run again.

if __name__ == '__main__':
    setPWM_threading=thread.Thread(target=set_pwm_thread)      #Define a thread for FPV and OpenCV
    setPWM_threading.setDaemon(True)                             #'True' means it is a front thread,it would close when the mainloop() closes
    setPWM_threading.start()                                     #Thread starts
    try:
        loop()                   # Load GUI
    except KeyboardInterrupt:
        tcpClicSock.close()          # Close socket or it may not connect with the server again
#!/usr/bin/python # -*- coding: UTF-8 -*- # File name   : controller.py # Description : Controller PC # Website     : www.adeept.com # E-mail      : <EMAIL> # Author      : William # Date        : 2018/08/22 # Modified    : seb3n # Mod date    : 2021/08/15 #A status value,ensure the mainloop() runs only once #A global variable,for future socket connection #Set a buffer size #Shows connection status #Global variables of input status #Call this function to replace data in '.txt' file #Call this function to replace data in '.txt' file #Call this function to import data from '.txt' file #When this function is called, controller commands the car to move forward #When this function is called, controller commands the car to move backward #tcpClicSock.send((var_pwm.get()).encode()) #GUI #The value of tcpClicSock changes in the function loop(),would also changes in global so the other functions could use it. #Set background color #Set text color #Set button color #Set line color #Set canvas color #Set oval color #Define a window named root #Main window title #Main window size, middle of the English letter x. #Set the background color of root window #Speed value saved in a StringVar #Set a default speed,but change it would not change the default speed value in the car,you need to click button'Set' to send the value to the car #Define the picture of logo,but only supports '.png' and '.gif' #Set a label to show the logo picture #Place the Label in a right position #Call this function to connect with the server #Define a thread for connection #'True' means it is a front thread,it would close when the mainloop() closes #Thread starts #Call this function to connect with the server #Define a thread for connection #'True' means it is a front thread,it would close when the mainloop() closes #Thread starts #Call this function to connect with the server #Get the IP address from Entry #If no input IP address in Entry,import a default IP #Define port serial #Define buffer size #Set connection value for socket #Try 5 times if disconnected #Connection with the server #Disable the Entry #Disable the Entry #'0' means connected #Define a thread for data receiving #'True' means it is a front thread,it would close when the mainloop() closes #Thread starts #A function for data receiving #Listening,and save the data in 'code_car' #Put the data on the label #print(code_car) #Define a Scale and put it in position #Define a Scale and put it in position #Define a Scale and put it in position #Define a Label and put it in position #Define a Label and put it in position #Define a Label and put it in position #Define a Label and put it in position #Define a Entry and put it in position #Define a Label and put it in position #Define a Button and put it in position #Define buttons and put these in position # Bind the buttons with the corresponding callback function # Bind the keys with the corresponding callback function # When these keys is released,call the function call_stop() # Press these keyss to call the corresponding function() # Ensure the mainloop runs only once # Run the mainloop() # Change the value to '1' so the mainloop() would not run again. #Define a thread for FPV and OpenCV #'True' means it is a front thread,it would close when the mainloop() closes #Thread starts # Load GUI # Close socket or it may not connect with the server again