Posted on Leave a comment

How to make UART Serial Console using Pyserial, Tkinter in python

Screenshot

The serial console is written in a python programming language. The GUI is made using the Tkinter library and the serial interface functions are provided by the pyserial library.

you can install pyserial from command prompt(windows)/terminal(linux)

Python Code

from tkinter import *
from tkinter import ttk
import serial
import serial.tools.list_ports
import datetime
import threading
import multiprocessing
import os

#for printing debugging messages in console
dbg = 0

gRoot = Tk()
#gRoot.geometry("480x280")
gRoot.title("Serial Console")
sty = ttk.Style()
sty.theme_use("alt")
gRoot.columnconfigure(0,weight=1)
gRoot.rowconfigure(0,weight=1)
#sty.configure("gframe.TFrame",background="white")
gFrame = ttk.LabelFrame(gRoot,text="Connection Setting",padding=10)
gFrame.grid(column=1,row=1, sticky=(W,E))

#Frame for COM messages

gFrame21 = ttk.Frame(gRoot,padding=10)
gFrame21.grid(column=2,row=1, sticky=(W))
#gRoot.resizable(0,0)


for x in range(10):
    gFrame.columnconfigure(x,weight = x)
    gFrame.rowconfigure(x,weight = x)
    
label1=ttk.Label(gFrame, text = "Serial Console")
label1.grid(column=2,row=0)
gFrame.rowconfigure(0,weight=2)

sty.configure("label2.TLabel",borderwidth=4,relief="ridge",foreground="red",ipadx=10)
label2=ttk.Label(gFrame,sty="label2.TLabel", text = "Select Com Port")
label2.grid(column=1,row=1, sticky = (N,E,W,S))

"""
Com Port List
"""
#Start
ports = serial.tools.list_ports.comports()
com_port_list = [com[0] for com in ports]
com_port_list.insert(0,"Select an Option")
if dbg == 1:
    print(com_port_list)
#END
com_value_inside = StringVar()
baud_value_inside = StringVar()
baud_menu = ttk.OptionMenu(gFrame,baud_value_inside,"select baud rate","9600",
                           '19200','28800','38400','57600','76800',
                           '115200','128000','153600','230400','256000','460800','921600')
baud_menu.grid(column=3, row=1, sticky = (E))
def com_port_list_update():
    global ports
    global com_port_list
    ports = serial.tools.list_ports.comports()
    com_port_list = [com[0] for com in ports]
    com_port_list.insert(0,"Select an Option")
    if dbg == 1:
        print(com_port_list)
    com_menu = ttk.OptionMenu(gFrame,com_value_inside,*com_port_list)
    com_menu.grid(column=2, row=1, sticky = (E))
    #Frame for the COM LIST
    gRoot_com_list = Toplevel(gRoot)
    x = gRoot.winfo_x()
    y = gRoot.winfo_y()
    gRoot_com_list.geometry("+%d+%d" %(x+200,y+200))
    gFrame01 = ttk.Frame(gRoot_com_list,padding=10)
    gFrame01.grid(column=0,row=1, sticky=(W))
    #Create a horizontal scrollbar
    scrollbar = ttk.Scrollbar(gFrame01, orient= 'horizontal')
    scrollbar.grid(column=1,row=2, sticky=W+E)

    Lb1 = Listbox(gFrame01, xscrollcommand = 1, width = 50, font= ('Helvetica 8 bold'))
    counter = 0;
    for x in ports:
        Lb1.insert(counter, str(x))
    #print (counter)
    counter += 1
    Lb1.grid(column=1,row=1, sticky=W+E)
    Lb1.config(xscrollcommand= scrollbar.set)

    #Configure the scrollbar
    scrollbar.config(command= Lb1.xview)


def serial_print():
    global serFlag
    global ser
    global counter1
    x =""
    #print("Task 1 assigned to thread: {}".format(threading.current_thread().name))
    #print("ID of process running task 1: {}".format(os.getpid()))
    if(serFlag):
        if(ser.in_waiting>0):
            #
            try:
                x = ser.read(ser.in_waiting)
                #x = ser.readline(ser.in_waiting)
                #x = ser.read_until(expected='\n', size=ser.in_waiting)
                #print(x)
                y = str(counter1)+": "+str(datetime.datetime.now())+" -> "+str(x.decode())
                Lb2.insert(counter1, str(y))
                Lb2.see("end")
                #print (counter1)
                counter1 += 1
                #gFrame.after(100,serial_print)
            except:
                pass
        ser.flush()
        gFrame.after(100,serial_print)


ser = serial.Serial()
serFlag = 0
def serial_connect(com_port,baud_rate):
    global ser
    ser.baudrate = baud_rate
    ser.port = com_port
    ser.timeout = 1
    ser._xonxoff=1
    ser.bytesize=serial.EIGHTBITS
    ser.parity=serial.PARITY_NONE
    ser.stopbits=serial.STOPBITS_ONE
    ser.open()
    global serFlag
    serFlag = 1
    
    t1 = threading.Thread(target = serial_print, args = (), daemon=1)
    t1.start()
    #t1.join()
    """
    P1 = multiprocessing.Process(target = serial_print, args=())
    P1.start()
    P1.join()
    """
    #serial_print()
counter1 = 0;


    
def serial_close():
    global ser
    global serFlag
    serFlag = 0
    ser.close()
    
def submit_value():
    if dbg == 1:
        print("selected option: {}".format(com_value_inside.get()))
        print(" Baud Rate {}".format(baud_value_inside.get()))
    serial_connect(com_value_inside.get(),baud_value_inside.get())


Lb2 = Listbox(gFrame21, width = 100, xscrollcommand = 1)
Lb2.grid(column=1, row = 1, sticky = W+E)
Sb2 = ttk.Scrollbar(gFrame21,orient = 'vertical')
Sb2.config(command=Lb2.yview)
Sb2.grid(column = 2,row =1, sticky=N+S)
Sb2v = ttk.Scrollbar(gFrame21,orient = 'horizontal')
Sb2v.grid(column = 1,row =2, sticky=W+E)
Sb2v.config(command = Lb2.xview)
Lb2.configure(xscrollcommand = Sb2v.set, yscrollcommand = Sb2.set)

def clear_listbox():
    Lb2.delete(0,END)
    
subBtn = ttk.Button(gFrame,text="submit",command = submit_value)
subBtn.grid(column=4,row=1, sticky = (E))

RefreshBtn = ttk.Button(gFrame,text="Get List",command = com_port_list_update)
RefreshBtn.grid(column=2,row=2, sticky = (E))



closeBtn = ttk.Button(gFrame,text="Disconnect",command = serial_close)
closeBtn.grid(column=4,row=2, sticky = (E))

clearBtn = ttk.Button(gFrame,text="Clear Messages",command = clear_listbox)
clearBtn.grid(column=3,row=2, sticky = (E))



"""
#Add a Listbox Widget
listbox = Listbox(win, width= 350, font= ('Helvetica 15 bold'))
listbox.pack(side= LEFT, fill= BOTH)

#Add values to the Listbox
for values in range(1,101):
   listbox.insert(END, values)
"""
def donothing():
   filewin = Toplevel(gRoot)
   button = Button(filewin, text="Do nothing button")
   button.pack()

def About_me():
   filewin = Toplevel(gRoot)
   Label1 = Label(filewin, text = "EXASUB.COM").pack()
   button = Button(filewin, text="Quit", command = filewin.destroy)
   button.pack()

menubar = Menu(gRoot)
filemenu = Menu(menubar, tearoff=0)
filemenu.add_command(label="New", command=donothing)
filemenu.add_command(label="Open", command=donothing)
filemenu.add_command(label="Save", command=donothing)
filemenu.add_command(label="Save as...", command=donothing)
filemenu.add_command(label="Close", command=donothing)

filemenu.add_separator()

filemenu.add_command(label="Exit", command=gRoot.quit)
menubar.add_cascade(label="File", menu=filemenu)
editmenu = Menu(menubar, tearoff=0)
editmenu.add_command(label="Undo", command=donothing)

editmenu.add_separator()

editmenu.add_command(label="Cut", command=donothing)
editmenu.add_command(label="Copy", command=donothing)
editmenu.add_command(label="Paste", command=donothing)
editmenu.add_command(label="Delete", command=donothing)
editmenu.add_command(label="Select All", command=donothing)

menubar.add_cascade(label="Edit", menu=editmenu)
helpmenu = Menu(menubar, tearoff=0)
helpmenu.add_command(label="Help Index", command=donothing)
helpmenu.add_command(label="About...", command=donothing)
menubar.add_cascade(label="Help", menu=helpmenu)
menubar.add_command(label = "EXASUB.com", command = About_me)
menubar.add_separator()
menubar.add_command(label = "Quit", command = gRoot.destroy)

gRoot.config(menu=menubar)
gRoot.mainloop()
Posted on Leave a comment

How to install and also uninstall python packages using PIP

Python’s functionality can be extended with scripts that are made to do different tasks. They are sometimes super easy to work with and can perform a myriad of tasks with just a few lines of code.

You can browse through many packages here: https://pypi.org/

to install these packages you need to have python software already installed in your computer.

Open Command Prompt

syntax for installing a package using PIP

pip install your-package-name-here

And let’s say you want to work with UART or serial data. You can install pyserial.

pip install pyserial

after your work is done you can also remove or uninstall the package using

pip uninstall pyserial
Posted on Leave a comment

How to make an Alarm Clock using Tkinter and Python

To make the python code into an executable. I followed this guide How to make a python script into an executable file.

Python Code

from tkinter import *
from tkinter import ttk
import time

timeVar = time.localtime()
#time.struct_time(tm_year=2022, tm_mon=12, tm_mday=3,
#tm_hour=13, tm_min=3, tm_sec=45, tm_wday=5, tm_yday=337, tm_isdst=0)

#print(timeVar.tm_sec)

root = Tk()

root.title("Time Display")
hourVar = StringVar()
minVar = StringVar()
secVar = StringVar()

Ahour = StringVar()
Amin = StringVar()
Asec = StringVar()
AsetTimeHour = StringVar()
AsetTimeMin = StringVar()
AsetTimeSec = StringVar()

frame = ttk.Frame(root)
frame.grid()

frame11 = ttk.Frame(root, padding = 10)
frame11.grid(column = 1,row=0)

s = ttk.Style()
s.theme_use("alt")

def update():
    global timeVar
        #while(1):
    timeVar = time.localtime()
    hourVar.set(str(timeVar.tm_hour))
    minVar.set(str(timeVar.tm_min))
    #minVar.set(str(59))
    secVar.set(str(timeVar.tm_sec))
    if ( (hourVar.get() == Ahour.get()) and (minVar.get() == Amin.get()) and (secVar.get() == Asec.get()) ):
        alarmWin = Toplevel(root)
        root.bell()
        alarmWin.title("Alarm")
        
        #alarmWin.geometry("200x100")
        s.configure("Aframe.TFrame", background = "cyan")
        Aframe = ttk.Frame(alarmWin, style ="Aframe.TFrame" ,padding = 100)
        #Aframe.configure(background = "cyan")
        Aframe.grid()
        
        ttk.Label(Aframe, text = "Alarm ").grid(column=2,row=0,sticky = (W,E))
        ttk.Button(Aframe, text="QUIT", command = alarmWin.destroy).grid(column=0, row=10)
        #root.update()
        #time.sleep(1)
    root.after(1000,update)
        


def alarmset():
    
    childWin = Toplevel(root)
    childWin.title("Alarm Set")
    frame1 = ttk.Frame(childWin)
    frame1.grid()
    ttk.Label(frame1, text = "Hour").grid(column=2,row=0,ipadx = 20,ipady=10)
    ttk.Entry(frame1,textvariable = AsetTimeHour).grid(column=2,row=1)
    ttk.Label(frame1, text = "Min").grid(column=3,row=0)
    ttk.Entry(frame1,textvariable = AsetTimeMin).grid(column=3,row=1)
    ttk.Label(frame1, text = "Sec").grid(column=4,row=0)
    ttk.Entry(frame1,textvariable = AsetTimeSec).grid(column=4,row=1)
    def Aset():
        try:
            xyz = AsetTimeHour.get()
            Ahour.set(str(int(AsetTimeHour.get())))
        except:
            Ahour.set("")
        try:
            Amin.set(str(int(AsetTimeMin.get())))
        except:
            Amin.set("")
        try:
            Asec.set(str(int(AsetTimeSec.get())))
        except:
            Asec.set("")
        #root1.destroy()
    
    ttk.Button(frame1, text="QUIT", command = childWin.destroy).grid(column=0, row=10)
    ttk.Button(frame1, text="Set", command = Aset).grid(column=1, row=10)
    
def alarmset15sec():
    global timeVar
    #timeVar.tm_min = 58
    x = int((timeVar.tm_sec + 15) if (timeVar.tm_sec + 15) <= 59 else (timeVar.tm_sec + 15)-60 )
    y= 0
    z = 0
    if x < 15:
        y = int((timeVar.tm_min + 1) if (timeVar.tm_min + 1) <= 59 else (timeVar.tm_min + 1)-60 )
        #y = ((int(minVar.get()) + 1) if (int(minVar.get()) + 1) <= 59 else int(minVar.get()) + 1 - 60)
        z = int((timeVar.tm_hour ))
        if y < 1:
            z = int((timeVar.tm_hour + 1) if (timeVar.tm_hour + 1) <= 23 else (timeVar.tm_hour + 15)-24 )
        try:
            Amin.set(str(y))
        except:
            Amin.set("")
        try:
            Asec.set(str(x))
        except:
            Asec.set("")
        try:
            Ahour.set(str(z))
        except:
            Ahour.set("")
            
    if x >= 15:
        y = int((timeVar.tm_min ))
        z = int((timeVar.tm_hour ))
        try:
            Amin.set(str(y))
        except:
            Amin.set("")
        try:
            Asec.set(str(x))
        except:
            Asec.set("")
        try:
            Ahour.set(str(z))
        except:
            Ahour.set("")
   
    
    
    

        
s.configure("timelabel.TLabel", font="Arial 24", padding = 20)
hourLabel = ttk.Label(frame, textvariable = hourVar, style = "timelabel.TLabel")
hourLabel.grid(column=1, row = 1,sticky = (E))
ttk.Label(frame,text = " : ", style = "timelabel.TLabel").grid(column=2,row=1)
minLabel = ttk.Label(frame,textvariable = minVar, style = "timelabel.TLabel")
minLabel.grid(column=3, row = 1,sticky = (E))
ttk.Label(frame,text = " : ", style = "timelabel.TLabel").grid(column=4,row=1)
secLabel = ttk.Label(frame, textvariable = secVar, style = "timelabel.TLabel")
secLabel.grid(column=5, row = 1,sticky = (E))

ttk.Label(frame11, text = "Alarm Time").grid(column=1,row=0)
ttk.Label(frame11, text = "Hour").grid(column=1,row=2)
ttk.Label(frame11, textvariable= Ahour).grid(column=1,row=3)

ttk.Label(frame11,text = " : ").grid(column=2,row=3)

ttk.Label(frame11, text = "Min").grid(column=3,row=2)
ttk.Label(frame11, textvariable= Amin).grid(column=3,row=3)

ttk.Label(frame11,text = " : ").grid(column=4,row=3)

ttk.Label(frame11, text = "Sec").grid(column=5,row=2)
ttk.Label(frame11, textvariable= Asec).grid(column=5,row=3)

ttk.Button(frame, text="Quit", command=root.destroy).grid(column=1, row=10)
ttk.Button(frame, text="Alarm Set", command = alarmset).grid(column=2, row=10)
ttk.Button(frame, text="Alarm Set 15 sec", command = alarmset15sec).grid(column=3, row=10)
update()
root.mainloop()
Posted on Leave a comment

How to make a python script into an executable file

To run a python script. You have to open python in either the command prompt or its IDLE.

We can make use of pyinstaller module. Which will take your script and add all the dependencies and create a standalone executable file which you can use just like any other software.

To install pyinstaller

open your command prompt and execute the following code

pip install pyinstaller

This will install pyinstaller .

After doing it. Browse into your script folder.

pyinstaller --onefile your-python-script.py

If you run the above line it will create a self containing executable file.

You can also have a directory in which all the dependency files are placed along with the executable file.

pyinstaller --onedir your-python-script.py

If you do want to have a console.

pyinstaller --onefile --noconsole your-python-script.py

If you want your executable file to have a custom icon. You can put a icon file in the same directory along with your Python script.

pyinstaller --onefile --noconsole -i "icon.ico" your-python-script.py