About OpenSkipper

Welcome to the OpenSkipper project, which provides Open Source C# code for Windows for integrating and displaying NMEA 0183, NMEA 2000 and AIS data from nautical instruments, GPS units and internet data sources. OpenSkipper can be run on a laptop aboard your boat to show electronic instruments displaying speed, heading, etc. Open Skipper can also receive and transmit data over multiple connections, including a serial port (for NMEA 0183), an ActiSense NGT-1-USB NMEA-2000-to-USB converter to read NMEA 2000 (N2K) data, and wired and wireless network connections (including TCP and UDP). It also contains a built-in webserver, so you can run OpenSkipper on a laptop and use this to display data on an iPad or Android phone or tablet.

OpenSkipper was initially developed by Dr Andrew Mason in the Yacht Research Unit and Dept of Engineering Science at the University of Auckland, New Zealand, with fantastic assistance from student Jason Drake. OpenSkipper was updated in 2014 by Timo Lappalainen and Kave Oy from Finland.

If you are interested in the NMEA 2000 standard, then Open Skipper provides both code and definition files for interpreting NMEA 2000 messages. This work uses the definition files developed by as part of his excellent CanBoat project.

NMEA 2000 messages can be received using the Actisense (www.actisense.com) NGT-1-USB NMEA-to-USB converter (a product that we recommend). We have not signed any non disclosure agreements with Actisense, but instead written our own low level COM-port driver. Our accessing of an NGT-1 in this way is not officially supported by Actisense. It works for us, but we take no responsibility in any way for any consequences.

Open Skipper contains XML definition files used to describe how an NMEA 2000, AIS and NMEA 0183 message should be decoded. These definition files are a beta release, have not been tested and contain errors, so please do not rely on any output from open skipper for your navigation. These definitions are unofficial, and are not supported by NMEA (www.nmea.org) or any other body in any way. We welcome community feedback on improvements to these.

Open Skipper is beta software designed to serve only as an aid for navigators. It in no way replaces the need to follow good nautical practices.

By using this software, you agree to the terms of the GNU Public License v3 (http://www.gnu.org/licenses/gpl.html), and in particular that:

There is no warranty for the program, to the extent permitted by applicable law. Except when otherwise stated in writing the copyright holders and/or other parties provide the program “as is” without warranty of any kind, either expressed or implied, including, but not limited to, the implied warranties of merchantability and fitness for a particular purpose. The entire risk as to the quality and performance of the program is with you. Should the program prove defective, you assume the cost of all necessary servicing, repair or correction.

In no event unless required by applicable law or agreed to in writing will any copyright holder, or any other party who modifies and/or conveys the program as permitted above, be liable to you for damages, including any general, special, incidental or consequential damages arising out of the use or inability to use the program (including but not limited to loss of data or data being rendered inaccurate or losses sustained by you or third parties or a failure of the program to operate with any other programs), even if such holder or other party has been advised of the possibility of such damages.

All trademarked terms are the property of their respective owners.

96 Responses to About OpenSkipper

  1. Dwight Kruger says:

    Looking for byte/bit level definitions of the NNMEA 2000 PGNs.

  2. admin says:

    I suggest you visit the CanBoat site… that’s where OpenSkipper gets its data from. Andrew

  3. Paul Williams says:

    Has anyone customized OpenSkipper to provide audible alarm settings? I have my engine instruments displaying, but I would like to add alarms for thresholds.

  4. admin says:

    Paul. We have been discussing the best way to do this. Tell us your ideas and how you would use this… Andrew

  5. Jacob says:

    Is there any way for open skipper to use a different device to communicate or have it look on a different COM port for the information? I already have a Maretron USB100 and it communicates on COM9 but I can’t find any way to make the information display on OpenSkipper.

  6. admin says:

    Connecting to Com9 should be poosible with OpenSkipper. However we have not worked with a Usb100. What new coding do you think is needed to use this device? From the Maretron website, running this unit in N2k-to-0183 mode should just work. Some decoding of the native N2k data received in N2kView mode will need to be coded in SolverStudio. Andrew

  7. Timo Lappalainen says:

    Open skipper reads any COM port which provides NMEA 0183 messages or N2k messages from Actisense. The only limitation is that port name has to start with COM, so COM9 is OK.

    USB100 seem to be just N2k-to-NMEA0183 converter so it should work fine. There are at least DPT sentence, which should work with distributed OpenSkipper version. With e.g. GGA I there is still error in definitions, which has been fixed on my debug version and next release.

    There are diffrent ways to display the information on OpenSkipper. One way is just to go to Tools-“Serial port listener” and Com9 and then speed (4800?) and mode to NMEA0183. Then press “open” and you should get raw data NMEA0183 data as e.g. with HyperTerminal. If that works, close the connection and go to “View”-“Data streams…”-“NMEA 0183 (COM ports)”, press add new and set the baud rate and com port (COM9) and press connect. Then you can go to “View”-“Decoded messages” and select NMEA 0183 stream you just created. Then you should see decoded data read from com port (=USB100). If you get that working then you just need to define your own displays how to view data. Timo

  8. Ubuntu says:

    Thank you for your work, and having this as GNU licensed software.

    Any plan to offer Linux version?

    All the best

  9. admin says:

    Thanks for your email. The current version should compile under Mono on Linux. (It certainly did a few years ago, but we have not tested it recently.) Andrew

  10. Olivier says:

    Hi there!
    There is now a quite useable Arduino Duo board with a nice CAN interface and SW library that make a very good CAN bus sniffer. I expect that the raw binary data out of the CAN interface to be close to the input of the analyzer in your software…. Is this the case…? I look to make a N2K to analog ( Yes, I still LOVE my old fashioned 40 years old Pen Lann indicators, which still work perfectly. I look to sniff sea speed, wind speed and direction, and look for the proper PGNs. Would you have a binary dataset from for example a DST800 airmar probe? That would be lovely!

  11. admin says:

    Olivier, we started with a CAN bus sniffer, and yes they can be very effective for reading N2K data. I would expect the Arduino output data to be very close to that produced by the Actisense NGT-1 that we support. OpenSkipper is designed to allow new “sources” to be added by writing new code that can interpret an incoming stream of N2K data in some specific format. This could come over a serial port, or even over ethernet if your Arduino can support TCP or UDP. And, no, I’m sorry but I don’t have any data from an Airmar DST800. Please let us know how you get on. Andrew

  12. Timo Lappalainen says:


    My friend bought Airmar DST800 and uses it with OpenSkipper, so I could ask him to record you DST800 data in OpenSkipper log format.


  13. admin says:

    Excellent idea, Timo. Andrew

  14. Lars says:

    Hi there
    Thanks for your grat work!

    Looking for a way to correct TWA and TWS for windshear and upwash and then plot and then output a windplot with the corrected data. Something like correcting with an angle when windspeed is between 0 and 5 knots, another angle when 5 tp 10 knots aso.

    Any possibilities to do so? Anything tried in this direction?

    Kind regards


  15. Timo Lappalainen says:

    I did not completely understood you way to correct wind data. I tried to study windshear and upwash terms, but I did not find any explanation how you could define fixed corrections.

    Wind handling need anyway some more handling. We should also get apparent data calculated by OpenSkipper, since sometimes systems does not comunicate with each others. Well, if you have all devices in same network they do. Also I would like to have average values instead of just current value.


  16. olivier says:

    Hi timo,

    If you could do that, that would be great! it would be needed to record the boot sequence too… there is a negotiation phase that i may need to replicate!


  17. Timo Lappalainen says:

    Hi Olivier,

    So I made test run with DST800. You can download logs by direct link http://www.kave.fi/Apps/Logs/Airmar_DST800.zip.
    There are Actisense ebl files which you can read with their “EBL Reader”. These EBL files has been generated on harbour and they hopefylly contains all communication from the beginning. Note that this may also contain some Actisense NGT initialization messages. Note also that there are own files for received and sent messages.

    The other file 20140907_Track is just message log from OpenSkipper. It contains all messages received on that boat, but does not contain any initialization.


  18. Bruno says:


    Great project! I try to build the project (v1.5) under Mono on Mac OS environment.
    I got these errors :
    CSC: error CS2001: Source file `ThirdParty/Compass.cs’ could not be found
    CSC: error CS2001: Source file `ThirdParty/Compass.designer.cs’ could not be found
    These files are not in the solution, could you help me please ?
    Thanks for your help.


  19. admin says:

    Our apologies; we were missing these files. I have now uploaded a new file, OpenSkipper-1.5 20140910-src.zip, which includes these files (with no other changes). Thanks for your interest in OpenSkipper, and alerting us to this problem. Andrew

  20. Lars says:

    Hi Timo and all

    regarding correction of TWA it wouldn’t be enough to correct for fixed values. Something like checking for TWA send by system and deciding what angle to correct with is the way to go. An logic like this would be the right way, I think:
    If TWA <= 20 AND TWS <= 6knts, then TWA=TWA-5,
    elsdif TWA <= 30 AND TWS <= 6knts, then TWA=TWA-3,

    You would have to look at values of both angle and speed and then correct both of these values and send them out too the system again. Some sort of table would be perfect to write correction values into.

    Question is if something like that it's possible and which way to go. any ideas?

    Kind regards and keep the good work! 🙂


  21. Timo Lappalainen says:

    Hi Lars,

    Sorry for delay…

    What happens if TWS is 6.1? There would be 5 deg step for TWA between 6 and 6.1 knots. This would easily cause TWA neagle jumping from point to point. I could imagine that correction could be some continuos formula cTWA=f(TWA,TWS). Can you find anything like that?

    I discussed about your idea with my brother who is hanglider. He explained me a bit about windshear and upwash.


  22. Lars says:

    Hi again – andsorryfordelay, too.

    My idea was to explain the concept.You are totally right: The more detailed data you want, the more datapoints you wouldhave to put into the system or make some intrapolation between the entrypoints.

    I wanted to know if something like that would be possible to do with help of Openskipper, or if that would crave enormous amount of time.

    Now I think you are able to judge this, don’t you?

    Kind regards and keep the good work! Cheers


  23. Ken says:

    Wanted to say great work guys.
    I have been researching NMEA2k interfaces for a small project which may be of interested to others here. But having trouble answering a simple question. Is there any specific reason for the lack of Bluetooth interfaces on the market? Like baud rate limitations or something else I’m missing?

    Most automotive CANbus J1939 adapters and applications on the market today are being built around Bluetooth only. I have an ELM327 OBD-II WiFi adapter that is about became obsolete due to this fact. Being the underlying protocol of NMEA2k is SAE J1939, will the standard ELM327 chipset communicate in the same way as these other expensive USB adapters over CAN Hi/Lo ports?

    Thinking a inexpensive BT adapter might add more value and interest to projects like OpenSkipper. As Oliver stated above, affordable project boards like Andruino have CAN built in now.

  24. admin says:

    My first work was using an ELM chip that was fine for reading N2k data, but cannot generate some of the N2k specific data types. Adding support for Bluetooth Canbus adapters would be good (and easy as I assume they just look like a serial port?).

  25. Timo Lappalainen says:

    Two answers:

    1. I try to look a way to implement some kind of common function handling y=f(x) and z=f(x,y) with interpolation. This actually then works also as common calibration function. So e.g. one has analog input for tank, but tank shape is strange (as they normally are in boats), then one can offer calibration vector for that. Some devices like Alba Combi, which I have, already have that internally.

    2. About BT adapters.
    Two problems:
    – Does someone, who is cabable to develop support for it to open skipper, that device for testing? Actisence costs about 200€ or $ and it works.
    – I do not have good experience of BT so I have even dumped BT mouse away due to random loss of connection. I use wireless tablet for looking data, but all systems are wired to main computer.

  26. Uwe Sauerbrey says:


    This is the first time I try to work with OpenSkipper. I work with Windows 8.1 and when I start OpenSkipper, I get an exception. Any proposals?

    Best Regards Uwe

    Informationen über das Aufrufen von JIT-Debuggen
    anstelle dieses Dialogfelds finden Sie am Ende dieser Meldung.

    ************** Ausnahmetext **************
    System.ArgumentException: Der angeforderte Wert “Ctrl” konnte nicht gefunden werden.
    bei System.Enum.TryParseEnum(Type enumType, String value, Boolean ignoreCase, EnumResult& parseResult)
    bei System.Enum.Parse(Type enumType, String value, Boolean ignoreCase)
    bei System.Windows.Forms.KeysConverter.ConvertFrom(ITypeDescriptorContext context, CultureInfo culture, Object value)
    bei DisplayDefinitions.DisplayInfo.AddToToolStrip(ToolStripMenuItem MainStrip, Int32 tag, EventHandler handler)
    bei OpenSkipperApplication.MainForm.LoadDisplays()
    bei OpenSkipperApplication.MainForm.LoadDefinitions()
    bei OpenSkipperApplication.MainForm.MainForm_Load(Object sender, EventArgs e)
    bei System.Windows.Forms.Form.OnLoad(EventArgs e)
    bei System.Windows.Forms.Control.CreateControl(Boolean fIgnoreVisible)
    bei System.Windows.Forms.Control.CreateControl()
    bei System.Windows.Forms.Control.WmShowWindow(Message& m)
    bei System.Windows.Forms.Control.WndProc(Message& m)
    bei System.Windows.Forms.Form.WndProc(Message& m)
    bei System.Windows.Forms.NativeWindow.Callback(IntPtr hWnd, Int32 msg, IntPtr wparam, IntPtr lparam)

    ************** Geladene Assemblys **************
    Win32-Version: 4.0.30319.34014 built by: FX45W81RTMGDR.
    CodeBase: file:///C:/Windows/Microsoft.NET/Framework64/v4.0.30319/mscorlib.dll.
    Assembly-Version: 1.5.2014.608.
    Win32-Version: 1.5.2014.0608.
    CodeBase: file:///C:/Users/Uwe/Downloads/OpenSkipper-1.5%2020140608/OpenSkipper.exe.
    Win32-Version: 4.0.30319.33440 built by: FX45W81RTMREL.
    CodeBase: file:///C:/Windows/Microsoft.Net/assembly/GAC_MSIL/System.Windows.Forms/v4.0_4.0.0.0__b77a5c561934e089/System.Windows.Forms.dll.
    Win32-Version: 4.0.30319.33440 built by: FX45W81RTMREL.
    CodeBase: file:///C:/Windows/Microsoft.Net/assembly/GAC_MSIL/System.Drawing/v4.0_4.0.0.0__b03f5f7f11d50a3a/System.Drawing.dll.
    Win32-Version: 4.0.30319.34239 built by: FX452RTMGDR.
    CodeBase: file:///C:/Windows/Microsoft.Net/assembly/GAC_MSIL/System/v4.0_4.0.0.0__b77a5c561934e089/System.dll.
    Win32-Version: 4.0.30319.33440 built by: FX45W81RTMREL.
    CodeBase: file:///C:/Windows/Microsoft.Net/assembly/GAC_MSIL/System.Windows.Forms.resources/v4.0_4.0.0.0_de_b77a5c561934e089/System.Windows.Forms.resources.dll.
    Win32-Version: 4.0.30319.34230 built by: FX452RTMGDR.
    CodeBase: file:///C:/Windows/Microsoft.Net/assembly/GAC_MSIL/System.Xml/v4.0_4.0.0.0__b77a5c561934e089/System.Xml.dll.
    Win32-Version: 4.0.30319.33440 built by: FX45W81RTMREL.
    CodeBase: file:///C:/Windows/Microsoft.Net/assembly/GAC_MSIL/System.Configuration/v4.0_4.0.0.0__b03f5f7f11d50a3a/System.Configuration.dll.
    Win32-Version: 4.0.30319.33440 built by: FX45W81RTMREL.
    CodeBase: file:///C:/Windows/Microsoft.Net/assembly/GAC_MSIL/System.Core/v4.0_4.0.0.0__b77a5c561934e089/System.Core.dll.
    Win32-Version: 4.0.30319.34230 built by: FX452RTMGDR.
    CodeBase: file:///C:/Windows/Microsoft.Net/assembly/GAC_MSIL/System.Xml/v4.0_4.0.0.0__b77a5c561934e089/System.Xml.dll.
    Win32-Version: 4.0.30319.33440 built by: FX45W81RTMREL.
    CodeBase: file:///C:/Windows/Microsoft.Net/assembly/GAC_MSIL/Accessibility/v4.0_4.0.0.0__b03f5f7f11d50a3a/Accessibility.dll.
    Win32-Version: 4.0.30319.33440 built by: FX45W81RTMREL.
    CodeBase: file:///C:/Windows/Microsoft.Net/assembly/GAC_MSIL/mscorlib.resources/v4.0_4.0.0.0_de_b77a5c561934e089/mscorlib.resources.dll.

    ************** JIT-Debuggen **************
    Um das JIT-Debuggen (Just-In-Time) zu aktivieren, muss in der
    Konfigurationsdatei der Anwendung oder des Computers
    (machine.config) der jitDebugging-Wert im Abschnitt system.windows.forms festgelegt werden.
    Die Anwendung muss mit aktiviertem Debuggen kompiliert werden.

    Zum Beispiel:

    Wenn das JIT-Debuggen aktiviert ist, werden alle nicht behandelten
    Ausnahmen an den JIT-Debugger gesendet, der auf dem
    Computer registriert ist, und nicht in diesem Dialogfeld behandelt.

  27. Timo Lappalainen says:


    I test OpenSkipper with W8.1, so it is not the OS problem. Please contact me directrly, so we can try to find problem. You find my contact info on http://www.kave.fi/Contact.html


  28. Timo Lappalainen says:


    So the problem with Uwes case was in language. On Displays.xml there are shortcut definition for each display e.g.
    So the Ctrl has to be defined with local language and in Uwes case in German Strg+1. Other solution would be just delete the row, if shortcuts are not necessary.

    I’ll try to find is it possible to make language independent.


  29. Ken says:

    Admin; I’ve started working on the BT adapter, but have a couple questions regarding the specific data types we need to include. So shoot me an Email please, we can hash them out quicker. And yes from the other end it should look just like a serial port.

  30. giuseppe says:

    I use an arduino for sniffer the N2K network, it work perfect. My question is. Is possible to explain the format of the data output from the NGT-1 interface? I want to try to emulate the format data output of the NGT-1 with my arduino, and use my arduino bord in openskipper for get the Nmea2000 data.
    Thank’s you very much.

  31. admin says:

    That sounds like a great project. I suggest you look at the code in CANReaders.cs, such as:
    /* This N2kDataReceived message goes:
    * [0] Priority
    * [1] PGN LSB=Least Significant Byte
    * [2] PGN Middle Byte
    * [3] PGN MSB=MostSignificant Byte
    * [4] Destination
    * [5] Source
    * [6,7,8,9] Time stamp, LSB…MSB
    * [10] N2k payload length
    * [11, 12, …] N2k payload (always 8 bytes in data seen so far)
    See also https://github.com/canboat/canboat, which also accesses the NGT-1 directly. I look forward to hearing how you get on. Andrew

  32. giuseppe says:

    Bingo, thank’s you very much.
    I use a nmea emulator + a terminal to watch the data coming out from nmea2000, An important thing is that if you have 0x10 byte is some part of the string (different of the ESCAPE) this 0x10 Byte is repeated 2 times.

  33. giuseppe says:

    I don’t undestand the time stamp [6,7,8,9] generation.
    The others bytes of the frame are very easy to generate with a fast arduino code.

  34. giuseppe says:

    You are sure that this piece of code work well?

    // Byte 14 : Length of n2k data
    buffer[14] = (byte)n2kFrame.Data.Length; // N2k data length : Bytes [15, CRCbyte)

    byte msgIdx = 15;

    for (int i = 0; i < n2kFrame.Data.Length; i++)
    if (n2kFrame.Data[i] == Escape)
    buffer[msgIdx++] = Escape;
    buffer[msgIdx++] = Escape;
    buffer[msgIdx++] = n2kFrame.Data[i];

    You fill the Buffer[14] with the lenght of the data (correct)
    But after you fill the buffer[16]……….and the buffer[15]?

    Another question…….. The 0x10 bytes on the header (if appen) must be repeted 2 times, but in yours code i don't see that.

  35. giuseppe says:

    I think this row:
    byte msgIdx = 15;
    must be changed with this:
    byte msgIdx = 14;

  36. Jim says:

    Your project sounds very interesting!
    I have modified OS to use EBL files as log files and have done some decoding of the Actisense data stream. Not sure, but some of this may help with your question / project.

    I find 6 different message types in Actisense data that have different formats.
    public const byte MSG_N2K_DATA = 0x93; // N2K Data Message type
    public const byte MSG_N2K_REQ = 0x94; // N2K Request Message type
    public const byte MSG_EBL_VER = 0x01; // EBL File Version Message
    public const byte MSG_EBL_TIME = 0x03; // EBL File Time Stamp Messages
    public const byte MSG_NGT_BEMCMD = 0xA0; // NGT BEMCMD message type
    public const byte MSG_NGT_SEND = 0xA1; // Send NGT specific message

    Since they have different formats, data length is not in the same place. 0x10 does need to be doubled when it occurs in the data of N2K messages.
    If your project intends on creating an EBL formatted file, i recall that 0x1B is not doubled with Actisense live feeds but it is doubled in EBL flies.
    Creating EBL formatted flies let you use the EBLReader to explore unknown PGN’s that are defined in the EBLReader.

    An example of N2K_REQ to request information about another PGN is:
    /// PackFrameRequest creates a message packet for the PGN 59904 that request information from other nodes.
    /// A request for information has a data field to specify the PGN about which information is being requested.
    /// The destination device and buffer for the message construction is also specified.
    /// specifies the PGN that the destination device is to provide information about
    /// specifies the destination device
    /// specifies the buffer in which the message will be created
    /// the length in bytes of the message created. This is always 16 bytes for the 59904 request.
    public static int PackFrame59904(int ReqPGN, int PGNDestination, byte[] buffer)
    buffer[0] = DLE;
    buffer[1] = STX;
    buffer[2] = Constants.MSG_N2K_REQ; // Command to send N2K message

    int pgn = 59904; // PGN to Request Information
    byte pgnLSB = (byte)(pgn & 0xFF);
    pgn >>= 8;
    byte pgnMDB = (byte)(pgn & 0xFF);
    pgn >>= 8;
    byte pgnMSB = (byte)(pgn & 0xFF);

    buffer[4] = 7; // Priority
    buffer[5] = pgnLSB;
    buffer[6] = pgnMDB;
    buffer[7] = pgnMSB;
    buffer[8] = (byte)PGNDestination;

    buffer[9] = 3; // Length of Message

    // TODO: Confirm that we do not need to watch for ESC bytes in PGN’s and double them.
    // ?? Are PGN’s constructed to avoid ever coding a byte to ESC?

    pgn = ReqPGN; // PGN that the destination device is to provide information about
    pgnLSB = (byte)(pgn & 0xFF);
    pgn >>= 8;
    pgnMDB = (byte)(pgn & 0xFF);
    pgn >>= 8;
    pgnMSB = (byte)(pgn & 0xFF);

    buffer[10] = pgnLSB;
    buffer[11] = pgnMDB;
    buffer[12] = pgnMSB;

    buffer[3] = (byte)(14 – 5); // Message length : Bytes [4, CRCbyte)

    // Calculate checksum
    int byteSum = 0;
    for (int i = 2; i < 13; i++)
    byteSum += buffer[i];
    byteSum %= 256;

    buffer[13] = (byte)((byteSum == 0) ? 0 : (256 – byteSum));

    buffer[14] = DLE;
    buffer[15] = ETX;

    return 16; // Length of message in buffer. Always 16 for 59904 request


    An example of sending the NGT a command message with NGT_SEND is:
    /* static unsigned char NGT_STARTUP_SEQ[] =
    { 0x11 // byte 1, Reset and set operating mode
    , 0x02 // byte 2, Operating mode = Transmit All (2)
    , 0x00 // byte 3, high order bits of operating mode?

    public static int Pack_Startup(byte[] buffer)
    buffer[0] = DLE;
    buffer[1] = STX;
    buffer[2] = Constants.MSG_NGT_SEND; // Command to send message to NGT; ChkSum starts with buffer[2] position.
    buffer[3] = 3; // Length of message

    buffer[4] = 0x11; // A1 11 = Reset & set operating mode
    buffer[5] = 0x02; // operating mode = Transmit All
    buffer[6] = 0x00;

    // Calculate checksum
    int byteSum = 0;
    for (int i = 2; i < 7; i++) byteSum += buffer[i];
    byteSum %= 256;
    buffer[7] = (byte)((byteSum == 0) ? 0 : (256 – byteSum));

    buffer[8] = DLE;
    buffer[9] = ETX;

    return 10;

    Other constants that may help…
    // Constants
    private const byte DLE = 0x10; // Escape char = Data Link Escape; In any DLE characters are double escaped (DLE DLE).
    private const byte STX = 0x02; // Start of Text N2K Message
    private const byte ETX = 0x03; // End Of Text N2K Message

    private const byte EBL_ESC = 0x1B; // EBL File Escape char = ESC; In any ESC characters are doubled (ESC ESC) in EBL files.
    private const byte EBL_STX = 0x01; // Start of Text for Actisense EBL File Message
    private const byte EBL_ETX = 0x0A; // End Of Text for Actisense EBL File Message

    Hope this helps.


  37. admin says:

    Thanks for all your feedback. I will have to check our code carefully (and hook up my Actisense unit again) when I get a chance. (From memory we have not written data to the N2K bus, and so our code may well have problems.) Please keep giving us feedback; it is really appreciated.

  38. giuseppe says:

    I appreciate your help, JIM.
    What is EBL?
    I want only emulate an Actisense interface with my arduino canbus module. Actisense interface cost about 200USD, I spend only 20USD for my arduino pro mini,mcp2515, mcp2551 and some other little components. At this moment I’m able with my arduino based board to get data from NMEA2000 bus, now I want take out this data like tha Actisense interface, and use my arduino based board with openskipper and other navigation programs like MAXSEA TIMEZERO.

  39. Jim says:

    Unless you are trying to closely emulate the Actisense interface, you may have no need to have the arduino respond to Actisense commands like the reset command that Pack_Startup builds. So of the 6 message types listed, you probably only need to work with 0x93 & 0x94.

    While I have not tried to write N2k data (message type 0x93) to the bus, I think the example of writing message request (0x94) might help as it is very similar and i can confirm that it works.

    PackFrame55904 flow creates an 0x94 message in a buffer starting with sequence. This should be the same for 0x93 messages except for the message-type number. 0x94 doesn’t have the rest of the header and places the data packet length in buffer[9]. That length is 3 bytes for the PGN being requested in the 59904 example. For 0x93, the length would be buffer[14]. Next is the data (which is the requested PGN for 59904). Then calculate CheckSum starting with buffer[2] (Msg_Type). That is followed by the terminating sequence

    As you probably know, N2K has a 48 bit timestamp is in msec vs DateTime’s 64 bits as time in 100-nanoseconds ticks

    Like you described, other than the DLE-STX and DLE-ETX sequences, DLE’s get doubled. As an aside, Actisense uses ESC (0x1B) as their command escape sequence so ESC gets doubled in the Actisense proprietary messages.

    My PC is connected to the N2K bus via an Actisense NGT. To experiment with writing N2K message to the bus I adding a tab in OpenSkipper that would display information about other devices connected to the N2K bus. When OpenSkipper gets a data message from a source that is unknown, It sends out PGN 59904 with PGN 126996 – (Request to transmit Product Information) in the data packet part of the message. Though i have yet to experiment with request PGN’s like 126998 – Request Configuration Information or 126464 – PGN List (Transmit and Receive).

    EBL files are binary stream files of N2K data that can be created by the Actisense app nmeaReader. Those files can by explored off-line with another Actisense app eblReader. The output display is similar to the Decoded Messages view in OpenSkipper. At first I would capture the N2K data from the boat with nmeaReader, then I could use OpenSkipper modified to read these files and compare Decoded Messages to help edit and add to the PGNDefns.N2kDfn.xml resource of OpenSkipper. I found that format more compact, so i modified OpenSkipper to enable keeping log files in EBL format so i could still explore them with the Actisense app.

  40. Timo Lappalainen says:


    I made beta version of OpenSkipper, which now has Chart control for time based display of data. You can find beta on http://www.kave.fi/Apps/index.html and it has wind speed chart form as sample. There are two new sample files:
    – Display_WindGraph.xml This defines ne form for wind graph. You can also use new control on any of your own forms.
    – DisplayChartWindGraph.xml this defines the chart. It is referenced on Display_WindGraph.xml on File:DisplayChartWindGraph.xml

    As default it shows now wind speed on seconds started from program start. On DisplayChartWindGraph.xml you can define x-axis size in seconds with Here it is set to 20 sec.

    This has several bad things and may be changed in future release. Anyway with DisplayChartWindGraph.xml one can define chart to be viewed as you like. Only problem that you need to know all chart settings on C#

  41. Timo Lappalainen says:


    There is newer OpenSkipper-beta.zip file available. This has now better chart handling and also two different chart sample (see under menu Wind) for web.

    To get chart usable for web, you have to enable history for data you want to use in charts. You can enable history in parameter settings Tools-“Parameter Explorer”–KeepHistory. For samples you must have RelativeWindSpeed_ms and RelativeWindAngle KeepHistory-value e.g. 500 (seconds). This is because when you change web page, it looses all data so the graph will be started from beginning. So the web pages I created asks history from server (OpenSkipper).

  42. David Watson says:

    I’ve been reading with interest all the very fine effort being undertaken in the arena of open source software for the marine industry. I too have been frustrated for many years with the mentality of the marine oligarchy and their protectionist attitude. I wish you all success.

    I am a builder, currently juggling the installation of an electronics package that comprises a million (not really) devices from two million (also not really) different manufacturers. My complaint has to do with the imperial back-patters at NMEA. Now, if you name happens to be Maersk or Evergreen, you probably have a 6+ figure budget to get all your toys up and running. The average boater does not.

    I’m tired of closed systems, closed or proprietary protocols, licensing fees payable to organizations that exist solely for the purpose of justifying their existence, and the such. Every time somebody comes to market with a new product, after paying NMEA to use 2K and/or, god forbid, the US Patent office, we are called upon to reimburse them. What if we used our buying power to say, “Hey. This is our network. If you want us to buy your product then you best make one that will connect to it. If not, then a long walk off a short dock would be appropriate.”

    I am currently implementing an RS485 ship-wide network. For those not familiar, it’s a balanced 2-wire (4 wire if you want to carry 12V and Gnd), multipoint, industrial strength transmission system capable of speeds up to 30+Mbps short-haul and 100Kbps for a kilometer. You can use UTP or CAT5 cable no problem and interfaces are cheap.

    Virtually every other known-to-man communication method, WiFi, 2.4GHz, I2C, SPI, RS232, CAN, Bluetooth, etc., etc., has a sub-dollar interface to 485. We have been developing an Integrated Bridge Management system for several years now and we use 485 for all our sensor data and for providing ‘command and control’ to the helm and remote stations as well as an android app. This IBMS is an in-house system for now and we’ll either adopt an open system or release ours depending. The key for us now is to consolidate our network communications. Aircraft have moved to fly-by-wire for the weight savings. Has anybody ever weighed how much copper goes into a boat? Multiple networks running multiple proprietary protocols?

    In any event, enough of my complaining. The purpose of this post is to invite anyone interested in the low-level aspect of communications to contact us with their ideas. For those continuing their fine efforts in development, you might want to consider the future consisting of a new (old) transmission platform for your wrappers (we used to call it packetizing).

    David Watson
    PT Asia Pacific Engineering
    [email protected]

  43. Timo Lappalainen says:


    Interesting development. Yet an other “standard”? RS485 is familiar for me. What would be the protocol over this network?

    On the pleasure boat market average owner does not know much about networks. They would like to have few data like speed, log and wind on cocpit. I think that first some big sensor/display manufacturer should come to market with some open network. But then it is risk for them that some other makes cheaper sensor etc.

  44. Giuseppe says:

    When i try to select the port of actisense i get this data coming out from nmea reader.
    Is possible to know the original reply coming from the NGT interface?

    10 02 A1 01 11 4D 10 03 21 50 41 52 4C 42 2C 31 2C 31 2C 60 40 34 41 43 40 2A 33 37 0D 0A

  45. Timo Lappalainen says:

    Hi all,

    If anybody is interested I made a code for Arduino, which at least partially replaces Actisense NGT interface. One can also make own e.g. RPM meter, temperature or battery monitor to NMEA2000 bus with this setup.

    I have also found more fixes for PGNDefns.N2kDfn.xml file for OpenSkipper.

  46. Owen Mace says:

    G’day all
    I would like to connect a sniffer to the n2k CZone bus on my boat to monitor batteries, bilge pumps, etc and to send me an SMS message if a parameter goes outside bounds. I am thinking about an Actisense NGT and an Android phone. Development for the phone to be Qt. (CZone development lab is in New Zealand, I believe.) No need to transmit to the n2k bus and I prefer to disable any transmission for safety reasons. Any thoughts or comments?
    Adelaide, South Australia

  47. admin says:

    Owen: I like the Actisense NGT and the software that comes with it, so I’m sure that would let you read the PGN’s that CZone use. You could also do the same more cheaply using a CAN device from a car; these will generally read N2k just fine (at least it worked for us some years ago). It gives you read-only access, which is what you want anyway. Re development, make sure you look at the Signal-K work (http://signalk.org); they are doing some good open source development projects. Hope this helps. Andrew

  48. admin says:

    Timo: That’s great. Have you told the signal-k folks about your progress? They’d be most interested. Do you have code and schematics available? Andrew

  49. Timo Lappalainen says:

    Owen: Actisense NGT is the easiest way to go. If you are familiar with programming and you can use soldering device, then you may 130 € with Arduino.

    Andrew: I’ll order Arduino Due, since Arduino Mega could not forward all packages. Mega worked fine, when I limited packets for informative packect only. But there are also handshaking and proprietary packets on bus, and I would like to forward those too.

    The project is under development so anyone who is interested can ask me directly for more information. It is not yet clean enough for publish and I am making modifications daily. My goal is to make cheap N2k device node, combiner for NMEA0183/N2k/PC.

  50. Owen Mace says:

    Your byte stream:
    10 02 A1 01 11 4D 10 03 21 50 41 52 4C 42 2C 31 2C 31 2C 60 40 34 41 43 40 2A 33 37 0D 0A
    when interpreted as ASCII is:
    and the last two bytes (OD OA) are Carriage Return and Line Feed. (An NMEA 0183 message?)
    Any help?
    Thanks Andrew for your suggestions. Someone at the Sydney Boat Show suggested an OLIMEX STM32 board for about AUD$50. It is an ARM development board with Arduino connectors so that I could add a GSM board to it. To be investigated along with SignalK and ActiSense!

Leave a Reply

Your email address will not be published. Required fields are marked *