Last active
June 22, 2016 13:20
-
-
Save gabonator/7150910 to your computer and use it in GitHub Desktop.
Garmin HUD protocol
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
CString Hex(int n) | |
{ | |
CString str; | |
str.Format( _T("%02x"), n ); | |
return str; | |
} | |
void SendHud(unsigned char* pBuf, int nLen) | |
{ | |
CArray<int> arrPacket; | |
arrPacket.Add( 0x10 ); | |
arrPacket.Add( 0x7b ); | |
arrPacket.Add( nLen+6 ); | |
arrPacket.Add( nLen ); | |
arrPacket.Add( 0x00 ); | |
arrPacket.Add( 0x00 ); | |
arrPacket.Add( 0x00 ); | |
arrPacket.Add( 0x55 ); | |
arrPacket.Add( 0x15 ); | |
for ( int i=0; i<nLen; i++) | |
arrPacket.Add( pBuf[i] ); | |
//crc | |
unsigned int nCrc = 0; | |
for ( int i=1; i<arrPacket.GetSize(); i++) | |
nCrc += arrPacket[i]; | |
nCrc = (-(int)nCrc) & 0xff; | |
arrPacket.Add( nCrc ); | |
arrPacket.Add( 0x10 ); | |
arrPacket.Add( 0x03 ); | |
CString strPacket; | |
for ( int i=0; i<arrPacket.GetSize(); i++) | |
{ | |
strPacket += Hex( arrPacket[i] ); | |
// stuffing | |
if ( i > 0 && i < arrPacket.GetSize()-2 && arrPacket[i] == 0x10 ) | |
strPacket += Hex( arrPacket[i] ); | |
} | |
bt.Send( strPacket ); | |
} | |
int Digit(int n) | |
{ | |
n = n % 10; | |
if ( n == 0 ) | |
return 10; | |
return n; | |
} | |
void SetTime(int nH, int nM) | |
{ | |
bool bColon = true; | |
bool bFlag = false; | |
bool bTraffic = true; | |
unsigned char arr[] = {0x05, | |
bTraffic ? 0xff : 0x00, | |
Digit(nH/10), Digit(nH), bColon ? 0xff : 0x00, | |
Digit(nM/10), Digit(nM), bFlag ? 0x00 : 0xff, 0x00}; | |
SendHud(arr, sizeof(arr)); | |
} | |
void SetDistance(int nDist) | |
{ | |
enum { | |
None = 0, | |
Metres = 1, | |
Kilometres = 3, | |
Miles = 5 | |
} units = Metres; | |
bool bDecimal = false; | |
unsigned char arr[] = {0x03, | |
Digit(nDist/1000), Digit(nDist/100), Digit(nDist/10), bDecimal ? 0xff : 0x00, Digit(nDist), (int)units}; | |
SendHud(arr, sizeof(arr)); | |
} | |
void SetDirection(int nDir) | |
{ | |
enum { | |
SharpRight = 0x02, | |
Right = 0x04, | |
EasyRight = 0x08, | |
Straight = 0x10, | |
EasyLeft = 0x20, | |
Left = 0x40, | |
SharpLeft = 0x80 | |
} eOutAngle = EasyRight; | |
unsigned char arr[] = {0x01, 0x01, 0x00, (int)eOutAngle}; | |
SendHud(arr, sizeof(arr)); | |
} | |
void SetLanes( CString strLanes ) | |
{ | |
for (int i=strLanes.GetLength(); i < 6; i++ ) | |
if (i&1) | |
strLanes = _T(" ") + strLanes; | |
else | |
strLanes = strLanes + _T(" "); | |
int nOutline = 0, nArrow = 0; | |
for ( int i=0; i<6; i++) | |
{ | |
char ch = (char)strLanes[i]; | |
if (ch == '0' || ch == '1') | |
nOutline |= 1<<(6-i); | |
if (ch == '1') | |
nArrow |= 1<<(6-i); | |
} | |
unsigned char arr[] = {0x02, nOutline, nArrow}; | |
SendHud(arr, sizeof(arr)); | |
} | |
void SetSpeedWarning(int nSpeed, int nLimit) | |
{ | |
bool bSpeeding = true; | |
bool bIcon = true; | |
unsigned char arr[] = {0x06, | |
(nSpeed/100)%10, Digit(nSpeed/10), Digit(nSpeed), 0xff, | |
(nLimit/100)%10, Digit(nLimit/10), Digit(nLimit), bSpeeding ? 0xff : 0x00, bIcon ? 0xff : 0x00}; | |
SendHud(arr, sizeof(arr)); | |
} | |
void ShowCameraIcon() | |
{ | |
unsigned char arr[] = {0x04, 0x01}; | |
SendHud( arr, sizeof(arr) ); | |
} | |
void ShowGpsLabel() | |
{ | |
unsigned char arr[] = {0x07, 0x01}; | |
SendHud( arr, sizeof(arr) ); | |
} |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
int ZD(int n) | |
{ | |
if (n==0) return 10; | |
return n; | |
} | |
void _SetTime(int nHr, int nMin) | |
{ | |
CArray<int>arrPacket; | |
// preamble | |
static unsigned char a =0; | |
arrPacket.Add(0x10); arrPacket.Add(0x7b); arrPacket.Add(0x0f); arrPacket.Add(0x09); arrPacket.Add(0x00); arrPacket.Add(0x00); arrPacket.Add(0x00); | |
arrPacket.Add(0x55); arrPacket.Add(0x15); arrPacket.Add(0x05); arrPacket.Add(0x00); | |
arrPacket.Add((nHr/10)%10); arrPacket.Add(ZD(nHr%10)); arrPacket.Add(0xff); arrPacket.Add(ZD((nMin/10)%10)); arrPacket.Add(ZD(nMin%10)); arrPacket.Add(0x00); arrPacket.Add(0xff); | |
//\10\7b\0f\09\00\00\00\55\15\05\00\00\08\ff\01\0a\00\ff\ed\10\03 | |
// crc | |
int nCrc = 0; | |
for (int i=0; i<arrPacket.GetSize(); i++) nCrc += arrPacket[i]; | |
nCrc = (0x10+(-nCrc))&0xff; | |
arrPacket.Add(nCrc); | |
// terminator | |
arrPacket.Add(0x10); arrPacket.Add(0x03); | |
CString strBuf; | |
for (int i=0; i<arrPacket.GetSize(); i++) strBuf += CString::FormatInline( _T("%02x"), arrPacket[i] ); | |
CString strRequest = CString::FormatInline( _T("$JS: Driver.HudRequest(\"%s\");\n"), strBuf); | |
CLowDevice::DeviceTerminalSend( strRequest ); | |
} | |
void _SetDistance(int nDistance ) | |
{ | |
CArray<int>arrPacket; | |
// preamble | |
arrPacket.Add(0x10); arrPacket.Add(0x7b); arrPacket.Add(0x0d); arrPacket.Add(0x07); arrPacket.Add(0x00); arrPacket.Add(0x00); arrPacket.Add(0x00); arrPacket.Add(0x55); arrPacket.Add(0x15); arrPacket.Add(0x03); arrPacket.Add(0x00); | |
// numeric | |
if ( nDistance < 100 && nDistance >= 0 ) | |
{ | |
arrPacket.Add(0x00);arrPacket.Add(nDistance/10);arrPacket.Add(0x00);arrPacket.Add(0x0a);arrPacket.Add(0x01); | |
} | |
if ( nDistance < 1000 && nDistance >= 100 ) | |
{ | |
arrPacket.Add(nDistance/100);arrPacket.Add(_ZD((nDistance/10)%10));arrPacket.Add(/*(nDistance/10)%10*/ 0x00);arrPacket.Add(/*0x0a*/ _ZD(nDistance%10));arrPacket.Add(0x01); | |
} | |
if ( nDistance < 10000 && nDistance >= 1000 ) | |
{ | |
int nZ = (nDistance / 10000)%10; | |
int nA = (nDistance / 1000)%10; | |
int nB = (nDistance / 100)% 10; | |
if (nB == 0) nB = 10; // desatinna bodka // jednotky (3=km, 5=mi) | |
arrPacket.Add(nZ);arrPacket.Add(nA);arrPacket.Add(0xff);arrPacket.Add(nB);arrPacket.Add(0x03); | |
} | |
// crc | |
int nCrc = 0; | |
for (int i=1; i<arrPacket.GetSize(); i++) nCrc += arrPacket[i]; | |
nCrc = (-nCrc)&0xff; | |
arrPacket.Add(nCrc); | |
// terminator | |
arrPacket.Add(0x10); arrPacket.Add(0x03); | |
CString strBuf; | |
for (int i=0; i<arrPacket.GetSize(); i++) strBuf += CString::FormatInline( _T("%02x"), arrPacket[i] ); | |
CString strRequest = CString::FormatInline( _T("$JS: Driver.HudRequest(\"%s\");\n"), strBuf); | |
CLowDevice::DeviceTerminalSend( strRequest ); | |
} | |
void _SetDirection(int nDir) | |
{ | |
CArray<int>arrPacket; | |
// nDistance = 900; | |
// preable | |
static unsigned char a =0; | |
arrPacket.Add(0x10); arrPacket.Add(0x7b); arrPacket.Add(0x0a); arrPacket.Add(0x04); arrPacket.Add(0x00); arrPacket.Add(0x00); arrPacket.Add(0x00); | |
arrPacket.Add(0x55); arrPacket.Add(0x15); arrPacket.Add(0x01); arrPacket.Add(0x01); | |
//arrPacket.Add(0x41); arrPacket.Add(0x40); // dolava | |
//arrPacket.Add(0x21); arrPacket.Add(0x20); // trochu dolava | |
//arrPacket.Add(0x05); arrPacket.Add(0x80); // ostro dolava | |
//arrPacket.Add(0x05); arrPacket.Add(0x04); // doprava | |
//arrPacket.Add(0x11); arrPacket.Add(0x10); arrPacket.Add(0x10); // rovno | |
switch (nDir) | |
{ | |
case CJunctionEntry::DirectionLeft: | |
case CJunctionEntry::DirectionExitLeft:arrPacket.Add(0x41); arrPacket.Add(0x40); break; | |
//case CJunctionEntry::DirectionSharpLeft: | |
case CJunctionEntry::DirectionEasyLeft: arrPacket.Add(0x21); arrPacket.Add(0x20); break; | |
//case CJunctionEntry::DirectionEnd: | |
//case CJunctionEntry::DirectionOutOfRoute: | |
case CJunctionEntry::DirectionExitRight: | |
case CJunctionEntry::DirectionEasyRight: | |
case CJunctionEntry::DirectionSharpRight: | |
case CJunctionEntry::DirectionRight: arrPacket.Add(0x05); arrPacket.Add(0x04); break; | |
case CJunctionEntry::DirectionSharpLeft: arrPacket.Add(0x05); arrPacket.Add(0x80); break; | |
case CJunctionEntry::DirectionKeepLeft: | |
case CJunctionEntry::DirectionKeepRight: | |
case CJunctionEntry::DirectionFollow: | |
case CJunctionEntry::DirectionStraight: arrPacket.Add(0x11); arrPacket.Add(0x10); arrPacket.Add(0x10); break; | |
default: | |
return; | |
// arrPacket.Add(0x00); arrPacket.Add(0x00); | |
} | |
/* | |
camera: | |
arrPacket.Add(0x10); arrPacket.Add(0x7b); arrPacket.Add(0x0a); arrPacket.Add(0x04); arrPacket.Add(0x00); arrPacket.Add(0x00); arrPacket.Add(0x00); | |
arrPacket.Add(0x55); arrPacket.Add(0x15); | |
arrPacket.Add(0x04); arrPacket.Add(0x01); arrPacket.Add(0x11); arrPacket.Add(0x10); arrPacket.Add(0x10); | |
01 ** 11 10 10: priamo, horna sipka, rb 180, pravy finish | |
** 01 11 10 10: ikony, GPS | |
*/ | |
// crc | |
int nCrc = 0; | |
for (int i=0; i<arrPacket.GetSize(); i++) nCrc += arrPacket[i]; | |
if ( arrPacket.GetSize() == 14 ) | |
nCrc = (0x20+(-nCrc))&0xff; | |
else | |
nCrc = (0x10+(-nCrc))&0xff; | |
arrPacket.Add(nCrc); | |
// terminator | |
arrPacket.Add(0x10); arrPacket.Add(0x03); | |
CString strBuf; | |
for (int i=0; i<arrPacket.GetSize(); i++) strBuf += CString::FormatInline( _T("%02x"), arrPacket[i] ); | |
CString strRequest = CString::FormatInline( _T("$JS: Driver.HudRequest(\"%s\");\n"), strBuf); | |
CLowDevice::DeviceTerminalSend( strRequest ); | |
} | |
void _SetLanes( CString strMask ) | |
{ BYTE bA = 0x15, bB = 0x02; | |
bA = 0; | |
bB = 0; | |
for ( int i=0; i<6; i++) | |
{ | |
char ch = strMask[i]; | |
if (ch == '0' || ch == '1') | |
bA |= 1<<(6-i); | |
if (ch == '1') | |
bB |= 1<<(6-i); | |
} | |
//\10\7b\09\03\00\00\00\55\15\02\1c\04\ed\10\03 | |
// 10 7b 09 03 00 00 00 55 1c 04 7e 0e 78 10 03 | |
CArray<int>arrPacket; | |
// preable | |
arrPacket.Add(0x10); arrPacket.Add(0x7b); arrPacket.Add(0x09); arrPacket.Add(0x03); arrPacket.Add(0x00); arrPacket.Add(0x00); arrPacket.Add(0x00); | |
arrPacket.Add(0x55); arrPacket.Add(0x15); arrPacket.Add(0x02); | |
arrPacket.Add(bA); arrPacket.Add(bB); | |
// crc | |
int nCrc = 0; | |
for (int i=0; i<arrPacket.GetSize(); i++) nCrc += arrPacket[i]; | |
nCrc = (0x20+0xf0+(-nCrc))&0xff; | |
arrPacket.Add(nCrc); | |
// terminator | |
arrPacket.Add(0x10); arrPacket.Add(0x03); | |
CString strBuf; | |
for (int i=0; i<arrPacket.GetSize(); i++) strBuf += CString::FormatInline( _T("%02x"), arrPacket[i] ); | |
CString strRequest = CString::FormatInline( _T("$JS: Driver.HudRequest(\"%s\");\n"), strBuf); | |
CLowDevice::DeviceTerminalSend( strRequest ); | |
} | |
void _SetSpeedWarn(int nSpd, int nLim, BOOL32 bWarn) | |
{ | |
if ( nSpd == 0 && nLim == 0 ) | |
return; | |
//\10\7b\10\10\0a\00\00\00\55\15\06\00\05\0a\ff\00\05\0a\00\ff\df\10\03 | |
//107b10100a00000055150600050aff00050a00ffdf1003 | |
CArray<int>arrPacket; | |
arrPacket.Add(0x10); arrPacket.Add(0x7b); arrPacket.Add(0x10); arrPacket.Add(0x10); arrPacket.Add(0x0a); arrPacket.Add(0x00); arrPacket.Add(0x00); arrPacket.Add(0x00); | |
arrPacket.Add(0x55); arrPacket.Add(0x15); | |
arrPacket.Add(0x06); arrPacket.Add((nSpd/100)%10); arrPacket.Add((nSpd/10)%10); arrPacket.Add(0x0a); | |
arrPacket.Add(0xff); arrPacket.Add((nLim/100)%10); arrPacket.Add((nLim/10)%10); arrPacket.Add(0x0a); | |
arrPacket.Add(bWarn); arrPacket.Add(0xff); | |
// crc | |
int nCrc = 0; | |
for (int i=0; i<arrPacket.GetSize(); i++) nCrc += arrPacket[i]; | |
nCrc = (0x20+(-nCrc))&0xff; | |
arrPacket.Add(nCrc); | |
// terminator | |
arrPacket.Add(0x10); arrPacket.Add(0x03); | |
CString strBuf; | |
for (int i=0; i<arrPacket.GetSize(); i++) strBuf += CString::FormatInline( _T("%02x"), arrPacket[i] ); | |
CString strRequest = CString::FormatInline( _T("$JS: Driver.HudRequest(\"%s\");\n"), strBuf); | |
CLowDevice::DeviceTerminalSend( strRequest ); | |
} |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
description of garmin protocol, stuffing and crc:
http://www8.garmin.com/support/commProtocol.html