Go Down

Topic: NMEA 2000 Shield (Read 398470 times) previous topic - next topic


Thanks Timo. Laziness on my part - RTFM, as they say.
And thanks for all the work you've put into this. I'm sure there are many more people who have benefited from all your effort.


As my opinion RTFM is not good attitude, since things may be written unclear or specially when you start to work with new things, it may be difficult to understand or find. Also even for simple things manuals may be so long, that who has time to read them from word to word. So if I know the answer, I'll never respond with RTFM. Instead as this case I'll answer to the question and point to the place, where it has been explained. This may help user next time to find answers for similar questions first from manual.

So please at least about my NMEA 2000 library do not hesitate to ask, if you do not find solution easily from manual. Asking may save you several hours instead of trying to understand my manual.


Hi all,

A million thanks for Timo and the others who have contributed code.  Life is good.

I'm working on building out an array of marine electronics for my boat.  I have an existing N2K network that I installed previously, and wanted to push my data onto it to make it available to my consumer electronics.

Just a quick note for those who are contemplating this path:


I wasted (although I've learned tons, so it's probably not wasted) about a week working on getting the NMEA stuff to compile.  I could not figure out why I was having cascading dependency problems.  I even deleted my entire IDE and started again.  Then I snagged a Due and transceiver to try and follow as closely to the original project as possible, which is when I discovered that the version of the Arduino IDE that I had installed was a mess (no option for additional boards.)  I dumped it, downloaded the one from arduino.cc, and installed the library chain.  And it compiles first time.  Aaarrrrggghhhhh!

You'd think as someone who's been using Linux since 1994, and various UNIX flavors for much longer, I would have known not to trust a pre-compiled package.  But since that issue didn't pop up in a lot of searching, I thought I'd memorialize my issue and solution here for the next person.

At any rate, many thanks again to all those contributors.  I'm sure there'll be questions in the future, as I'm planning on putting together a network of low-cost low-power sensors based on the Nano and tying them in to my existing N2K network.



Just want to remind about KBox project, which has nice package for N2k bus with WiFi output etc. Check it at https://hackaday.io/project/11055-kbox


Also, there's a typo on line 58 of NMEA2000_mcp.h

   tNMEA2000_mcp(unsigned char _N2k_CAN_CS_pin, unsigned char _N2k_CAN_clockset = MCP_16MHz

should be:

   tNMEA2000_mcp(unsigned char _N2k_CAN_CS_pin, unsigned char _N2k_CAN_clockset = MCP_16MHZ



Why? See mcp_can_dfs.h ... line 255: #define MCP_16MHz   1


This is why the boss at my first sysadmin job insisted that we compile everything from source ourselves.  Because package managers only complicate things.  Turns out that even though I stripped out the packages and reinstalled the new IDE in my home directory (may the aforementioned BOFH forgive me for ever installing in my home directory) I hadn't actually checked to make sure that ALL the files were deleted.  Turns out that there was a copy of the seed version installed in /usr/share/arduino/libraries/.  Which wouldn't be a problem, except that even though I installed in my home directory (a thousand pardons sir), the IDE decided to default to the shared library location and was using that library, which has it capitalized.  Which is why nothing would compile without the change.

So I deleted them, quit all IDE sessions, reloaded, and tried again.  I still required the "MHZ" in my trial program.  Rebooting didn't help.  Somewhere the IDE was hiding that define with the capital Z, and I couldn't find it.

So I got medieval on it.  Removed everything, from everywhere.  Downloads, folders, everything.  "sudo find /* | grep mcp" found a bunch of stuff hiding in /tmp.  Stripped it all.  Started over from scratch, redownloading and reinstalling.  Deleted all my CAN test sketches (OK, that may have been a bit much, but I was frustrated).  Which was a bummer as I had a working three node setup (two nanos and a due) all talking even with all this namespace clashing.

So, after the complete nuke drop and reinstall, I've got the three nodes talking again, without the capital "Z" but this is crazy.  I have no idea which of my other projects I've broken by doing this.

I once worked in a shop where the suits decided that Silicon Graphics was the next Sun, and dropped a bunch of IRIX machines on us and told us to use them.  We had to port everything.  This feels a lot like that, except that was the early 1990's and I was getting paid...


-- I think the moral of this story is "If you've ever done anything with CAN in the arduino environment before attempting the NMEA2000 stuff, delete it ALL and start from scratch."


I am sorry, but I do not understand. On original SeedStudio CAN bus code I could not find that definition at all. See. https://github.com/Seeed-Studio/CAN_BUS_Shield . As far as I know peppeve (https://github.com/peppeve/CAN_BUS_Shield) implemented that, when he added support for Maple Mini 8MHz.


Not that it overly matters now, I've got it all working.  But in the interest of my own curiosity, here's what I've found.

In the version of the library that was initially installed, this was the header:
Code: [Select]
  2012 Copyright (c) Seeed Technology Inc.  All right reserved.
  2014 Copyright (c) Cory J. Fowler  All Rights Reserved.

  Contributor: Cory J. Fowler

When you peruse the file, starting in line 439 you get:
Code: [Select]
#define MCP_20MHZ    0
#define MCP_16MHZ    1
#define MCP_8MHZ     2

Which obviously translates over to the .cpp file, yet those are the only instances.  All the rest of the times the "Z" appears lower case, as in lines 241-:
Code: [Select]
 *  Speed 8M
#define MCP_8MHz_1000kBPS_CFG1 (0x00)
#define MCP_8MHz_1000kBPS_CFG2 (0x80)
#define MCP_8MHz_1000kBPS_CFG3 (0x80)

#define MCP_8MHz_500kBPS_CFG1 (0x00)

In fact, in the entire library folder, there are only these instances:
Code: [Select]
     ./grep MHZ *
keywords.txt:MCP_16MHZ           LITERAL1
keywords.txt:MCP_20MHZ           LITERAL1
mcp_can.cpp:        case (MCP_8MHZ):
mcp_can.cpp:        case (MCP_16MHZ):
mcp_can.cpp:        case (MCP_20MHZ):
mcp_can_dfs.h:#define MCP_20MHZ    0
mcp_can_dfs.h:#define MCP_16MHZ    1
mcp_can_dfs.h:#define MCP_8MHZ     2

I think the only reason I even ran into it, beyond the "broken not broken" nature of the library caching system in the arduino IDE, is that the cheap Aliexpress breakout boards I got came with 8MHz crystals instead of 16MHz.  So in using the #define to allow for the different speeds, I got caught out with conflicting libraries.

At any rate, a million thanks again for the N2k code.  I've got my sensors up and talking and it's great. 



Jan 28, 2017, 01:40 pm Last Edit: Jan 28, 2017, 02:39 pm by Pelle8879
Hi Timo!
I would like to send compass direction in degrees to NMEA2000 and would like to know how to do that.
I do not like the way GPS is determining compass direction when standing still.
A have a compass solution using two GPS-es. I am reading NMEA0183 from each and then I calculate Compass direction (0-360) with an arduino DUE.

The problem I have is to send degrees to NMEA2000 (If there are any message type for that).
How do external compasses send compass direction on NMEA2000?

I can send NMEA0183 message but would like to send similar to NMEA2000 bus.
This is the spec. for xxHDT in NMEA0183.
1) Heading Degrees, true
2) T = True
3) Checksum
Could you please help me?


Heading will be provided with NMEA 2000 PGN 127250.

Have you looked in e.g. WindMonitor example in my NMEA2000 library? So instead of call SetN2kWindSpeed(...) in WindMonitor use call SetN2kTrueHeading(N2kMsg,0,DegToRad(HeadingInDegrees));

Remember also change SetProductInformation(...) and SetDeviceInformation(...) in setup() to match your device.

You can find message creating functions in N2kMessages.h.

How accurate heading you can get with two GPS? I have Vector GPS compass, which is accurate, but expensive.


Thank you Timo!
I plan to use two RTK-recievers fetching Base station data over TCP and therefore I will get position within dm accuracy (at clear sky), that means... very good GPS-accuracy. I have not calculated the accuracy but it depends of course of the distance from front to rear antennas.
I will immediatly try to setup your suggested solution.
Thanks a lot for your info!
If I have further questions regarding connections for CAN-Bus I hope you will be helpful also.
Thanks again!


Please check the documents folder, there are sample schemas. With due I prefer to use MCP2562, which has ability to use 3.3 V IO as required with DUE.


Jan 29, 2017, 08:31 am Last Edit: Jan 29, 2017, 01:46 pm by Pelle8879
Thanks Timo, I really appreciate your help! :)


I read that most people are using arduino duo or mega. I'm not quite clear if it is possible to create low cost engine monitoring system and output to n2k with arduino uno and some kind of can driver?

Go Up