Skip to content

Commit e486aed

Browse files
authored
Merge pull request #6 from NoahRosa/master
Add MicroNMEA examples
2 parents a338f8b + 19768ac commit e486aed

4 files changed

Lines changed: 467 additions & 4 deletions

File tree

README.md

Lines changed: 16 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -7,19 +7,32 @@ This device uses alternatively I2C or UART to communicate. An I2C or UART instan
77

88
## Examples
99

10-
There are 2 examples with the X-NUCLEO-GNSS1A1 library.
10+
There are 4 examples with the X-NUCLEO-GNSS1A1 library.
1111

1212
* X_NUCLEO_GNSS1A1_HelloWorld_I2C: This example code provides a simple command line interface
1313
to communicate with the sensor via I2C protocol
1414

1515
* X_NUCLEO_GNSS1A1_HelloWorld_UART: This example code provides a simple command line interface
1616
to communicate with the sensor via UART protocol
1717

18+
* X_NUCLEO_GNSS1A1_MicroNMEA_I2C: This example code shows how to communicate with the sensor via
19+
I2C protocol using the lightweight Arduino MicroNMEA library.
20+
21+
* X_NUCLEO_GNSS1A1_MicroNMEA_UART: This example code shows how to communicate with the sensor via
22+
UART protocol using the lightweight Arduino MicroNMEA library.
23+
24+
## Dependencies
25+
26+
The X-NUCLEO-GNSS1A1 library requires the following Arduino library:
27+
28+
* MicroNMEA: https://github.com/stevemarple/MicroNMEA
29+
1830
## Note
1931

2032
The device works only in an outdoor enviroment with a clear view of the sky.
21-
In order to prevent data loss the update function should be called at least 20 times per second.
22-
Both the examples need at least 16KB of RAM in order to work properly.
33+
In order to prevent data loss the update function used in the HelloWorld examples should be called at least 20 times per second.
34+
Both the HelloWorld examples need at least 16KB of RAM in order to work properly. The RAM requirements for the MicroNMEA examples
35+
depend on the board architecture and can vary from 1KB to 3KB.
2336

2437
## Documentation
2538

Lines changed: 257 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,257 @@
1+
/**
2+
******************************************************************************
3+
* @file X_NUCLEO_GNSS1A1_MicroNMEA_I2C.ino
4+
* @author AST
5+
* @version V1.0.0
6+
* @date January 2018
7+
* @brief Arduino test application for the STMicrolectronics X-NUCLEO-GNSS1A1
8+
* GNSS module expansion board based on TeseoLIV3F.
9+
******************************************************************************
10+
* @attention
11+
*
12+
* <h2><center>&copy; COPYRIGHT(c) 2019 STMicroelectronics</center></h2>
13+
*
14+
* Redistribution and use in source and binary forms, with or without modification,
15+
* are permitted provided that the following conditions are met:
16+
* 1. Redistributions of source code must retain the above copyright notice,
17+
* this list of conditions and the following disclaimer.
18+
* 2. Redistributions in binary form must reproduce the above copyright notice,
19+
* this list of conditions and the following disclaimer in the documentation
20+
* and/or other materials provided with the distribution.
21+
* 3. Neither the name of STMicroelectronics nor the names of its contributors
22+
* may be used to endorse or promote products derived from this software
23+
* without specific prior written permission.
24+
*
25+
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
26+
* AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
27+
* IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
28+
* DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE
29+
* FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
30+
* DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
31+
* SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
32+
* CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
33+
* OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
34+
* OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
35+
*
36+
******************************************************************************
37+
*/
38+
39+
//NOTE: In order for this example to work, the jumper J4 on the device should
40+
// be moved to J8
41+
//NOTE: This example is compatible with the Arduino Uno board
42+
43+
#include <MicroNMEA.h>
44+
#include <Wire.h>
45+
46+
//I2C communication parameters
47+
#define DEFAULT_DEVICE_ADDRESS 0x3A
48+
#define DEFAULT_DEVICE_PORT 0xFF
49+
#define I2C_DELAY 1
50+
51+
#define RESET_PIN 7
52+
53+
#ifdef ARDUINO_SAM_DUE
54+
#define DEV_I2C Wire1
55+
#endif
56+
57+
#ifdef ARDUINO_ARCH_STM32
58+
#define DEV_I2C Wire
59+
#endif
60+
61+
#ifdef ARDUINO_ARCH_AVR
62+
#define DEV_I2C Wire
63+
#endif
64+
65+
// Refer to Stream devices by use
66+
HardwareSerial& console = Serial;
67+
TwoWire& gps = DEV_I2C;
68+
69+
//I2C read data structures
70+
char buff[32];
71+
int idx = 0;
72+
73+
//MicroNMEA library structures
74+
char nmeaBuffer[100];
75+
MicroNMEA nmea(nmeaBuffer, sizeof(nmeaBuffer));
76+
77+
78+
bool ledState = LOW;
79+
volatile bool ppsTriggered = false;
80+
81+
82+
void ppsHandler(void);
83+
84+
85+
void ppsHandler(void)
86+
{
87+
ppsTriggered = true;
88+
}
89+
90+
91+
void gpsHardwareReset()
92+
{
93+
//reset the device
94+
digitalWrite(RESET_PIN, LOW);
95+
delay(50);
96+
digitalWrite(RESET_PIN, HIGH);
97+
98+
//wait for reset to apply
99+
delay(2000);
100+
101+
}
102+
103+
//Read 32 bytes from I2C
104+
void readI2C(char *inBuff)
105+
{
106+
gps.beginTransmission(DEFAULT_DEVICE_ADDRESS);
107+
gps.write((uint8_t) DEFAULT_DEVICE_PORT);
108+
gps.endTransmission(false);
109+
gps.requestFrom((uint8_t)DEFAULT_DEVICE_ADDRESS, (uint8_t) 32);
110+
int i = 0;
111+
while (gps.available())
112+
{
113+
inBuff[i]= gps.read();
114+
i++;
115+
}
116+
}
117+
118+
//Send a NMEA command via I2C
119+
void sendCommand(char *cmd)
120+
{
121+
gps.beginTransmission(DEFAULT_DEVICE_ADDRESS);
122+
gps.write((uint8_t) DEFAULT_DEVICE_PORT);
123+
MicroNMEA::sendSentence(gps, cmd);
124+
gps.endTransmission(true);
125+
}
126+
127+
void setup(void)
128+
{
129+
console.begin(115200); // console
130+
gps.begin(); // gps
131+
132+
pinMode(LED_BUILTIN, OUTPUT);
133+
digitalWrite(LED_BUILTIN, ledState);
134+
135+
//Start the module
136+
pinMode(RESET_PIN, OUTPUT);
137+
digitalWrite(RESET_PIN, HIGH);
138+
console.println("Resetting GPS module ...");
139+
gpsHardwareReset();
140+
console.println("... done");
141+
142+
// Change the echoing messages to the ones recognized by the MicroNMEA library
143+
sendCommand("$PSTMSETPAR,1231,0x00000042");
144+
sendCommand("$PSTMSAVEPAR");
145+
146+
//Reset the device so that the changes could take plaace
147+
sendCommand("$PSTMSRR");
148+
149+
delay(4000);
150+
151+
//Reinitialize I2C after the reset
152+
gps.begin();
153+
154+
//clear i2c buffer
155+
char c;
156+
idx = 0;
157+
memset(buff, 0, 32);
158+
do
159+
{
160+
if (idx == 0)
161+
{
162+
readI2C(buff);
163+
delay(I2C_DELAY);
164+
}
165+
c = buff[idx];
166+
idx++;
167+
idx %= 32;
168+
}
169+
while ((uint8_t) c != 0xFF);
170+
171+
pinMode(2, INPUT);
172+
attachInterrupt(digitalPinToInterrupt(2), ppsHandler, RISING);
173+
}
174+
175+
void loop(void)
176+
{
177+
//If a message is recieved print all the informations
178+
if (ppsTriggered)
179+
{
180+
ppsTriggered = false;
181+
ledState = !ledState;
182+
digitalWrite(LED_BUILTIN, ledState);
183+
184+
// Output GPS information from previous second
185+
console.print("Valid fix: ");
186+
console.println(nmea.isValid() ? "yes" : "no");
187+
188+
console.print("Nav. system: ");
189+
if (nmea.getNavSystem())
190+
console.println(nmea.getNavSystem());
191+
else
192+
console.println("none");
193+
194+
console.print("Num. satellites: ");
195+
console.println(nmea.getNumSatellites());
196+
197+
console.print("HDOP: ");
198+
console.println(nmea.getHDOP()/10., 1);
199+
200+
console.print("Date/time: ");
201+
console.print(nmea.getYear());
202+
console.print('-');
203+
console.print(int(nmea.getMonth()));
204+
console.print('-');
205+
console.print(int(nmea.getDay()));
206+
console.print('T');
207+
console.print(int(nmea.getHour()));
208+
console.print(':');
209+
console.print(int(nmea.getMinute()));
210+
console.print(':');
211+
console.println(int(nmea.getSecond()));
212+
213+
long latitude_mdeg = nmea.getLatitude();
214+
long longitude_mdeg = nmea.getLongitude();
215+
console.print("Latitude (deg): ");
216+
console.println(latitude_mdeg / 1000000., 6);
217+
218+
console.print("Longitude (deg): ");
219+
console.println(longitude_mdeg / 1000000., 6);
220+
221+
long alt;
222+
console.print("Altitude (m): ");
223+
if (nmea.getAltitude(alt))
224+
console.println(alt / 1000., 3);
225+
else
226+
console.println("not available");
227+
228+
console.print("Speed: ");
229+
console.println(nmea.getSpeed() / 1000., 3);
230+
console.print("Course: ");
231+
console.println(nmea.getCourse() / 1000., 3);
232+
console.println("-----------------------");
233+
nmea.clear();
234+
}
235+
236+
//While the message isn't complete
237+
while (!ppsTriggered )
238+
{
239+
char c ;
240+
if (idx == 0)
241+
{
242+
readI2C(buff);
243+
delay(I2C_DELAY);
244+
}
245+
//Fetch the character one by one
246+
c = buff[idx];
247+
idx++;
248+
idx %= 32;
249+
//If we have a valid character pass it to the library
250+
if ((uint8_t) c != 0xFF)
251+
{
252+
console.print(c);
253+
nmea.process(c);
254+
}
255+
}
256+
257+
}

0 commit comments

Comments
 (0)