NMEA2000 Library  0.1
Library to handle NMEA 2000 Communication written in C++
N2kMsg.cpp
Go to the documentation of this file.
1/*
2N2kMsg.cpp
3
4Copyright (c) 2015-2024 Timo Lappalainen, Kave Oy, www.kave.fi
5
6Permission is hereby granted, free of charge, to any person obtaining a copy of
7this software and associated documentation files (the "Software"), to deal in
8the Software without restriction, including without limitation the rights to use,
9copy, modify, merge, publish, distribute, sublicense, and/or sell copies of the
10Software, and to permit persons to whom the Software is furnished to do so,
11subject to the following conditions:
12
13The above copyright notice and this permission notice shall be included in all
14copies or substantial portions of the Software.
15
16THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED,
17INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A
18PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT
19HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF
20CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE
21OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
22*/
23
24#include "N2kMsg.h"
25#include "N2kTimer.h"
26#include <math.h>
27#include <stdlib.h>
28#include <string.h>
29#include <ctype.h>
30//#include <MemoryFree.h> // For testing used memory
31
32#define Escape 0x10
33#define StartOfText 0x02
34#define EndOfText 0x03
35#define MsgTypeN2k 0x93
36
37#define MaxActisenseMsgBuf 400
38
39// NMEA2000 uses little endian for binary data. Swap the endian if we are
40// running on a big endian machine. There is no reliable, portable compile
41// check for this so each compiler has to be added manually.
42#if defined(__GNUC__) && defined (__BYTE_ORDER__)
43#if __BYTE_ORDER__ == __ORDER_BIG_ENDIAN__
44#define HOST_IS_BIG_ENDIAN
45#endif
46#endif
47
48//*****************************************************************************
49// On Arduino round() is a macro, hence the definition check. On other systems
50// it is a function that may or may not be implemented so we do it ourselves.
51#if !defined(round)
52double round(double val) {
53 return val >= 0
54 ? floor(val + 0.5)
55 : ceil(val - 0.5);
56}
57#endif
58
59//*****************************************************************************
60tN2kMsg::tN2kMsg(unsigned char _Source, unsigned char _Priority, unsigned long _PGN, int _DataLen) {
61 Init(_Priority,_PGN,_Source,255);
62 if ( _DataLen>0 && _DataLen<MaxDataLen ) DataLen=_DataLen;
63 ResetData();
64 if ( PGN!=0 ) MsgTime=N2kMillis();
65}
66
67//*****************************************************************************
68void tN2kMsg::SetPGN(unsigned long _PGN) {
69 Clear();
70 if ( PGN==0 ) PGN=_PGN;
72}
73
74//*****************************************************************************
75void tN2kMsg::Init(unsigned char _Priority, unsigned long _PGN, unsigned char _Source, unsigned char _Destination) {
76 DataLen=0;
77 Priority=_Priority & 0x7;
78 SetPGN(_PGN);
79 Source=_Source;
80 Destination=_Destination;
81#if !defined(N2K_NO_ISO_MULTI_PACKET_SUPPORT)
82 TPMessage=false;
83#endif
84}
85
86//*****************************************************************************
88 if ( DataLen>0 ) {
89 memset(Data,0xff,DataLen);
90 }
91}
92
93//*****************************************************************************
95 PGN=0;
96 DataLen=0;
97 MsgTime=0;
98}
99
100//*****************************************************************************
101void tN2kMsg::AddFloat(float v, float UndefVal) {
102 if (v!=UndefVal) {
104 } else {
106 }
107}
108
109//*****************************************************************************
110void tN2kMsg::Add8ByteDouble(double v, double precision, double UndefVal) {
111 if (v!=UndefVal) {
112 SetBuf8ByteDouble(v,precision,DataLen,Data);
113 } else {
116 }
117}
118
119//*****************************************************************************
120void tN2kMsg::Add4ByteDouble(double v, double precision, double UndefVal) {
121 if (v!=UndefVal) {
122 SetBuf4ByteDouble(v,precision,DataLen,Data);
123 } else {
125 }
126}
127
128//*****************************************************************************
129void tN2kMsg::Add4ByteUDouble(double v, double precision, double UndefVal) {
130 if (v!=UndefVal) {
131 SetBuf4ByteUDouble(v,precision,DataLen,Data);
132 } else {
134 }
135}
136
137//*****************************************************************************
138void tN2kMsg::Add3ByteDouble(double v, double precision, double UndefVal) {
139 if (v!=UndefVal) {
140 SetBuf3ByteDouble(v,precision,DataLen,Data);
141 } else {
142 SetBuf3ByteInt(0x7fffff,DataLen,Data);
143 }
144}
145
146//*****************************************************************************
147void tN2kMsg::Add2ByteDouble(double v, double precision, double UndefVal) {
148 if (v!=UndefVal) {
149 SetBuf2ByteDouble(v,precision,DataLen,Data);
150 } else {
152 }
153}
154
155//*****************************************************************************
156void tN2kMsg::Add2ByteUDouble(double v, double precision, double UndefVal) {
157 if (v!=UndefVal) {
158 SetBuf2ByteUDouble(v,precision,DataLen,Data);
159 } else {
161 }
162}
163
164//*****************************************************************************
165void tN2kMsg::Add1ByteDouble(double v, double precision, double UndefVal) {
166 if (v!=UndefVal) {
167 SetBuf1ByteDouble(v,precision,DataLen,Data);
168 } else {
170 }
171}
172
173//*****************************************************************************
174void tN2kMsg::Add1ByteUDouble(double v, double precision, double UndefVal) {
175 if (v!=UndefVal) {
176 SetBuf1ByteUDouble(v,precision,DataLen,Data);
177 } else {
179 }
180}
181
182//*****************************************************************************
183void tN2kMsg::Add2ByteInt(int16_t v) {
185}
186
187//*****************************************************************************
188void tN2kMsg::Add2ByteUInt(uint16_t v) {
190}
191
192//*****************************************************************************
193void tN2kMsg::Add3ByteInt(int32_t v) {
195}
196
197//*****************************************************************************
198void tN2kMsg::Add4ByteUInt(uint32_t v) {
200}
201
202//*****************************************************************************
203void tN2kMsg::AddUInt64(uint64_t v) {
205}
206
207//*****************************************************************************
208void tN2kMsg::AddByte(unsigned char v) {
209 Data[DataLen]=v; DataLen++;
210}
211
212//*****************************************************************************
213void tN2kMsg::AddStr(const char *str, int len, bool UsePgm, unsigned char fillChar) {
214 SetBufStr(str,len,DataLen,Data,UsePgm,fillChar);
215}
216
217//*****************************************************************************
218// Add AIS String
219// make sure characters fall into range defined in table 14
220// https://www.itu.int/dms_pubrec/itu-r/rec/m/R-REC-M.1371-1-200108-S!!PDF-E.pdf
221void tN2kMsg::AddAISStr(const char *str, int len) {
222 unsigned char *buf=Data+DataLen;
223 for (; len>0 && *str!=0 && DataLen<MaxDataLen; len--, DataLen++, buf++, str++) {
224 char c = toupper((int)*str);
225 *buf=(c >= 0x20 && c <= 0x5F) ? c : '?';
226 }
227
228 if ( len > MaxDataLen-DataLen ) len=MaxDataLen-DataLen;
229 if ( len>0 ) memset(buf,'@',len);
230}
231
232
233//*****************************************************************************
234void tN2kMsg::AddVarStr(const char *str, bool UsePgm) {
235 int len=(str!=0?strlen(str):0);
236 AddByte(len+2);
237 AddByte(1);
238 if ( len>0 ) SetBufStr(str,len,DataLen,Data,UsePgm,0xff);
239}
240
241//*****************************************************************************
242void tN2kMsg::AddBuf(const void *buf, size_t bufLen) {
243 if ( DataLen<MaxDataLen ) {
244 if ( DataLen+bufLen>MaxDataLen ) bufLen=MaxDataLen-DataLen;
245 } else bufLen=0;
246
247 if ( bufLen>0 ) {
248 memcpy(Data+DataLen,buf,bufLen);
249 DataLen+=bufLen;
250 }
251}
252
253//*****************************************************************************
254unsigned char tN2kMsg::GetByte(int &Index) const {
255 if (Index<DataLen) {
256 return Data[Index++];
257 } else return 0xff;
258}
259
260//*****************************************************************************
261int16_t tN2kMsg::Get2ByteInt(int &Index, int16_t def) const {
262 if (Index+2<=DataLen) {
263 return GetBuf2ByteInt(Index,Data);
264 } else return def;
265}
266
267//*****************************************************************************
268uint16_t tN2kMsg::Get2ByteUInt(int &Index, uint16_t def) const {
269 if (Index+2<=DataLen) {
270 return GetBuf2ByteUInt(Index,Data);
271 } else return def;
272}
273
274//*****************************************************************************
275uint32_t tN2kMsg::Get3ByteUInt(int &Index, uint32_t def) const {
276 if (Index+3<=DataLen) {
277 return GetBuf3ByteUInt(Index,Data);
278 } else return def;
279}
280
281//*****************************************************************************
282uint32_t tN2kMsg::Get4ByteUInt(int &Index, uint32_t def) const {
283 if (Index+4<=DataLen) {
284 return GetBuf4ByteUInt(Index,Data);
285 } else return def;
286}
287
288//*****************************************************************************
289uint64_t tN2kMsg::GetUInt64(int &Index, uint64_t def) const {
290 if (Index+8<=DataLen) {
291 return GetBuf8ByteUInt(Index,Data);
292 } else return def;
293}
294
295//*****************************************************************************
296double tN2kMsg::Get1ByteDouble(double precision, int &Index, double def) const {
297 if (Index<DataLen) {
298 return GetBuf1ByteDouble(precision,Index,Data,def);
299 } else return def;
300}
301
302//*****************************************************************************
303double tN2kMsg::Get1ByteUDouble(double precision, int &Index, double def) const {
304 if (Index<DataLen) {
305 return GetBuf1ByteUDouble(precision,Index,Data,def);
306 } else return def;
307}
308
309//*****************************************************************************
310double tN2kMsg::Get2ByteDouble(double precision, int &Index, double def) const {
311 if (Index+2<=DataLen) {
312 return GetBuf2ByteDouble(precision,Index,Data,def);
313 } else return def;
314}
315
316//*****************************************************************************
317double tN2kMsg::Get2ByteUDouble(double precision, int &Index, double def) const {
318 if (Index+2<=DataLen) {
319 return GetBuf2ByteUDouble(precision,Index,Data,def);
320 } else return def;
321}
322
323//*****************************************************************************
324double tN2kMsg::Get3ByteDouble(double precision, int &Index, double def) const {
325 if (Index+3<=DataLen) {
326 return GetBuf3ByteDouble(precision,Index,Data,def);
327 } else return def;
328}
329
330//*****************************************************************************
331double tN2kMsg::Get4ByteDouble(double precision, int &Index, double def) const {
332 if (Index+4<=DataLen) {
333 return GetBuf4ByteDouble(precision,Index,Data,def);
334 } else return def;
335}
336
337//*****************************************************************************
338double tN2kMsg::Get4ByteUDouble(double precision, int &Index, double def) const {
339 if (Index+4<=DataLen) {
340 return GetBuf4ByteUDouble(precision,Index,Data,def);
341 } else return def;
342}
343
344//*****************************************************************************
345double tN2kMsg::Get8ByteDouble(double precision, int &Index, double def) const {
346 if (Index+8<=DataLen) {
347 return GetBuf8ByteDouble(precision,Index,Data,def);
348 } else return def;
349}
350
351//*****************************************************************************
352float tN2kMsg::GetFloat(int &Index, float def) const {
353 if (Index+4<=DataLen) {
354 return GetBufFloat(Index,Data,def);
355 } else return def;
356}
357
358//*****************************************************************************
359bool tN2kMsg::GetStr(char *StrBuf, size_t Length, int &Index) const {
360 unsigned char vb;
361 bool nullReached = false;
362 StrBuf[0] = '\0';
363 if ((size_t)Index+Length<=(size_t)DataLen) {
364 for (size_t i=0; i<Length; i++) {
365 vb = GetByte(Index);
366 if (! nullReached) {
367 if (vb == 0x00 || vb == '@') {
368 nullReached = true; // either null or '@' (AIS null character)
369 StrBuf[i] = '\0';
370 StrBuf[i+1] = '\0';
371 } else {
372 StrBuf[i] = vb;
373 StrBuf[i+1] = '\0';
374 }
375 } else {
376 StrBuf[i] = '\0';
377 StrBuf[i+1] = '\0';
378 }
379 }
380 return true;
381 } else return false;
382}
383
384//*****************************************************************************
385bool tN2kMsg::GetStr(size_t StrBufSize, char *StrBuf, size_t Length, unsigned char nulChar, int &Index) const {
386 unsigned char vb;
387 bool nullReached = false;
388 if ( StrBufSize==0 || StrBuf==0 ) {
389 Index+=Length;
390 return true;
391 }
392 StrBuf[0] = '\0';
393 if ((size_t)Index+Length<=(size_t)DataLen) {
394 size_t i;
395 for (i=0; i<Length && i<StrBufSize-1; i++) {
396 vb = GetByte(Index);
397 if (! nullReached) {
398 if (vb == 0x00 || vb == nulChar ) {
399 nullReached = true; // either null or '@' (AIS null character)
400 StrBuf[i] = '\0';
401 } else {
402 StrBuf[i] = vb;
403 }
404 } else {
405 StrBuf[i] = '\0';
406 }
407 }
408 StrBuf[i] = '\0';
409 for (;i<Length;i++) GetByte(Index); // Stopped by buffer size, so read out bytes from message
410 for (;i<StrBufSize;i++) StrBuf[i] = '\0'; // Stopped by length, fill buffer with 0
411 return true;
412 } else return false;
413}
414
415//*****************************************************************************
416bool tN2kMsg::GetVarStr(size_t &StrBufSize, char *StrBuf, int &Index) const {
417 size_t Len=GetByte(Index)-2;
418 uint8_t Type=GetByte(Index);
419 if ( Type!=0x01 ) { StrBufSize=0; return false; }
420 if ( StrBuf!=0 ) {
421 GetStr(StrBufSize,StrBuf,Len,0xff,Index);
422 } else {
423 Index+=Len; // Just pass this string
424 }
425 StrBufSize=Len;
426 return true;
427}
428
429//*****************************************************************************
430bool tN2kMsg::GetBuf(void *buf, size_t Length, int &Index) const {
431 bool ret=true;
432
433 if ((size_t)Index+Length<=(size_t)DataLen) {
434 if ( buf!=0 ) {
435 memcpy(buf,Data+Index,Length);
436 } else {
437 Index+=Length; // Just pass this string
438 }
439 } else {
440 Index=DataLen;
441 ret=false;
442 }
443 return ret;
444}
445
446//*****************************************************************************
447bool tN2kMsg::SetByte(uint8_t v, int &Index) {
448 if (Index<DataLen) {
449 Data[Index]=v;
450 Index++;
451 return true;
452 } else
453 return false;
454}
455
456//*****************************************************************************
457bool tN2kMsg::Set2ByteUInt(uint16_t v, int &Index) {
458 if (Index+1<DataLen) {
459 SetBuf2ByteUInt(v,Index,Data);
460 return true;
461 } else
462 return false;
463}
464
465//*****************************************************************************
466template<typename T>
467T byteswap(T val);
468
469template<>
470uint8_t byteswap(uint8_t val) {
471 return val;
472}
473
474template<>
475int8_t byteswap(int8_t val) {
476 return val;
477}
478
479template<>
480uint16_t byteswap(uint16_t val) {
481 return (val << 8) | (val >> 8);
482}
483
484template<>
485int16_t byteswap(int16_t val)
486{
487 return byteswap((uint16_t) val);
488}
489
490template<>
491uint32_t byteswap(uint32_t val) {
492 return ((val << 24)) |
493 ((val << 8) & 0xff0000UL) |
494 ((val >> 8) & 0xff00UL) |
495 ((val >> 24));
496}
497
498template<>
499int32_t byteswap(int32_t val) {
500 return byteswap((uint32_t) val);
501}
502
503template<>
504uint64_t byteswap(uint64_t val) {
505 return ((val << 56)) |
506 ((val << 40) & 0xff000000000000ULL) |
507 ((val << 24) & 0xff0000000000ULL) |
508 ((val << 8) & 0xff00000000ULL) |
509 ((val >> 8) & 0xff000000ULL) |
510 ((val >> 24) & 0xff0000ULL) |
511 ((val >> 40) & 0xff00ULL) |
512 ((val >> 56));
513}
514
515template<>
516int64_t byteswap(int64_t val) {
517 return byteswap((uint64_t) val);
518}
519
520//*****************************************************************************
521template<typename T>
522T GetBuf(size_t len, int& index, const unsigned char* buf) {
523 T v{0};
524
525 // This could be improved by casting the buffer to a pointer of T and
526 // doing a direct copy. That is, if unaligned data access is allowed.
527 memcpy(&v, &buf[index], len);
528 index += len;
529
530#if defined(HOST_IS_BIG_ENDIAN)
531 v = byteswap(v);
532#endif
533
534 return v;
535}
536
537//*****************************************************************************
538template<typename T>
539void SetBuf(T v, size_t len, int& index, unsigned char* buf) {
540#if defined(HOST_IS_BIG_ENDIAN)
541 v = byteswap(v);
542#endif
543
544 // This could be improved by casting the buffer to a pointer of T and
545 // doing a direct copy. That is, if unaligned data access is allowed.
546 memcpy(&buf[index], &v, len);
547 index += len;
548}
549
550//*****************************************************************************
551void SetBufDouble(double v, int &index, unsigned char *buf) {
552 if ( sizeof(double)==8 && !N2kIsNA(v) ) {
553 int64_t iv;
554 memcpy(&iv,&v,8);
555 SetBuf(iv, 8, index, buf);
556 } else { // on AVR double=float
557 SetBuf((int64_t)N2kInt64NA,8,index,buf);
558 }
559}
560
561//*****************************************************************************
562void SetBufFloat(float v, int &index, unsigned char *buf) {
563 int32_t iv;
564 if ( !N2kIsNA(v) ) {
565 memcpy(&iv,&v,4);
566 } else {
567 iv=N2kInt32NA;
568 }
569 SetBuf(iv, 4, index, buf);
570}
571
572#define N2kInt8OR 0x7e
573#define N2kUInt8OR 0xfe
574#define N2kInt16OR 0x7ffe
575#define N2kUInt16OR 0xfffe
576#define N2kInt32OR 0x7ffffffe
577#define N2kUInt32OR 0xfffffffe
578
579#define N2kInt32Min -2147483648L
580#define N2kInt24OR 8388606L
581#define N2kInt24Min -8388608L
582#define N2kInt16Min -32768
583#define N2kInt8Min -128
584
585//*****************************************************************************
586void SetBuf8ByteDouble(double v, double precision, int &index, unsigned char *buf) {
587 int64_t vll;
588 if ( !N2kIsNA(v) ) {
589 if ( sizeof(double)<8 ) {
590 double fp=precision*1e6;
591 int64_t fpll=1/fp;
592 vll=v*1e6L;
593 vll*=fpll;
594 } else {
595 vll=v/precision;
596 }
597 } else {
598 vll=N2kInt64NA;
599 }
600 SetBuf(vll, 8, index, buf);
601}
602
603//*****************************************************************************
604void SetBuf4ByteDouble(double v, double precision, int &index, unsigned char *buf) {
605 double vd=round((v/precision));
606 int32_t vi = (vd>=N2kInt32Min && vd<N2kInt32OR)?(int32_t)vd:N2kInt32OR;
607 SetBuf<int32_t>(vi, 4, index, buf);
608}
609
610//*****************************************************************************
611void SetBuf4ByteUDouble(double v, double precision, int &index, unsigned char *buf) {
612 double vd=round((v/precision));
613 uint32_t vi = (vd>=0 && vd<N2kUInt32OR)?(uint32_t)vd:N2kUInt32OR;
614 SetBuf<uint32_t>(vi, 4, index, buf);
615}
616
617//*****************************************************************************
618void SetBuf3ByteDouble(double v, double precision, int &index, unsigned char *buf) {
619 double vd=round((v/precision));
620 int32_t vi = (vd>=N2kInt24Min && vd<N2kInt24OR)?(int32_t)vd:N2kInt24OR;
621 SetBuf<int32_t>(vi, 3, index, buf);
622}
623
624//*****************************************************************************
625int16_t GetBuf2ByteInt(int &index, const unsigned char *buf) {
626 return GetBuf<int16_t>(2, index, buf);
627}
628
629//*****************************************************************************
630uint16_t GetBuf2ByteUInt(int &index, const unsigned char *buf) {
631 return GetBuf<uint16_t>(2, index, buf);
632}
633
634//*****************************************************************************
635uint32_t GetBuf3ByteUInt(int &index, const unsigned char *buf) {
636 return GetBuf<uint32_t>(3, index, buf);
637}
638
639//*****************************************************************************
640uint32_t GetBuf4ByteUInt(int &index, const unsigned char *buf) {
641 return GetBuf<uint32_t>(4, index, buf);
642}
643
644//*****************************************************************************
645uint64_t GetBuf8ByteUInt(int &index, const unsigned char *buf) {
646 return GetBuf<uint64_t>(8, index, buf);
647}
648
649//*****************************************************************************
650double GetBuf1ByteDouble(double precision, int &index, const unsigned char *buf, double def) {
651 int8_t vl = GetBuf<int8_t>(1, index, buf);
652 if (vl==0x7f) return def;
653
654 return vl * precision;
655}
656
657//*****************************************************************************
658double GetBuf1ByteUDouble(double precision, int &index, const unsigned char *buf, double def) {
659 uint8_t vl = GetBuf<uint8_t>(1, index, buf);
660 if (vl==0xff) return def;
661
662 return vl * precision;
663}
664
665//*****************************************************************************
666double GetBuf2ByteDouble(double precision, int &index, const unsigned char *buf, double def) {
667 int16_t vl = GetBuf<int16_t>(2, index, buf);
668 if (vl==0x7fff) return def;
669
670 return vl * precision;
671}
672
673//*****************************************************************************
674double GetBuf2ByteUDouble(double precision, int &index, const unsigned char *buf, double def) {
675 uint16_t vl = GetBuf<uint16_t>(2, index, buf);
676 if (vl==0xffff) return def;
677
678 return vl * precision;
679}
680
681//*****************************************************************************
682double GetBuf8ByteDouble(double precision, int &index, const unsigned char *buf, double def) {
683 int64_t vl = GetBuf<int64_t>(8, index, buf);
684 if (vl==0x7fffffffffffffffLL) return def;
685
686 return vl * precision;
687}
688
689//*****************************************************************************
690double GetBufDouble(int &index, const unsigned char *buf, double def) {
691 int64_t vl = GetBuf<int64_t>(8, index, buf);
692 double ret;
693 // On avr double==float, so we test it also. Currently no handling for avr.
694 if ( sizeof(double)==8 && !N2kIsNA(vl) ) {
695 memcpy(&ret,&vl,8);
696 if ( isnan(ret) ) ret=def;
697 } else {
698 ret=def;
699 }
700 return ret;
701}
702
703//*****************************************************************************
704float GetBufFloat(int &index, const unsigned char *buf, float def) {
705 int32_t vl = GetBuf<int32_t>(4, index, buf);
706 float ret;
707 if ( !N2kIsNA(vl) ) {
708 memcpy(&ret,&vl,4);
709 if ( isnan(ret) ) ret=def;
710 } else { // On avr double==float
711 ret=def;
712 }
713 return ret;
714}
715
716//*****************************************************************************
717double GetBuf3ByteDouble(double precision, int &index, const unsigned char *buf, double def) {
718 int32_t vl = GetBuf<int32_t>(3, index, buf);
719 if (vl==0x007fffff) return def;
720
721 return vl * precision;
722}
723
724//*****************************************************************************
725double GetBuf4ByteDouble(double precision, int &index, const unsigned char *buf, double def) {
726 int32_t vl = GetBuf<int32_t>(4, index, buf);
727 if (vl==0x7fffffff) return def;
728
729 return vl * precision;
730}
731
732//*****************************************************************************
733double GetBuf4ByteUDouble(double precision, int &index, const unsigned char *buf, double def) {
734 uint32_t vl = GetBuf<uint32_t>(4, index, buf);
735 if (vl==0xffffffff) return def;
736
737 return vl * precision;
738}
739
740//*****************************************************************************
741void SetBuf2ByteDouble(double v, double precision, int &index, unsigned char *buf) {
742 double vd=round((v/precision));
743 int16_t vi = (vd>=N2kInt16Min && vd<N2kInt16OR)?(int16_t)vd:N2kInt16OR;
744 SetBuf(vi, 2, index, buf);
745}
746
747//*****************************************************************************
748void SetBuf2ByteUDouble(double v, double precision, int &index, unsigned char *buf) {
749 double vd=round((v/precision));
750 uint16_t vi = (vd>=0 && vd<N2kUInt16OR)?(uint16_t)vd:N2kUInt16OR;
751 SetBuf(vi, 2, index, buf);
752}
753
754//*****************************************************************************
755void SetBuf1ByteDouble(double v, double precision, int &index, unsigned char *buf) {
756 double vd=round((v/precision));
757 int8_t vi = (vd>=N2kInt8Min && vd<N2kInt8OR)?(int8_t)vd:N2kInt8OR;
758 SetBuf(vi, 1, index, buf);
759}
760
761//*****************************************************************************
762void SetBuf1ByteUDouble(double v, double precision, int &index, unsigned char *buf) {
763 double vd=round((v/precision));
764 uint8_t vi = (vd>=0 && vd<N2kUInt8OR)?(uint8_t)vd:N2kUInt8OR;
765 SetBuf(vi, 1, index, buf);
766}
767
768//*****************************************************************************
769void SetBuf2ByteInt(int16_t v, int &index, unsigned char *buf) {
770 SetBuf(v, 2, index, buf);
771}
772
773//*****************************************************************************
774void SetBuf2ByteUInt(uint16_t v, int &index, unsigned char *buf) {
775 SetBuf(v, 2, index, buf);
776}
777
778//*****************************************************************************
779void SetBuf3ByteInt(int32_t v, int &index, unsigned char *buf) {
780 SetBuf(v, 3, index, buf);
781}
782
783//*****************************************************************************
784void SetBuf4ByteUInt(uint32_t v, int &index, unsigned char *buf) {
785 SetBuf(v, 4, index, buf);
786}
787
788//*****************************************************************************
789void SetBufUInt64(uint64_t v, int &index, unsigned char *buf) {
790 SetBuf(v, 8, index, buf);
791}
792
793//*****************************************************************************
794void SetBufStr(const char *str, int len, int &index, unsigned char *buf, bool UsePgm, unsigned char fillChar) {
795 int i=0;
796 if ( UsePgm ) {
797 for (; i<len && str[i]!=0; i++, index++) {
798 buf[index]=pgm_read_byte(&(str[i]));
799 }
800 } else {
801 for (; i<len && str[i]!=0; i++, index++) {
802 buf[index]=str[i];
803 }
804 }
805 for (; i<len; i++, index++) {
806 buf[index]=fillChar;
807 }
808}
809
810//*****************************************************************************
811void PrintBuf(N2kStream *port, unsigned char len, const unsigned char *pData, bool AddLF) {
812 if (port==0) return;
813
814 for(int i = 0; i<len; i++) {
815 if (i>0) { port->print(F(",")); };
816 // Print bytes as hex.
817 port->print(pData[i], 16);
818 }
819
820 if (AddLF) port->println(F(""));
821}
822
823//*****************************************************************************
824void tN2kMsg::Print(N2kStream *port, bool NoData) const {
825 if (port==0 || !IsValid()) return;
826 port->print(N2kMillis()); port->print(F(" : "));
827 port->print(F("Pri:")); port->print(Priority);
828 port->print(F(" PGN:")); port->print(PGN);
829 port->print(F(" Source:")); port->print(Source);
830 port->print(F(" Dest:")); port->print(Destination);
831 port->print(F(" Len:")); port->print(DataLen);
832 if (!NoData) {
833 port->print(F(" Data:"));
834 PrintBuf(port,DataLen,Data);
835 }
836 port->println(F(""));
837}
838
839//*****************************************************************************
840void AddByteEscapedToBuf(unsigned char byteToAdd, uint8_t &idx, unsigned char *buf, int &byteSum)
841{
842 buf[idx++]=byteToAdd;
843 byteSum+=byteToAdd;
844
845 if (byteToAdd == Escape) {
846 buf[idx++]=Escape;
847 }
848}
849
850//*****************************************************************************
851// Actisense Format:
852// <10><02><93><length (1)><priority (1)><PGN (3)><destination (1)><source (1)><time (4)><len (1)><data (len)><CRC (1)><10><03>
854 unsigned long _PGN=PGN;
855 unsigned long _MsgTime=MsgTime;
856 uint8_t msgIdx=0;
857 int byteSum = 0;
858 uint8_t CheckSum;
859 unsigned char ActisenseMsgBuf[MaxActisenseMsgBuf];
860
861 if (port==0 || !IsValid()) return;
862 // Serial.print("freeMemory()="); Serial.println(freeMemory());
863
864 ActisenseMsgBuf[msgIdx++]=Escape;
865 ActisenseMsgBuf[msgIdx++]=StartOfText;
866 AddByteEscapedToBuf(MsgTypeN2k,msgIdx,ActisenseMsgBuf,byteSum);
867 AddByteEscapedToBuf(DataLen+11,msgIdx,ActisenseMsgBuf,byteSum); //length does not include escaped chars
868 AddByteEscapedToBuf(Priority,msgIdx,ActisenseMsgBuf,byteSum);
869 AddByteEscapedToBuf(_PGN & 0xff,msgIdx,ActisenseMsgBuf,byteSum); _PGN>>=8;
870 AddByteEscapedToBuf(_PGN & 0xff,msgIdx,ActisenseMsgBuf,byteSum); _PGN>>=8;
871 AddByteEscapedToBuf(_PGN & 0xff,msgIdx,ActisenseMsgBuf,byteSum);
872 AddByteEscapedToBuf(Destination,msgIdx,ActisenseMsgBuf,byteSum);
873 AddByteEscapedToBuf(Source,msgIdx,ActisenseMsgBuf,byteSum);
874 // Time?
875 AddByteEscapedToBuf(_MsgTime & 0xff,msgIdx,ActisenseMsgBuf,byteSum); _MsgTime>>=8;
876 AddByteEscapedToBuf(_MsgTime & 0xff,msgIdx,ActisenseMsgBuf,byteSum); _MsgTime>>=8;
877 AddByteEscapedToBuf(_MsgTime & 0xff,msgIdx,ActisenseMsgBuf,byteSum); _MsgTime>>=8;
878 AddByteEscapedToBuf(_MsgTime & 0xff,msgIdx,ActisenseMsgBuf,byteSum);
879 AddByteEscapedToBuf(DataLen,msgIdx,ActisenseMsgBuf,byteSum);
880
881
882 for (int i = 0; i < DataLen; i++) AddByteEscapedToBuf(Data[i],msgIdx,ActisenseMsgBuf,byteSum);
883 byteSum %= 256;
884
885 CheckSum = (uint8_t)((byteSum == 0) ? 0 : (256 - byteSum));
886 ActisenseMsgBuf[msgIdx++]=CheckSum;
887 if (CheckSum==Escape) ActisenseMsgBuf[msgIdx++]=CheckSum;
888
889 ActisenseMsgBuf[msgIdx++] = Escape;
890 ActisenseMsgBuf[msgIdx++] = EndOfText;
891
892// if ( port->availableForWrite()>msgIdx ) { // 16.7.2017 did not work yet
893 port->write(ActisenseMsgBuf,msgIdx);
894// }
895 //Serial.print("Actisense data:");
896 //PrintBuf(msgIdx,ActisenseMsgBuf);
897 //Serial.print("\r\n");
898}
#define pgm_read_byte(var)
Definition: N2kDef.h:46
#define F(str)
Definition: N2kDef.h:64
void AddByteEscapedToBuf(unsigned char byteToAdd, uint8_t &idx, unsigned char *buf, int &byteSum)
Definition: N2kMsg.cpp:840
void SetBufDouble(double v, int &index, unsigned char *buf)
Writes a double value into a byte array buffer
Definition: N2kMsg.cpp:551
uint16_t GetBuf2ByteUInt(int &index, const unsigned char *buf)
Extracts 2 bytes out of the given buffer and converts it to an integer value.
Definition: N2kMsg.cpp:630
double GetBuf8ByteDouble(double precision, int &index, const unsigned char *buf, double def)
Extracts 8 bytes out of the given buffer and converts it to a double value.
Definition: N2kMsg.cpp:682
int16_t GetBuf2ByteInt(int &index, const unsigned char *buf)
Extracts 2 bytes out of the given buffer and converts it to an integer value.
Definition: N2kMsg.cpp:625
void SetBuf2ByteInt(int16_t v, int &index, unsigned char *buf)
Writes an integer value into a byte array buffer using 2 bytes To write a integer value into a certai...
Definition: N2kMsg.cpp:769
double GetBuf1ByteDouble(double precision, int &index, const unsigned char *buf, double def)
Extracts the specified numbers of bytes out of the given buffer and converts it to a double value.
Definition: N2kMsg.cpp:650
void SetBuf2ByteUDouble(double v, double precision, int &index, unsigned char *buf)
Writes a double unsigned value into a byte array buffer using 2 bytes.
Definition: N2kMsg.cpp:748
#define N2kInt32Min
Definition: N2kMsg.cpp:579
void SetBufStr(const char *str, int len, int &index, unsigned char *buf, bool UsePgm, unsigned char fillChar)
Writes a string into a byte array buffer.
Definition: N2kMsg.cpp:794
double round(double val)
Definition: N2kMsg.cpp:52
double GetBuf2ByteUDouble(double precision, int &index, const unsigned char *buf, double def)
Extracts 2 bytes out of the given buffer and converts it to a double value.
Definition: N2kMsg.cpp:674
void SetBuf(T v, size_t len, int &index, unsigned char *buf)
Definition: N2kMsg.cpp:539
double GetBuf2ByteDouble(double precision, int &index, const unsigned char *buf, double def)
Extracts 2 bytes out of the given buffer and converts it to a double value.
Definition: N2kMsg.cpp:666
double GetBuf4ByteUDouble(double precision, int &index, const unsigned char *buf, double def)
Extracts 4 bytes out of the given buffer and converts it to a double value.
Definition: N2kMsg.cpp:733
#define N2kInt16OR
Definition: N2kMsg.cpp:574
double GetBufDouble(int &index, const unsigned char *buf, double def)
Extracts bytes out of the given buffer and converts it to a double value.
Definition: N2kMsg.cpp:690
#define N2kInt32OR
Definition: N2kMsg.cpp:576
void SetBuf3ByteDouble(double v, double precision, int &index, unsigned char *buf)
Writes a double signed value into a byte array buffer using 3 bytes.
Definition: N2kMsg.cpp:618
#define StartOfText
Definition: N2kMsg.cpp:33
#define N2kInt24Min
Definition: N2kMsg.cpp:581
#define N2kInt8OR
Definition: N2kMsg.cpp:572
void SetBuf2ByteDouble(double v, double precision, int &index, unsigned char *buf)
Writes a double signed value into a byte array buffer using 2 bytes.
Definition: N2kMsg.cpp:741
#define N2kUInt8OR
Definition: N2kMsg.cpp:573
void PrintBuf(N2kStream *port, unsigned char len, const unsigned char *pData, bool AddLF)
Print out a buffer (byte array)
Definition: N2kMsg.cpp:811
#define MaxActisenseMsgBuf
Definition: N2kMsg.cpp:37
#define N2kUInt32OR
Definition: N2kMsg.cpp:577
float GetBufFloat(int &index, const unsigned char *buf, float def)
Extracts the specified numbers of bytes out of the given buffer and converts it to an float value.
Definition: N2kMsg.cpp:704
double GetBuf1ByteUDouble(double precision, int &index, const unsigned char *buf, double def)
Extracts 1 byte out of the given buffer and converts it to a double value.
Definition: N2kMsg.cpp:658
T GetBuf(size_t len, int &index, const unsigned char *buf)
Definition: N2kMsg.cpp:522
#define MsgTypeN2k
Definition: N2kMsg.cpp:35
void SetBufFloat(float v, int &index, unsigned char *buf)
Writes a float value into a byte array buffer.
Definition: N2kMsg.cpp:562
uint64_t GetBuf8ByteUInt(int &index, const unsigned char *buf)
Extracts 8 bytes out of the given buffer and converts it to an integer value.
Definition: N2kMsg.cpp:645
#define EndOfText
Definition: N2kMsg.cpp:34
#define N2kUInt16OR
Definition: N2kMsg.cpp:575
void SetBuf4ByteDouble(double v, double precision, int &index, unsigned char *buf)
Writes a double signed value into a byte array buffer using 4 bytes.
Definition: N2kMsg.cpp:604
void SetBufUInt64(uint64_t v, int &index, unsigned char *buf)
Writes an unsigned integer 64bit value into a byte array buffer using 8 bytes To write a integer valu...
Definition: N2kMsg.cpp:789
void SetBuf4ByteUDouble(double v, double precision, int &index, unsigned char *buf)
Writes a double unsigned value into a byte array buffer using 4 bytes.
Definition: N2kMsg.cpp:611
#define N2kInt8Min
Definition: N2kMsg.cpp:583
void SetBuf3ByteInt(int32_t v, int &index, unsigned char *buf)
Writes an integer value into a byte array buffer using 3 bytes To write a integer value into a certai...
Definition: N2kMsg.cpp:779
void SetBuf2ByteUInt(uint16_t v, int &index, unsigned char *buf)
Writes an unsigned integer value into a byte array buffer using 2 bytes.
Definition: N2kMsg.cpp:774
void SetBuf8ByteDouble(double v, double precision, int &index, unsigned char *buf)
Writes a double signed value into a byte array buffer using 8 bytes.
Definition: N2kMsg.cpp:586
#define N2kInt24OR
Definition: N2kMsg.cpp:580
void SetBuf1ByteUDouble(double v, double precision, int &index, unsigned char *buf)
Writes a double unsigned value into a byte array buffer using 1 byte.
Definition: N2kMsg.cpp:762
double GetBuf4ByteDouble(double precision, int &index, const unsigned char *buf, double def)
Extracts 4 bytes out of the given buffer and converts it to a double value.
Definition: N2kMsg.cpp:725
#define N2kInt16Min
Definition: N2kMsg.cpp:582
uint32_t GetBuf4ByteUInt(int &index, const unsigned char *buf)
Extracts 4 bytes out of the given buffer and converts it to an integer value.
Definition: N2kMsg.cpp:640
void SetBuf4ByteUInt(uint32_t v, int &index, unsigned char *buf)
Writes an unsigned integer value into a byte array buffer u ing 4 bytes To write a integer value into...
Definition: N2kMsg.cpp:784
void SetBuf1ByteDouble(double v, double precision, int &index, unsigned char *buf)
Writes a double signed value into a byte array buffer using 1 byte.
Definition: N2kMsg.cpp:755
uint32_t GetBuf3ByteUInt(int &index, const unsigned char *buf)
Extracts 3 bytes out of the given buffer and converts it to an integer value.
Definition: N2kMsg.cpp:635
T byteswap(T val)
#define Escape
Definition: N2kMsg.cpp:32
double GetBuf3ByteDouble(double precision, int &index, const unsigned char *buf, double def)
Extracts 3 bytes out of the given buffer and converts it to a double value.
Definition: N2kMsg.cpp:717
This File contains the class tN2kMsg and all necessary functions to handle a NMEA2000 Message.
const uint32_t N2kUInt32NA
Constant "Not Available" for a unsigned 32bit int value.
Definition: N2kMsg.h:61
const int8_t N2kInt8NA
Constant "Not Available" for a signed 8bit value.
Definition: N2kMsg.h:55
const int16_t N2kInt16NA
Constant "Not Available" for a signed 16bit int value.
Definition: N2kMsg.h:59
const int64_t N2kInt64NA
Constant "Not Available" for a signed 64bit int value.
Definition: N2kMsg.h:67
const int32_t N2kInt32NA
Constant "Not Available" for a signed 32bit int value.
Definition: N2kMsg.h:63
const uint16_t N2kUInt16NA
Constant "Not Available" for a unsigned 16bit int value.
Definition: N2kMsg.h:57
const uint8_t N2kUInt8NA
Constant "Not Available" for a unsigned 8bit int value.
Definition: N2kMsg.h:53
bool N2kIsNA(double v)
Verify that the specified value is equal to "Not available".
Definition: N2kMsg.h:80
uint32_t N2kMillis()
Definition: N2kTimer.cpp:48
The file contains function and classes for best timing performance.
Streaming Class to handle all Streams generated by the Library.
Definition: N2kStream.h:60
size_t print(const char *str)
Print string to stream.
Definition: N2kStream.cpp:32
virtual size_t write(const uint8_t *data, size_t size)=0
Write data to stream.
size_t println(const char *str)
Print string and newline to stream.
Definition: N2kStream.cpp:75
unsigned char Data[MaxDataLen]
Byte array which carries all the data of the NMEA2000 message.
Definition: N2kMsg.h:675
void Add2ByteUDouble(double v, double precision, double UndefVal=N2kDoubleNA)
Add double value to the buffer using 2 bytes.
Definition: N2kMsg.cpp:156
void AddFloat(float v, float UndefVal=N2kFloatNA)
Add float value to the buffer This method adds a float value to the message buffer using SetBufFloat ...
Definition: N2kMsg.cpp:101
void AddStr(const char *str, int len, bool UsePgm=false, unsigned char fillChar=0xff)
Add string value to the buffer The string will be added to the end (indicated by DataLen) of the byte...
Definition: N2kMsg.cpp:213
void Add2ByteUInt(uint16_t v)
Add unsigned integer value to the buffer using 2 bytes The value will be added to the end (indicated ...
Definition: N2kMsg.cpp:188
double Get3ByteDouble(double precision, int &Index, double def=N2kDoubleNA) const
Get a double from 3 bytes out of Data The fixed point integer mechanism is used.
Definition: N2kMsg.cpp:324
double Get4ByteDouble(double precision, int &Index, double def=N2kDoubleNA) const
Get a double from 4 bytes out of Data The fixed point integer mechanism is used.
Definition: N2kMsg.cpp:331
double Get1ByteDouble(double precision, int &Index, double def=N2kDoubleNA) const
Get a double from 1 bytes out of Data The fixed point integer mechanism is used.
Definition: N2kMsg.cpp:296
bool GetVarStr(size_t &StrBufSize, char *StrBuf, int &Index) const
Get a string out of Data This method determines the length of the string by it self,...
Definition: N2kMsg.cpp:416
void Add4ByteUDouble(double v, double precision, double UndefVal=N2kDoubleNA)
Add double value to the buffer using 4 bytes.
Definition: N2kMsg.cpp:129
void Add2ByteInt(int16_t v)
Add integer value to the buffer using 2 bytes The value will be added to the end (indicated by DataLe...
Definition: N2kMsg.cpp:183
void Add4ByteDouble(double v, double precision, double UndefVal=N2kDoubleNA)
Add double value to the buffer using 4 bytes.
Definition: N2kMsg.cpp:120
void Add3ByteDouble(double v, double precision, double UndefVal=N2kDoubleNA)
Add double value to the buffer using 3 bytes.
Definition: N2kMsg.cpp:138
bool IsValid() const
Checks if the Message Meta Content is valid Basic check if the message object is valid,...
Definition: N2kMsg.h:760
void AddByte(unsigned char v)
Add byte value to the buffer The byte will be added to the end (indicated by DataLen) of the byte arr...
Definition: N2kMsg.cpp:208
void ResetData()
Fills the whole data buffer with 0xff.
Definition: N2kMsg.cpp:87
void Add2ByteDouble(double v, double precision, double UndefVal=N2kDoubleNA)
Add double value to the buffer using 2 bytes.
Definition: N2kMsg.cpp:147
void Add1ByteUDouble(double v, double precision, double UndefVal=N2kDoubleNA)
Add double value to the buffer using 1 byte.
Definition: N2kMsg.cpp:174
bool Set2ByteUInt(uint16_t v, int &Index)
Set a 2byte unsigned integer in Data.
Definition: N2kMsg.cpp:457
void Add1ByteDouble(double v, double precision, double UndefVal=N2kDoubleNA)
Add double value to the buffer using 1 byte.
Definition: N2kMsg.cpp:165
void Print(N2kStream *port, bool NoData=false) const
Print out the whole content of the N2kMsg Object.
Definition: N2kMsg.cpp:824
void AddUInt64(uint64_t v)
Add unsigned integer value to the buffer using 8 bytes The value will be added to the end (indicated ...
Definition: N2kMsg.cpp:203
void AddBuf(const void *buf, size_t bufLen)
Add byte array to the buffer.
Definition: N2kMsg.cpp:242
uint16_t Get2ByteUInt(int &Index, uint16_t def=0xffff) const
Get an unsigned integer from 2 bytes out of Data.
Definition: N2kMsg.cpp:268
double Get2ByteDouble(double precision, int &Index, double def=N2kDoubleNA) const
Get a double from 2 bytes out of Data The fixed point integer mechanism is used.
Definition: N2kMsg.cpp:310
unsigned char Source
Source of the NMEA2000 message.
Definition: N2kMsg.h:669
void Add8ByteDouble(double v, double precision, double UndefVal=N2kDoubleNA)
Add double value to the buffer using 8 bytes.
Definition: N2kMsg.cpp:110
static const int MaxDataLen
Maximum number of bytes that can be stored in the data buffer With fast packet the first frame can ha...
Definition: N2kMsg.h:663
float GetFloat(int &Index, float def=N2kFloatNA) const
Get a float out of Data.
Definition: N2kMsg.cpp:352
double Get2ByteUDouble(double precision, int &Index, double def=N2kDoubleNA) const
Get a double from 2 bytes out of Data The fixed point integer mechanism is used.
Definition: N2kMsg.cpp:317
void AddVarStr(const char *str, bool UsePgm=false)
Add string value to the buffer This method determines the length of the string by it self using strle...
Definition: N2kMsg.cpp:234
unsigned char Priority
Priority of the NMEA2000 message.
Definition: N2kMsg.h:665
bool SetByte(uint8_t v, int &Index)
Set a byte in Data.
Definition: N2kMsg.cpp:447
uint32_t Get3ByteUInt(int &Index, uint32_t def=0xffffffff) const
Get an unsigned integer from 3 bytes out of Data.
Definition: N2kMsg.cpp:275
double Get1ByteUDouble(double precision, int &Index, double def=N2kDoubleNA) const
Get a double from 1 bytes out of Data The fixed point integer mechanism is used.
Definition: N2kMsg.cpp:303
void Add3ByteInt(int32_t v)
Add integer value to the buffer using 3 bytes The value will be added to the end (indicated by DataLe...
Definition: N2kMsg.cpp:193
virtual void Clear()
Clears the content of the N2kMsg object The method sets the PGN, DataLen and MsgTime to zero.
Definition: N2kMsg.cpp:94
unsigned long MsgTime
timestamp (ms since start [max 49days]) of the NMEA2000 message
Definition: N2kMsg.h:677
void Add4ByteUInt(uint32_t v)
Add unsigned integer value to the buffer using 4 bytes The value will be added to the end (indicated ...
Definition: N2kMsg.cpp:198
bool TPMessage
Message is a MultiPacket Message.
Definition: N2kMsg.h:685
void SetPGN(unsigned long _PGN)
Set the Parameter Group Number of the message *.
Definition: N2kMsg.cpp:68
unsigned char GetByte(int &Index) const
Get the value from a byte out of Data.
Definition: N2kMsg.cpp:254
uint64_t GetUInt64(int &Index, uint64_t def=0xffffffffffffffffULL) const
Get an unsigned integer from 8 bytes out of Data.
Definition: N2kMsg.cpp:289
int16_t Get2ByteInt(int &Index, int16_t def=0x7fff) const
Get an integer from 2 bytes out of Data.
Definition: N2kMsg.cpp:261
bool GetBuf(void *buf, size_t Length, int &Index) const
Get a byte array out of Data.
Definition: N2kMsg.cpp:430
bool GetStr(char *StrBuf, size_t Length, int &Index) const
Get a string out of Data.
Definition: N2kMsg.cpp:359
void AddAISStr(const char *str, int len)
Add string value to the buffer after filtering characters as defined in ITU-R M.1371-1 The string wil...
Definition: N2kMsg.cpp:221
double Get4ByteUDouble(double precision, int &Index, double def=N2kDoubleNA) const
Get a double from 4 bytes out of Data The fixed point integer mechanism is used.
Definition: N2kMsg.cpp:338
void Init(unsigned char _Priority, unsigned long _PGN, unsigned char _Source, unsigned char _Destination=0xff)
Initialisation of the N2kMsg object.
Definition: N2kMsg.cpp:75
tN2kMsg(unsigned char _Source=15, unsigned char _Priority=6, unsigned long _PGN=0, int _DataLen=0)
Construct a new t N2k Msg object.
Definition: N2kMsg.cpp:60
void SendInActisenseFormat(N2kStream *port) const
Print out the whole content of the N2kMsg Object using the Actisense Format.
Definition: N2kMsg.cpp:853
double Get8ByteDouble(double precision, int &Index, double def=N2kDoubleNA) const
Get a double from 8 bytes out of Data The fixed point integer mechanism is used.
Definition: N2kMsg.cpp:345
uint32_t Get4ByteUInt(int &Index, uint32_t def=0xffffffff) const
Get an unsigned integer from 4 bytes out of Data.
Definition: N2kMsg.cpp:282
int DataLen
Number of bytes already stored in tN2kMsg::Data of this message.
Definition: N2kMsg.h:673
unsigned long PGN
Parameter Group Number (PGN) of the NMEA2000 message.
Definition: N2kMsg.h:667
unsigned char Destination
Destination of the NMEA2000 message.
Definition: N2kMsg.h:671