I had a laugh when I started tumbling around on the web, trying to get a proper starting point for learning Python ! I heard about the famous Pink Floyd rock band funding the no less famous “Python and the Holy Grail” with a part of their substantial earning from “Dark Side of the Moon” album. But I was far from imagining that a developer would name a programming language after the hilarious Monty Python gang…
However, learning a new code is less fun than the Monty Python, and generates more stress than listening to Clare Torry solo… Anyway, I wanted to get into this language which is growing fast in popularity among many developers from institutional organisations down to apprentice developers. And it is interesting to get back to learning and how it feels to get into something (almost) new. Some years ago, my dear colleagues gently convinced me to volunteer to go back to university and obtain a degree in nuclear physics in order to get the accreditation for running the analysis of radio active compounds: at 50, it’s quite a challenge ! After all, I like challenges thus my constant interest in new tech and this blog.
Let’s get back to Python for now. Getting Pyhton installed is pretty easy, just get to the official page and download the package which fits your configuration. If you are new at Python, it is suggested that you go for the latest version which is 3.x.x. I tumbled through the web looking at a convenient IDE ad found that notepad++ is definitely a fine editor for Python. In addition, you can verify and launch your code from inside Notepad++ which is very handy. As for any new language, starting programming is a mix of easy successes and fast achievements as well as long boring full stops because of these tiny little #%$#?@& changes in structure or parameters definition. At least two (among few) things confused me quite a lot: the indentation of code and the programming of GUI (Graphic User interface) !
I am happy to share my first application which is a plain simple although handy console which reads data from serial communication ports.
from tkinter import * from time import sleep import serial # Instanciate object ser = serial.Serial() _applicationName = "ComWithMe" _btnWidth = 10 # Functions def ControlComPort(*args): if (ser.isOpen()): # Close port try: ser.close() varPortOpenText.set("Open") except serial.Exception as e1: exit() else: # Set port parameters # Extract parameters from entry field vParams = varComPortParam.get() param = vParams.split(',', 4) ser.port = param ser.baudrate = int(param) #115200 ser.bytesize = int(param) #serial.EIGHTBITS ser.parity = param #serial.PARITY_NONE ser.stopbits = int(param) #serial.STOPBITS_ONE # Open port try: ser.open() varPortOpenText.set("Close") except serial.Exception as e1: exit() def ResetComPort(*args): # reset port if (ser.isOpen()): try: ser.dtr = 1 ser.rtscts = 1 time.sleep(0.05) ser.dtr = 0 ser.rtscts = 0 if (varClearOnReset.get()): txtReadData.delete(1.0, END) except serial.Exception as e2: exit() def ReadData(): if (ser.isOpen()): if ser.inWaiting() > 0: varDataInLabel.set("Data in *") line = "" try: line = ser.readline() except serial.Exception as e1: exit() else: txtReadData.insert(END, line) if (varAutoScroll.get()): txtReadData.see(END) root.after(250, StatusTimer) root.after(10, ReadData) # check serial again soon def StatusTimer(): varDataInLabel.set("Data in") root = Tk() root.title(_applicationName) # root.iconbitmap(r"C:\Users\dlongueville\Documents\python\icons\CommWithMe.ico") #Define frame content = Frame(root) # Define Tkinter variables varAutoScroll = BooleanVar() varClearOnReset = BooleanVar() varPortOpenText = StringVar() varComPortParam = StringVar() varDataInLabel = StringVar() # Set variables varAutoScroll.set(True) varClearOnReset.set(True) varPortOpenText.set("Open") # Change default comm port parameters acroding to your configuration varComPortParam.set("COM35,115200,8,N,1") varDataInLabel.set("Data in") # Define widgets chkAutoScroll = Checkbutton(content, text = "Auto scroll", variable = varAutoScroll, onvalue = True, width = _btnWidth) chkClearOnReset = Checkbutton(content, text = " Clr on Rst", variable = varClearOnReset, onvalue = True, width = _btnWidth) btnComPortCtrl = Button(content, textvariable = varPortOpenText, command = ControlComPort, width = _btnWidth) btnReset = Button(content, text = "Reset", command = ResetComPort, width = _btnWidth) btnQuit = Button(content, text = "Quit", command = root.destroy, width = _btnWidth) entComPortParam = Entry(content, textvariable = varComPortParam, width = _btnWidth * 2) txtReadData = Text(content) lblText = Label(content, textvariable = varDataInLabel) # Define grid content.pack(fill = BOTH, expand = True) content.columnconfigure(1, weight = 1) content.columnconfigure(3, pad = 7) content.rowconfigure(6, weight = 1) content.rowconfigure(7, pad = 7) # https://goo.gl/yUZYWj # Placewidgets lblText.grid(sticky = W, pady = 4, padx = 5, row = 0, column = 0) txtReadData.grid(sticky = E + W + S + N, rowspan = 6, columnspan = 2, padx = 5, row = 1, column = 0) btnQuit.grid(pady = 4, row = 0, column = 3) btnComPortCtrl.grid(pady = 4, row = 1, column = 3) btnReset.grid(pady = 4, row = 2, column = 3) chkAutoScroll.grid(pady = 4, row = 3, column = 3) chkClearOnReset.grid(pady = 4, row = 4, column = 3) entComPortParam.grid(sticky = W, padx = 5, row = 7, column = 0) # Set window properties # width x height + x + y root.geometry("500x300+50+50") root.minsize(width = 500, height = 300) # root.resizable(width = False, height = True) btnComPortCtrl.focus() # https://goo.gl/hzc820 root.after(10, ReadData) root.mainloop()
It works out of the box and looks like
All you have to do is to set the communication port according to your configuration by changing the string at the bottom of the window. The default configuration string is “”COM35,115200,8,N,1”, which stands for comm port “COM35”, baudrate 115200, 8 bits of data, No parity check and 1 stop bit. The Reset button will reboot your Arduino and clear the actual “Data in” content if the “Clr on Rst” check box is activated.