They Can Talk?

The next big hurdle in this DIY chartplotter project (which I need to name, because that’s too long to type), is to get the Raspberry Pi microprocessor to communicate with the Arduino motor control unit in the stern.

After talking to a few people, including Al Thomason (who has much more experience in Arduino and microprocessors than I), I have decided that the communication architecture will be NMEA 0183 over the I2C bus. I chose NMEA 0183 is a very easy, standardized messaging protocol, with many devices supporting it. It makes sense that this project, in the end, should be able to communicate with other devices. The new NMEA 2000 format has all sorts of political and copyright issues that I don’t want to deal with until it gets figured out by others. I chose I2C because it’s only 3 wires, and you can have over 100 devices on the bus (ignoring details like capacitance, interference, and device support). With a repeater, or something similar, the distances between devices shouldn’t be a problem either.

So, with that in mind, I decided to perform a test to see if I could get the Arduino device and the Raspberry Pi device to communicate with each other. For this test, the communication is going to be “backwards” – that is, the Arduino is going to send a message to the Raspberry Pi, rather than the other way around.

Borrowing heavily from pages on the web , I wrote a simple Arduino sketch that counts from 0 to 360 and back to 0 again, every second, infinitely, to generate a fake compass heading. I then generate an NMEA $HCHDG sentence with that heading inserted – once consumed by OpenCPN, the heading should slowly rotate around the compass rose back and forth. The code for the sketch is here:


#include <Wire.h>

#define SLAVE_ADDRESS 0x04
int heading = 0;
bool increasing;
String buffer;

/*
    Setup Method
*/
void setup()
{
    //Setup Arduino for I2C Slave
    pinMode(13, OUTPUT);
    Serial.begin(9600);
    Wire.begin(SLAVE_ADDRESS);
    Wire.onReceive(receiveData);
    Wire.onRequest(sendData);

    Serial.println("I2C Configured");

    //Setup communications
    buffer = "";
    increasing = true;
    heading = 0;

}

/*
    Loop Method
*/
void loop()
{
    //Get compass heading
    getHeading();

    //Send Compass heading message across wire
    sendData();

    delay(200);
}

/*
    Method to receive data across I2C Bus
*/
void receiveData(int byteCount)
{
    while (Wire.available())
    {
        char c = (char) Wire.read();
        buffer += c;
        if (buffer.endsWith("\r\n"))
        {
            Serial.println(buffer);
            buffer = "";
        }
    }
}

/*
    Method to send data across I2C bus
*/
void sendData()
{
    Wire.beginTransmission(SLAVE_ADDRESS);
    Wire.write(getNMEA());
    Wire.endTransmission();
}

/*
    Method to return current heading as an NMEA0183 HCHDG message
*/
char *getNMEA()
{
    char nmeastr[32] = "$HCHDG";
    char intStr[8];

    strcat(nmeastr, itoa(heading, intStr, 10));
    strcat(nmeastr, ",,,,");

    //Generate checksum
    int checksum = 0;
    for(int i=0; i&lt;strlen(nmeastr); i++)
    {
        checksum ^= nmeastr[i];
    }

    strcat(nmeastr, itoa(checksum, intStr, 10));
    strcat(nmeastr, "\r\n");

    Serial.println(nmeastr);
    return nmeastr;
}

/*
    Method to get the current compass heading
*/
void getHeading()
{
    //TODO: Pull from digital magnetometer device. Currently just makes up a heading
    if (increasing)
    {
        if (heading < 360)
        {
            heading++;
        }
        else
        {
            increasing = false;
        }
    }
    else
    {
        if (heading > 0)
        {
            heading--;
        }
        else
        {
            increasing = true;
        }

    }
    Serial.print("Current Heading : ");
    Serial.println(heading);
}

As for the physical connection between the devices, I decided to go with standard CAT-5 cable. I had a couple extra breakout boards for Ethernet jacks, so I wired those up directly to the SDA and SCL lines on both devices, using only three of the 8 wires available:

IMG_20130829_104530

Now, to see if they can talk.

References:

Advertisements

Leave a Reply

Fill in your details below or click an icon to log in:

WordPress.com Logo

You are commenting using your WordPress.com account. Log Out / Change )

Twitter picture

You are commenting using your Twitter account. Log Out / Change )

Facebook photo

You are commenting using your Facebook account. Log Out / Change )

Google+ photo

You are commenting using your Google+ account. Log Out / Change )

Connecting to %s

%d bloggers like this: