May 14th 2011
I’ve been put onto an interesting project recently, doing some embedded Python development for a Telit GM862-GPS unit. Being new to this type of thing it took me a while to get a development environment set up that I was happy with. In an effort to share what I’ve learned, here’s my setup:
(To be clear I’m using the Roundsolutions development starter kit for the Telit GM862-GPS with my Macbook pro.)
First of all I had to install the usb-serial driver (PL2303_1.2.1r2.dmg) to get the serial port working. Once that’s installed and it’s connected the serial device /dev/tty.usbserial appeared for use.
Next I followed this guide and connected to the device using the GNU Screen command that’s included with Snowleopard. This command worked nicely:
screen -S telit -T vt100 /dev/tty.usbserial 115200,crtcts,-parity,-cstopb
Typing AT returned OK and I knew I was in business!
I soon found that deploying code over serial manually was pretty tedious, it’s easy to mess up the AT commands. I wrote this script to automate the process, making deployment as easy as
telit-send-python.py telit example.py.
The next issue I hit was that my code was sometimes being crapped up during transfer. I eventually figured out I was using the wrong line terminators for my files, Unix style just uses \n where as the Telit module demands \n\r (DOS style). To convert my files in Emacs I used the buffer-file-coding-system command, so
M-x set buffer-file-coding-system undecided dos.
Next I realised backspace wasn’t being transmitted properly across Screen, there’s an option in the Advanced section of Terminal preferences “Delete sends Cntrl-H” which resolved it for me. Unfortunately I found it messed up my normal SSH sessions, a better solution is to have this fixed in GNU Screen, add these lines to your ~/.screenrc:
bindkey -d ^? stuff ^H bindkey -d ^@ stuff ^H
Another annoyance with Screen was that I wasn’t able to scroll up like normal in my Terminal windows. Luckily fixing that was pretty easy, I added this to my ~/.screenrc :
termcapinfo xterm* ti@:te@
Messing with SMS at commands I realised that the body of a SMS needs to be terminated with 0x1a, it bit tricky to type but there’s a solution, Screen’s “digraph” feature. To send 0x1a here’s what I did:
C-a C-v 0x1a.
So the next thing I really wanted to was to get the Telit version of Python running locally, allowing me to test things interactively at a ‘REPL’. The units run a modified version of Python 1.5.2 and unfortunately I had no luck compiling or installing a version that old under Snowleopard. My solution in the end was to install the Windows version TelitPy1.5.2+_V4.1.exe using Wine. I then set up a little shell-script shortcut to launch it easily. (It installs to ~/.wine/drive_c/Program\ Files/Python/python.exe )
Now I’ve got a pretty sweet set up, but having the PCB dangling off the side of my Macbook in Starbucks isn’t really an option. So I plugged it into my Linux server at home and then I can SSH in and deploy code / interact with the Terminal. (Using Emacs’ tramp feature I can edit the code directly over SSH too.)
Only thing worth noting is that the naming convention for serial devices seems different in Linux. Also I found that sometimes the LANG environment variable ended up corrupting the binary transfer. Here’s the Screen command I ended up using:
unset LANG && screen -S telit -T vt100 /dev/ttyUSB0 115200,crtcts,-parity,-cstopb.
Read the Stty man page for details about those serial options at the end.
I also sometimes needed to check what Screen’s really sending out, helpful for debugging problems with transmitting binary data. It’s not hard though, just start a Screen session and run this command inside it:
stty raw; cat > binary-file-name.
(Just make sure to exit using the C-a :quit screen command rather, most special keys will be sent directly through into your file.)
Finaly while I’m waiting for the Python debugging board to arrive I needed to have some way of getting output through to the serial port. Otherwise it’s hard to know if your code even ran at all. Turns out it’s not too hard, here’s a (noddy) example:
import SER, MOD, MDM, GPS, sys # Set the baud rate SER.set_speed('115200', '8N1') # Send stout and stderr over serial # http://forum.sparkfun.com/viewtopic.php?t=6289 class SerWriter: def write(self, s): SER.send(s + '\r') sys.stdout = sys.stderr = SerWriter() # You get the idea... print "Lovely stuff"
Thanks for reading, I’d be interested to hear how any tips you’ve got in the comments. Also if anyone knows a better support forum / community than the Roundsolutions one let me know.
Edit: I’ve just discovered Sparkfun’s evaluation board. The board looks a lot nicer, it’s cheaper and Sparkfun actually list prices and stock. I’ve just been browsing their forum and it’s way friendlier too, I would definitely go with Sparkfun over Roundsolutions if you get the choice.
Edit 2: I’ve had all sorts of problems uploading Python scripts larger than about 7kb to the Telit module. In the end I updated my script to send files in chunks with enough delay for the module to catch up. I also had problems deleting large files until I removed the quotes around a file name. Much much more details on this forum post.
Edit 3: I’ve just been shown this great guide about Telit Python development, well worth reading.