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
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
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.
|