I’ve been put onto an exciting 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. 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 was installed 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 Snow Leopard. 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 since it’s easy to mess up the AT commands. So I wrote this script to automate the process, making deployment as easy as typing
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 uses
\n whereas 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 Ctrl-H” which resolved it for me. Unfortunately, I found that messed up my other 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 an SMS needs to be terminated with 0x1a, it’s a 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 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 Snow Leopard. 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 an option. So I plugged it into my Linux server at home, so then I could SSH in and deploy code / interact with the Terminal. (Using Emacs' tramp feature I can edit the code directly over SSH too.)
The 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 sending out, helpful for debugging problems with transmitting binary data. It’s not hard though, start a Screen session and run this command inside it:
stty raw; cat > binary-file-name.
(Make sure to exit using the
C-a :quit screen command since most special keys will be sent directly through into your file.)
Finally, 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. It turns out it’s not too hard, here’s an 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 any tips you have 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 list prices and stock. I’ve had a look through their forum too, and it seems much friendlier. I’d go with the Sparkfun board over the Roundsolutions one next time.
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. For more details check out this forum post.
Edit 3: Someone has just shown me this great guide about Telit Python development, well worth reading.