ttlappalainen / NMEA2000

NMEA2000 library for Arduino
519 stars 216 forks source link

Failed to open #48

Open andrewhodel opened 7 years ago

andrewhodel commented 7 years ago

Whenever I use these libraries CAN_BUS_Shield NMEA2000 NMEA2000_mcp

and any of the examples in NMEA2000 I get "failed to open CAN device".

However, if I use just the MCP2515 library I can get the MFD to send data with the queryOBD function.

Can you perhaps do me a favor and provide a binary data dump of some initial traffic? I would like to understand the NMEA data flow. It seems that a 59904 PGN needs to be sent every so often just to have the mfd (Raymarine) start sending data?

Would multiple devices on a network just see that a 59904 was being sent and not send their own, I guess what I am saying is why wouldn't broadcast be default?

A binary file of the first few thousand bytes between a "listener" and an MFD to just get some basic GPS data would be really helpful.

Thanks

ttlappalainen commented 7 years ago

Please tell first what board and shield you are using? Also do you have latest versions of all libraries from my github? Others may not be up to date. What do you mean with MCP2515 library?

Do you mean you get error "CAN device failed to open"? With NMEA2000_mcp you normally get that, if library can not communicate with MCP2515. That may be due to different CS pin than default 53.

andrewhodel commented 7 years ago

The board is a pro mini with a https://www.amazon.com/CHENBO-Electronics-Receiver-Controller-Development/dp/B015W4D9WY/ref=sr_1_1?ie=UTF8&qid=1493030455&sr=8-1&keywords=Mcp2515

Why does the example not show how to change the cs pin?

Yes I am using the latest versions of your libraries directly from git.

Also I would like a binary file which is a data dump of the first few thousand bytes so I can understand the process to simply get data via the fast packet protocol that nmea2000 uses.

andrewhodel commented 7 years ago

I set #define USE_MCP_CAN_CLOCK_SET 8 and #define N2k_SPI_CS_PIN 10 in Arduino/libraries/NMEA2000/NMEA2000_CAN.h and it still just repeats CAN device failed to open.

I have also set correctly the interrupt pin with #define N2k_CAN_INT_PIN 2 in the main program.

#define N2k_CAN_INT_PIN 2
#include <Arduino.h>
#include <NMEA2000_CAN.h>

void setup() {
  Serial.begin(115200);
  NMEA2000.SetForwardStream(&Serial);  // PC output on due native port
  NMEA2000.SetForwardType(tNMEA2000::fwdt_Text); // Show in clear text
  NMEA2000.Open();
}

void loop() {
  NMEA2000.ParseMessages();
}
ttlappalainen commented 7 years ago

It may be a challence to get Pro Mini work. Do you have older or newer board? I am mainly interested that does it have 2K or 1K RAM? If it has only 1K, then you may need to forget it. Also hopefullyt you have 5V board, since your CAN BUS shield is for 5V operating.

Do you have interrupt wire connected or not? If it isn't, then do not define #define N2k_CAN_INT_PIN at all. At beginning you can anyway leave it undefined, so it will not use interrupt. If you get board working, you can then test does it runs with interrupt.

I could not find is your CAN BUS shield with 8MHz or 16 MHZ clock. You use #define USE_MCP_CAN_CLOCK_SET 8 only, if your shield is with 8MHz clock. It does not have anything to do with your board clock.

Since you have anyway so little memory, you need to limit buffers as I have described 15. of April on issue https://github.com/ttlappalainen/NMEA2000/issues/20. Also do not modify NMEA2000_CAN.h. Add definitions before including. So you should have:

// #define N2k_CAN_INT_PIN 2 // Uncomment, when works without interrupt!

define N2k_SPI_CS_PIN 10

// #define USE_MCP_CAN_CLOCK_SET 8 // Uncomment, if your CAN BUS shield has 8 MHz clock

include

include

void setup() { Serial.begin(115200); NMEA2000.SetN2kCANMsgBufSize(2); NMEA2000.SetN2kCANSendFrameBufSize(30); NMEA2000.EnableForward(false); // You may try to comment this, when you got it first working. NMEA2000.SetForwardStream(&Serial); // PC output on due native port NMEA2000.SetForwardType(tNMEA2000::fwdt_Text); // Show in clear text NMEA2000.Open(); } ...

Note also that if you get error "CAN device failed to open", it means that board fails to communicate with MCP2515 via SPI.

andrewhodel commented 7 years ago

I set everything as you asked and it is still doing the same thing.

The shield has an 8mhz clock and it is set that way via define USE_MCP_CAN_CLOCK_SET 8.

The Pro Mini is 5v and the can shield works fine. I can get the data using the ODBMPG example from this library - https://github.com/franksmicro/Arduino/tree/master/libraries/MCP2515

The trouble is that it does not work right with your libraries.

This is why I originally asked if you could provide a binary dump of the first few thousand bytes of a NMEA2k conversation between a MFD and a listener so that I can just simply recreate the handshaking, address request and broadcast process.

I am aware of the bit format I just do not know where the PGN goes and what bits represent in what order the different required fields.

Here's what I have but I need the actual bit mappings:

CANbus frames have a 32 bit identifier and up to 8 bytes (yes, this is quite adorable) of payload. The wire format contains additional bits here and there, a length field and a CRC and DC-correcting tailer. All this is probably interesting if you create the controllers, but for anyone writing software it doesn’t matter. Especially the part about the frame identifier is either 11 bit or 29 bits, you can ignore. At least for NMEA2000 only CAN2.0B with 29 bit identifiers are used.

On the software side, you get: 1) 32bit frame identifier, 2) the length indicator, and 3) the >=8 bytes of data. Everything else is handled by your interfacing hardware. Hurray.

The 32 bit identifier is a bitfield consisting of source, destination, priority and the Parameter Group Number (PGN).

from - https://lassekarstensen.wordpress.com/2016/08/09/nmea2000-and-canbus/

ttlappalainen commented 7 years ago

There is about 2500 lines of code for handling bus communication and an other 2500 lines for handling messages. I have been working with N2k protocol and code since 2013. I have spent several hundreds hours for digging and coding and also discussing with others. Do you really want to redo this work?

I have some options for you:

  1. Start to debug mcp_can, why it does not initialize. Follow the code from error to mcp_can. Error appears, if CANOpen fails. That leads you to method MCP_CAN::mcp2515_init on line 416 on mcp_can.cpp. It seem to have test for definition DEBUG_MODE, which you need to define to get more debug lines printed. You can also add more debug lines find out why it does not work. Also follow your MCP2515 library and what is the difference. In principle they are doing the same thing.

  2. Buy Arduino Mega and CAN-BUS Shield V1.2 from seedstudio, since that is proved to work. I personally like more Teensy, for which there are schemas on my git. Just for note that current version of FlexCAN lib with Teensyduino does not work. One have to use old version of FlexCAN library. If you wan't to transmit GPS messages, you may anyway have problems with memory, since GPS it needs larger buffers for reliable operation.

  3. If you still will like to write your own, you need to study N2k protocol more. Read my library document how to test N2k without any Arduinos or how to test it with Arduino, but without real bus. Also study from J1939 documents how address claiming should be done (or read from NMEA2000.cpp code) and how to respond with product information query. Well also you have to study how to handle single frame or fast packet messages. On Nk2Messages.cpp you can find how to construct different messages. You can also find content of messages either on OpenSkipper project PGNDefns.N2kDfn.xml or CAN boat project pgn.h definition. Attached is few second log from my bus traffic, which you can read with Actisense EBL reader.

COM4 ATEN USB Seria_20150806_131215.rx.zip

andrewhodel commented 7 years ago

How many bytes is each frame from the CAN bus for nmea2000?

Why are there newline characters in the data dump, that can't be exactly what comes over the bus because there's no reason to delimit frames when there is a strict frame size.

Is there a place where address claiming is documented like this:

  1. send a frame that looks like this, byte N is this field, byte NN is this field

  2. expect a frame (or set of frames representing a fast packet) that looks like this, byte N is this field, byte NN is this field

Here is what I have so far, but it is not yet complete... these are just tidbits I've compiled from various sources... you know like not wanting to use pgn.h because the complier "magic" can only include what's needed at run time...

/*
Here is the structure of a CANBUS Message

THIS DOES NOT SEEM RIGHT PER EVERYTHING WRITTEN ABOUT NMEA2000, IT IS STRANGE BECAUSE CAN IS SUPPOSED TO HAVE THE SAME FRAME SIZE AS IT JUST USES A SINGLE PULSE OF A SQUARE WAVE WITH BITS ENCODED IN EACH PULSE

Field Name                          Number of Bits        Explanation
Start-of-frame                      1                     Denotes the start of frame transmission
Identifier                          11                    A (unique) identifier which also represents the message priority
Remote transmission request (RTR)   1                     Must be dominant (0) for data frames and recessive (1) for remote request frames (see Remote Frame, below)
Identifier extension bit (IDE)      1                     Must be dominant (0) for base frame format with 11-bit identifiers
Reserved bit (r0)                   1                     Reserved bit. Must be dominant (0), but accepted as either dominant or recessive.
Data length code (DLC)              4                     Number of bytes of data (0–8 bytes)[a]
Data field                          0–64 (0-8 bytes)      Data to be transmitted (length in bytes dictated by DLC field)
CRC                                 15                    Cyclic redundancy check
CRC delimiter                       1                     Must be recessive (1)
ACK slot                            1                     Transmitter sends recessive (1) and any receiver can assert a dominant (0)
ACK delimiter                       1                     Must be recessive (1)
End-of-frame (EOF)                  7                     Must be recessive (1)

----------------

It is defined in MCP2515.h as CANMSG

typedef struct {
  boolean isExtendedAdrs;
  unsigned long adrsValue;
  boolean rtr;
  byte dataLength;
  byte data[8];
} CANMSG;

NMEA 2000 uses the 8 'data' bytes as follows and calls it fast packet:

data[0] is an 'order' that increments, or not (depending somewhat on implementation).
If the size of the packet <= 7 then the data follows in data[1..7]
If the size of the packet > 7 then the next byte data[1] is the size of the payload
and data[0] is divided into 5 bits index into the fast packet, and 3 bits 'order
that increases.
This means that for 'fast packets' the first bucket (sub-packet) contains 6 payload
bytes and 7 for remaining. Since the max index is 31, the maximal payload is
6 + 31 * 7 = 223 bytes

----------------

data[0] is an 'order' that increments, or not (depending somewhat on implementation).
If the size of the packet is less than or equal than 7 bytes then the data follows in data[1..7]
because it would all fit in the CANMSG.data[8] character array

If the size of the packet (which could be multiple CANMSG reads from the CAN bus) is more than 7 bytes
then the next byte data[1] is the size of the payload (the entire packet, which is a maximum of 223 bytes)
and data[0] is divided into 5 bits index into the fast packet, and 3 bits 'order
that increases.

This means that for 'fast packets' the first bucket (sub-packet) contains 6 payload
bytes and 7 for remaining. Since the max index is 31, the maximal payload is
6 + 31 * 7 = 223 bytes

----------------

NMEA 2000 FAQ: data field at First frame of a fast packet
•  Byte 1:  
b0 – b4 = 00000, b0  =LSB 
b5  –  b7  = 3 -bit sequence counter to distinguish separate fast-packet messages of the same PGN, b5 is the LSB of the counter. 

•  Byte 2 = Total  number of data bytes to be transmitted in the message (0 to 223).  
After Byte 2, the frame also includes up to (6) data bytes in the first frame (and up to (7) data bytes in following frames).

NMEA 2000 FAQ:  data field at Additional frames of a fast packet
•  Byte 1:  
b0 – b4 = 1 to 31, 5 bit frame counter,  b0  =LSB 
b5  –  b7  = 3 -bit sequence counter which shall be the same value as in the first frame, b5 is the LSB of the counter. 

•  Byte 2-8:
7 bytes of transmitted data. Unused bits in the last frame of a fast-packet message shall be filled with "1" bits.
*/

It would be nice to have a simple raw binary "exact binary representation of what frames to send to actually get data back from the CAN bus", then I could start making it work.

FXVT commented 7 years ago

Bonjour,

Sketch: Battery Monitor I also have the message CAN device failed to open right after the instruction NMEA2000.Open();

I use an Arduino Uno R3 and a CAN-Shield from https://www.elecrow.com/canbus-shield-p-1133.html This devices works fine with other sketch based on different libraries, but not yours.

I have downloaded the latest versions of your libraries and example from Github. Le battery monitor example sketch use 77% and 14% for the global variables My own sketch use 95% and 39 % With both sketches I have the message.

I certainely mess something with the CAN INT PIN variable, but I don't know that to change.

The final aim is to create a sketch who translate the datas coming from a Victron BMV700 Battery controler and inject this datas to the N2K network of the boat. I have already writen this sketch, based on other libraries, It works well, but it does'nt send datas like Product Informations, version, ... to the network.

Merci FX VAN THUAN

ttlappalainen commented 7 years ago

Have you read on my library main page comments on "Memory requirements"? Note that given 14% for the global variables is not right, since library uses dynamic object creation and buffers.

FXVT commented 7 years ago

Bonjour,

Thank you for your prompt reply. Ok, now I understand. I am going to order Mega boardsto replace the Uno boards I have on the boat :-(

Regards. FX

FXVT commented 7 years ago

Bonjour,

Hourra, I get the message ! "... CAN device ready Start address claim Pri:6 PGN:60928 Source:22 Dest:255 Len:8 Data:1,0,E0,7C,0,AA,46,C0 ..."

The change I have done is to add this line: #define N2k_SPI_CS_PIN 10 before: `#include // This will automatically choose right CAN library and create suitable NMEA2000 object

include

` Welll, I get this result with an UNO R3. May be I will get new problems later. So, anyway I have order 2 Arduino MEGA boards, just in case.

Thanks for all. Now I can go ahead.

FX VAN THUAN

ersingencturk commented 2 years ago

per fxvt's answer, in my case it was io15 of esp, so changing to #define N2k_SPI_CS_PIN 15 works for me now.