NMEA 2000 Shield

timolappalainen I am the new man in town, how do I obtain your 2000 library and hardware ??.

Looking into the future with my crystal ball there will be a transition over from CanBus to Ethernet ( it's already started, Can Bus is not fast enough for some apps, radar for example )

Have you chaps thought about writing your own 'Shareware Open Standard' and support Library for Ethernet so that users and manufacturer's do not have to keep paying for expensive Nema2000 licences, strikes me such a library would be very popular with end users as it would cause industry suppliers to standardise on one format therefore making their products all communicate with one another regardless of manufacture.

For embedded I prefer to use either Teensy or ESP32. Both has build in CAN and so requires only tranceiver e.g. MCP2562. Download the library and install it. Also download necessary libraries NMEA2000_Teensy and FlexCAN for Teensy or NMEA2000_esp32 for ESP32. Note that if you use Teensyduino, do not install FlexCAN with it. Or if you have done it already, delete FlexCAN from "C:\Program Files (x86)\Arduino\hardware\teensy\avr\libraries".

Read the NMEA2000_library_reference.pdf. There is not much about Teensy or ESP32, but they only differs of required "driver".

RPi is also possible for bigger projects and has ethernet and WiFi ready. There is example NMEA0183/Examples/NMEA2000ToNMEA0183 at master · ttlappalainen/NMEA0183 · GitHub. It works with PiCAN2 board or with my board, which has also NMEA0183 and 1-wire.

For 'Shareware Open Standard' there is already SignalK. And big manufacturers like Garmin, Raymarine, Lowrance would not go to any open standard. And Nmea is already planning OneNet and most big manufacturers are already participated.

Hello Timo,

Thanks for your great job !

I would like to change my hardware MEGA2560+Shield for a Arduino Due + a Can Transceiver.
I'd like to chose a ready to plug transceiver does it work with a SN65HVD230 based ?

https://fr.aliexpress.com/item/SN65HVD230-CAN-bus-transceiver-communication-module-for-arduino/32686393467.html

Regards.
FX VAN THUAN

Why not to Teensy? Smaller and better.

Library does not see the tranceiver, so it works.

Anyhow people have had more problems with SN65HVD230 than with MCP2562 tranceiver. I have used only that and never had any tranceiver problems.

Bonjour Timo,

Thanks for tout advice. I am going tout dig the Teensy track.

Merci.
FX

There is brakout board at http://skpang.co.uk/catalog/teensy-canbus-breakout-board-include-teensy-32-p-1507.html or just buy parts and follow NMEA2000/Examples/TeensyActisenseListenerSender at master · ttlappalainen/NMEA2000 · GitHub for basic connection. You probably do not need extra USB as on that device.

Bonjour autopilotNOR,

I use this 3 lines of code to get more stable values for the RPM:

int rpm_reel = 0;
....
rpm_reel = rpm_reel / 10; // Pour arrondir à 10 et ainsi eviter que le nombre flucute trop
rpm_reel = rpm_reel * 10; // Pour arrondir à 10 et ainsi eviter que le nombre flucute trop

So the value is always a multiple of 10.

I don't use the FreqMesure, but I am going to try it because I have a limitation with my current sketch.
I use interrupts and I have to use a dedicated Arduino board to mesure RPM and Temperatures (Engine and Fridge), and an other one to get datas from the Victron BMV700 Battery controler.
This last app uses interrupts as well.

The project is to merge this two applications on the same Mega Board.
Today, each board works well separately , but the new sketch I am writing for the Mega is not yet reliable because of the interrupts.

Amicalement.
FX

You can get very stable value by using FreqMeasureMulti library and low pass filter with it:

double ReadRPM() {
#define FilterWeight 0.005
static double Average=0;
...
 while ( FreqMeasure.available() ) {
    double PulseWidth=FreqMeasure.read();
    Average = (FilterWeight * PulseWidth + (1 - FilterWeight) * Average);
 }

 return FreqMeasureMulti::countToFrequency(Average)*60;
}

You need to poll above fast enough.

Low pass filter value FilterWeight depends of your altenator frequency. I think above value was with altenator providing pulses with factor 11. For higher frequency you have to change it even smaller.

Too small value on low pass filter make result stable, but response is slower and opposite. The problem with above is that with RPM measuring you do not get reading constantly. So above filter value may be OK with 4000 RPM, but a bit lazy below 1000 RPM. One solution is to make it adaptive as I have, but the code is a more complex.

Timo,
I've had good success with the NMEA 2000 libraries, so I started to take a look at your NMEA0183>NMEA2000 conversion routines.
They only seem to deal with navigation/GPS parameters? Do any exist for converting DBT or depth sentences form NMEA0183?
I have a transducer which spits out NMEA0183 at 4800Baud which I might try to integrate into the N2K network.

Both the sounder and the plotter are at home over the winter so I can experiment.

Apologies if I haven't found the right docs on GitHub!

Cheers, Graeme

I do not seem to have parsers for depth on NMEA0183 library. They are relative easy to add, but just now I am relative busy. I could add them within 2-3 weeks.

timolappalainen:
I do not seem to have parsers for depth on NMEA0183 library. They are relative easy to add, but just now I am relative busy. I could add them within 2-3 weeks.

If you find the time over the next few months - great - otherwise don't worry about it!

Bonjour Timo,

I have these messages when I compile:

[color=red]C:\Users\VANTHUAN\Documents\Arduino\libraries\NMEA2000\src/N2kMsg.h:83:7: warning: type 'struct tN2kMsg' violates one definition rule [-Wodr]

 class tN2kMsg

       ^

C:\Users\VANTHUAN\Documents\Arduino\libraries\NMEA2000\src\N2kMsg.h:83:7: note: a different type is defined in another translation unit

 class tN2kMsg

       ^

C:\Users\VANTHUAN\Documents\Arduino\libraries\NMEA2000\src/N2kMsg.h:96:8: note: the first difference of corresponding definitions is field 'TPMessage'

   bool TPMessage;

        ^

C:\Users\VANTHUAN\Documents\Arduino\libraries\NMEA2000\src\N2kMsg.h:83:7: note: a type with different number of fields is defined in another translation unit

 class tN2kMsg

       ^

C:\Users\VANTHUAN\Documents\Arduino\libraries\NMEA2000\src/N2kCANMsg.h:28:7: warning: type 'struct tN2kCANMsg' violates one definition rule [-Wodr]

 class tN2kCANMsg

       ^

C:\Users\VANTHUAN\Documents\Arduino\libraries\NMEA2000\src\N2kCANMsg.h:28:7: note: a different type is defined in another translation unit

 class tN2kCANMsg

       ^

C:\Users\VANTHUAN\Documents\Arduino\libraries\NMEA2000\src/N2kCANMsg.h:39:11: note: the first difference of corresponding definitions is field 'N2kMsg'

   tN2kMsg N2kMsg;

           ^

C:\Users\VANTHUAN\Documents\Arduino\libraries\NMEA2000\src\N2kCANMsg.h:39:11: note: a field of same name but different type is defined in another translation unit

   tN2kMsg N2kMsg;

           ^

C:\Users\VANTHUAN\Documents\Arduino\libraries\NMEA2000\src/N2kMsg.h:83:7: note: type 'struct tN2kMsg' should match type 'struct tN2kMsg' that itself violate one definition rule

 class tN2kMsg

       ^

C:\Users\VANTHUAN\Documents\Arduino\libraries\NMEA2000\src\N2kMsg.h:83:7: note: the incompatible type is defined here

 class tN2kMsg

       ^

C:\Users\VANTHUAN\Documents\Arduino\libraries\NMEA2000\src/NMEA2000.h:79:7: warning: type 'struct tNMEA2000' violates one definition rule [-Wodr]

 class tNMEA2000

       ^

C:\Users\VANTHUAN\Documents\Arduino\libraries\NMEA2000\src\NMEA2000.h:79:7: note: a different type is defined in another translation unit

 class tNMEA2000

       ^

C:\Users\VANTHUAN\Documents\Arduino\libraries\NMEA2000\src/NMEA2000.h:367:17: note: the first difference of corresponding definitions is field 'N2kCANMsgBuf'

     tN2kCANMsg *N2kCANMsgBuf;

                 ^

C:\Users\VANTHUAN\Documents\Arduino\libraries\NMEA2000\src\NMEA2000.h:367:17: note: a field of same name but different type is defined in another translation unit

     tN2kCANMsg *N2kCANMsgBuf;

                 ^

C:\Users\VANTHUAN\Documents\Arduino\libraries\NMEA2000\src/N2kCANMsg.h:28:7: note: type 'struct tN2kCANMsg' should match type 'struct tN2kCANMsg' that itself violate one definition rule

 class tN2kCANMsg

       ^

C:\Users\VANTHUAN\Documents\Arduino\libraries\NMEA2000\src\N2kCANMsg.h:28:7: note: the incompatible type is defined here

 class tN2kCANMsg

       ^

C:\Users\VANTHUAN\Documents\Arduino\libraries\NMEA2000\src/NMEA2000.h:213:9: warning: type 'struct tMsgHandler' violates one definition rule [-Wodr]

   class tMsgHandler {

         ^

C:\Users\VANTHUAN\Documents\Arduino\libraries\NMEA2000\src\NMEA2000.h:213:9: note: a different type is defined in another translation unit

   class tMsgHandler {

         ^

C:\Users\VANTHUAN\Documents\Arduino\libraries\NMEA2000\src/NMEA2000.h:217:18: note: the first difference of corresponding definitions is field 'pNMEA2000'

       tNMEA2000 *pNMEA2000;

                  ^

C:\Users\VANTHUAN\Documents\Arduino\libraries\NMEA2000\src\NMEA2000.h:217:18: note: a field of same name but different type is defined in another translation unit

       tNMEA2000 *pNMEA2000;

                  ^

C:\Users\VANTHUAN\Documents\Arduino\libraries\NMEA2000\src/NMEA2000.h:79:7: note: type 'struct tNMEA2000' should match type 'struct tNMEA2000' that itself violate one definition rule

 class tNMEA2000

       ^

C:\Users\VANTHUAN\Documents\Arduino\libraries\NMEA2000\src\NMEA2000.h:79:7: note: the incompatible type is defined here

 class tNMEA2000

       ^

C:\Users\VANTHUAN\Documents\Arduino\libraries\NMEA2000_mcp/NMEA2000_mcp.h:42:7: warning: type 'struct tNMEA2000_mcp' violates one definition rule [-Wodr]

 class tNMEA2000_mcp : public tNMEA2000

       ^

C:\Users\VANTHUAN\Documents\Arduino\libraries\NMEA2000_mcp\NMEA2000_mcp.h:42:7: note: a type with different bases is defined in another translation unit

 class tNMEA2000_mcp : public tNMEA2000

       ^[/color]

[color=blue]Le croquis utilise 30644 octets (12%) de l'espace de stockage de programmes. Le maximum est de 253952 octets.
Les variables globales utilisent 1093 octets (13%) de mémoire dynamique, ce qui laisse 7099 octets pour les variables locales. Le maximum est de 8192 octets.[/color]

The compilation go to the end.
At the end, I have the message in blue color, but I also have the messages in red.
What does it means ?
Anyway it seems to work well. The data I send can be read on the MFD.

Merci.
FX

Looks like you would have two copies of NMEA2000 libraries with different names under your libraries. Search e.g. NMEA2000.h from your libraries and check that it founds only one.

Bonjour Timo,

Well... the NMEA2000 was actually unique.
But the problem was around the libraries directories indeed.
I have erased the previous NMEA2000 directory, then re-downloaded and added the library into the Adruino IDE and the error disappeard.

Merci beaucoup. :slight_smile:
Regards.
FXVT

Bonjour Timo,

I use a MultiDevice Sketch (2 devices: Engine and Battery) and the problem is that the ProductInformation is not always reliable on the B&G Triton (Menu Parameters/Sources/Engine or Battery).
Most of the time, it does'nt recognise the devices.

I meet different cases:

  • No product found: The Triton does not recognise any "Arduino Device", but it is ok for the other regular devices (pilot, VHF, MFD...) (Picture N°1). Off course, it does'nt display anything from the Arduino

  • The Device Name is strange, like "???00?????????????POX!..." : In this case, despite a strange name, it is Ok, the Triton displays correct datas coming from the Arduino (Pictures 2, 3, 5)

  • The Device Name is OK: The device name displayed by the Triton is faithful to the name set in the NMEA2000.SetProductInformation. Of course, in this last case, the Triton can display the datas (Pictures 4, 5). Nevertheless I have never had the correct name for 2 devices at the same time.
    The best result I have is when the 2 devices have been both recognized with strange names.

I don't change anything in my sketch, and I have to switch on/off several times the whole network and the instuments to get sometime a correct display.

Anyway, the datas (RPM, Voltage, T°) are always correctely send on the network, because the Raymarine devices (A78 MFD and i70) always recieve and display these datas, even if they don't recognise the device's names send by the Arduino.
The trouble is only with the B&G Triton who need to get a device name to be able to display its datas.

I use an Arduino Mega with Canbus Shield who work well when using single-device sketches.

Merci.
Regards.
FX

1 Triton No Product.jpg

2 Triton curious name.jpg

3 Triton Engine name OK.jpg

4 Triton Battery name OK.jpg

5 Triton Display OK.jpg

  • Do you use interrupt with NMEA2000 library? With interrupts library is more reliable, since it buffers frames on both send and receive side.

  • Take care you have big enough buffers. As default with mcp you should have 50 frame buffer, which should be big enough on small systems. You can set buffer sizes on setup() with commands
    NMEA2000.SetN2kCANSendFrameBufSize(150);
    NMEA2000.SetN2kCANReceiveFrameBufSize(150);
    Call those before calling anything else for library.

  • Have you tested without using multidevice system? It is still open for me is it even possible to do NMEA certification with my multidevice support. There is no requirement that device sending different types should act as multi device - specially, if device is just for your own.

Other data will be sent to bus right, since you do it. NMEA 2000 logic and communication requires that you do not loose input frames, which means that it is best to use interrupting and never ever have a delay() in your code. If you use other libraries for sensors, you should also check that they do not have delay or spent do long for reading data. E.g. normal DallasTemperature library in synchronous mode may cause long delays, so that e.g. product information requests will be lost.

Again I prefer to check e.g. Teensy 3.2 or higher - less power consuming, more flash/RAM, faster, smaller layout, better CAN.

Bonjour Timo,

I have clearly understood concerning the Teensy vs Mega. And if I have too much troubles, I will change for a Teensy, who is moreover faster.

As far as I know, I don't use interrupts neither delay in my sketch.
But it is possible that the libraries I use contain such instruction. I use Freqcount.h.

I also use DallasTemperature.h with the lowest temperature resolution (9 bits, 0,5°C) to get the fastest response (93.75 ms)

I will edit my sketch with the buffer adjustements and try that as soon as I return to the boat.

Merci.
Regards.
FX

You have to use DallasTemperature in async. I use it with full 12 bit resolution and max. off time is 10 ms, which is still much - you may get 24 frames on that time. With 93 ms off time othere systems may give up with fast packets.

I have one old one wire code, which I can send you, if you send me personal message. I still use a lot 1-wire, but not with direct pin. Instead I use "DS2482-100 Single-Channel 1-Wire Master" chip to take of most 1-wire communication and i2c_t3c library with Teensy, so that I have 1-wire communication totally interrupt handled.

Freqcount does not cause delays.

I am looking for the motor temperature sensor to connect to my axiom 7 via NMEA 2000 i can use external sensor I just need the simple programming script is anyone have it ?

There is example TemperatureMonitor on NMEA2000 library, which sends data to the bus. You just need to add code for temperature sensor you use. If you are going to use 1-wire sensor and Teensy, send me your email by personal message, so I can send you sketch, which sends several different 1-wire sensor values to the bus.