Three Modes of Operation
The RaspiBrick firmware has been designed to support essentially 3 different programming modes:
- Python programs running locally on the brick
Called Autonomous Python Mode
- Java Programs running locally on the brick
Called Autonomous Java Mode
- Programs written in any programming language (Python, Java, C#, C/C++, Objective-C, Scratch, etc.) running on a remote device (PC, Smartphone, Raspberry Pi, Arduino, etc).
Called Remote Python Mode, Remote Java Mode, etc.
Moreover there are tools to download and start the autonomous programs without the need of a file transfer utility nor a remote SSH terminal/virtual desktop. With RaspiBrick you can build a real autonomous robot that runs applications without any locally or remotely attached device.
RaspiPyLib: The Kernel Robotics Library written in Python
Because the language of choice for the Raspberry Pi is Python (accessing low-level C routines), a Python Library RaspiPyLib was developed that uses the well-known Python modules for the GPIO and camera ports. Some third party Python code from Adafruit and others for the I2C and PWM support are integrated. They are taken as is without any modifications.
RaspiPyLib has the same neat object-oriented design like other libraries developed during the recent years for the Lego NXT and EV3 robotics hardware (NxtJLib, EV3JLib) with the difference that these older libraries are written in Java.
RaspiPyLib shields the user from the low-level code to access the GPIO, the I2C and camera devices. So Python scripts are simplified by an order of magnitude to run simple robotics applications like rotating a motor, displaying information on the 7-segment display or reading I2C- based sensors.
RaspiJLibA: A Failed Approach
Because we used Java for many years in our robotics classes with pleasure and success, and also because there are many colleagues all over the world that like our OOP based Java robotics libraries for the Lego NXT and EV3, we wanted to support Java on the RaspiBrick robot too. It is obvious to apply the same software design as for Python: The well-known Java GPIO Pi4J library (based on JNI) makes the link between the hardware and our Java library.
The work was almost accomplished when we realized that the support for the ultrasonic sensor failed, because pulse length of around 1 ms must be measured with high precision. This is just an impossible task for Java SE because of the overhead of internal processes and the JNI. So we had to look for another solution to support Java.
BrickGate: A TCP/IP Socket Server Gateway
The idea was to still use the successful Python RaspiPyLib library, but link it to Java by a TCP/IP socket client/server. A socket server called BrickGate written in Python runs locally on the brick and uses RaspiPyLib to access the hardware. BrickGate listens for IP clients connecting to a specific IP port (1299). Once connected, the client sends coded information to the BrickGate server (typically commands for the actuators) and reports results (typically sensor values). Because an IP localhost connection can be used, Java and Python can run at the same time on the same system.
The advantage if this concept is evident: Because an IP link is used, the client may either run on the brick itself or on a remote client located anywhere on the Internet and written in any programming language that support TCP/IP clients.
BrickGate: Command Protocol
The BrickGate server is fully written in Python and uses the classes of the RaspiBrick Python library extensively. The program behaves like an autonomous Python robotics program with the addition of a socket server and a parser that interprets and executes the incoming commands.
All communications from the client to the BrickGate server (called commands) and back to the client (called responses) use a human readable text based protocol (strings). Commands consist of 2, 3, 4 or 5 fields separated by a colon and must be terminated by a newline character (the linefeed character is used on the server side as end-of-command indicator). The general format is:
|Left DC motor, right DC motor
|Servo motor at header
S12, S13, S14, S15
|svo0, svo1, svo2, svo3
front left, front right, rear left, rear right
|lss0, lss1, lss2, lss3
The param fields may be omitted or set to n, if no parameter is needed. Prior to invoke a method of a device, the device object must be created by sending
(with the exception of the robot device, that is always created by default)
The method and parameter fields corresponds to the autonomous Python library and are invoked by calling the Python eval() function. Example:
The command gear.forward(2000) is sent by the client program as "gear.forward.2000" . The BrickGate server splits the fields, creates a new Gear object gear (if not yet done) and invokes eval("gear.forward(2000)").
As you see this is similar to remote method invocation (RMI), The BrickGate server in Java uses reflection for the same task.
Every command execution will be confirmed by the server by sending back a response string. Until the response is received no other command should be sent to the server. This provides a simple handshaking between client and server. The response is normally an integer in string format with the following meaning:
(converted to int)
|Data from a sensor
||Command successfully executed
||Instance creation failed
If the command invokes a method with a boolean return type, the response is "0" for false and "1" for true.
A Linux Console For Testing Remote Commands
For testing purposes and during development of your own direct mode client library, a console program where you can send single commands and get the responses may be of great help. As a generic hint how to develop direct-mode programs in any programming language, refer to the following program written in good-old plain-C:
void error(const char *msg)
int main(int argc, char *argv)
int sockfd, portno, n;
struct sockaddr_in serv_addr;
struct hostent *server;
if (argc < 3)
fprintf(stderr, "usage %s hostname port\n", argv);
portno = atoi(argv);
sockfd = socket(AF_INET, SOCK_STREAM, 0);
if (sockfd < 0)
error("ERROR opening socket");
server = gethostbyname(argv);
if (server == NULL)
fprintf(stderr, "ERROR, no such host\n");
bzero((char *)&serv_addr, sizeof(serv_addr));
serv_addr.sin_family = AF_INET;
serv_addr.sin_port = htons(portno);
if (connect(sockfd,(struct sockaddr *) &
serv_addr,sizeof(serv_addr)) < 0)
printf("Please enter a command: (^C to quit): ");
fgets(buf, 255, stdin);
n = write(sockfd, buf, strlen(buf));
if (n < 0)
error("ERROR writing to socket");
int done = 0;
int k = 0;
n = read(sockfd, buf, 255);
if (n < 0)
error("ERROR reading from socket");
if (buf[n - 1] == 10)
done = 1;
for (i = 0; i < n; i++)
response[k + i] = buf[i];
k += n;
printf("Response: %s\n", response);
Under Linux/MacOS you compile the program in a terminal using the built-in gcc command line compiler:
gcc client.c -o client
and execute it with
./client 192.168.0.5 1299
A Java Terminal For Testing Remote Commands
Here a version in Java using the convenient Console window from the ch.aplu.util package. Every command execution also reports the response time, so you can convince yourself that the system is fast enough to be used in most robotics applications.
public class RaspiClientConsole
class StreamReader extends Thread
private InputStream is;
public StreamReader(InputStream is)
this.is = is;
public void run()
String response = "";
response = readResponse(is);
catch (Exception ex)
System.out.println("Exception in readResponse: " + ex.getMessage());
int rc = 0;
rc = Integer.parseInt(response);
catch (NumberFormatException ex)
if (rc >= 0)
System.out.print("Response: " + response);
System.out.println(" in " + timer.getTime() / 1000 + " ms");
System.out.println("Response (error): " + responseMsg[-rc]);
private String readResponse(InputStream is) throws IOException
if (is == null)
byte buf = new byte;
ByteArrayOutputStream baos = new ByteArrayOutputStream();
boolean done = false;
int len = is.read(buf);
if (len == -1)
throw new IOException("Stream closed");
baos.write(buf, 0, len);
if (buf[len - 1] == 10) // \n
done = true;
String s = baos.toString("UTF-8");
return s.substring(0, s.length() - 1); // Remove \n
String responseMsg =
"OK", "SEND_FAILED", "ILLEGAL_METHOD",
"ILLEGAL_INSTANCE", "CMD_ERROR", "CREATION_FAILED"
private int port = 1299;
private OutputStream os = null;
private InputStream is = null;
private HiResTimer timer = new HiResTimer();
ch.aplu.util.Console c = new ch.aplu.util.Console();
c.print("IP address? ");
String ipAddress = c.readLine();
System.out.println("Trying to connect to " + ipAddress);
Socket s = new Socket(ipAddress, port);
os = s.getOutputStream();
is = s.getInputStream();
StreamReader sr = new StreamReader(is);
String command = "";
command = c.readLine();
if (command.length() == 0)
catch (Exception ex)
private void sendCommand(String cmd) throws IOException
if (cmd == null || cmd.length() == 0 || os == null)
throw new IOException("sendCommand failed.");
cmd += "\n"; // Append \n
byte ary = cmd.getBytes(Charset.forName("UTF-8"));
public static void main(String args)
Execute the program locally using WebStart
Your find information about all classes and their methods here.
At the moment three remote libraries are available (download see right column). If you want to implement a remote library for another programming language, the easiest way is to download and port the Python or Java library.
- RaspiPyLib (Python V2.7)
- RaspiJlib (Java)
- RaspiAndroidLib (Java for Android)