Go Down

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


Thanks. I have been thinking to make FAQ, improve documents and add some more schematics, but unfortunately time is currently very limited. Specially should make clear schemas for ESP32 and Teensies, since I prefer to use those instead of old Arduino boards. They are also used in some commercial products with my library as far as I know.

Under library Documents there are some old schemas. Arduino DUE has internal CAN controller, like ESP32 and Teensies, so connection only differs on pins to be connected. I know that when one starts from cratch it would be better to have few lines with dashes how to start and what you need.

NMEA Simulator you can run by using example ActisenseListenerSender, which works fine with Teensy 3.2.

Under Examples on library, there are e.g. MessageSender, which send several different PGNs. And DataDisplay2, which shows some PGNs in clear text. Byt combining those and cleaning unnecessary you can make your own. It is very difficult to do example, which satisfies everybody, since all new ideas are different. As with other libraries with examples I have tried to show how to use it in basics and one has to combine briks for own system.


Oct 20, 2020, 06:25 am Last Edit: Oct 20, 2020, 06:27 am by soggygeek
I am working on a project to make a Battery Monitoring System with an Arduino Mega, a BMS Shield of our own design, (core component is an Analog Devices LTC6810 Battery Stack Monitor), and a Seeed Studio 2.0 Canbus Shield.  A friend is doing the hardware design and I am working on the software.  We have made a proto board to play with the LTC6810, and we have also been playing with the Canbus Shield.   The intent is to communicate battery status to a Raspberry Pi running OpenPlotter (in my case) and to a Garmin MFD for my friend's case.

Communications with the LTC6810 are via SPI.  I have been slowly building my Arduino programming skills.  I can successfully communicate with the LTC6810 using a slightly-modified sketch supplied by the chip manufacturer.  We have the BMS chip connected to the Mega using the ICSP pins on the Canbus shield, with CS connected to Pin 8.  Communications with the chip with these settings works as expected.

I can also successfully send NMEA messages using your NMEA2000 library and playing with the supplied test programs (NMEA_MessageSender and NMEA_BatteryMonitor).  Awesome to see (hard-coded) data showing up on the Raspberry Pi Signal K Dashboard.  For this we are using CS Pin 9 and 16Mhz clock, using the mcp_can library for the Seeed Studio Canbus Shield 2.0

Without changing any hardware, I can run the BMS Test program and it works to read voltages from the BMS chip.  Then I upload NMEA_BatteryMonitor, again, no hardware/wiring changes needed, and it runs and transmits NMEA messages successfully.

My problem comes when I try to put the two together into one sketch.  In my setup, I first initialize the BMS chip, and I get the appropriate response back, then I set up the NMEA2000 using the code copied directly from NMEA_BatteryMonitor, and call NMEA2000.Open.  As soon as I do that, I lose comms with the BMS.

I verified that it is the NMEA2000 calls that are causing the problem.

Feeling that this is probably a SPI conflict issue, I flailed my way down through the code, to the mcp_can library.  I find in mcp_can.cpp, code that looks like this:

Code: [Select]
byte MCP_CAN::mcp2515_readRegister(const byte address)
    byte ret;

    ret = spi_read();

    return ret;

From Googling, the SPI_HAS_TRANSACTION and SPI_BEGIN and SPI_END allow you to change SPI settings (mode, speed) between two different devices you are trying to talk to with different settings on the same SPI bus.  Am I correct in believing this?
BTW, SPI_BEGIN and SPI_END are defined up front in mcp_can.cpp as
Code: [Select]
#define SPI_BEGIN()        pSPI->beginTransaction(SPISettings(10000000, MSBFIRST, SPI_MODE0))
#define SPI_END()          pSPI->endTransaction()

So my first question is, where is SPI_HAS_TRANSACTION defined?  I haven't been able to find it in the code.
If I can #define SPI_HAS_TRANSACTION and add similar code into the SPI handling for the BMS chip, should this resolve my problem?  How much of performance hit would that be?  Our application doesn't need very fast updates, but I'm not sure how that would affect the NMEA2000 timing.  On the Arduino, we would just be sending data on NMEA2000 for display elsewhere.
Any guidance would be helpful.
Some background reading for others facing this same issue:
https://forum.arduino.cc/index.php?topic=185306.0  (a discussion about a similar problem)



SPI_HAS_TRANSACTION is defined somewhere depending of MCU.

As I have many times prefered use Teensy 3.2 or up. It has internal CAN tranceiver, takes less power, is smaller sized. I also prefer to use isolated tranceiver to avoid ground loop.


I have been studying a bit the hardware that would be needed to be able to transmit to the Can Bus. I have seen isolation requests with TI ISO1050 and VA-0505s, I have also seen some solution with MCP2562-E that obtains the power from the bus (+ 12v, GND ). Actually my knowledge of electronics is null and I do not understand the concept of isolating the GNDs. I have also found another very economical application the SN65HVD230 CAN Board that can work with systems with built-in CAN such as teensy 3.6, 4.0, ESP32 ESP, etc.
Does anyone know or have used the SN65HVD230 CAN Board? does it really work? It is a really cheap solution, does it have any drawbacks? Thanks for your suggestions and help.


I definetely need to write document for hw.

I have heard people using SN65HVD230 and also hear may of them burning it. I do not know is is more sensitive than MCP2562, which I even run power polarity reversed a while - naturally it did not work, but worked after fixin right power.

It depends of your hw do you need isolation or not.
- If you make device, which does not connect to system 0V enywhere else than on N2k bus, then you do not need isolation. You can e.g. have device, which reads simple input state by using optoisolation components. You you can measure temperature or pressure, if your sensor is totally isolated.
- Either you practically do not need isolation, if you feed your device on near of yor N2k power feed = power cables from device to N2k power feed<0.5 m.
- If you measure e.g. engine oil pressure or temperature directly from engine sensor, then your sensor 0V is connected to system 0V. If you in this case use unisolated tranceiver, your 0V is connected through N2k bus and through engine 0V making ground loop, which may cause fancy and difficult effects even on other systems. In this case you should use isolated tranceiver.

Wikipedia has good article about "Ground loop".


Timo, you are a great teacher. Indeed, my project is very simple and I only intend to read data from the N2k bus and transmit some data from arduido sensors such as DHT11 temperature, magnetic compass type HMC5883 or / and a neo-7 gps. And display the data on a 3.5 or 40 inch screen. I believe that the can bus has enough power to power this example.
However, I am already working on an isolated system with direct power from the boat's battery, but that will be one more step. First I just want to try a nmea N2k simulator and this example to design the code in arduino.
Thank you for your help, without you most of us could not even start a project.


Oct 25, 2020, 05:17 am Last Edit: Oct 25, 2020, 05:18 am by soggygeek
Just to follow up... here is what I did to get things working... (Arduino Mega 2650 with Canbus Shield and 6810 BMS chip, both running with SPI communications).  It may not be absolutely correct, but it appears to be working.  I don't understand half of the things I'm doing--just sorta cutting and pasting code from simple Sketches that do work individually, but I'm learning a little at a time.

First, set the SPI settings up for the two different devices like this:

Code: [Select]
#define N2k_SPI_CS_PIN 9  // Pin for SPI CS for the Canbus
#define LTC681x_CS_PIN 8  // Pin for SPI CS for the LTC6810

// variables for two different SPI communications setups
SPISettings settingsNMEA(10000000, MSBFIRST, SPI_MODE0);
SPISettings settings6810(SPI_CLOCK_DIV16, MSBFIRST, SPI_MODE3);

In the code:

Code: [Select]
  // code here that talks to the 6810 BMS module

  // code here that talks to the NMEA Canbus shield

So I reset the SPI settings for every conversation.  I don't know the cost of this time-wise, but I don't have a need for super-fast communications. 

If I were really trying to do two-way NMEA 2000 communications, I am not sure how well this would work.  But right now, my Arduino is just blindly sending battery status.  I am receiving that status on my Raspberry Pi with a Can Hat running OpenPlotter and Signal K, as NMEA2000 data.  Haven't tried yet with a real NMEA 2000 device, like a Multifunction Display, and nobody else is on my NMEA2000 "network" (2 wires strung between the two devices connected to Can H and Can L).



Will you do the work and collect list of common issues? I do not have time.

In support they say: "We do not support NMEA 0183 and 2000 protocols yet. However, a bidirectional module will be available for purchase in Q3 2019." So for now this is wrong topic.
Yeah, we're well past Q3-2019. They abandoned support for that claim, and the entire reason I bought the system in the first place. I wouldn't be here if it were otherwise.
I think I am here to see if anyone else is trying to crack this system, but it looks like it's going to be one of those "reinvent the wheel" things.


Oct 30, 2020, 01:32 am Last Edit: Oct 30, 2020, 05:43 am by wonderplum
Bennett Trim Tab NMEA2000  "insect"  PGN:130576.  
Does anyone have information/code on Calibration method for this device? Currently the unit is toggling between 0 and 100 indicating "Hello I am on the buss but please calibrate me" Thanks for your help... this is a road block for me.


If you have own device, you can naturally calibrate it by your self.

In general as far as I know there is no standard way to do that. Device may believe if you set current tab position by using standard 126208 command group function. It could then set current position and save difference as offset. But for scaling I do not see any method.


RE: Bennett Trim Tab Calibration method.

Thanks Timo,
Don't understand your first sentence. I have Bennett trim tab Sensors(2), NMEA1 N2K interface hooked up to a Teensy 3.2 and 1050 bus driver. This is working fine and responding with toggled values of 0/100 for both tabs (Port&Stbd). I do not have a Maretron DSM200 MFD available to me which is capable of calibrating the NMEA1 trim tab interface (see attached extract). I presume that calibration parameters are stored internal to the Bennett NMEA1 module.

Maybe as you noted the answer may be with 126208 command group function.

I did see an earlier post  (Sept 2019) by autopilotNOR on the same subject. Perhaps he has resolved by now. Wonder if this forum supports direct question to members?


I quicly checked Bennet trim tab, but did not found how they work. Please explain your system more precicely.
You say "NMEA1 N2K interface hooked up to a Teensy 3.2".
1. Does Bennet trim tab connect directly to N2k bus.
2. Or do yo get analog or digital signal from trim tab to Teensy, which you translate and send to bus from Teensy with my library.

In case 2. you can send to bus what ever value you like with scale and offset.

You can send peronal messages to forum users.


Hi Timo

RE: Bennett Trim Tab Calibration method.

Further to your last reply (thank you!), here is my hardware/software config:
Bennett trim tab sensors are LVDT sensors (Ie measure the change in the measured inductance of a coil as a metal rod is inserted into the coil. The Bennett NMEA1 or "insect" as Bennett calls it is an encapsulated module which takes an input from the LVDT sensors (2 - 1 Port, 1 Stbd trim tab positions) and converts it into a PGN:130576 message onto the N2K bus. The Teensy 3.2 that I have (using your code and a tad of mine)  reads the PGN:130576 message and displays on the Arduino monitor screen. As mentioned before I see a toggling between 0 and 100 data sent for both trim tab position. I have concluded that I have to send Calibration parameters to the Bennett NMEA1. This is where I have come to a grinding stop and need some help. Thanks.


You have at least three possibilities:
1. Contact Bennet and request calibrarion commands and procedure.
2. If you just use your Teensy to show tab positions, make your own calibration table to it.
3. Borrow DSM200 and do calibration with it. You can then also spy network how to do it.

Note that it is possible that Bennet can not be calibrated and calibration on DSM200 will be done by using internal calibration table -> option 2.


Nov 02, 2020, 06:36 pm Last Edit: Nov 02, 2020, 06:40 pm by wonderplum
Hi Timo,

RE: Bennett Trim Tab Calibration method.

As I said before: The  Bennet NMEA1  (LVDT to N2K module is sending 0 and 100 alternatively on the Buss with no change in position of the  trim tabs. There is no other data that I can see. Tell me this: how do you "Calibrate" a signal that is simply toggling between 2 values?  Thnx.

I would like to send a message to autopilotNOP regarding his post on the same subject to see if he got anywhere. There does not appear to be an option on my message screen to send a message. Any help on this? Thnx

Go Up