SimpleSerialization - serial communication for the Arduino/ArduPilot

I was searching for a way to exchange data between an Arduino/ArduPilot and a Java application. There are already several solutions to do this but none of them really met my requirements. So I decided to write a library that implements a mechanism called serialization/deserialization. The now called SimpleSerialization library allows you to define a data structure (or object) that will be converted into a stream which then can be sent via a serial connection.

Downloads
The distribution: SimpleSerialization-1.0.zip
The project page: code.google.com/p/simpleserialization.

What you can do with it
- debug an Arduino application in a very convenient way
- remote control an Arduino
- setup a hardware-in-the-loop simulation
- and more

An example SimpleSerialization application could be to feed an Arduino with GPS data at 5Hz and attitude data at 30Hz. In return the Arduino would send the calculated actuator commands back at a rate of 10Hz. All this data would be exchanged via a single serial connection.

Requirements
- an Arduino or ArduPilot
- a serial connection from a PC to the Arduino
- and additional 2KB of flash memory when used with the ArduPilot
- the Arduino IDE
- a Java IDE (e.g. Processing or Eclipse)



The SimpleSerialization library is part of my UAV Playground project where I explore various aspects of UAVs like microcontrollers, simulators and remote controlled model airplanes.

Views: 3349

Tags: ArduPilot, Arduino, C, C++, Java, communication, debug, deserialization, hardware-in-the-loop, serial, More…serialization


3D Robotics
Comment by Chris Anderson on June 5, 2009 at 4:47pm
Are you using the hardware serial port or software serial on any digital pin?
Comment by jaron on June 6, 2009 at 3:54am
I'm using the hardware serial port but from a software architecture's point of view it would be very easy to switch to any other serial interface or device. I wasn't very lucky with the soft serial approach.
Comment by Bryan Cuervo on June 6, 2009 at 4:36am
Jaron,
Thank you for your UAV Playground! I got it running this week and the UAVsim will be a big help in learning the effects of PID tuning. I want to try your SimpleSerialization next for hardware-in-the-loop simulation. Have you done this yet for your autopilot and tailess UAV?
Comment by jaron on June 6, 2009 at 2:27pm
You're welcome Bryan. I haven't done a hardware-in-the-loop simulation yet but the SimpleSerialization library is another step forward to an autonomous flight. Next I will start to implement some of the autopilot code from the UAVsim on an Arduino/ArduPilot and that's where the SimpleSerialization is becoming helpful.
I don't hesitate because I think that we'll see some interesting developments in UAV hardware in the near future. For example the Arduino Mega based ArduPilot that will better fit my style of programming.

3D Robotics
Comment by Chris Anderson on June 6, 2009 at 3:38pm
Yes, we've never got software serial to work reliably, either.
Comment by Zachary Long on June 9, 2009 at 12:38pm
Jaron, recently tried to use your SimpleSerialization with my own data structure but I am having some issues. I constructed my classes based off of your examples/source but I still have a few questions. I have posted my source code below, can you tell me what I am doing wrong ? Also can you explain the

Project goal: turn on and off two LEDS using a processing based interface and arduino

Arduino Code:

#include
#include "Message.h"

int greenLedPin = 7;
int redLedPin =8;
long connectionSpeed = 9600;
Message incomming;
Message outgoing;
long R_status=0;
long G_status = 0;
/*
* This is the callback function that is called whenever the data is updated.
*/
void dataUpdate(SerializationData *data)
{

if(((Message *)data)->getTitle() == "red_Set")
{
if (((Message *)data)->getData() == 1)
{
digitalWrite(redLedPin, HIGH);
R_status = 1;
}
else
{
digitalWrite(redLedPin, LOW);
R_status = 0;
}
// outgoing.setTitle("red_Status");
// outgoing.setData(R_status);
}
else if (((Message *)data)->getTitle()== "green_Set")
{
if (((Message *)data)->getData() == 1)
{
digitalWrite(greenLedPin, HIGH);
G_status = 1;
}
else
{
digitalWrite(greenLedPin, LOW);
G_status = 0;
}
}
}

void setup()
{
pinMode(greenLedPin, OUTPUT);
pinMode(redLedPin, OUTPUT);
incomming.setUpdateCallback(&dataUpdate);
SimpleSerialization.begin(connectionSpeed);
SimpleSerialization.addDeserializableData(&incomming);
}

void loop() {
SimpleSerialization.processInput();
}

Message.h :
/*
* This is the declaration of the Message class whose instance (object) is going
* to be serialized and sent via the serial connection.
*
*/

#ifndef _MESSAGE_H
#define _MESSAGE_H

#include "SimpleSerialization.h"

class Message : public SerializationData {
public:
int getDataSize();
void readData(SerializationInputStream& input);
void writeData(SerializationOutputStream& output);
char* getTitle() { return message; };
void setTitle(char *message) { strcpy(this->message, message); };
int getData() { return pi; }
void setData(int pi) { this->pi = pi; }
private:
char message[32];
int pi;
};

#endif /* _MESSAGE_H */

Message.cpp:
/*
* This is the definition of the Message class whose instance (object) is going
* to be serialized and sent via the serial connection.
*/

#include "Message.h"

int Message::getDataSize() {
int size = SerializationTypes::SIZEOF_INTEGER + strlen(message);
size += SerializationTypes::SIZEOF_FLOAT;
return size;
}

void Message::readData(SerializationInputStream& input) {
input.readString(message);
pi = input.readInteger();
}

void Message::writeData(SerializationOutputStream& output) {
output.writeString(message);
output.writeInteger(pi);
}

Processing Side:
/*
* Replace "COM4" with the serial port your Arduino is connected to.
* Replace 115200 with the baud rate your Arduino communicates.
*
* A very simple example that sends an integer value to the Arduino when the
* mouse is pressed or released. The Arduino then turns an LED on or off.
* Have a look at the Arduino SwitchLed example to see how the value is received.
*/

import jaron.simpleserialization.*;
import processing.serial.*;

String serialPort = "COM8";
int connectionSpeed = 9600;
SerializationSerialConnection conn;
Message mess;

int r_status=0;
int g_status =0;



void setup() {
// The Processing setup
size(200, 200);
frame.setTitle("LED Control");

// Initialize the serialization
conn = new SerializationSerialConnection(this, serialPort, connectionSpeed);
PFont font;
font = loadFont("text.vlw");
textFont(font);
background(0);
mess = new Message();
}

void draw() {

stroke(255,255,255);
if(g_status == 0)
{
fill(255,255,255);
}
else
{
fill(0,255,0);
}
String s = "Green LED";
rect(100,5,50,50);
text(s,100,70);

if(r_status == 0)
{
fill(255,255,255);
}
else
{
fill(255,0,0);
}

s = "Red LED";

rect(5,5,50,50);
text(s,5,70);
}
void mousePressed() {
// If the mouse is pressed then send 1 to the Arduino

if(mouseX > 5 && mouseX < 55 && mouseY > 5 && mouseY < 55)
{
if(r_status ==1)
{
r_status = 0;
}
else
{
r_status = 1;
}
mess.setTitle("red_Set");
mess.setData(r_status);
conn.write(mess);
delay(10);
//conn.read();
}
else if((mouseX > 100 && mouseX < 150) && (mouseY > 5 && mouseY < 55))
{
if(g_status ==1)
{

g_status = 0;
}
else
{
g_status = 1;
}
mess.setTitle("green_Set");
mess.setData(g_status);
conn.write(mess);
delay(10);
//conn.read();
}



}

Message.java:
/*
* This is the Message class whose instance (object) is going to be deserialized
* from the data that was sent via the serial connection.
*/

import jaron.simpleserialization.*;

public class Message extends SerializationData {
private String message = "";
private int pi;

public String getTitle() {
return message;
}

public void setTitle(String message) {
this.message = message;
}

public int getData() {
return pi;
}

public void setData(int pi) {
this.pi = pi;
}

public int getDataSize() {
int size = SerializationTypes.SIZEOF_STRING + message.length();
size += SerializationTypes.SIZEOF_FLOAT;
return size;
}

public void readData(SerializationInputStream input) {
message = input.readString();
pi = input.readInteger();
}

public void writeData(SerializationOutputStream output) {
output.writeString(message);
output.writeInteger(pi);
}
}
Comment by jaron on June 9, 2009 at 3:05pm
Replace
if(((Message *)data)->getTitle() == "red_Set")
with
if(strcmp(((Message *)data)->getTitle(), "red_Set") == 0)

and
else if (((Message *)data)->getTitle()== "green_Set")
with
else if (strcmp(((Message *)data)->getTitle(), "green_Set") == 0)

Have a look at this example: SimpleSerialization-Example-ToggleLEDs.zip
Comment by jaron on June 9, 2009 at 11:12pm
And if you are planning to define more than one class whose instances you want to send via SimpleSerialization, then make sure you set different pre- and postamble values for them. Have a look at the Timer class of the MultipleData example where it is shown how this is done (setPreamble and setPostamble).
This is not necessary if you are using multiple instances of the same class (Message: message1, message2).
Comment by Zachary Long on June 12, 2009 at 1:58pm
Jaron,

Is it possible to declare multiple instances of the SimpleSerialization each pointing at a separate serial port. Forgive the extra stuff in the code...

Thanks

EX:

SimpleSerialization serA;
SimpleSerialization serB;

void setup()
{

navD.setUpdateCallback(&navUpdate);
wayD.setUpdateCallback(&waypointUpdate);
servoD.setUpdateCallback(&servoUpdate);


serA.begin(&Serial,9600);
serB.begin(&Serial1,9600);


serA.addDeserializableData(&navD);
serA.addDeserializableData(&wayD);
serB.addDeserializableData(&navD);
serB.addDeserializableData(&servoD);


}

void loop() {

// read in from serial port
serA.processInput(); //xbee
serB.processInput(); //ardupilot
Comment by jaron on June 12, 2009 at 2:43pm
I haven't tried it yet but I don't see any reason why this shouldn't work. I've tried to keep the examples as simple as possible and that's why I didn't show the initialization with a different port.

It's nice to see people digging into the code and using the undocumented features!

Comment

You need to be a member of DIY Drones to add comments!

Join DIY Drones

Groups

Season Two of the Trust Time Trial (T3) Contest 
A list of all T3 contests is here. The current round, the Drone Delivery Challenge, is here

© 2014   Created by Chris Anderson.   Powered by

Badges  |  Report an Issue  |  Terms of Service