NMEA 2000 Shield

Hopefully you have enough memory on your system. tN2kDeviceList class is for that purpose and there is example DeviceAnalyzer, where that has been used. You just create object:

pN2kDeviceList = new tN2kDeviceList(&NMEA2000);

and that automatically catches new devices and device changes on the bus. In well made system you should glue your data to NMEA NAME. You can e.g. have two devices sending "PGN 127505 Fluid Level" information from different tanks. And both may have same instance values. So the only way is to separate them by source. But due to address claiming, source may change. So here you can then use

pN2kDeviceList->FindDeviceByName(name);

and you can then get tNMEA2000::tDevice, where you have all information - also source.
You have to also periodically check ReadResetIsListUpdated and if that returs true, you check your watch devices source again.

The class does not have any enumeration function, but due to structure it is as effient to to use:

for ( size_t i=0; i<=N2kMaxCanBusAddress; i++) {
  const tNMEA2000::tDevice *pDevice=pN2kDeviceList->FindDeviceBySource(i);
  if ( pDevice!=0 ) {
    // Do something
  }
}

Note that on tNMEA2000::tDevice you can also read PGN:s they transmits and all other information available from device.

I prefer to have at least Due for using tDeviceList. I have tested it on Mega, but on bigger system memory runs out. Again with Teensy 3.2 you can do a lot more.

Timo, thank you for fast reply.
That is, at least at the moment, too complex for me.
I do not understand how the classes are working.
If you can recommend documents to study this stuff, that would be helpful.

What document you mean? About c++ classes, NMEA2000 library or NMEA2000 protocol? For NMEA2000 library there the one inside documents, but there is not much about tDeviceList. For NMEA2000 protocol I have not found good free document. Information is around in small pieces.

But using tDeviceList is far more easier than try to do it yourself from the scratch. And about your original question "if one of two similar devices is alive on the bus", what you actually mean with that? How do you define "similar device"? Do you know their product code? Or do you know the PGN, they should send? For both questions tDeviceList is an simple solution, because it collects all device information automatically just by joining it to NMEA2000 object as I wrote earlier and as it is on DeviceAnalyzer.

I prefer you to study how to use classes. You do not need to write them, but you need to use them.

Timo, my problem is my missing knowledge with c++ classes.
So, first I have to look for a c++ book and do my homework.

Maybe you can help me with the following problem:

I can read PGN 129284 NavigationInfo with Actisense Listener, all 15 fields have the correct information.

But, with the following sketch all fields have wrong info, for instance, SID is always 255.
PGN 126992 SystemTime is working correct.

NMEA2000_Rx_Waypoint_0_0.ino (2.73 KB)

There was a bug in ParseN2kPGN129284. I updated the fix to the library.

Timo, thanks a lot, it is working fine now.

I also tried PGN129285 and PGN130074 to get position of the next waypoint.
But, with this two PGN´s I got a compiling error with the line
if (ParseN2k...

As I can see in N2kMessages.H, this data is probably stored in a database.

Do yo have an example, how to read such a database?

Unfortunately there is no parser functions for those PGN:s written. Also noticed that I should have been more carefull on accepting merge for those messages, since the writer comments does not match to then parameter list.

There is no database on NMEA2000 protocol. Protocol is just for exchanging data between devices. So the database, all database and route ID:s are manufacturer specific.

Also both of those messages are rather complicate to handle. I do not have NMEA2000 plotter for testing waypoint data exchanging, so I am not how they do it. NMEA2000 fastpacket can carry only few waypoints. So they either send several fastpackets for single route so that you separate data by waypoint start ID. Other possiblity is to use transport protocol, which can move about 1800 bytes data. But even that gets full with long route. And on the other hand currently library does not support large transport protocol packets.

For the 130074 document says "Complex request of this PGN should return the Waypoints of a WP-List". So the devices does not send that automatically. Also other waypoint/route information will be returned with "Complex request" - and I really agree the name of request.

For 129285 document says "It can be requested or may be transmitted without a
request, typically at each Waypoint advance." So also this is rather complex and has same problems as other waypoint/route information PGNs.

Timo, thank you for new information.
For me PGN 129284 is sufficient.

I have a Lowrance HDS9, and I checkt how PGN´s 129284, 129285, 130074 are working:

129284: HDS is sending this, as far as I navigate to a waypoint. A route is not necessary.

130074: is send automatically, as far as I save a new waypoint.

129285: is send automatically, as far a route is active.

Hey Timo,

do you have tested the Teensy3.x together with the SN65HVD234?

I have a couple of them and since they are not that cheap and due to the readme of the FlexCAN library the SN65HVD´s seems to be a bit more stable or at least support higher bandwidth at 3.3v ( I know that the NMEA2K library just use 500K) I would like to use them.
They also just need 3.3v and not both 5&3.3v like the MCP2562.

So is there anything against using them instead the MCP2562 in combination of teensy boards?

Regards..

That is on the hw side and library does not known anything about it. So if you think it ise better, just use it.

And NMEA 2000 runs 250 kb/s NOT 500 kb/s

Hello,

even if I am already afraid to ask, is there somebody so nice to explain me what that with SID - Sequencial ID is about?
I am workign on the battery monitor right now and found this for the SID in the N2kMessages.h at DC detailed status:

"Sequence ID. If your device is e.g. boat speed and heading at same time, you can set same SID for different messages to indicate that they are measured at same time."

Thank you!

The explanation for SID has been just copied, but the meaning is same. On Maretron document they write:

SID – The sequence identifier field is used to tie related PGNs together. For example, the GPS200 will transmit identical SIDs for 126992 (System Time), 128259 (Speed), 129026 (COG and SOG, Rapid Update), 129029 (GNSS Position Data), 129539 (GNSS DOPs), and 129540 (GNSS Satellites in View) to indicate that the readings are linked together (i.e., the data from each PGN was taken at the same time although they are reported at slightly different times).

Will that explain it better?

So it could be same for DC information. You can provide DC status and battery status information with same SID, if they are measured at same time. Due to transmission delay there will be small difference, when messages will be received, but for same SID receiver can then use same time for values e.g. for calculations.

I guess I got it now, thank you!

To clarify as example:

If I have now an device like GPS I could use the heading SID for a message which will show me the position on the map and could use the same SID and the value generated or measured by one sensor use at the same time in another message wich will be for example feedback for the autopilot.

If I see this right than the matter of this is to reduce the traffic on the bus or at least reduce the amount of times the values to be send needed to be generated or measured by the sensor system or in this case GPS.

So in case of the battery monitor which is for to batteries I could use several values/SID´s like the DCType for both batteries if the same generator is charging both of them.

Hopefully Right?

I did not understood your example. What you mean with "in another message wich will be for example feedback for the autopilot."? In bus system you just mostly provide messages to the bus and not to specific device. Also many PGNs messages can not be sent to specific destination.

Also you can not use SID for reducing traffic. If your device is sending some message, it should send it in periodically with same defined period. With the complex group function it is possible to change period for specific message, but it should then be steady.

Either I did not understood the last sentence. Normally SID is incrementing value. So if you battery monitor measures 3 batteries and measures all voltages on same time and then start to send messages for each battery, you use for first period e.g. SID=1 for all 3 127508 PGNs - each will have different BatteryInstance. On next period you set SID=2 for each message. But if you measure values just before sending each msg, you do not measure them at same time. Then you should in principle set SID=1 for first msg, SID=2 for second and SID=3 for last. Then on next period you set SID=4 for first and so on. This is since they are not measured "at same time".

ok, than i thought completly wrong but understood it now. THX

Hello,

I came now to the point to connect the MFD ( Raymarne Axiom 9RV ) to the bus of the teensy to test if I get communication to the MFD.

After I didn´t got shown anything from the extern teensy´s on the Axiom ( during the network scan nothing showed up ) I to the messagesender and the Datadisplay to test the communication on the bus. I can see all comming from the messagesender on the datadisplay, but again nothing seems to be available on the MFD.

I stuck now a bit and don´t know where to start to troubleshoot and locate the problem.

Is there any advise you have for me to get further?

Kindly regards..

  • Again, do you have proper termination resistors on the bus?

  • Instead of using DataDisplay, use ActisenseListener example and NMEA Reader. You should see both MessageSender messages and Axiom messages on the bus. If you do not see Axiom, have you crossed CAN L and CAN H.

Hello Timo,

termination is 100% ok. First just used the 120 ohm resistor parallel to H/L on each end one. Than after it didn´t worked I connected through an original cable and terminators.

I use the SN65HVD234 with Teensy 3.2 like shown one the picture ArduinoDue_CAN_with_SN65HVD234.jpg. To test I used the standart sketches, just added/modified to use with teensy.

The Actisence listener sketch and listening on the bus with Actisense NMEAReader wasn´t successfull. There is a lot of load during when opend the com port from the Teensy running the actisense listener sketch.

Like mentionedthe datadisplay was showing the data send from the second teensy running the messagesender sketch.

I´ll test from beginning one more time just to be sure..

I located the problem!

Even the Axiom is delivering 12V from the bus connector, I have to connect from extern 12 V to the bus wire. Now it seems to work!

Hello Timo,

I just found this document PGN NMEA Overview on nmea.org regarding the PGN´s and the temperatur PGN 130312 is deprecated.

Is that the reason why there are to PGN´s ( 130312 & 130316 ) for temperatur in the library?

Thanks.