Go Down

Topic: NMEA 2000 Shield (Read 384946 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.

Go Up