The hard work has already been done, first by the pioneering
efforts of Kees Verruijt at canboat , and now by the development of a NMEA2000 Arduino library by Timo Lappalainen.
I am using the NMEA2000 library with an Arduino Due board. The
Due has a built-in CAN controller (in fact 2 of them), missing only an external
CAN transceiver to get attached to a N2K backbone. With the arrangement
described below, I first ran the library example ‘TemperatureMonitor’, sending 2
fixed temperature values to the N2K network. The result can be seen in the
following screen capture of the B&G Touch 7 display, showing the sea and
cabin temperature values sent by this example.
I then proceeded to develop a replacement for the Actisense
NGW-1, which translates fast NMEA 0183 heading sentences to their equivalent
N2K PGN. For this, I also made use of the TinyGPS++ library, which takes care
of parsing the NMEA 0183 sentences.
All this is done with a deceptively short Arduino sketch (‘Heading
Converter’), which I reproduce in its entirety here.
// Convert fast heading data from NMEA 0183 to NMEA 2000
#include <Arduino.h>
#include <NMEA2000_CAN.h>
#include <N2kMessages.h>
#include <TinyGPS++.h>
TinyGPSPlus gps;
TinyGPSCustom heading(gps, "HCHDG", 1); // $HCHDG sentence, 1st element
void setup() {
Serial2.begin(9600);
NMEA2000.SetProductInformation("00000001", 100,"Heading converter", "1.0.0.11 (2016-04-13)", "1.0.0.0 (2016-04-13)");
NMEA2000.SetDeviceInformation(1, 140, 60, 2046);
NMEA2000.SetForwardOwnMessages();
NMEA2000.SetMode(tNMEA2000::N2km_NodeOnly,22);
NMEA2000.EnableForward(false);
NMEA2000.Open();
}
void loop()
{
tN2kMsg N2kMsg;
if (heading.isUpdated())
{
SetN2kMagneticHeading(N2kMsg, 1, DegToRad(atof(heading.value())));
NMEA2000.SendMsg(N2kMsg);
NMEA2000.ParseMessages();
}
while (Serial2.available() > 0)
gps.encode(Serial2.read());
}