Joining Raspberry Pi and Arduino applications with SIMPL
eightLeds.py Checklist
- 1. The tclSurrogate daemon must be up and running in the background on a known port number. The default port number=8000.
- 2. The environment variable
PYTHONPATH
must be set to the directory that contains the SIMPL python modules, such ascsimpl.py
.
To run this script on the Rasp Pi remotely from your other Linux box, you may use SSH; for example (note the uppercase X
),
ssh -X pi@10.0.1.32
where (in this case) pi
is the user and 10.0.1.32
is the local IP address of the Rasp Pi.
This Python SIMPL sender script may be run from the command line on the SSH console terminal as:
python eightLeds.py
Note that eightLeds.py
is compatible with Python versions 2 and 3.
If you are successful, you should see something like the picture in Figure 3.
When buttons are pushed on the GUI along with Send, the corresponding LEDs on the Arduino should illuminate.
Testing Using arduinoSim.py
Next, we'll discuss an important feature of a modular SIMPL application. Because each SIMPL module communicates via a well-defined messaging protocol, it is very easy to swap out modules for test stubs during the testing stage. We'll look at how this might work for testing our eightLeds.py
module without actually connecting an Arduino to the Rasp Pi.
This approach is also useful if you don't have an Arduino handy, but you still want to try out the demo.
In the test configuration, the Arduino sketch has been replaced by a Python application running on the Rasp Pi (Figure 4). This Python application uses the Python-SIMPL library tclSimpl.py
to connect into the SIMPL application via the tclSurrogate protocol in exactly the same way that the real Arduino sketch does.
The full listing of arduinoSim.py
is shown in Listing 3.
Listing 3
arduinoSim.py
01 #import required modules 02 import tclsimpl 03 import sys 04 if sys.version < '3': 05 from Tkinter import * 06 import tkMessageBox 07 else: 08 from tkinter import * 09 from tkinter import messagebox 10 11 # defines 12 BRINKY_RITE = 0 13 14 global leds 15 16 def deconstructMsg(nee): 17 # extract the incoming message 18 intoken,status = nee.unpackMsg(nee.BIN, "hb") 19 20 if intoken == BRINKY_RITE: 21 for num in range(8): 22 bit = 1 << num 23 if status & bit: 24 leds[num]["text"] = "ON" 25 else: 26 leds[num]["text"] = "OFF" 27 28 29 # define functionality to be performed whan a message is received 30 def hndlMessage(a, b): 31 # receive a message 32 messageSize, senderId = nee.receive() 33 34 if messageSize == -1: 35 # error 36 print("receive error") 37 sys.exit(-1) 38 39 # examine the message 40 deconstructMsg(nee) 41 42 # reply to sending program 43 retVal = nee.reply(senderId) 44 if retVal == -1: 45 print("reply error") 46 sys.exit(-1) 47 48 # define callback function when exit button is selected 49 def finish(event): 50 sys.exit(0) 51 52 53 #***** main part of program ****************************** 54 55 # constructor for simpl class object 56 nee = tclsimpl.Simpl("8000:localhost:ARDUINO") 57 58 # initialize Tk for graphics 59 root = Tk() 60 61 # get the receive fifo file descriptor 62 fd = nee.whatsMyFd() 63 64 # attach a callback for incoming simpl messages 65 root.tk.createfilehandler(fd, READABLE, hndlMessage) 66 67 rowframe = Frame(root) 68 rowframe.pack(fill=BOTH) 69 70 leds = [None] * 8 71 for num in range(8): 72 73 leds[num] = Button(rowframe, borderwidth=2, relief=SOLID, justify=CENTER, \ bg="Yellow", fg="Black", text="OFF", font=("Times", 12, "bold"), width=3) 74 leds[num].pack(side=LEFT) 75 76 # the bottom frame of buttons 77 rowframe = Frame(root) 78 rowframe.pack(fill=BOTH) 79 80 # build an exit button widget 81 button = Button(root) 82 button["text"] = "Exit" 83 button.bind("<Button>", finish) 84 button.pack() 85 86 # handle user input and simpl messaging 87 root.mainloop()
The first thing you might notice is the similarity to the eightLeds.py
code itself. Why reinvent the wheel? The key line in this test stub is line 56. Here we are telling the arduinoSim code to connect to the tclSurrogate port via the TCP/IP local host loopback socket. This allows arduinoSim.py
to run on the same node (Rasp Pi) as the eightLeds.py
code but still connect via the tclSurrogate daemon.
To run this test, simply start the arduinoSim as
python arduinoSim.py
on a console terminal (or an ssh -X
window). It is then simply a matter of running the eightLeds.py
code exactly as before. This code has no way to "know" that a stub is running in place of the Arduino. All the messaging interactions are identical, so a thorough test can be performed without changing a single line of the eightLeds.py
module.
Buy this article as PDF
(incl. VAT)