Pages: [1]   Go Down
Author Topic: Using Arduino libraries and classes on PCs - designing remote procedure call  (Read 1277 times)
0 Members and 1 Guest are viewing this topic.
Central MN, USA
Offline Offline
Tesla Member
***
Karma: 73
Posts: 7197
Phi_prompt, phi_interfaces, phi-2 shields, phi-panels
View Profile
WWW
 Bigger Bigger  Smaller Smaller  Reset Reset

I have experience using OOP and I appreciate its encapsulation, polymorphism, and inheritance. What I want to achieve is OOP across the boundary between different processors. Say I have one arduino and one PC. I develop class code for Arduino. Fine, done that many times. Then on the PC side I want to create some instances of parallel objects and interact with them, although the functionality only exists with Arduino, say RTC or character LCD. I wanted to do, on PC:

RTC rtc;
LiquidCrystal lcd(2,3,4,5,6,7);

So later I may do, on PC,
date=rtc.get_epoch();
lcd.println(date); and expect the LCD connected to Arduino to print date.

You may ask why I would want that on a PC?! The answer is two fold:

Re-usability of Arduino library. For instance if I decide to use a raspberry pi for a project and I need hardware such as an RTC and LCD, I don't have to search or write RTC or LCD library for raspberry pi, or such library for the pi to tell Arduino to do RTC or LCD. Instead I just use the Arduino libraries. This will save lots of time.

Portability of the main project developed on the PC/pi. If I do decide to write a library for raspberry pi then what happens if I move to a different system, such as a small laptop, for its processing power? If I can just use the Arduino library instead, the main project code needs no change.

To make this work, I imagine there has to be a pipe or socket. On one side is Arduino, having lots of classes. On the other side is PC, having parallel classes. A messaging function on the PC side is called every time a parallel class function is called. A message is assembled and sent to arduino, where the actual hardware and library are. Then a function on arduino side decodes the message and executes it by calling the proper method on instance. My initial thought of implementing OOP across processors, lacking a better term, is to implement a high speed messaging system between the host (PC/pi) and the Arduino via UART. The Arduino will decode the messages and executes LiquidCrystal * lcd=LiquidCrystal(2,3,4,5,6), then when another message asking the lcd to print, it will use lcd->print.

So my questions:

Have someone done something similar? I know about the firmata but that is not nearly as complex as what I am trying to do.

Is there a term for such thing? OOP socket? I think ANSI escape sequence is essentially like what I described, calling various functions to influence the behavior of a screen.

Thanks.
« Last Edit: June 03, 2013, 11:11:04 am by liudr » Logged


North Queensland, Australia
Offline Offline
Edison Member
*
Karma: 70
Posts: 2171
View Profile
WWW
 Bigger Bigger  Smaller Smaller  Reset Reset

I think I'm getting what you are intending.

Before you go making many libraries for loads of platforms, consider using an Ethernet shield with the Arduino rather than serial. Ethernet is a common interface already implemented on things like the Pi and PC, also using TCP gives an added level of reliability, and allows things like browser-based apps, which have all the perks a web-server has to offer ( database interactivity, large file system, many CPU's ).

Like you said, you will need to turn the Arduino sketch into a wrapper for the LCD display which ever method you take. But as a standard for performance, try and allow batching of commands on both the client and Arduino side.
This will allow less talk time overhead, and you can leave the Arduino with large work sets, similar to how the traditional GPU's work.

As the Arduino implements no object model ( Windows uses COM interfaces for example ), its not really an OOP situation as there is nothing to guarantee anything about the implementation on either side of the communication, only the data sent.

The client code ( Pi or PC ) can implement the same methods as the LCD class, but there is nothing enforcing it.
Logged


Central MN, USA
Offline Offline
Tesla Member
***
Karma: 73
Posts: 7197
Phi_prompt, phi_interfaces, phi-2 shields, phi-panels
View Profile
WWW
 Bigger Bigger  Smaller Smaller  Reset Reset

So essentially function calls over TCP? Sounds like a good way to go. I think the error handling is much better than serial. So if I used official arduino ethernet shield, how much buffering does the shield offer, if I implement batch commands? I have no idea if the TCP implements flow control so that the receiving end tells the sending end to pause when receiving buffer is full.
Logged


Global Moderator
Dallas
Online Online
Shannon Member
*****
Karma: 207
Posts: 12921
View Profile
WWW
 Bigger Bigger  Smaller Smaller  Reset Reset

Have someone done something similar? I know about the firmata but that is not nearly as complex as what I am trying to do.

I think Bitlash has similar functionality.

Quote
Is there a term for such thing?

Yes.  Remote Procedure Call / RPC.  There are dozens (hundreds?) of variations.  You may even be able to find a ready-to-use CORBA (ORB) for Atmel processors.
Logged

Central MN, USA
Offline Offline
Tesla Member
***
Karma: 73
Posts: 7197
Phi_prompt, phi_interfaces, phi-2 shields, phi-panels
View Profile
WWW
 Bigger Bigger  Smaller Smaller  Reset Reset

Thanks. I think remote procedure call is a pretty accurate term for what I wanted to do. I had read a brief description of cobra on wiki. It seems to be not very well designed and implemented. I did get a few ideas though. For example, the use of TCP connection (as recommended by pYro_65), the use of URI for resource, and human-readable formats etc. I am thinking about rewriting my HTTP GET URI interpreter anyway so I am thinking about using this rewritten interpreter to translate the message from a client (PC/PI) for the host (Arduino). A typical message to set cursor of lcd instance #0 could read:

CALL /lcd.0.setCursor?col=2&row=1

Then the interpreter will store the lcd.0.setCursor in URI string, and the key value pairs in keys[][] and values[][] and indicate the number of pairs with params=2.

When this is passed to the next function, it validates the lcd class exists, the #0 object exists, and setCursor is a valid method name for lcd class.

After that an lcd.rpc is called to make the actual lcd[0]->setCursor() function call after checking that the parameters match the function profile and parsing the values into integers etc.

Seems quite a bit of work but surely sounds to me that it is doable.
Logged


Central MN, USA
Offline Offline
Tesla Member
***
Karma: 73
Posts: 7197
Phi_prompt, phi_interfaces, phi-2 shields, phi-panels
View Profile
WWW
 Bigger Bigger  Smaller Smaller  Reset Reset

I found an RPC standard version 2 as RFC1831. It is only 19 pages and I seem to be understanding what it is describing! This standard is from 1995. Are there any newer standards?
Logged


Global Moderator
Dallas
Online Online
Shannon Member
*****
Karma: 207
Posts: 12921
View Profile
WWW
 Bigger Bigger  Smaller Smaller  Reset Reset

This standard is from 1995. Are there any newer standards?

Yes.  But, DEC was doing RPC (and doing it well) in the 60's and 70's so a standard from 1995 is at least two decades past DEC's success.  Don't discount it just because, from your current perspective, it seems "old".  If you understand it and it gives you what you want then use it.

DEC's version eventually became this... http://en.wikipedia.org/wiki/DCE/RPC  It has a very binary on-wire format which makes it a good choice for a microcontroller (small easy to decode packets) but it can be difficult to troubleshoot if you are implementing it from scratch (it sounds as though you are).

"Newer" RPC methods typically use a very text on-wire format (like XML) which makes it resource intensive for a microcontroller but are very easy to troubleshoot.
Logged

Sweden
Offline Offline
Sr. Member
****
Karma: 11
Posts: 451
View Profile
 Bigger Bigger  Smaller Smaller  Reset Reset

So my questions:

Have someone done something similar? I know about the firmata but that is not nearly as complex as what I am trying to do.

Is there a term for such thing? OOP socket? I think ANSI escape sequence is essentially like what I described, calling various functions to influence the behavior of a screen.
Hi!

Yes this is part of where I am going with the Cosa Arduino project. I see that you and others have already touched on the necessary components to make this happen. CORBA and RPCGEN are maybe the most well known middleware tools. To get this in place we need to allow different types of "communication media" (ranging from UART, I2C to Ethernet and WiFi), add a layer for reliable communication if not available (checksum, sequence numbers and retransmission), serialization, proxy and adapter library (ORB) and code generation of the interface.

In Cosa I have defined a serialization method (Ciao) which captures common C/C++ data types. This can be used for argument and result passing for remote procedure calls/method invocation.

For now I am working on the distribution of classes/functions over a set of Arduino's (e.g. Mega and Tiny's). And using Virtual Wire and TWI for low level communication. All code is by hand right now but the next step is to code generate from interface descriptions. Using the C++ class would be possible but they are not always suitable as a distributed interface (the CORBA dilemma). As reference you could look at the dtools research project (See the Cosa README and CIAO.txt for references and links).

A possible direction is to use OMG Data Distribution Service (DDS) and CORBA serialization (IIOP). Unfortunately this ORB infra-structure is not directly light weight and uses strings for method names but the technology of interface description language, code generation of adapters and proxy are reusable.

I envision (as you) "freely" partitioning software to run on several interconnected processors (such as moving LCD/OneWire handling to a ATtiny) while maintaining the same interface. This would also allow faster system composition with a different type of shields interconnected with high speed serial link(s) instead of "pins".

BW: If you are interested in graphics serialization X11 could be a starting point. The Cosa Canvas has a scripting language that would allow serialization, i.e. sending graphics commands over a serial line to another processor.

Cheers!

Links:
1. https://github.com/mikaelpatel/Cosa
2. http://cosa-arduino.blogspot.se/
3. http://dl.dropboxusercontent.com/u/993383/Cosa/doc/html/index.html
4. http://forum.arduino.cc/index.php?topic=150299.0
5. https://github.com/mikaelpatel/Cosa/blob/master/CIAO.txt
« Last Edit: June 03, 2013, 02:23:30 pm by kowalski » Logged

Central MN, USA
Offline Offline
Tesla Member
***
Karma: 73
Posts: 7197
Phi_prompt, phi_interfaces, phi-2 shields, phi-panels
View Profile
WWW
 Bigger Bigger  Smaller Smaller  Reset Reset

Thanks kowalski. Can I say that the ciao library will support message assembling and disassembling thus making it useful for constructing RPC interface?

Coding badly, I get it. The standard has been almost 20 years old but not obsolete. I plan to use this standard for some initial testing and learn my way into making a working RPC interface for Arduino.
Logged


Sweden
Offline Offline
Sr. Member
****
Karma: 11
Posts: 451
View Profile
 Bigger Bigger  Smaller Smaller  Reset Reset

Thanks kowalski. Can I say that the ciao library will support message assembling and disassembling thus making it useful for constructing RPC interface?
Yes! The class Ciao may be used to assemble messages (write). There is still parsing (read) to be implemented. And code generation from a description language. This can be done as an interpreter of the Ciao data type descriptors though a mapping to the function/method is needed. The type descriptors are also part of the Ciao data format. This allows schema of data structure to be transmitted as well. Please see the example sketches for Ciao and the messages for streaming Arduino pin values (as Firmata).

There is an overhead with Ciao even if it is small compared to IIOP/XDR  (byte prefix) and data is transmitted in native order for AVR (little-endian). This reduces the overhead when communicating with a PC/Intel host.

Cheers!
Logged

Offline Offline
Newbie
*
Karma: 0
Posts: 9
View Profile
 Bigger Bigger  Smaller Smaller  Reset Reset

Taking the original usecase from first message, there're actually few wrapper libraries which allow to control Arduino from host, including with high-level rapid-prototyping languages. What libraries differ in is of course hardware/protocols support. As an example, I can give my arduino-hosted project (Python). What distinguishes it from other similar libs I saw is faithful following of (basic) Arduino API, e.g.:

Code:
    def setup():
        pinMode(LED, OUTPUT)

    def loop():
        digitalWrite(LED, HIGH)
        delay(1000)
        digitalWrite(LED, LOW)
        delay(1000)

It uses BusPirate protocol to communicate with the board (and thus portable across at least few boards, like original BusPirate, and Arduino, MSP430 Launchpad which have BusPirate software work-alikes).
Logged

Pages: [1]   Go Up
Jump to: