Go Down

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

timolappalainen

Sorry I did not read it carefully. I read that it was #define N2k_CAN_INT_PIN 10, which would define that pin 10 will be used for interrupt. You must have #define N2k_SPI_CS_PIN 10 (or 9) for UNO.

You do not need interrupt wire for communication. In tha case you must not have #define N2k_CAN_INT_PIN xx as you do not. Interrupt is critical, if you read bus data, because otherwise you will easily loose data.

Do you have UNO connected to the bus? Since you have NGT, I'll prefer to connect UNO and NGT to the bus with right terminator resistor. Leave MFD out at this moment. Then you can read bus traffic via NGT. I also prefer to change NGT to read oll messages instead of filtering anything. This you select on NMEA Reader. Since you now have:
NMEA2000.EnableForward(false);
That disables all message forwarding to USB. So it won't print any messages anymore.
You could also uncomment
NMEA2000.SetForwardType(tNMEA2000::fwdt_Text);
So it will show something as clear text.

So if you do not see any messages sent by UNO on NMEA Reader, then you have to really debug, what goes wrong with UNO. You can search println on NMEA2000.cpp and uncomment those in some places and see, if you find place, where it stops. As I mentioned I do not have UNO, you have to do the tests.

r2d290

Hello

Thanks for the reply and clarification regarding interrupt. I've left the boat now, but I'm eager to get back with more information within a few days.

Quote
Do you have UNO connected to the bus?
I'm not totally clear on this question. If the "bus" is defined by the thing on the boat that looks like:
TTTTT (the thing that the MDF, the CD-player and my NGT is connected to), then yes - the Arduino is connected to the bus, but via the NGT. Or did you mean the MOD-bus shield? Then yes, the Modbus-shield is connected to the pins in the UNO.

So: MFD<-->TTTT <--NGTcabel--NGT--NGTcabel(with DB9-connector)-->Modbus-shield <--> Arduino <--> USBcabel --> PC.

And when I was reading from the entire system with NGT, it was like:
MFD<-->TTTT <--NGTcabel--NGT--NGTcabel(with DB9-connector)--> <--DB9toUSB-cabel--> PC.

Hope this made sense. If not, please ask for clarification :)

Quote
Since you have NGT, I'll prefer to connect UNO and NGT to the bus with right terminator resistor. Leave MFD out at this moment. Then you can read bus traffic via NGT
Do you mean that I can connect my UNO (or do you mean the MOD-BUS DB9-connector?) to to the TTTTT in the boat, without using the NGT in between? That would be too awesome. How is that done? Do I need a special cabel or something, since the Mod-Bus shield has a DB9-connector, and the TTTTT has a circular connector with 5 pins. What does the NGT-1 even do, btw? I thought it was kind of "decrypting" the NMEA-2000 signal to a serial-signal.

Btw: What is the "right" terminator resistor, and where is this supposed to be placed?
If I don't remember totaly wrong, there is already a resistor at the end of the TTTTT. Does this have anything to do with it?

I have TeamViewer to the computer on the boat, so I tried what you said regarding changing filtering in NMEA Reader. I could not find this option. The closest I found was Edit -> Preferences -> Transfer: Receive All, but this option was disabeled by a reason? See attached pic.

Code: [Select]
NMEA2000.EnableForward(false);
That disables all message forwarding to USB. So it won't print any messages anymore.

The only thing it prints to the Serial monitor is my Serial.println()-lines. But (and this might be important?) before I added this line, it only printed rubbish - mostly squares without line break. I have tried all the baude-rates on the serial-monitor, but I assume the correct is 115200. Is it supposed to print anything else than rubish to the Serial-monitor?
But - even with that line, I'm still abel to read things on the NMEA-reader through the USB-cabel when the Arduino is set to debug-mode..

Quote
You could also uncomment
NMEA2000.SetForwardType(tNMEA2000::fwdt_Text);
So it will show something as clear text.
Well, yes - it returned "something" as clear text now, but still a lot of rubbish. See attached picture.
Actually - I think the rubish is printed regardless of the EnableForward(false)-line.

Quote
As I mentioned I do not have UNO, you have to do the tests.
I will be more than happy to do some troubleshooting with this - If you can only get me started with the part with connecting the Arduino to the bus without the NGT, so that I can use the NGT to troubleshoot with.

Again, thanks a lot!

timolappalainen

I am sorry to tell you that you have understood this a bit (or maybe a lot) wrong. The bus means NMEA 2000 bus - see e.g. image on bottom of page http://www.actisense.com/products/nmea-2000/ngt-1/ngt-1. Devices on bus we can call just device or also as node sometimes. Each device on bus will get own address or also called source on code. Bus is similar as street, which has houses each with own number so that post knows where to deal messages (=letters).

So now you have MDF. This is one device. NGT is an other device. On picture there are also wind and log sensors. They both are own devices. All has been connected together with bus cable, which actually has two communication wires CAN L (blue wire) and CAN H (white wire) Other three wires on bus cable are shield (gray), 0 V (black) and 12 V (red). There is no magic with this cable. If you like to save expensive  NMEA2000 connectors, you can search DeviceNet connectors and you will find same stuff. Or you can even just cut the cable and use screw terminals.

The point of my NMEA 2000 library is to make device that connects directly to the bus (CAN L and CAN H). And if you like you can also take power for the board from the bus, if you have right voltage converter like UNO has. So to connect UNO to the bus is similar as my schema https://github.com/ttlappalainen/NMEA2000/blob/master/Documents/ArduinoMega_CAN_with_MCP2515_MCP2551.pdf. And if you do not want to glue MCP2515, MCP 2551 and other stuff yourself, you should buy http://wiki.seeed.cc/CAN-BUS_Shield_V1.2/.

So you configuration, where you have UNO with MODBUS shield can not work at all, since the communication on N2k bus (=NMEA 2000 bus) is different than on serial on the other side of NGT. No I do not actually understand, why lower level library mcp_can even reports that communication opens, if you have wrong shield!

When you have right shield, you connect your UNO just an other device as in picture I mentioned above. And the termination resistors marked by A2K-TER-F on picture are just 120 ohm resistors on nice (and expensive) package.

If your NGT id not tightly srewed to the boat, take it with you to home and you can start to develop system at home. Then buy CAN bus shield and connect it to NGT on N2k side. Also connect termination resistors to your short bus - for short test bus one is enough. Then connect NGT ont the serial side to PC with serial to USB as you had. And finally connect UNO USB to PC. Now with TemperatureMonitor example you have bus system with two devices - UNO and NGT. With NMEA Monitor you should see what your TempertureMonitor (UNO) sends to the bus. When taht works, you can go to the boat and connect them to same bus with MFD, and you should see TemperatureMonitor as a device on MFD device list.

And some answers:
- Yes, you can connect UNO to TTTTT with CAN bus shield.
- You do not need special cable. As I mentioned, you just need to connect CAN L and CAN H on shield to related wires on the bus. Or you can by NMEA 2000 T-bone and suitable connectors.
- Yes, NGT converts NMEA 2000 to Actisense serial format, which I also use in my library on PC side communication. E.g. Maretron uses a bit different encoding. You need NGT to get data to PC. You you can use Arduino DUE or Mega or Teensy with my example ActisenseReader.
- Terminal resistors has to be on both end of the bus. So you can have bus through the boat from aft to bow and devices connected on the middle (as in picture) with some T-connector. Terminals should then be on the aft and bow ends of the cable. Each cable from T-connector to device must not exceed 6 meters.

Have a nice eastern!

r2d290

Hello.
Thanks for your great reply. Now, things is starting to be a bit more clear.

Quote
So you configuration, where you have UNO with MODBUS shield can not work at all, since the communication on N2k bus (=NMEA 2000 bus) is different than on serial on the other side of NGT. No I do not actually understand, why lower level library mcp_can even reports that communication opens, if you have wrong shield!
I'm so sorry for the confusion. I don't know why I was suddenly start talking about Modbus-shield. I don't have a modbus-shield, I have - as you link to - a CAN-BUS Shield V1.2 :)

Actually, I think I will go back to the boat now, bring back a few NMEA2000 Connectors, the two terminal resistors, the ngt and the UNO with CAN-bus shield, and see what more I can do :)

r2d290

Wohoo, I made it :) The MFD is now showing a water temperature of 15.5 degrees (Wished it was so well).
It was a bit easier when I did not have the NGT between the bus and the CAN-bus shield :)

Now, time to start experimenting with some real data. Thank you so much for your help :)

timolappalainen

Great you got it running. You could also test does it work with interrupt by defining right line with
#define N2k_CAN_INT_PIN xx
Since system has to handle all messages, without interrupt it may loose address claiming or ISO request messages, which MDF:s use time to time to check are devices alive. If you look MFD device list, your device may time to time disappear, if those messages has been missed. This is not critical for information like temperature, but like I have my Arduino as NMEA0183->NMEA2000 converter for GPS, my MFD start to alarm, if it looses device.

Please report, if you get your UNO system working and what exeptions there may be. With execptions I mean e.g. those buffer definitios etc.

xotet

Hi Timo, first of all thanks for your work and thanks to share with all the comunity.

 It´s possible to adapt the library to work with arduino ZERO + CAN BUS shield? since is the same size factor than UNO and more powerfull??

 I´m planing my project wich consisit of a simple Tanks and Battery Monitor with an LCD on the main cabin.

 Thanks in advance



 

timolappalainen

Hi,

I do not see why not. The main problem with Uno was low memory, which could be fixed with buffer settings. So with Zero board you do not need to define smaller buffers.

I could not find information is CAN BUS shield compatible with Zero board. Please note that Zero uses 3.3 V IO. Also you need to check, which IOs are CS and int.

Have you checked https://hackaday.io/project/11055-kbox? It's nice hw with lot of ready functions.

xotet

Hi,

I do not see why not. The main problem with Uno was low memory, which could be fixed with buffer settings. So with Zero board you do not need to define smaller buffers.

I could not find information is CAN BUS shield compatible with Zero board. Please note that Zero uses 3.3 V IO. Also you need to check, which IOs are CS and int.

Have you checked https://hackaday.io/project/11055-kbox? It's nice hw with lot of ready functions.
Thanks Timo

 I found Kbox very interesting since include also a bridge to nmea0183 to nmea2000 and wifi hotspot, hopefully I can use with my AIS nmea0183.


seamaster

#189
May 13, 2017, 09:11 am Last Edit: May 13, 2017, 09:23 am by seamaster Reason: Insert images
Hi again guys!
after couple of months of other tasks I'm back on my project. everithing went well until i ran into problem, so i need your help to resolve it.
Here is my setup:
Simple bus with 2 devices made by me. each device is terminated with 120ohm resitor between Net-L and Net-H.
on the receiving side, Arduino Uno with CanBus shield running the Actisense_listener example code:
Code: [Select]

#define N2k_SPI_CS_PIN 10
//#define N2k_CAN_INT_PIN 21
#include <SoftwareSerial.h>
#include <Arduino.h>
#include <NMEA2000_CAN.h>
//SoftwareSerial mySerial(3, 4); // RX, TX
void setup() {
  Serial.begin(4800);
 //  mySerial.begin(38400);
  NMEA2000.SetForwardType(tNMEA2000::fwdt_Text); // Show in clear text
  NMEA2000.SetForwardStream(&Serial);  // PC output on due native port
 
  NMEA2000.Open();
}

void loop() {
  NMEA2000.ParseMessages();
// if (Serial.available()) {
 //   mySerial.write(Serial.read());

}




on the transmitting side Teensy 3.2 with MCP2551 running the Temperature monitor example code:

Code: [Select]


// Demo: NMEA2000 library. Send main cabin temperature to the bus.

#include <Arduino.h>
#include <NMEA2000_CAN.h>  // This will automatically choose right CAN library and create suitable NMEA2000 object
#include <N2kMessages.h>

// List here messages your device will transmit.
const unsigned long TransmitMessages[] PROGMEM={130310L,130311L,130312L,0};

void setup() {
  // Set Product information
  NMEA2000.SetProductInformation("00000001", // Manufacturer's Model serial code
                                 100, // Manufacturer's product code
                                 "Simple temp monitor",  // Manufacturer's Model ID
                                 "1.1.0.21 (2016-12-31)",  // Manufacturer's Software version code
                                 "1.1.0.0 (2016-12-31)" // Manufacturer's Model version
                                 );
  // Set device information
  NMEA2000.SetDeviceInformation(112233, // Unique number. Use e.g. Serial number.
                                130, // Device function=Temperature. See codes on http://www.nmea.org/Assets/20120726%20nmea%202000%20class%20&%20function%20codes%20v%202.00.pdf
                                75, // Device class=Sensor Communication Interface. See codes on  http://www.nmea.org/Assets/20120726%20nmea%202000%20class%20&%20function%20codes%20v%202.00.pdf
                                2040 // Just choosen free from code list on http://www.nmea.org/Assets/20121020%20nmea%202000%20registration%20list.pdf                              
                               );
  // Uncomment 2 rows below to see, what device will send to bus. Use e.g. OpenSkipper or Actisense NMEA Reader                          
  Serial.begin(115200);
  NMEA2000.SetForwardStream(&Serial);
  // If you want to use simple ascii monitor like Arduino Serial Monitor, uncomment next line
  NMEA2000.SetForwardType(tNMEA2000::fwdt_Text); // Show in clear text. Leave uncommented for default Actisense format.

  // If you also want to see all traffic on the bus use N2km_ListenAndNode instead of N2km_NodeOnly below
  NMEA2000.SetMode(tNMEA2000::N2km_NodeOnly,22);
  //NMEA2000.SetDebugMode(tNMEA2000::dm_Actisense); // Uncomment this, so you can test code without CAN bus chips on Arduino Mega
  //NMEA2000.EnableForward(false); // Disable all msg forwarding to USB (=Serial)
  // Here we tell library, which PGNs we transmit
  NMEA2000.ExtendTransmitMessages(TransmitMessages);
  NMEA2000.Open();
}


void loop() {
  SendN2kTemperature();
  NMEA2000.ParseMessages();
}

double ReadCabinTemp() {
  return CToKelvin(22.5); // Read here the true temperature e.g. from analog input
}

double ReadWaterTemp() {
  return CToKelvin(15.5); // Read here the true temperature e.g. from analog input
}

#define TempUpdatePeriod 1500

void SendN2kTemperature() {
  static unsigned long TempUpdated=millis();
  tN2kMsg N2kMsg;

  if ( TempUpdated+TempUpdatePeriod<millis() ) {
    TempUpdated=millis();
    SetN2kTemperature(N2kMsg, 1, 1, N2kts_MainCabinTemperature, ReadCabinTemp());
    NMEA2000.SendMsg(N2kMsg);
    SetN2kEnvironmentalParameters(N2kMsg, 1, N2kts_MainCabinTemperature, ReadCabinTemp());
    NMEA2000.SendMsg(N2kMsg);
    SetN2kOutsideEnvironmentalParameters(N2kMsg, 1, ReadWaterTemp());
    NMEA2000.SendMsg(N2kMsg);
    // Serial.print(millis()); Serial.println(", Temperature send ready");
  }
}



I have terminal program (CoolTerm) connected to the USB/Serial port on the Arduino Uno (listener) to monitor what will be coming over the N2K bus. When I connect to the port it shows me that:
See attachment called Coolterm1.png

when I start the Teensy 3.2
and open the Serial Monitor to the Teensy USB/Serial port I get this

See attachment called Teensy_Monitor1.png


on the receiving side (Arduino Uno board)  get this:
See attachment called Coolterm2.png


unfortunately the reception stops right a way after few lines are received.
if i reset the Teensy board, it reboots and i receive few lines again on the Uno board. Please note I do not need to do, touch/reset/restart/disconnect-reconnect or any of this sort  to the uno board. I just leave it alone to wait for the next transmission from the Teensy board.

If i look at the serial monitor on the teensy side, i notice that it continue to send PGNs (or at-least looks that way for about a 30-45sec:

See attachment call Teensy_Monitor2.png


and then it comes up with the message that one of the PGNs has failed to send.

I'm lost here... Im not sure if this is HW or software issue. Im thinking the HW is fine as few messages go through with no problem but then the translissin to the N2K buss seams to stop (no more bl=inks on the receive and transmit LEDs) while the serial monitor keep shows the PGNs being generated and flying by...

Is it a buffer of some kind that gets filled/blocked? I'm willing to run any tests to troubleshoot that issue but i have to admit, I think I'm way better with HW than with SW (please note i said "better", not "good"  :smiley-confuse: )  

Any help or any ideas how to fix that are appreciated!
 
I receive some PGN, but then it stops.. Why, oh why?


timolappalainen

First I prefer to switch Uno and Teensy sketches. Uno does not have not enough memory with default buffers. Read library issue https://github.com/ttlappalainen/NMEA2000/issues/20 and at least start from my post on 15.4.2017. Also use Serial.begin(115200); instead Serial.begin(4800); despite this is not the problem in this case.

As you see on your first two pictures sent and received PGN:s 60928 and 130312 messgaes does not match. So I expect there is already some memory overflow on Uno.

On your last picture I expect that Teensy will not actually send anything at all. As default library has 40 frame send buffer. So it can buffer 40 single frame messages like PGN 130312 and when this buffer becomes full, it will cause error "... send failed". Note that as default library will forward own messages to stream (=USB in your case), when they have been tried to send. It does not mean that they have been actually sent to bus. So now in your last case on Teensy CAN bus control logic tries to send messages without success. It is probably trying to wait bus as become free, but it is blocked for some reason.

Note also that library does not work with latest Teensy FlexCan library. See issue https://github.com/sarfata/NMEA2000_teensy/issues/5. But as you have managed to receive something on Uno, I expect that you do not have 1.35 or newer Teensyduino.

seamaster

Hi Timo,
Thanks for the reply and recommendations. One remark only for clarification - I did not take the screen grabs simultaneously, therefore there could be difference in the transmit and received PGNs captured. It doesn't necessary means that we have the data corruption on the UNO board.

After reading your post, here is what i did:

I made a new Teensy3.2 board with MCP2551 which I will call NEW TEENSY for the purpose of that post. it has the same connections as the original one I made.
The first teensy board that I made I will be calling ORIGINAL TEENSY
and the Arduino UNO with CAN shield I will be calling UNO
Test cases:
1. Benchmark
 a. UNO on the receiving side,
 b.  ORIGINAL TEENSY on the transmit side
Result 1: when i run the listener code on the UNO I get "CAN ready" on the serial monitor of the UNO. When I run "Battery monitor" example on the ORIGINAL TEENSY, I receive couple of PGNs on the UNO serial monitor, then it stoppes (as i explained in my previous post)
2. Test with the NEW TEENSY
 a. UNO on the receiving side,
 b.  NEW TEENSY on the transmit side
Result 2: when i run the listener code on the UNO I get "CAN ready" on the serial monitor of the UNO. When I run "Battery monitor" example on the NEW TEENSY, I receive couple of PGNs on the UNO serial monitor, then it stoppes. in my opinion both teensy boards behave identical..
3. Test TEENSY only boards as recommended by you:
 a. NEW TEENSY on the receiving side
 b. ORIGINAL TEENSY on the transmit side (same SW that successfully sens few PGNs to the UNO in the BEnchmark case)
Result 3:
the NEW TEENSY does not get anything on the serial monitor when i run the listener SW. I do not get the "CAN ready" message :(
When i run the The Battery Monitor on the ORIGINAL TEENSY, there is nothing showing up on the NEW TEENSY serial monitor
4. Test two TEENSY only boards (same as Test 3 but reversed board functions)
 a. ORIGINAL TEENSY receiving
 b. NEW TEENSY transminting
Result 4:
Same as Result 3 nothing on the receiving board serial monitor


So after doing all that I think that there is some problem either with the listener code, or with the HW receiving portion on the Teensy boards (both of them).
But what bugs me is that I'm not getting the "CAN ready" message... so it makes me think that its the SW implementation on the Teensy
Any comments?


timolappalainen

The examples I have published has been cross tested with Mega and Teensy boards with Arduino 1.81 and Teensyduino 1.35 except FlexCAN library has been from Teensyduino 1.33.

So I made cross test again but also updated Arduino IDE to 1.82 and Teensyduino 1.36. ActisenseListener on Mega and TemperatureMonitor on Teensy.
-> Listener works and listens messages from my Garmin MFD. Monitor does not send anything.

So I replaced "C:\Program Files (x86)\Arduino\hardware\teensy\avr\libraries\FlexCAN" with http://www.kave.fi/Apps/Arduino/Teensy/FlexCAN.zip and rebuild all - !!NOTE!! rebuild all is important!
-> TemperatureMonitor now appears on Garmin and also messages appears on ActisenseListener in clear text.

Then I swithed ActisenseListener to Teensy and TemperatureMonitor to Mega. Again everything works fine.

So this proofs that both code works on Teensy and Mega. Important is  - what I mentioned earlier post - that you need old version of FlexCAN library.

seamaster

#193
May 17, 2017, 06:14 pm Last Edit: May 17, 2017, 06:21 pm by seamaster
Hi Timo,
thanks for the help!
I'm glad to report that the problem is solved. After i read your latest post i went to "manage my libraries" checked my installed libraries. I found two instances of FlexiCAN. One was listed under legacy in the application container (MAC) and the other one under mydocuments\ARDUINO\libraries.
I did remove both and then added zip file FlexiCAN library.
Success!
Off I go to the next step - buy my new Simrad EVO3 display to replace my failed Furuno depth-sounder, so I can continue my pet project :)
Thanks a lot again!

seamaster

Hi all,
here is a brief update:
yesterday I received my Simrad NSS9 EVO3 display. Last night i hooked up the teensy 3.2 and MCP2551 to it and ran some battery monitor code on it and it works! it's great that all proof of concept worked well, with little hiccups... now the real work should start.

Next is to design the proper schematic, board layout, and of course write the software.
I'm planning to have at least 4 temp probes inputs (TMP36), 6X 0V-30V  inputs and 2X 16bit 0V-3.3V inputs to measure current with 500uV shunts
One issue that I noticed is that simple resistor divider does not work that great as i get some noise on the readings. Someone helped me write some code for running average and the readings are much smoother now, but i would prefer to add some RC filtering on the input pins as well.

I noticed also that the MFD will not display what I put in the manufacturer information. it always states "Manufacturer: Unknown"
shouldn't it display
"Manufacturer: SeaNav"
based on the example code below?
Code: [Select]

const tNMEA2000::tProgmemConfigurationInformation BatteryMonitorConfigurationInformation PROGMEM={
                                       "SeaNav, john.doe@unknown.com", // Manufacturer information
                                       "First attempt", // Installation description1
                                       "No real information send to bus" // Installation description2

Go Up