You are viewing an older revision! See the latest version

Interfacing with Python

Initial experiments with getting mbed talking with python using the pyserial extension...

Setup

On windows, installed python, win32 extensions and pyserial:

On Mac OS X (10.5 or later):

  • Python is already installed.
  • Run Terminal.app and type sudo easy_install pyserial at the prompt to install PySerial.
  • Also type ls /dev/tty.usbmodem* to find the device name of the mbed USB serial connection.

On Linux, or other unix-like:

  • Python is most-likely already installed; if not see your OS's install system or visit http://www.python.org/download/
  • In a terminal type sudo easy_install pyserial to install PySerial.
  • Also type ls /dev/ttyACM* to find the device name of the mbed USB serial connection.

Test the Connection

On Windows, connect to COM15 with default 9600 8N1 setting:

#!python
python
>>> import serial
>>> serdev = 15
>>> s = serial.Serial(serdev)
>>> s.write("hello")
>>> s.close()

or when on a Macintosh (in this case /dev/tty.usbmodem1912):

#!python
>>> import serial
>>> serdev = '/dev/tty.usbmodem1912'
>>> s = serial.Serial(serdev)
>>> s.write("hello")
>>> s.close()

or when on a Linux/unix system (in this case /dev/ttyACM0):

#!python
>>> import serial
>>> serdev = '/dev/ttyACM0'
>>> s = serial.Serial(serdev)
>>> s.write("hello")
>>> s.close()

Status light flickered. Cool!

For more basic info, see http://pyserial.wiki.sourceforge.net/pySerial

Python RPC Library

The mbed Libraries support RPC, which means you can create objects and control them remotely :)

Here are two examples of doing rpc from python over different transport mechanisms...

Python RPC via HTTP

First, we need a binary on the mbed which acts as an http server, converting http requests to rpc calls. This requires the HttpServer

Once this is on the mbed, plug it in to your home router and power it up. With the serial port enabled, it should show the i/f comping up, and print out it's ip address that was assigned via DHCP.

If you put this ip address in to a browser, followed by /rpc/, you should get a page showing the actions it can perform (e.g. http://192.168.0.4/rpc/). (you can also put an index.htm on the usb disk if you want, and it'll serve that at root).

Here is a first cut of a Python RPC library which uses the mbed RPC mechanism to map Python classes on to the mbed Library C++ Interface classes. We can use the mbed.py interface to talk to it over the network from a host pc...

e.g.

#!python
python
>>> from mbed import *
>>> rpc_http("192.168.0.4")
>>> x = DigitalOut(3) # LED3
>>> x.write(1)
>>> x.read()
1
>>>

Python RPC via Serial

We know how to make Python talk to Serial. So if we make a simple Serial to RPC bridge...

/* RPCSerial - RPC over a serial port transport
 * sford
 *
 * When running, you can send RPC commands to the mbed
 * via the serial port, to create and manipulate objects
 *
 * Example:
 * > "/DigitalOut/new,2\n"
 * > > "objXYZ\n"
 * > "/objXYZ/write,1\n"
 * > "\n"
 * > "/objXYZ/read"
 * > "1\n"
 */ 

#include "mbed.h"

Serial pc(USBTX, USBRX);

int main() {
	
	// setup the classes that can be created dynamically
    Base::add_rpc_class<AnalogIn>();
    Base::add_rpc_class<AnalogOut>();
    Base::add_rpc_class<DigitalIn>();
    Base::add_rpc_class<DigitalOut>();
    Base::add_rpc_class<PwmOut>();
    Base::add_rpc_class<Timer>();
    Base::add_rpc_class<SPI>();
    Base::add_rpc_class<SPI3>();
    Base::add_rpc_class<Serial>();
    Base::add_rpc_class<BusOut>();
    Base::add_rpc_class<BusIn>();

    char command[256] = {0};
    char response[256] = {0};

	// receive commands, and send back the responses
	while(1) {
		pc.gets(command, 256);
		rpc(command, response); 
		pc.printf("%s\n", response);
	}
}

Download this binary on to the mbed, and ensure the serial port is enabled (you can play directly using teraterm, as long as transmit is sent to LF+CR)

We can talk over a serial transport to the serial-to-RPC bridge we just made using the same mbed.py file as before...

#!python
python
>>> from mbed import *
>>> serdev = 15 # or '/dev/tty.usbmodem1912' for Mac or '/dev/ttyACM0' for Linux/unix
>>> rpc_serial(serdev, 9600)
>>> x = DigitalOut(3) # LED3
>>> x.write(1)
>>> x.read()
1
>>>

All wikipages