Using Python and Tkinter to send keystrokes to a dsPIC via serial

Aron Horan is working on an interesting remote controlled robot system, to which he’s sending text characters from a PC in real time via a serial connection. He and I have both been investigating ways to use Python to send a character immediately every time a keyboard key is pressed (without needing to press return afterwards). We both tried writing Python console applications to do it, but ran into difficulties. Various workarounds are discussed online, but they all seem a bit messy, so I decided to ditch the console approach and use Tkinter instead. Tkinter is the standard GUI toolkit for Python and is usually installed when you install Python itself.

The first program I wrote is "keysender_basic.py" which opens a small Tkinter window and waits for keypresses to occur. Each time a keypress event is detected, a callback function is triggered which transmits the corresponding character to the open serial port. This is what it looks like:

Screenshot of keysender_basic.py

The Python code is shown below. I’m running Python 2.7.6 and I have PySerial installed. The serial port device number will probably need to be changed for most USB-to-serial converters. It’s currently set to open device 0 (same as COM1).

# keysender_basic.py - Send keypresses to a microcontroller
# Written by Ted Burke
# Last updated 9-12-2013

import Tkinter
import serial

# Define a keyboard callback function. This will be called
# every time a key is pressed anywhere in the window. 
def key(event):
    print "Sending", repr(event.char)
    ser.write(event.char)

# Open first serial port
ser = serial.Serial(0, 38400, timeout=1)

# Create a Tk GUI window
root = Tkinter.Tk()

# Bind all keypresses to the "key" function (define above)
root.bind("<Key>", key)

# Just place a simple label in the window
Tkinter.Label(root, text="Press some keys!").pack()

# Enter the Tkinter main event loop. The program will stay
# in this event loop until it's time to exit.
root.mainloop()

# Close serial port
ser.close()

The second program I wrote is "keysender.py". This is similar to the last one, except that it includes some additional buttons for sending a selection of characters using mouse clicks. This is what it looks like:

Screenshot of keysender.py

The full Python code is shown below. The serial port device number will probably need to be changed for most USB-to-serial converters. It’s currently set to open device 0 (same as COM1).

# keysender.py - Send single characters to a microcontroller
# Written by Ted Burke
# Last updated 9-12-2013

import Tkinter
import serial

# Define a keyboard callback function. This will be called
# every time a key is pressed anywhere in the window. 
def key(event):
    print "Sending", repr(event.char)
    ser.write(event.char)

# Callback function for the 'A' button
def a_press():
    print "Sending 'a'"
    ser.write('a')

# Callback function for the 'B' button
def b_press():
    print "Sending 'b'"
    ser.write('b')

# Callback function for the 'C' button
def c_press():
    print "Sending 'c'"
    ser.write('c')

# Open first serial port
ser = serial.Serial(0, 38400, timeout=1)

# Create a Tk GUI window
root = Tkinter.Tk()

# Bind all keypresses to the "key" function (define above)
root.bind("<Key>", key)

# Create a few buttons and connect each one to a function
a = Tkinter.Button(root, text='A', command=a_press)
b = Tkinter.Button(root, text='B', command=b_press)
c = Tkinter.Button(root, text='C', command=c_press)

# Lay out buttons in the GUI
a.grid(row=0, column=0, sticky='EW')
b.grid(row=1, column=0, sticky='EW')
c.grid(row=2, column=0, sticky='EW')
root.columnconfigure(0, weight=1)

# Enter the Tkinter main event loop. The program will stay
# in this event loop until it's time to exit.
root.mainloop()

# Close serial port
ser.close()
Advertisements
This entry was posted in Uncategorized and tagged , , , , , , , , , , , , . Bookmark the permalink.

Leave a Reply

Fill in your details below or click an icon to log in:

WordPress.com Logo

You are commenting using your WordPress.com account. Log Out /  Change )

Google+ photo

You are commenting using your Google+ account. Log Out /  Change )

Twitter picture

You are commenting using your Twitter account. Log Out /  Change )

Facebook photo

You are commenting using your Facebook account. Log Out /  Change )

Connecting to %s