Mon p’tit python ! (Part 1)

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.

python

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[0]
		ser.baudrate = int(param[1]) #115200
		ser.bytesize = int(param[2]) #serial.EIGHTBITS
		ser.parity = param[3] #serial.PARITY_NONE
		ser.stopbits =  int(param[4]) #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

python_1

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.

Enjoy !

Leave a Reply

You must be logged in to post a comment.