Server Software (C++, Palm)

Overview of the Bluetooth & Infrared server application, operable on the Palm handheld

This is a brief overview of the administration server application on the Palm handheld.

The application is structured like this:
        Bluetooth server > Main application > Lego infrared interface

The main application acts like a centralized controller, receiving user commands from the client (cellphone) via Bluetooth and forwarding them through the IR transceiver
to the Lego RCX computer, as RCX-interpretable opcode (Operation code; an instruction that the Lego computer understands) IR samples.

This section provides a little more detailed information about the different parts of the application.

This whole application was written in C++ using the PalmOS Developer Suite.

The Bluetooth Server
The Bluetooth wrapper server on the handheld consists of several classes that form a stable base on which one could easily build new extensions for different uses (i.e other protocol (Set of rules used to define a data transmission method) implementations, client implementations, etc):

  + BtServerBase
    + BtRFCOMMServer 
       + MobileRobotics


BtBase is an abstract class with pure virtual methods providing the most basic functions for Bluetooth radio initialization among other things. It is from this class that one can derive server and client implementations.

BtServerBase is an example of an abstract (protocol-less) server implementation. This class provides expected basic server functions that must be implemented in derived, protocol-dependent implementations.

BtRFCOMMServer is a protocol-independent socket (A socket through which network connections may be initiated) implementation of BtServerBase. It allows for a Bluetooth server application through the RFCOMM serial protocol (stream-based) and the choice for our application. One can use this class as it is, as it automatically handles incoming clients with default functions. One should derive applicationspecific classes from this class and override the default methods for client handling etc.

MobileRobotics is our application-specific implementation of the BtRFCOMMServer class. It overrides default handling methods for incoming data among other things, and manages the infrared interface in order to forward incoming commands. The main application code in turn controls this class.

BtDevice encapsulates a single Bluetooth device (name, address, etc).

BtSocketPair simplifies server and client socket communications by pairing them.

BtDataPacket is used in data transfers, for a simple and effective way of encapsulating and sending any type of data.

BtCustomEvent is a custom application event used to communicate pending operations to the main application code.

We are using a socket approach to our structure, and RFCOMM as the communications protocol as stated above. The server application flow looks something like this:

] Main application initializes Bluetooth server
] Bluetooth server classes initialize the Bluetooth radio and wait for result
] Main application receives radio initialization result and continues to start the server
] Server does maintenance; retrieves local device information and reports result
] Server continues to set up a socket that is used to listen for incoming client connections
] Application enters idle mode waiting for clients to connect
] When a client connects, the listening socket is paired up with the incoming
connection if there is room
] Server puts inbound and outbound sockets in a list and opens a new listening socket

The infrared interface
The infrared interface to the Lego RCX is controlled by the MobileRobotics class, which also is a part of the Bluetooth server itself. The class used to control the ir transciever is only one:

Here is some background information regarding the Lego infrared
device and protocol:

RCXInterface uses the OmniRemote developer kit to emulate the Lego
RCX consumer infrared transceiver (see reference section)

Ir settings used by the Lego RCX ir transciever: 2400 baud, 72/76kHz, odd parity, 1 stop bit, 8 data bits, invert data, LSB first

Basically this is how a Lego Protocol packet looks like:

0x55 0xff 0x00 O1 ~O1 O2 ~O2 .. On ~On S ~S

Where the first three bytes (the header) are constants The following n bytes are the Opcodes/instructions for the RCX to execute The last byte is the checksum, the sum of all the opcode bytes

NOTE: All opcodes are followed by their complement, as is the

You may only send the same opcode packet twice in a row if you toggle the 0x08 bit in the opcode being sent (the RCX doesn't execute the same opcode twice in a row)

The RCX immediately echoes the sent packet, with the bytes backwards.

The OmniRemote library developer kit used is a set of functions provided in order to be able to emulate the correct Lego RCX consumer ir, which PalmOS natively does not. The
RCXInterface class is a passive class, used by MobileRobotics to build ir packets, send packets and receive packets through the transciever.

The basic application flow for the whole system looks something like

[ The Bluetooth connection retrieves a data packet through a client socket
] Code in the MobileRobotics class interprets the user command sent and forwards it to the Lego RCX

The RCX sensor programming
The Lego RCX comes with various sensors for one to control and read from. We use a touch sensor in the main steering system which triggers when the front wheels are centered. In such a case, the RCX will be instructed to shut off that particular engine controlling the steering to be able to perform a straight ahead steering. This program is written in NQC, a language written by Dave Baum, and then downloaded to the RCX and run. The program is active the whole session. Another program is available for manually overriding the power up / down function, in case of connection loss.

The Palm Pilot server application GUI consists of one large text field in which various debugging information is shown such as Bluetooth status and clients connecting, as well as received commands. Battery level meters for both the Palm Pilot and the RCX are available and displayed on screen at all times. There are also two connection status icons available for the Blutooth and IR connection, respectively. They show "ok" when connection is established and "--" when there is an error with the connection.

The client/server connection between the cellphone and the Palm Pilot works actually quite nice, with a few unexplainable interrupts causing the connection to fail. This is probably because of an overload in data transmission.The RFCOMM protocol is credit based (this is specific to the Palm Pilot Bluetooth library) i.e you need one credit for each data transmission - both inbound and outbound. Replies from the RCX back to the Palm Pilot is unreliable, but plausible. We use it only when retrieving the RCX battery level in millivolts. Also, it has been concluded that when trying to receive an IR transmission with the OmniRemote Library when there is no active communication the Palm Pilot application freezes and needs a reset. For full source code, se the appendix section and the end of this document.

Links - RCX Internals, the place for RCX programming - Lego Mindstorms Internals, another big resource - Official site of OmniRemote, which made this project possible - Discusses the Lego IR protocol in C++ - PalmOS official site with documentation and forums - NQC, an RCX programming language - Interesting Bluetooth programming forum - Palm Programming FAQ

A note on compilers
Programming PalmOS is tedious. It's HELL. But with the right developer environment you'll be one step ahead. I used the PalmOS Developer Suite ( which is a setup for the popular Eclipse developer environment. It can manage your make files and resources quite nifty. The biggest problem is handling multiple text sections, when you write too much code, since there's a 64kb barrier per section I believe. Therefore I've gathered my experience about configuring the PalmOS Developer Suite and working with multiple code sections in this article. Hope it helps!

If you produce more code than allowed in the current section you'll get compiler errors telling you that the "text section or segment is too large". What you need to do is to define a new section and tell the compiler to put the rest of the code within that. You can define more sections if you need even more space. I had to use one extra section in the mobileRobotics server application.

To define new sections, you must first create (or edit) a section definition file and put it where the compiler can find it. Just create a new text file and name it "sections.def".

Now, within the definition file there are several options one might define and use but I'll only cover the means necessary to provide extra code sections. First we need to supply the application name and the associated developer id. I'll use the file I used for mobileRobotics as an example:

application { "MobileRobotics" dev_ }

Now we'll define the new section(s):

multiple code { "ext1" }

The only thing one needs to provide is a name for the section, in this case it's very intuitive and creative: "ext1". You'll reference this name later in your code.

So to define two new sections the file would look like this:

application { "MobileRobotics" dev_ }
multiple code { "section1" "section2" }

You may also include standard C/C++ comments in this file.

Now we need a header file to reference these new sections in order to be able to use them. The only thing we need to do is to provide a #define for each segment we previously defined. In our case it would look like this (from the sections header file):

#define EXT_SEG __attribute__ ((section("ext1")))

Where EXT_SEG is the name of the defined value and "ext1" is our section name previously chosen.

Finally we're ready to put it to use. You only need to put the FUNCTION OR METHOD PROTOTYPES in the extra section, the BODY OF THE FUNCTION OR METHOD IS AUTOMATICALLY PLACED THERE. So to show an example, I'll grab something right out of the mobileRobotics server source code (from the RFCOMMServer header file):

virtual Boolean init(Char *serviceName, UInt16 maxNumClients, Boolean advanceCredit) EXT_SEG;

As you can see this applies to methods as well as functions. The class needn't be defined to an extra segment nor does its attributes, only its METHOD PROTOTYPES.

Read more here: Logo  
Page viewed times mobileRobotics is powered by Source Forge