Skip to content

KimBP/NMEA2000

 
 

Repository files navigation

NMEA2000 library for Arduino

Object oriented NMEA2000 library for Arduino type Boards

Library gives you easy way to make different kind of NMEA2000 bus devices like NMEA2000→PC interface (like Actisense NGT1), NMEA0183→NMEA2000 converter, sensor (e.g. temperature, wind) node.

To use Arduino Due board internal CAN you will also need NMEA2000_due library and due_can library, which you can download from https://github.com/collin80/due_can

To use Arduino boards with MCP2515 CAN bus controller, you will also need NMEA2000_mcp library and mcp_can library. mcp_can library can be originally found on https://github.com/Seeed-Studio/CAN_BUS_Shield Note that NMEA2000_mcp library uses developed version of mcp_can library, which allows also to use 8MHz clock and has been tested with Maple Mini. So until these improvements has not been implemented to Seeed-Studio, use library found on https://github.com/peppeve/CAN_BUS_Shield

To use a Teensy 3.1/3.2 board internal CAN with a MCP2551 CAN transeiver (or similar, see FlexCAN documentation), you will need the [NMEA2000_teensy library](https://github.com/sarfata/NMEA2000_teensy) contributed by [Thomas Sarlandie](https://twitter.com/sarfata/) and the [FlexCAN library](https://github.com/teachop/FlexCAN_Library). FlexCan library is already included in [Teensyduino]https://www.pjrc.com/teensy/teensyduino.html extension.

To use avr processors internal CAN you need also NMEA2000_avr library and avr_can library, which you can download from https://github.com/thomasonw/avr_can

Thanks

I thank Kees Verruijt for his excellent CanBoat project and Dr Andrew Mason for OpenSkipper project. I originally started to learn NMEA 2000 via OpenSkipper project, which development I continued. PGN library on OpenSkipper and so on this library is mostly based on Kees work. Also it appeared that some code parts are probably originally from CanBoat even I have found them from other sources. Actisense message format handling I have learned from OpenSkipper project.

I also thank for anybody who has extended library with new PGNs or processor support.

Changes

19.09.2016 Lot of testing behind - hopefully works now better.

  • NOTE! New method SetN2kCANSendFrameBufSize. Added buffer for frames to be sent. This takes more RAM and may be critical for low RAM systems.

  • If frame sending fails, system now buffers frames to be sent automatically and tries to resend them on next call for ParseMessages. With this feature it solved my problem that time to time my MFD could not receive important GNSS or SOG/GOG messages and informed error.

  • System now also has more reliable response to the Product Information ISO request (PGN 126998). Unfortunately if your system does not poll often enough incoming messages (ParseMessages), you still may loose the request itself. This is specially the case if you system spends some time reading sensors like 1-wire system. Even with 1-wire asynchronous read, it may spend 10 ms interrupts disabled. Within 10 ms there may be about 30 messages on bus.

  • New methods SetConfigurationInformation and SetProgmemConfigurationInformation. System can now also handle Configuration Information ISO request to (PGN 126998). Default configuration information is saved to PROGMEM.

  • NOTE! Reload also NMEA2000_due!

17.09.2016 Temporary fix for problem to respond product information ISO request.

12.09.2016 Thanks for people (usauerbrey, OzOns), who noted below problems

  • NOTE! If you are using NMEA2000_can, remember to update that too!

  • Fix for ISORequest handling. Now responds allways also for broadcasts.

  • Some fixes to avoid compiler warnings.

  • Fix for parsing PGN 127257/Attitude

09.08.2016 NOTE! Fixed PGN 130310, PGN 130311 and added SetHandleOnlyKnownMessages(), which effects backward compatibility. See below.

  • NOTE! On PGN 130310 and PGN 130311 description says that "Atmospheric pressure in Pascals. Use function mBarToPascal". There was scaling error and now they works like description. After update you have to provide value on Pascals and really use mBarToPascal, if you have your value in mBar.

  • NOTE! Added SetHandleOnlyKnownMessages(). If you have called SetForwardOnlyKnownMessages(true), library did not handle unknown messages. After update, this effects only message forwarding - as it should have been. So call also SetHandleOnlyKnownMessages(true), if you want to disable any handling for unknown messages.

  • NMEA 2000 Library reference update.

  • Added ExtendSingleFrameMessages and ExtendFastPacketMessages. With these one can own list of known messages so that it is not necessary to duplicate message list as, if used only SetSingleFrameMessages and SetFastPacketMessages.

  • Added discrete status flags for transmission parameters (PGN 127493), thanks for testing Jason.

06.08.2016 Added SetISORqstHandler for setting handler for ISO requests. Thanks thomasonw.

30.07.2016 NMEA 2000 Library reference update.

Added example TeensyActisenseListenerSender. Example contains code, schematics and document.

19.07.2016 Fixed discrete status on engine dynamic parameters (PGN 127489), thanks Jason.

Added new PGN 127257, vessel attitude. Only sending has been tested with NMEA Reader

12.07.2016 Added to API — Optional message lists by thomasonw

25.06.2016 Corrected Battery Current in ParseN2kPGN127508 by thomasonw.

23.03.2016 Additional PGN 129038, PGN 129039, PGN 129285, PGN 130074 support by adwuk.

13.03.2016 Fix of using PROGMEM. Now also product information defined to PROGMEM works right.

13.03.2016 Fix of using PROGMEM. Still does not work right with product information in PROGMEM. So all changes after 09.03 are still under validation.

13.03.2016 More memory optimization - thanks for thomasonw. Constant message strings has been marked with F(…​) moving them to flash instead of RAM.

Note also that there is new funtion void tNMEA2000::SetProductInformation(const tProductInformation *_ProductInformation); So one can save memory by defining product information to flash by using syntax:
const tProductInformation BatteryMonitorProductInformation PROGMEM={
1300, // N2kVersion
…​
See example BatteryMonitor.ino

12.03.2016 Memory tuning. Currently multi device and user definable message filters has not been implemented, so I changed buffer sizes to minimum.

There is also new function void tNMEA2000::SetN2kCANMsgBufSize(const unsigned char _MaxN2kCANMsgs); to define buffer size for received N2k messages. Note that library has to collect fast packet frames, which may arrive fragmented from different devices, so as default this buffer size has been set to 5. If your device is only sending some data (mode is tNMEA2000::N2km_NodeOnly), you do not need to catch all fast packet messages (if any), so you can set buffer size smaller.

09.03.2016 Additional PGN 127250, PGN 128275 Support by adwuk.

08.03.2016 AVR CAN support by thomasonw.

02.02.2016 NOTE! Updates, which effects backward compatibility. See list below.

  • PGN 127489, SetN2kPGN127489 EngineOilTemp and EngineCoolantTemp is in Kelvins as in other temperature functions. So add for call to this function CToKelvin(…​)

  • Some function names withing N2kMessages have been changed. Change function names listed below!
    SetN2kPGNSystemTime → SetN2kSystemTime
    ParseN2kPGNSystemTime → ParseN2kSystemTime
    SetN2kPGNTrueHeading → SetN2kTrueHeading
    SetN2kPGNMagneticHeading → SetN2kMagneticHeading

  • Variable types has been changed on some functions in N2kMessages. So when you get an compiler error about functions in N2kMessages, check carefully all parameter definitions for function from N2kMessages.h.

  • If you do not have value for some parameter for functions in N2kMessages, use related N2kxxxxNA constant defined in N2kMsg.h. So e.g. if you only have wind speed, call
    SetN2kWindSpeed(N2kMsg, 1, ReadWindSpeed(),N2kDoubleNA,N2kWind_Apprent);

  • If you are reading values from N2k bus, you can now check does some value exist by using function N2kIsNA. So if you e.g. call
    ParseN2kOutsideEnvironmentalParameters(N2kMsg,SID,WaterTemperature,OutsideAmbientAirTemperature,AtmosphericPressure);
    then check pressure value with
    if ( !N2kIsNA(AtmosphericPressure) ) { // It is available, so we can show it!

  • Added reference document to the documents, which hopefully helps to get started.

23.01.2016 Added PGN 127493 support. NMEA2000_mcp has now interrupt support. Some other fixes.

23.01.2016 Added some comments to samples and several new message readers. Also added support for 130316 extended temperature. Added new include N2kMessagesEnumToStr.h for translating library enums to clear text. This is now just for preliminary so I may changes texts in coming future. Added also new examples DataDisplay2.ini and MessageSender.ino. They are extended versions of DataDisplay.ino and TemperatureMonitor.ino.

05.12.2015 Added NMEA2000_CAN.h and some fixes. Library has been originally developed with Arduino Software 1.6.5 On Arduino Software 1.6.6 it is possible to include libraries within included files, so now it is possible to just include one file NMEA2000_CAN.h, which automatically selects right CAN library according. So you can have same code for different hw. Currently supported CAN libraries are mcp_can, due_can and teensy. Note! NMEA2000_CAN.h is now used on examples TemperatureMonitor and WindMonitor!

Hardware setup

To use Arduino NMEA2000 library you will need either

  • Arduino Due and CAN-bus_transceiver chip e.g. MCP2562 or SN65HVD234. I used MCP2562, since that was available also in DIP package. Under Documents there is file ArduinoDUE_CAN_with_MCP2562.pdf for using MCP2562 and file ArduinoDue_CAN_with_SN65HVD234.jpg for using SN65HVD234.

  • Arduino Mega and MCP2515 CAN-bus controller + MCP2551 CAN-bus_transceiver or buy CAN_BUS shield card. Under documents there is file ArduinoMega_CAN_with_MCP2515_MCP2551.pdf for layout to build CAN-bus interface by yourself. MCP2515, MCP2551, ocillator and few components cost only few euros, if you are handy and used to use soldering device.

  • Teensy 3.1/3.2 board with a MCP2551 CAN transeiver (or similar, see FlexCAN documentation).

Library has been also used with Maple Mini board, which is much cheaper than arduino.

If you using Arduino for transfering all messages to PC, I’ll prefere Due version, since it is more powerful. I Also prefere it, if you use handle messages (like GNSS) containing 8 byte double values. Arduino Mega has only 4 byte double, so you may loose some accuracy.

Software setup

You need at least Arduino Software 1.6.6 for this sample. I’ll expect you are familiar with Arduino and using libraries. When your Arduino environment is ready,

  • Download NMEA2000 library zip.

  • Download either NMEA2000_due, NMEA2000_mcp or NMEA2000_teensy (https://github.com/sarfata/NMEA2000_teensy) library zip depending you hw.

  • Download either due_can (https://github.com/collin80/due_can) or mcp_can (https://github.com/peppeve/CAN_BUS_Shield) library zip depending you hw or install Teensyduino for Teensy 3.1/3.2 boards.

  • Install all libraries (Add .ZIP library).

  • Open NMEA2000\Examples\TemperatureMonitor.

  • Connect you Arduino to USB and NMEA2000 bus.

  • Send sketch to Arduino.

  • If you have Multi Function Display (e.g. Garmin GMI-20) on your NMEA2000 bus, you should see on it’s NMEA2000 bus devices new device "Simple temp monitor" on the list.

So you are ready to play with your own device. Check also the NMEA2000\Examples\ActisenseListener, which reads all data from NEMA2000 bus and sends it to PC.

Using Arduino Software older than 1.6.6

With latest version of Arduino sw it is possible to simply include NMEA2000_CAN.h, which automatically selects necessary CAN libraries. For older versions you have to add library includes to main project file. So depending on board add lines:

For use board with MCP2515 SPI can bus tranceiver and mcp_can library
#include <N2kMsg.h>
#include <NMEA2000.h>
#include <SPI.h>
#include <mcp_can.h> // https://github.com/peppeve/CAN_BUS_Shield
#include <NMEA2000_mcp.h>
#define N2k_SPI_CS_PIN 53 // Pin for SPI Can Select
tNMEA2000_mcp NMEA2000(N2k_SPI_CS_PIN);

For use with Arduino due and due_can library
#include <N2kMsg.h>
#include <NMEA2000.h>
#include <due_can.h> // https://github.com/collin80/due_can
#include <NMEA2000_due.h>
tNMEA2000_due NMEA2000;

For use with Teensy 3.1/3.2 board and FlexCan>
#include <N2kMsg.h>
#include <NMEA2000.h>
#include <FlexCAN.h>
#include <NMEA2000_teensy.h> // https://github.com/sarfata/NMEA2000_teensy>;
tNMEA2000_teensy NMEA2000;

For use with Atmel AVR processors internal CAN controller
#include <N2kMsg.h>
#include <NMEA2000.h>
#include <avr_can.h> // https://github.com/thomasonw/avr_can
#include <NMEA2000_avr.h> // https://github.com/thomasonw/NMEA2000_avr
tNMEA2000_avr NMEA2000;

License

2015-2016 Copyright (c) Kave Oy, www.kave.fi All right reserved.

Author: Timo Lappalainen

This library is free software; you can redistribute it and/or
modify it under the terms of the GNU Lesser General Public
License as published by the Free Software Foundation; either
version 2.1 of the License, or (at your option) any later version.
This library is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
Lesser General Public License for more details.
You should have received a copy of the GNU Lesser General Public
License along with this library; if not, write to the Free Software
Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA  02110-
1301  USA

About

NMEA2000 library for Arduino

Resources

Stars

Watchers

Forks

Releases

No releases published

Packages

No packages published

Languages

  • C++ 69.3%
  • C 30.7%