Skip to content

Commit 555f553

Browse files
committed
Add getMode
1 parent 47805a0 commit 555f553

File tree

2 files changed

+154
-4
lines changed

2 files changed

+154
-4
lines changed

src/SparkFun_Unicore_GNSS_Arduino_Library.cpp

Lines changed: 135 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -420,7 +420,8 @@ void um980ProcessMessage(SEMP_PARSE_STATE *parse, uint16_t type)
420420
// Does this response contain the command we are looking for?
421421
if (strcasecmp((char *)scratchPad->unicoreHash.sentenceName, ptrUM980->commandName) == 0) // Found
422422
{
423-
ptrUM980->debugPrintf("Unicore Lib: Query response: %s", parse->buffer);
423+
ptrUM980->debugPrintf("Hash response: %s", parse->buffer);
424+
ptrUM980->modeHandler(parse->buffer, parse->length);
424425
ptrUM980->commandResponse = UM980_RESULT_RESPONSE_COMMAND_OK;
425426
}
426427
break;
@@ -502,6 +503,67 @@ bool UM980::setMode(const char *modeType)
502503
return (sendCommand(command));
503504
}
504505

506+
// getMode returns int representing its current mode
507+
// #MODE,97,GPS,FINE,2389,337235000,0,0,18,969;MODE ROVER SURVEY,*18
508+
// #MODE,97,GPS,FINE,2389,338172000,0,0,18,968;MODE BASE TIME 60,*72
509+
// #MODE,97,GPS,FINE,2283,499142000,0,0,18,22;MODE BASE -1280206.5680 -4716804.4030 4086665.4840,*60
510+
// Unknown = 0
511+
// SURVEY = 1
512+
// UAV = 2
513+
// AUTOMOTIVE = 3
514+
// BASE with survey time (survey-in) = 4
515+
// BASE with fixed coordinates = 5
516+
int8_t UM980::getMode(uint16_t maxWaitMs)
517+
{
518+
Um980Result result;
519+
520+
clearBuffer();
521+
522+
// Send command and check for OK response
523+
result = sendString("MODE", maxWaitMs);
524+
if (result != UM980_RESULT_OK)
525+
return (-2);
526+
527+
commandResponse = UM980_RESULT_RESPONSE_COMMAND_WAITING; // Reset
528+
529+
modeType = UM980_MODE_UNKNOWN; // Reset
530+
531+
unicoreLibrarySemaphoreBlock = true; // Prevent external tasks from harvesting serial data
532+
533+
// Feed the parser until we see a response to the command
534+
int wait = 0;
535+
while (1)
536+
{
537+
if (wait++ == maxWaitMs)
538+
{
539+
debugPrintf("Unicore Lib: Response timeout");
540+
unicoreLibrarySemaphoreBlock = false; // Allow external tasks to control serial hardware
541+
return (-1);
542+
}
543+
544+
updateOnce(); // Will call um980ProcessMessage() and modeHandler()
545+
546+
if (modeType != UM980_MODE_UNKNOWN)
547+
{
548+
unicoreLibrarySemaphoreBlock = false; // Allow external tasks to control serial hardware
549+
return ((int8_t)modeType);
550+
}
551+
552+
if (commandResponse == UM980_RESULT_RESPONSE_COMMAND_ERROR)
553+
{
554+
debugPrintf("Unicore Lib: Query failure");
555+
unicoreLibrarySemaphoreBlock = false; // Allow external tasks to control serial hardware
556+
return (-2);
557+
}
558+
559+
delay(1);
560+
}
561+
562+
unicoreLibrarySemaphoreBlock = false; // Allow external tasks to control serial hardware
563+
564+
return (-3); // Uncaught error
565+
}
566+
505567
// Directly set a base mode: setModeBase("40.09029479 -105.18505761 1560.089")
506568
bool UM980::setModeBase(const char *baseType)
507569
{
@@ -1044,6 +1106,8 @@ bool UM980::sendCommand(const char *command, uint16_t maxWaitMs)
10441106
// Looks for a query response ('#')
10451107
// Some commands like MASK or CONFIG have responses that begin with $
10461108
//'#' begins the responses to queries, ie 'MODE', ends with the result (ie MODE ROVER)
1109+
// #MODE,97,GPS,FINE,2389,337235000,0,0,18,969;MODE ROVER SURVEY,*18
1110+
// #MODE,97,GPS,FINE,2389,338172000,0,0,18,968;MODE BASE TIME 60,*72
10471111
// #MODE,97,GPS,FINE,2283,499142000,0,0,18,22;MODE BASE -1280206.5680 -4716804.4030 4086665.4840,*60
10481112

10491113
//'$' begins the responses to commands, ie 'MODE ROVER', ends with OK
@@ -1769,6 +1833,76 @@ char *UM980::getVersionFull(uint16_t maxWaitMs)
17691833
return ((char *)"Error2");
17701834
}
17711835

1836+
// Cracks a given MODE response into settings
1837+
void UM980::modeHandler(uint8_t *response, uint16_t length)
1838+
{
1839+
// We've received a response such as #MODE,97,GPS,FINE,2389,338172000,0,0,18,968;MODE BASE TIME 60,*72
1840+
modeType = UM980_MODE_UNKNOWN;
1841+
1842+
// Extract the mode type
1843+
char *responsePointer = strcasestr((char *)response, ";MODE");
1844+
if (responsePointer != nullptr) // Found
1845+
{
1846+
// Obtain the value following the search string
1847+
responsePointer += strlen(";MODE"); // Move the position to the end of the word
1848+
1849+
// Skip any whitespace
1850+
while (*responsePointer && isspace(*responsePointer))
1851+
responsePointer++;
1852+
1853+
// Now 'responsePointer' should point at the start of the next term
1854+
1855+
char *typePointer = nullptr;
1856+
1857+
typePointer = strcasestr(responsePointer, "BASE");
1858+
if (typePointer != nullptr) // Found
1859+
{
1860+
char *baseTypePointer = nullptr;
1861+
baseTypePointer = strcasestr(typePointer, "TIME");
1862+
if (baseTypePointer != nullptr) // Found
1863+
{
1864+
modeType = UM980_MODE_BASE_SURVEY_IN;
1865+
}
1866+
else
1867+
{
1868+
// Response contains non-text such as:
1869+
// #MODE,97,GPS,FINE,2283,499142000,0,0,18,22;MODE BASE -1280206.5680 -4716804.4030 4086665.4840,*60
1870+
modeType = UM980_MODE_BASE_FIXED;
1871+
}
1872+
}
1873+
else
1874+
{
1875+
// Response contains ROVER
1876+
// #MODE,97,GPS,FINE,2389,337235000,0,0,18,969;MODE ROVER SURVEY,*18
1877+
1878+
typePointer = strcasestr(responsePointer, "SURVEY");
1879+
if (typePointer != nullptr) // Found
1880+
{
1881+
modeType = UM980_MODE_ROVER_SURVEY;
1882+
return;
1883+
}
1884+
1885+
typePointer = strcasestr(responsePointer, "UAV");
1886+
if (typePointer != nullptr) // Found
1887+
{
1888+
modeType = UM980_MODE_ROVER_UAV;
1889+
return;
1890+
}
1891+
1892+
typePointer = strcasestr(responsePointer, "AUTOMOTIVE");
1893+
if (typePointer != nullptr) // Found
1894+
{
1895+
modeType = UM980_MODE_ROVER_AUTOMOTIVE;
1896+
return;
1897+
}
1898+
}
1899+
}
1900+
else
1901+
{
1902+
// This mode response did not contain ;MODE
1903+
}
1904+
}
1905+
17721906
// Cracks a given CONFIG response into settings
17731907
void UM980::configHandler(uint8_t *response, uint16_t length)
17741908
{

src/SparkFun_Unicore_GNSS_Arduino_Library.h

Lines changed: 19 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -48,9 +48,20 @@ typedef enum
4848
UM980_RESULT_RESPONSE_COMMAND_WAITING,
4949
UM980_RESULT_RESPONSE_COMMAND_CONFIG,
5050
UM980_RESULT_RESPONSE_COMMAND_MASK,
51+
UM980_RESULT_RESPONSE_COMMAND_MODE,
5152
UM980_RESULT_CONFIG_PRESENT,
5253
} Um980Result;
5354

55+
typedef enum
56+
{
57+
UM980_MODE_UNKNOWN = 0,
58+
UM980_MODE_ROVER_SURVEY, // 1
59+
UM980_MODE_ROVER_UAV, // 2
60+
UM980_MODE_ROVER_AUTOMOTIVE, // 3
61+
UM980_MODE_BASE_SURVEY_IN, // 4
62+
UM980_MODE_BASE_FIXED, // 5
63+
} Um980Mode;
64+
5465
#define um980BinarySyncA ((uint8_t)0xAA)
5566
#define um980BinarySyncB ((uint8_t)0x44)
5667
#define um980BinarySyncC ((uint8_t)0xB5)
@@ -154,10 +165,13 @@ class UM980
154165

155166
bool unicoreLibrarySemaphoreBlock = false; // Gets set to true when the Unicore library needs to interact directly
156167
// with the serial hardware
157-
char configStringToFind[50] = {'\0'}; //ie, "COM3 115200"
158-
bool configStringFound = false; // configHandler() sets true if we find the intended string
168+
char configStringToFind[50] = {'\0'}; // ie, "COM3 115200"
169+
bool configStringFound = false; // configHandler() sets true if we find the intended string
159170
long configLong = 0; // configHandler() sets value if one is following the search term, ie COM3
160-
float configFloat; // configHandler() sets value if one is following the search term, ie 5.00
171+
float configFloat; // configHandler() sets value if one is following the search term, ie 5.00
172+
173+
bool modeFound = false; // modeHandler() sets true if we find a valid mode response
174+
Um980Mode modeType = UM980_MODE_UNKNOWN; // modeHandler() sets modeType after getMode() is called
161175

162176
protected:
163177
HardwareSerial *_hwSerialPort = nullptr;
@@ -211,6 +225,7 @@ class UM980
211225

212226
// Mode
213227
bool setMode(const char *modeType);
228+
int8_t getMode(uint16_t maxWaitMs = 1500);
214229
bool setModeBase(const char *baseType);
215230
bool setModeBaseGeodetic(double latitude, double longitude, double altitude);
216231
bool setModeBaseECEF(double coordinateX, double coordinateY, double coordinateZ);
@@ -323,6 +338,7 @@ class UM980
323338

324339
void unicoreHandler(uint8_t *data, uint16_t length);
325340
void configHandler(uint8_t *response, uint16_t length);
341+
void modeHandler(uint8_t *response, uint16_t length);
326342

327343
bool initBestnav(uint8_t rate = 1);
328344
UNICORE_BESTNAV_t *packetBESTNAV = nullptr;

0 commit comments

Comments
 (0)