|
| 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>© 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