RPC Interface Library

The RPC interface can be really useful because it makes it possible to interface with mbed without having to worry about the communication method. However, Many projects require more than just Digital and Analog I/O and want to make use of the mbeds interfaces or work with many of the libraries which have already been written for various sensors and actuators. This library provides a method of adding RPC functionality without you having to write any of the communication or RPC code. It is made up of 3 parts:

  • RPCFunction - A class which can be used to call user defined functions over RPC
  • RPCVariable - A class which allows you to read and write the value of a variable on mbed using RPC
  • SerialRPCInterface - A class which will set up RPC over Serial

Import libraryRPCInterface

Library to provide a mechanism to make it easier to add RPC to custom code by using RPCFunction and RPCVariable objects. Also includes a class to receive and process RPC over serial.

The mbedRPC software libraries such as for Java, Matlab and LABVIEW also support the RPCFunction and RPCVariable so as to simplify the connection on both the mbed and computer software.

RPCFunction

The RPCFunction object makes it possible to call a custom function over RPC. The function must be of the form void foo(char * input, char * output). To use you first create the function, you then create the RPCFunction object when you attach the function and give it a name by which it will be called over RPC. You might use the input and ouput strings to pass several numeric values by using sscanf and sprintf to read and write the input and output strings. Alternativly you might not need the strings and instead just call the function.

//Create a function of the required format
void foo(char * input, char * output);
//Attach it to an RPC object
RPCFunction rpc_foo(&foo, "foo");

void foo(char * input, char * output){
   int x,y;
   sscanf(input, "%i, %i", &x, &y);

   //Do something here......

   sprintf(output, "%i, %i", x, y );
}

To run this function over RPC you then call the run method on the RPCFunction object. The function you define can be used to wrap the common interactions with class methods that you wish to call over RPC.

Here is an example of it being used to return the value from an I2C Range finder. Using the RPCFunction has made the Rangefinder avaliable over RPC as its library doesn't include support for RPC.

Import program

00001 /**
00002 * Copyright (c)2010 ARM Ltd.
00003 * Released under the MIT License: http://mbed.org/license/mit
00004 */
00005 #include "mbed.h"
00006 #include "SerialRPCInterface.h"
00007 #include "SRF08.h"
00008 
00009 using namespace mbed;
00010 
00011 //Create the interface on the USB Serial Port
00012 SerialRPCInterface RPC(USBTX, USBRX);
00013 void ReadRange(char * input, char * output);
00014 RPCFunction RangeFinder(&ReadRange, "RangeFinder");
00015 SRF08 srf08(p9, p10, 0xE0);      // Define SDA, SCL pin and I2C address 
00016 DigitalOut myled(LED1);
00017 
00018 int main() {
00019 
00020     while(1) {
00021         
00022     
00023         myled = 1;
00024         wait(0.2);
00025         myled = 0;
00026         wait(0.2);
00027     }
00028 }
00029 
00030 //As neither I2C nor the SRF08 library is avalible directly over RPC we create a Custom Function which we make RPCable by attaching to an RPCFunction
00031 void ReadRange(char * input, char * output){
00032     //Format the output of the srf08 into the output string
00033     sprintf(output, "%f", srf08.read());
00034 }

Information

RPC command to read the range: /RangeFinder/run

A complete example using the range finder and software on a computer will be written up soon

Import libraryRPCInterface

No documentation found.

RPC variable

RPCVariable allows you to read and write the value of any variable on mbed. You do this by creating an RPCVariable object and then attaching the variable you want to access over RPC.

//First create the variables you wish to use
float f;
int i;
char c;
//Then attach them to an RPCVariable Object
RPCVariable<float> rpc_f(&f, "f");
RPCVariable<int> rpc_i(&i, "i");
RPCVariable<char> rpc_c(&c, "c");

Information

The RPC commands to read and write the float f would be:

  • /f/write 0.123
  • /f/read

Here is an example of this being used to control a Motor taking feedback from a QEI. None of the control is implemented on mbed, this must be done on the computer however this method has qucikly given the computer access to the Motor and QEI class neither of which are otherwise not avaliable over RPC

Import program

00001 /**
00002 * Copyright (c)2010 ARM Ltd.
00003 * Released under the MIT License: http://mbed.org/license/mit
00004 */
00005 
00006 #include "mbed.h"
00007 #include "QEI.h"
00008 #include "Motor.h"
00009 #include "SerialRPCInterface.h"
00010 
00011 //Create the interface on the USB Serial Port
00012 SerialRPCInterface SerialInterface(USBTX, USBRX);
00013 
00014 QEI Encoder(p29 ,p30, NC, 48);
00015 Motor Wheel(p23, p21, p22);
00016 
00017 //Create float variables
00018 float MotorOutput = 50;
00019 float Percentage = 0;
00020 
00021 //Make these variables accessible over RPC by attaching them to an RPCVariable
00022 RPCVariable<float> RPCMotorOut(&MotorOutput, "MotorOutput");
00023 RPCVariable<float> RPCPercentage(&Percentage, "Percentage");
00024 
00025 int main(){
00026 
00027     Encoder.reset();
00028     float NoPulses;
00029     
00030     while(1){ 
00031          NoPulses = Encoder.getPulses();
00032         Percentage = ((NoPulses / 48) * 100);
00033         //RPC will be used to set the value of MotorOutput.
00034         Wheel.speed((MotorOutput - 50) * 2 / 100);
00035         wait(0.005);
00036     }
00037 }

Information

  • rpc command to get the position: /percentage/read
  • rpc command to set the motor speed: /MotorOutput/write 0.8

A complete example of closed loop motor control using the code above and a computer running a software package will be written up soon.

Note that this is entirly asynchronous and so you could get unexpected results if the code on mbed and an interupt driven RPC handler both try to write different values to the variable at the same time.It won't be possible to predict which value has been written into the variable. As such it would be advisable to consider some variables as only written to over RPC and only read by mbed code and other variables the opposite.

The RPCVariable is well suited to the motor and QEI which can be updated whenever however the I2C Range Finder is better suited to the RPCFunction as every reading has to be requested from the device.

These two classes should help you to add RPC to projects which go beyond just reading and writing to mbed's pins. RPCFunction and RPCVariable interfaces are included in the software libraries so as with the rest of the RPC interface you can communicate with mbed without having to design and implement the communication protocol etc.

To avoid having to format your data into and out of strings both on mbed and in your software on the computer, but still have synchronous communication you could combine the RPCvariables and RPCFunctions. Here is the Range finder example using this approach:

float Range = 0;
RPCVariable rpc_range(&Range, "Range");

void RangeFinder(char * input, char * output){
 Range = srf08.read();
}

RPCFunction rpc_GetRange(&RangeFinder, "RangeFinder");

Information

To get the Range now requires 2 RPC commands:

  • /RangeFinder/run
  • /Range/read

This does mean that you have to make a few more RPC requests (and so your communication will be slower) but it could be useful if you want to avoid parsing strings either on mbed or in the software you are working with.

Import libraryRPCInterface

No documentation found.

SerialRPCInterface

SerialRPCInterface will set up RPC for serial by registering all the base classes and setting up the serial port on an intterupt. When a serial communication is recevied it will pass the commands to the RPC and return the response. This leaves your own code to run on mbed.

To use all you have to do is create it at the top of your program

SerialRPCInterface SerialInterface(USBTX, USBRX);

You can then write the rest of your code as required.

Import library

Public Member Functions

  SerialRPCInterface (PinName tx, PinName rx, int baud=9600)
  Constructor.
void  Disable (void)
  Disable the RPC.
void  Enable (void)
  Enable the RPC.