ttlappalainen / NMEA2000

NMEA2000 library for Arduino
542 stars 228 forks source link

Yacht Devices RAW Can format #202

Open MrClowny666 opened 3 years ago

MrClowny666 commented 3 years ago

Hello,

I'm just starting out on my C++ journey and yes, I probably should have started with something easier I admit! However, I have an ESP32 circuit connected to my Raymarine HUD and reading and writing PGN's and I'm quite pleased! The one problem I have is something isn't quite right with some of the PGN's and I know it is me, however I can't physically attached my ESP to my machine as I'm having to use OTA.

The one question is is there a network NMEA reader software that can read the SEASMART example over TCP so I can see where I am going wrong, or do I need to try and write an convertor from NMEA2K to RAW format for example so I can use the Yacht Devices CAN reader? I know their gateway utilises the Seasmart format, but I don't think the reader does.

I know you don't like the adding new formats but any help would be appreciated?

ttlappalainen commented 3 years ago

Send it over TSP as actisense format so that com2tcp can read it. From com2tcp you forward it to com-0-com. Then yo can read it with NMEA Simulator or Actisense Reader.

dagnall53 commented 11 months ago

Timo.. Sorry to open an old issue, but I have also been exploring the YD 'CAN Log Viewer', as it does nicely work with UDP (unlike the much nicer Actisense tool that is limited to Serial). (although I can get that working with a virtual serial port!) I have constructed a simple sender (see below..) , but I'm having trouble building the "HEX version of the 29 bit message Id" as required by the YD format page 59. I presume this data must be present somewhere in the code, before you split it into more useful components, but I have been unable to find a nice simple N2kMsg.[name for the 29 bit message Id] ??? to let me print it at 8 hex characters.
You do separate it out nicely for PGN etc, and I was able to to construct a Cleartext function in the very structurally similar Actisense format that seems to work nicely..

Is there a variable/function I can call to get the original 29bit message Identifier?

FYI below is my N2KtoCleartextA Actisense cleartext function to place ClearText in buffer buf. I think it replicates code you already have, but allows me to use methods other than 'streams' to work on it afterwards. My YD equivalent is also shown below: The formatting in this post is horrid, but I hope you can see what I have done..

Many thanks Dagnall

void N2KtoCleartextA(char * buf, const tN2kMsg& N2kMsg){ // Place actisense cleartext format cleartext of N2kMsg in buf. char hexchar[6]; sprintf(buf,"%u : Pri:%u PGN%u Source:%u Dest:%u Len:%u",N2kMillis(),N2kMsg.Priority,N2kMsg.PGN,N2kMsg.Source,N2kMsg.Destination,N2kMsg.DataLen ); if (N2kMsg.DataLen >=1) { strcat(buf," Data:"); for (int i = 0; i < N2kMsg.DataLen; i++) { sprintf(hexchar,"%X",N2kMsg.Data[i]); strcat(buf,hexchar); // NB Clear text sends single char hex for as one char ,so do not use %02H !! if (i < (N2kMsg.DataLen-1)){strcat(buf,","); } } } strcat(buf,"\r\n"); }

My code so far for the "Yachtdevices" Cleartext is: (but its faking the 29 bit message id by using .PGN for now.. ! ) `void timeToString(char* string){ uint32_t nowMillis = millis(); byte hours = nowMillis / 3600000; nowMillis %= 3600000; byte minutes = nowMillis / 60000; nowMillis %= 60000; float sec =nowMillis/1000; sprintf(string, "%02d:%02d:%5.3f",hours, minutes, sec); }

void N2KtoCleartext(char * buf, const tN2kMsg& N2kMsg){ // Yachtdevices cleartext format cleartext of N2kMsg in buf. //hh:mm:ss.ddd ddd is ms time D =R (from Nmea2000) msgid is 29 bits .. ?https://endige.com/2050/nmea-2000-pgns-deciphered/ // char hexchar[6]; char msgid[12];

timeToString(buf); sprintf(msgid," R 0x%06X",N2kMsg.PGN); strcat(buf,msgid); if (N2kMsg.DataLen >=1) { strcat(buf," "); for (int i = 0; i < N2kMsg.DataLen; i++) { sprintf(hexchar,"%02X",N2kMsg.Data[i]); strcat(buf,hexchar); // NB Clear text sends single char hex for as one char ,so do not use %02H !! if (i < (N2kMsg.DataLen-1)){strcat(buf," "); } } } strcat(buf,"\r\n"); } `

dagnall53 commented 11 months ago

Ive just noted a major flaw in my assumptions.. the YD format only has 8 data bytes.. So I have no idea how they communicate long messages! Also they seem to suggest the PGN is only 3 characters in the msgid..
I have asked them to elaborate. (also corrected a simpler issue with the imeToString(buf).. Should have used float at the end for secs.. void timeToString(char* string){ uint32_t nowMillis = millis(); byte hours = nowMillis / 3600000; nowMillis %= 3600000; byte minutes = nowMillis / 60000; nowMillis %= 60000; float sec = nowMillis; sprintf(string, "%02d:%02d:%5.3f",hours, minutes, sec/1000); }

ttlappalainen commented 11 months ago

YD USB-N2k device can be configured to accept Actisence format. Doesn't YD 'CAN Log Viewer' have that? My NMEA Simulator can read Actisense format from UDP. Unfortunately ony paid version parses data to values.

dagnall53 commented 11 months ago

No, It seems very limited.. It does have command line settings,(how useful is that in the days of windows!!). but none for Actisense.. And their format is strange, limited to 8 characters. I have yet to sort it out!. Thanks for replying!. Dagnall [image: image.png]

On Sun, 3 Dec 2023 at 09:24, Timo Lappalainen @.***> wrote:

YD USB-N2k device can be configured to accept Actisence format. Doesn't YD 'CAN Log Viewer' have that? My NMEA Simulator can read Actisense format from UDP. Unfortunately ony paid version parses data to values.

— Reply to this email directly, view it on GitHub https://github.com/ttlappalainen/NMEA2000/issues/202#issuecomment-1837421584, or unsubscribe https://github.com/notifications/unsubscribe-auth/ABVA5ICYTNFODO3IACLEXBTYHRAOTAVCNFSM4WNMHFW2U5DIOJSWCZC7NNSXTN2JONZXKZKDN5WW2ZLOOQ5TCOBTG42DEMJVHA2A . You are receiving this because you commented.Message ID: @.***>

ttlappalainen commented 11 months ago

Normally raw CAB format is something like: ABCD 01 02 03 04 05 06 07 08 ABCD is the 29 bit CAN ID and others are frame bytes (max 8). CAN ID will be constructed from PGN, priority, source and destination. On NMEA2000.cpp there is function N2ktoCanID, which can be used for that. It is not published, but you can use by declaring with extern on your code. For each message you need to find is it fast packet or not. There is function tNMEA2000::IsFastPacketPGN but that is unfortunately protected. You can move that on your library under public or just rely that if data length<=8, message is single frame. It works for most messages, but not all. If Message is single frame, just send frame out as required frame format. If it is fastpacket, you need to split it to separated frames. You can find code on NMEA2000.cpp starting from line 1456. Note that you need to keep track for each PGN sequence counter and increment it after PGN has been sent.

Or you can buy license for my Simulator and just send in Actisense format to UDP.