Skip to content

Commit 3826751

Browse files
committed
Version 1.1. Wildcar for handlers
1 parent b372836 commit 3826751

File tree

7 files changed

+114
-21
lines changed

7 files changed

+114
-21
lines changed

README.md

+20-7
Original file line numberDiff line numberDiff line change
@@ -4,9 +4,14 @@ An Arduino library to parse NMEA sentences.
44

55
NMEA is a communication standard in the marine equipment industry: GPS, anemometers,... The NMEAParser library allows you to analyze NMEA sentences and associate handlers to each of those that need to be recognized. The library provides the means to associate a handler to each identifier and also provides functions to retrieve the arguments of the sentence in different data formats: character, integer, float, character string.
66

7+
## Changelog
8+
9+
* ```1.1``` : Added joker in type. Remove binaries from ```extra```
10+
* ```1.0``` : Initial release
11+
712
## Memory footprint
813

9-
On an Arduino Uno, an instance of a NMEAParser requires 97 bytes with only one handler. 8 bytes per additional handler are required.
14+
On an Arduino Uno, an instance of a NMEAParser requires 97 bytes with only one handler. 8 bytes per additional handler are required.
1015

1116
## Using NMEAParser
1217

@@ -28,7 +33,7 @@ In ```setup``` you configure your parser as you wish using the following functio
2833

2934
### ```void addHandler(<type>, <handler>)```
3035

31-
where ```<type>``` is a character string and the type of sentence to recongnize, and ```<handler>``` the function to call when a sentence is recognize. ```<type>``` can be a string stored un RAM or a string stored in flash : ```F("ASTRI")```. If ```<type>``` has more than 5 characters, it is trucated.
36+
where ```<type>``` is a character string and the type of sentence to recongnize, and ```<handler>``` the function to call when a sentence is recognize. ```<type>``` can be a string stored un RAM or a string stored in flash : ```F("ASTRI")```. If ```<type>``` has more than 5 characters, it is trucated.
3237

3338
For example, suppose you want to recognize the following sounder sentences which give the water depth below keel (DBK) and below surface (DBS):
3439

@@ -51,6 +56,14 @@ parser.addHanlder("SDDBS", handleDepthBelowSurface);
5156

5257
```handleDepthBelowKeel``` and ```handleDepthBelowSurface``` are functions that will be called when sentences are recognized.
5358

59+
With version 1.1, ```<type>``` may include hyphens. An hyphens matches any character. For instance if you want the handler to match all sentences coming from the sounder, you would write:
60+
61+
```C++
62+
parser.addHandler("SD---", handleSounder);
63+
```
64+
65+
```handleSounder``` function would be called for any sentence with the type beginning with SD.
66+
5467
### ```void setDefaultHandler(<handler>)```
5568

5669
When a sentence is succefully parsed but none of the handler correspond to it, ```<handler>``` is called. It is a function corresponding to a ```void f(void)``` prototype. By default, no function is called.
@@ -108,9 +121,9 @@ void handleDepthBelowSurface(void)
108121
}
109122
```
110123
111-
### ```bool getType(<type>)```
124+
### ```bool getType(<type>) / bool getType(<num>, <charType>)```
112125
113-
Put the type of the sentence in ```<type>```. It can be a ```char *``` or a ```String```. Return ```true``` if a type has been parsed, ```false``` otherwise.
126+
3 versions of ```getType``` exist. The first one puts the type of the sentence in ```<type>```. It can be a ```char *``` or a ```String```. Return ```true``` if a type has been parsed, ```false``` otherwise. The second one puts a character of the type at position ```<num>```
114127
115128
### ```uint8_t argCount()```
116129
@@ -122,7 +135,7 @@ Return the error. The returned code can be:
122135
123136
* ```NMEA::NO_ERROR```: no error;
124137
* ```NMEA::UNEXPECTED_CHAR```: a char which is not expected in the sentence has been encountered;
125-
* ```NMEA::BUFFER_FULL```: the sentence is too long to fit in the buffer;
138+
* ```NMEA::BUFFER_FULL```: the sentence is too long to fit in the buffer;
126139
* ```NMEA::TYPE_TOO_LONG```: the sentence type has more than 5 characters;
127140
* ```NMEA::CRC_ERROR```: the CRC is wrong;
128141
* ```NMEA::INTERNAL_ERROR```: the internal state of the parser is wrong, should not happen by the way.
@@ -174,7 +187,7 @@ We define 2 other handlers for anything else than ```ARLED``` and for errors
174187
void errorHandler()
175188
{
176189
Serial.print("*** Error : ");
177-
Serial.println(parser.error());
190+
Serial.println(parser.error());
178191
}
179192

180193
void unknownCommand()
@@ -219,7 +232,7 @@ The ```gen``` subdirectory contains ```nmeagen```, a NMEA sentence generator pro
219232

220233
## Test program
221234

222-
The ```test``` subdirectory contains a test program that compile on Linux or Mac OS X. It takes sentences from the standard input, parse them and print out the type, the arguments and if an error occured.
235+
The ```test``` subdirectory contains a test program that compile on Linux or Mac OS X. It takes sentences from the standard input, parse them and print out the type, the arguments and if an error occured.
223236

224237
---
225238
# Additional links

examples/Wild/Wild.ino

+67
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,67 @@
1+
/*
2+
* NMEAParser library.
3+
*
4+
* A NMEA example to switch ON or OFF the built in LED but with the use
5+
* of wild char in the type
6+
*
7+
* Sentences to send are :
8+
*
9+
* $ARLE1*2B
10+
*
11+
* to switch the LED on and
12+
*
13+
* $ARLE0*2A
14+
*
15+
* to switch the LED off
16+
*
17+
* Set the serial monitor end of line to <cr><lf>
18+
*/
19+
#include <NMEAParser.h>
20+
21+
/* A parser with only one handler */
22+
NMEAParser<1> parser;
23+
24+
void errorHandler()
25+
{
26+
Serial.print("*** Error : ");
27+
Serial.println(parser.error());
28+
}
29+
30+
void unknownCommand()
31+
{
32+
Serial.print("*** Unkown command : ");
33+
char buf[6];
34+
parser.getType(buf);
35+
Serial.println(buf);
36+
}
37+
38+
void ledHandler()
39+
{
40+
Serial.print("Got ARLEx with ");
41+
Serial.print(parser.argCount());
42+
Serial.println(" arguments");
43+
44+
char wantedLedState;
45+
if (parser.getType(4, wantedLedState)) { // get the 4th character ot the type
46+
if (wantedLedState == '0' || wantedLedState == '1') {
47+
digitalWrite(LED_BUILTIN, wantedLedState == '0' ? LOW : HIGH);
48+
}
49+
else {
50+
Serial.println("x should be 0 or 1");
51+
}
52+
}
53+
}
54+
55+
void setup() {
56+
Serial.begin(115200);
57+
parser.setErrorHandler(errorHandler);
58+
parser.addHandler("ARLE-", ledHandler);
59+
parser.setDefaultHandler(unknownCommand);
60+
pinMode(LED_BUILTIN, OUTPUT);
61+
}
62+
63+
void loop() {
64+
if (Serial.available()) {
65+
parser << Serial.read();
66+
}
67+
}

extra/gen/nmeagen

-8.59 KB
Binary file not shown.

extra/test/sent.txt

-10
This file was deleted.

extra/test/testNMEA

-17 KB
Binary file not shown.

library.properties

+1-1
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,5 @@
11
name=NMEAParser
2-
version=1.0
2+
version=1.1
33
author=Glinnes Hulden
44
maintainer=Glinnes Hulden
55
sentence=A simple Arduino library to parse NMEA sentences.

src/NMEAParser.h

+26-3
Original file line numberDiff line numberDiff line change
@@ -244,22 +244,32 @@ template <size_t S> class NMEAParser {
244244
/*
245245
* convert a one hex digit char into an int. Used for the CRC
246246
*/
247-
int8_t hexToNum(const char inChar)
247+
static int8_t hexToNum(const char inChar)
248248
{
249249
if (isdigit(inChar)) return inChar - '0';
250250
else if (isupper(inChar) && inChar <= 'F') return inChar - 'A' + 10;
251251
else if (islower(inChar) && inChar <= 'f') return inChar - 'a' + 10;
252252
else return -1;
253253
}
254254

255+
static bool strnwcmp(const char *s1, const char *s2, uint8_t len)
256+
{
257+
while (len-- > 0) {
258+
if (*s1 != *s2 && *s1 != '-' && *s2 != '-') return false;
259+
s1++;
260+
s2++;
261+
}
262+
return true;
263+
}
264+
255265
/*
256-
* return the slot number fo a handler. -1 if not found
266+
* return the slot number for a handler. -1 if not found
257267
*/
258268
int8_t getHandler(const char *inToken)
259269
{
260270
/* Look for the token */
261271
for (uint8_t i = 0; i < mHandlerCount; i++) {
262-
if (strncmp(mHandlers[i].mToken, inToken, 5) == 0) {
272+
if (strnwcmp(mHandlers[i].mToken, inToken, 5)) {
263273
return i;
264274
}
265275
}
@@ -604,6 +614,19 @@ template <size_t S> class NMEAParser {
604614
}
605615
#endif
606616

617+
bool getType(uint8_t inIndex, char &outTypeChar)
618+
{
619+
if (mIndex > 0) {
620+
uint8_t endPos = startArgPos(0);
621+
if (inIndex < endPos) {
622+
outTypeChar = mBuffer[inIndex];
623+
return true;
624+
}
625+
else return false;
626+
}
627+
else return false;
628+
}
629+
607630
NMEA::ErrorCode error() {
608631
return mError;
609632
}

0 commit comments

Comments
 (0)