From e24f293c0ff680f2f432721177d8e66de1bc2dbb Mon Sep 17 00:00:00 2001 From: Danila Loginov Date: Sat, 1 Sep 2018 04:52:37 +0300 Subject: [PATCH 1/3] chore: configure Visual Studio Code to work with the library --- .vscode/settings.json | 25 +++++++ examples/UbxGpsNavPvt/UbxGpsNavPvt.ino | 7 +- .../Auto-configuration-Mega.ino | 74 ++++++++++--------- .../Serial-Bridge-Mega/Serial-Bridge-Mega.ino | 8 +- .../Serial-Bridge-Uno/Serial-Bridge-Uno.ino | 13 ++-- src/UbxGps.cpp | 27 +++---- src/UbxGps.h | 52 ++++++------- src/UbxGpsNavPosecef.h | 2 +- src/UbxGpsNavPosllh.h | 2 +- src/UbxGpsNavPvt.h | 2 +- src/UbxGpsNavSol.h | 2 +- 11 files changed, 123 insertions(+), 91 deletions(-) create mode 100644 .vscode/settings.json diff --git a/.vscode/settings.json b/.vscode/settings.json new file mode 100644 index 0000000..af39c0e --- /dev/null +++ b/.vscode/settings.json @@ -0,0 +1,25 @@ +{ + "C_Cpp.default.defines": [ + // Fixes `Serial1`, `Serial2`, `Serial3` undefined. + "UBRR1H", + "UBRR2H", + "UBRR3H", + // Fixes `Serial` undefined. + "USBCON", + ], + "C_Cpp.default.includePath": [ + // Fixes `Arduino.h` and related headers undefined. + "C:/Program Files (x86)/Arduino/hardware/arduino/avr/cores/arduino", + "C:/Program Files (x86)/Arduino/hardware/arduino/avr/variants/standard", + "C:/Program Files (x86)/Arduino/hardware/tools/avr/avr/include", + "C:/Program Files (x86)/Arduino/hardware/tools/avr/lib/gcc/avr/5.4.0/include", + // Fixes `SoftwareSerial.h` undefined. + "C:/Program Files (x86)/Arduino/hardware/arduino/avr/libraries/SoftwareSerial/src", + // Fixes library files undefined. + "${workspaceFolder}/src", + ], + "editor.rulers": [ + 120, + ], + "editor.tabSize": 4, +} \ No newline at end of file diff --git a/examples/UbxGpsNavPvt/UbxGpsNavPvt.ino b/examples/UbxGpsNavPvt/UbxGpsNavPvt.ino index f31645d..9b9d881 100644 --- a/examples/UbxGpsNavPvt/UbxGpsNavPvt.ino +++ b/examples/UbxGpsNavPvt/UbxGpsNavPvt.ino @@ -8,10 +8,11 @@ * GND - GND */ -#include "UbxGpsNavPvt.h" +#include +#include -#define PC_BAUDRATE 9600 -#define GPS_BAUDRATE 9600 +#define PC_BAUDRATE 9600 +#define GPS_BAUDRATE 9600 #define DATETIME_FORMAT "%04d.%02d.%02d %02d:%02d:%02d" #define DATETIME_LENGTH 20 diff --git a/extras/Configuration/Auto-configuration-Mega/Auto-configuration-Mega.ino b/extras/Configuration/Auto-configuration-Mega/Auto-configuration-Mega.ino index 9a77530..aa0157f 100644 --- a/extras/Configuration/Auto-configuration-Mega/Auto-configuration-Mega.ino +++ b/extras/Configuration/Auto-configuration-Mega/Auto-configuration-Mega.ino @@ -10,16 +10,18 @@ * GND - GND */ -#define PC_SERIAL Serial +#include + +#define PC_SERIAL Serial #define PC_BAUDRATE 115200L -#define GPS_SERIAL Serial3 +#define GPS_SERIAL Serial3 // Default baudrate is determined by the receiver manufacturer. -#define GPS_DEFAULT_BAUDRATE 9600L +#define GPS_DEFAULT_BAUDRATE 9600L // Wanted buadrate at the moment can be 9600L (not changed after defaults) or 115200L (changed by the // `changeBaudrate()` function with a prepared message). -#define GPS_WANTED_BAUDRATE 115200L +#define GPS_WANTED_BAUDRATE 115200L // Array of possible baudrates that can be used by the receiver, sorted descending to prevent excess Serial flush/begin // after restoring defaults. You can uncomment values that can be used by your receiver before the auto-configuration. @@ -40,7 +42,7 @@ void setup() PC_SERIAL.begin(PC_BAUDRATE); PC_SERIAL.println("Starting auto-configuration..."); - // Restore the receiver default configuration + // Restore the receiver default configuration. for (byte i = 0; i < sizeof(possibleBaudrates) / sizeof(*possibleBaudrates); i++) { PC_SERIAL.print("Trying to restore defaults at "); @@ -49,7 +51,7 @@ void setup() if (i != 0) { - delay(100); // Little delay before flushing + delay(100); // Little delay before flushing. GPS_SERIAL.flush(); } @@ -57,23 +59,23 @@ void setup() restoreDefaults(); } - // Switch the receiver serial to the default baudrate + // Switch the receiver serial to the default baudrate. if (possibleBaudrates[sizeof(possibleBaudrates) / sizeof(*possibleBaudrates) - 1] != GPS_DEFAULT_BAUDRATE) { PC_SERIAL.print("Switching to the default baudrate which is "); PC_SERIAL.print(GPS_DEFAULT_BAUDRATE); PC_SERIAL.println("..."); - delay(100); // Little delay before flushing + delay(100); // Little delay before flushing. GPS_SERIAL.flush(); GPS_SERIAL.begin(GPS_DEFAULT_BAUDRATE); } - // Disable NMEA messages by sending appropriate packets + // Disable NMEA messages by sending appropriate packets. PC_SERIAL.println("Disabling NMEA messages..."); disableNmea(); - // Switch the receiver serial to the wanted baudrate + // Switch the receiver serial to the wanted baudrate. if (GPS_WANTED_BAUDRATE != GPS_DEFAULT_BAUDRATE) { PC_SERIAL.print("Switching receiver to the wanted baudrate which is "); @@ -82,33 +84,33 @@ void setup() changeBaudrate(); - delay(100); // Little delay before flushing + delay(100); // Little delay before flushing. GPS_SERIAL.flush(); GPS_SERIAL.begin(GPS_WANTED_BAUDRATE); } - // Increase frequency to 100 ms + // Increase frequency to 100 ms. PC_SERIAL.println("Changing receiving frequency to 100 ms..."); changeFrequency(); - // Disable unnecessary channels like SBAS or QZSS + // Disable unnecessary channels like SBAS or QZSS. PC_SERIAL.println("Disabling unnecessary channels..."); disableUnnecessaryChannels(); - // Enable NAV-PVT messages + // Enable NAV-PVT messages. PC_SERIAL.println("Enabling NAV-PVT messages..."); enableNavPvt(); PC_SERIAL.println("Auto-configuration is complete!"); - delay(100); // Little delay before flushing + delay(100); // Little delay before flushing. GPS_SERIAL.flush(); } -// Send a packet to the receiver to restore default configuration +// Send a packet to the receiver to restore default configuration. void restoreDefaults() { - // CFG-CFG packet + // CFG-CFG packet. byte packet[] = { 0xB5, // sync char 1 0x62, // sync char 2 @@ -136,10 +138,10 @@ void restoreDefaults() sendPacket(packet, sizeof(packet)); } -// Send a set of packets to the receiver to disable NMEA messages +// Send a set of packets to the receiver to disable NMEA messages. void disableNmea() { - // Array of two bytes for CFG-MSG packets payload + // Array of two bytes for CFG-MSG packets payload. byte messages[][2] = { {0xF0, 0x0A}, {0xF0, 0x09}, @@ -163,7 +165,7 @@ void disableNmea() {0xF1, 0x06}, }; - // CFG-MSG packet buffer + // CFG-MSG packet buffer. byte packet[] = { 0xB5, // sync char 1 0x62, // sync char 2 @@ -179,23 +181,23 @@ void disableNmea() }; byte packetSize = sizeof(packet); - // Offset to the place where payload starts + // Offset to the place where payload starts. byte payloadOffset = 6; - // Iterate over the messages array + // Iterate over the messages array. for (byte i = 0; i < sizeof(messages) / sizeof(*messages); i++) { - // Copy two bytes of payload to the packet buffer + // Copy two bytes of payload to the packet buffer. for (byte j = 0; j < sizeof(*messages); j++) { packet[payloadOffset + j] = messages[i][j]; } - // Set checksum bytes to the null + // Set checksum bytes to the null. packet[packetSize - 2] = 0x00; packet[packetSize - 1] = 0x00; - // Calculate checksum over the packet buffer excluding sync (first two) and checksum chars (last two) + // Calculate checksum over the packet buffer excluding sync (first two) and checksum chars (last two). for (byte j = 0; j < packetSize - 4; j++) { packet[packetSize - 2] += packet[2 + j]; @@ -206,10 +208,10 @@ void disableNmea() } } -// Send a packet to the receiver to change baudrate to 115200 +// Send a packet to the receiver to change baudrate to 115200. void changeBaudrate() { - // CFG-PRT packet + // CFG-PRT packet. byte packet[] = { 0xB5, // sync char 1 0x62, // sync char 2 @@ -244,10 +246,10 @@ void changeBaudrate() sendPacket(packet, sizeof(packet)); } -// Send a packet to the receiver to change frequency to 100 ms +// Send a packet to the receiver to change frequency to 100 ms. void changeFrequency() { - // CFG-RATE packet + // CFG-RATE packet. byte packet[] = { 0xB5, // sync char 1 0x62, // sync char 2 @@ -268,10 +270,10 @@ void changeFrequency() sendPacket(packet, sizeof(packet)); } -// Send a packet to the receiver to disable unnecessary channels +// Send a packet to the receiver to disable unnecessary channels. void disableUnnecessaryChannels() { - // CFG-GNSS packet + // CFG-GNSS packet. byte packet[] = { 0xB5, // sync char 1 0x62, // sync char 2 @@ -293,10 +295,10 @@ void disableUnnecessaryChannels() sendPacket(packet, sizeof(packet)); } -// Send a packet to the receiver to enable NAV-PVT messages +// Send a packet to the receiver to enable NAV-PVT messages. void enableNavPvt() { - // CFG-MSG packet + // CFG-MSG packet. byte packet[] = { 0xB5, // sync char 1 0x62, // sync char 2 @@ -314,7 +316,7 @@ void enableNavPvt() sendPacket(packet, sizeof(packet)); } -// Send the packet specified to the receiver +// Send the packet specified to the receiver. void sendPacket(byte *packet, byte len) { for (byte i = 0; i < len; i++) @@ -325,7 +327,7 @@ void sendPacket(byte *packet, byte len) printPacket(packet, len); } -// Print the packet specified to the PC serial in a hexadecimal form +// Print the packet specified to the PC serial in a hexadecimal form. void printPacket(byte *packet, byte len) { char temp[3]; @@ -344,7 +346,7 @@ void printPacket(byte *packet, byte len) PC_SERIAL.println(); } -// If there is a data from the receiver, read it and send to the PC or vice versa +// If there is a data from the receiver, read it and send to the PC or vice versa. void loop() { if (GPS_SERIAL.available()) diff --git a/extras/Configuration/Serial-Bridge-Mega/Serial-Bridge-Mega.ino b/extras/Configuration/Serial-Bridge-Mega/Serial-Bridge-Mega.ino index 1cf1399..80e38be 100644 --- a/extras/Configuration/Serial-Bridge-Mega/Serial-Bridge-Mega.ino +++ b/extras/Configuration/Serial-Bridge-Mega/Serial-Bridge-Mega.ino @@ -8,8 +8,10 @@ * GND - GND */ -#define PC_BAUDRATE 9600 -#define GPS_BAUDRATE 9600 +#include + +#define PC_BAUDRATE 9600 +#define GPS_BAUDRATE 9600 void setup() { @@ -17,7 +19,7 @@ void setup() Serial3.begin(GPS_BAUDRATE); } -// If there is a data from the receiver, read it and send to the PC or vice versa +// If there is a data from the receiver, read it and send to the PC or vice versa. void loop() { if (Serial3.available()) diff --git a/extras/Configuration/Serial-Bridge-Uno/Serial-Bridge-Uno.ino b/extras/Configuration/Serial-Bridge-Uno/Serial-Bridge-Uno.ino index d87198b..1bc8eb0 100644 --- a/extras/Configuration/Serial-Bridge-Uno/Serial-Bridge-Uno.ino +++ b/extras/Configuration/Serial-Bridge-Uno/Serial-Bridge-Uno.ino @@ -12,13 +12,14 @@ * GND - GND */ -#define PC_BAUDRATE 9600 -#define GPS_BAUDRATE 9600 -#define GPS_RX 3 -#define GPS_TX 2 - +#include #include +#define PC_BAUDRATE 9600 +#define GPS_BAUDRATE 9600 +#define GPS_RX 3 +#define GPS_TX 2 + SoftwareSerial ss(GPS_TX, GPS_RX); void setup() @@ -27,7 +28,7 @@ void setup() ss.begin(GPS_BAUDRATE); } -// If there is a data from the receiver, read it and send to the PC or vice versa +// If there is a data from the receiver, read it and send to the PC or vice versa. void loop() { if (ss.available()) diff --git a/src/UbxGps.cpp b/src/UbxGps.cpp index 5e020c4..544fa0b 100644 --- a/src/UbxGps.cpp +++ b/src/UbxGps.cpp @@ -1,4 +1,4 @@ -#include "UbxGps.h" +#include UbxGps::UbxGps(HardwareSerial &serial) : serial(serial) { @@ -44,61 +44,62 @@ boolean UbxGps::ready() { byte c = this->read(); - // Carriage is at the first or the second sync byte, should be equals + // Carriage is at the first or the second sync byte, should be equals. if (p < 2) { if (c == UBXGPS_HEADER[p]) { p++; } - // Reset if not + // Reset if not. else { p = 0; } } - // Sync with header after success + + // Sync with header after success. else { - // Put the byte read to a particular address of this object which depends on the carriage position + // Put the byte read to a particular address of this object which depends on the carriage position. if (p < (this->size + 2)) { ((unsigned char *)(this))[p - 2 + this->offsetClassProperties] = c; } - // Move the carriage forward + // Move the carriage forward. p++; // Carriage is at the first checksum byte, we can calculate our checksum, but not compare, because this byte - // is not read + // is not read. if (p == (this->size + 2)) { this->calculateChecksum(); } // Carriage is at the second checksum byte, but only the first byte of checksum read, check if it equals to - // ours + // ours. else if (p == (this->size + 3)) { - // Reset if not + // Reset if not. if (c != this->checksum[0]) { p = 0; } } - // Carriage is after the second checksum byte, which has been read, check if it equals to ours + // Carriage is after the second checksum byte, which has been read, check if it equals to ours. else if (p == (this->size + 4)) { - // Reset the carriage + // Reset the carriage. p = 0; - // The readings are correct and filled the object, return true + // The readings are correct and filled the object, return true. if (c == this->checksum[1]) { this->carriagePosition = p; return true; } } - // Reset the carriage if it is out of a packet + // Reset the carriage if it is out of a packet. else if (p > (this->size + 4)) { p = 0; diff --git a/src/UbxGps.h b/src/UbxGps.h index f6bb2c4..0ea6afc 100644 --- a/src/UbxGps.h +++ b/src/UbxGps.h @@ -1,37 +1,37 @@ #ifndef UBXGPS_H_ #define UBXGPS_H_ -#include "Arduino.h" +#include const unsigned char UBXGPS_HEADER[] = {0xB5, 0x62}; class UbxGps { - public: - void begin(long); - boolean ready(); - - protected: - UbxGps(HardwareSerial &); - void setLength(unsigned char); - - private: - int available(); - byte read(); - void calculateChecksum(); - - // Class properties - HardwareSerial &serial; - unsigned char offsetClassProperties = 8; - unsigned char offsetHeaders = 4; - unsigned char size; - unsigned char carriagePosition; - unsigned char checksum[2]; - - // Headers (common) - unsigned char headerClass; - unsigned char headerId; - unsigned short headerLength; +public: + void begin(long); + boolean ready(); + +protected: + UbxGps(HardwareSerial &); + void setLength(unsigned char); + +private: + int available(); + byte read(); + void calculateChecksum(); + + // Class properties. + HardwareSerial &serial; + unsigned char offsetClassProperties = 8; + unsigned char offsetHeaders = 4; + unsigned char size; + unsigned char carriagePosition; + unsigned char checksum[2]; + + // Headers (common). + unsigned char headerClass; + unsigned char headerId; + unsigned short headerLength; }; #endif diff --git a/src/UbxGpsNavPosecef.h b/src/UbxGpsNavPosecef.h index 15f2a62..1d1f831 100644 --- a/src/UbxGpsNavPosecef.h +++ b/src/UbxGpsNavPosecef.h @@ -1,7 +1,7 @@ #ifndef UBXGPSNAVPOSECEF_H_ #define UBXGPSNAVPOSECEF_H_ -#include "UbxGps.h" +#include class UbxGpsNavPosecef : public UbxGps { diff --git a/src/UbxGpsNavPosllh.h b/src/UbxGpsNavPosllh.h index b39ddd4..2c17eba 100644 --- a/src/UbxGpsNavPosllh.h +++ b/src/UbxGpsNavPosllh.h @@ -1,7 +1,7 @@ #ifndef UBXGPSNAVPOSLLH_H_ #define UBXGPSNAVPOSLLH_H_ -#include "UbxGps.h" +#include class UbxGpsNavPosllh : public UbxGps { diff --git a/src/UbxGpsNavPvt.h b/src/UbxGpsNavPvt.h index 69804be..f18831b 100644 --- a/src/UbxGpsNavPvt.h +++ b/src/UbxGpsNavPvt.h @@ -1,7 +1,7 @@ #ifndef UBXGPSNAVPVT_H_ #define UBXGPSNAVPVT_H_ -#include "UbxGps.h" +#include class UbxGpsNavPvt : public UbxGps { diff --git a/src/UbxGpsNavSol.h b/src/UbxGpsNavSol.h index fd54a39..f55f4d1 100644 --- a/src/UbxGpsNavSol.h +++ b/src/UbxGpsNavSol.h @@ -1,7 +1,7 @@ #ifndef UBXGPSNAVSOL_H_ #define UBXGPSNAVSOL_H_ -#include "UbxGps.h" +#include class UbxGpsNavSol : public UbxGps { From c26f435774a06f3be00a613ea2bdfc6b4a37a77b Mon Sep 17 00:00:00 2001 From: Danila Loginov Date: Mon, 3 Sep 2018 02:25:12 +0300 Subject: [PATCH 2/3] feat: parametrize class to use both Hardware and Software serials --- .../UbxGpsNavPvtMega.ino} | 7 +- examples/UbxGpsNavPvtUno/UbxGpsNavPvtUno.ino | 56 +++++++++ src/UbxGps.cpp | 113 ----------------- src/UbxGps.h | 119 ++++++++++++++++-- src/UbxGpsNavPosecef.h | 5 +- src/UbxGpsNavPosllh.h | 5 +- src/UbxGpsNavPvt.h | 5 +- src/UbxGpsNavSol.h | 5 +- 8 files changed, 183 insertions(+), 132 deletions(-) rename examples/{UbxGpsNavPvt/UbxGpsNavPvt.ino => UbxGpsNavPvtMega/UbxGpsNavPvtMega.ino} (91%) create mode 100644 examples/UbxGpsNavPvtUno/UbxGpsNavPvtUno.ino delete mode 100644 src/UbxGps.cpp diff --git a/examples/UbxGpsNavPvt/UbxGpsNavPvt.ino b/examples/UbxGpsNavPvtMega/UbxGpsNavPvtMega.ino similarity index 91% rename from examples/UbxGpsNavPvt/UbxGpsNavPvt.ino rename to examples/UbxGpsNavPvtMega/UbxGpsNavPvtMega.ino index 9b9d881..0a543c4 100644 --- a/examples/UbxGpsNavPvt/UbxGpsNavPvt.ino +++ b/examples/UbxGpsNavPvtMega/UbxGpsNavPvtMega.ino @@ -11,12 +11,13 @@ #include #include -#define PC_BAUDRATE 9600 -#define GPS_BAUDRATE 9600 +#define GPS_BAUDRATE 115200L +#define PC_BAUDRATE 115200L + #define DATETIME_FORMAT "%04d.%02d.%02d %02d:%02d:%02d" #define DATETIME_LENGTH 20 -UbxGpsNavPvt gps(Serial3); +UbxGpsNavPvt gps(Serial3); char datetime[DATETIME_LENGTH]; diff --git a/examples/UbxGpsNavPvtUno/UbxGpsNavPvtUno.ino b/examples/UbxGpsNavPvtUno/UbxGpsNavPvtUno.ino new file mode 100644 index 0000000..2ea4ede --- /dev/null +++ b/examples/UbxGpsNavPvtUno/UbxGpsNavPvtUno.ino @@ -0,0 +1,56 @@ +/** + * The sketch parses UBX messages from u-blox NEO-7M and outputs ready GPS data to a serial port in a CSV format. + * + * u-blox NEO-7M - Arduino Uno + * VCC - 5V + * RX - 3 + * TX - 2 + * GND - GND + */ + +#include +#include +#include + +#define GPS_BAUDRATE 115200L +#define GPS_RX 3 +#define GPS_TX 2 +#define PC_BAUDRATE 115200L + +#define DATETIME_FORMAT "%04d.%02d.%02d %02d:%02d:%02d" +#define DATETIME_LENGTH 20 + +SoftwareSerial ss(GPS_TX, GPS_RX); +UbxGpsNavPvt gps(ss); + +char datetime[DATETIME_LENGTH]; + +void setup() +{ + Serial.begin(PC_BAUDRATE); + gps.begin(GPS_BAUDRATE); +} + +void loop() +{ + if (gps.ready()) + { + snprintf(datetime, DATETIME_LENGTH, DATETIME_FORMAT, gps.year, gps.month, gps.day, gps.hour, gps.min, gps.sec); + + Serial.print(datetime); + Serial.print(','); + Serial.print(gps.lon / 10000000.0, 7); + Serial.print(','); + Serial.print(gps.lat / 10000000.0, 7); + Serial.print(','); + Serial.print(gps.height / 1000.0, 3); + Serial.print(','); + Serial.print(gps.gSpeed * 0.0036, 5); + Serial.print(','); + Serial.print(gps.heading / 100000.0, 5); + Serial.print(','); + Serial.print(gps.fixType); + Serial.print(','); + Serial.println(gps.numSV); + } +} diff --git a/src/UbxGps.cpp b/src/UbxGps.cpp deleted file mode 100644 index 544fa0b..0000000 --- a/src/UbxGps.cpp +++ /dev/null @@ -1,113 +0,0 @@ -#include - -UbxGps::UbxGps(HardwareSerial &serial) : serial(serial) -{ - this->carriagePosition = 0; -} - -void UbxGps::setLength(unsigned char length) -{ - this->size = length + this->offsetHeaders; -} - -void UbxGps::begin(long speed) -{ - return this->serial.begin(speed); -} - -int UbxGps::available() -{ - return this->serial.available(); -} - -byte UbxGps::read() -{ - return this->serial.read(); -} - -void UbxGps::calculateChecksum() -{ - memset(this->checksum, 0, 2); - - for (int i = 0; i < this->size; i++) - { - this->checksum[0] += ((unsigned char *)(this))[i + this->offsetClassProperties]; - this->checksum[1] += this->checksum[0]; - } -} - -boolean UbxGps::ready() -{ - unsigned char p = this->carriagePosition; - - while (this->available()) - { - byte c = this->read(); - - // Carriage is at the first or the second sync byte, should be equals. - if (p < 2) - { - if (c == UBXGPS_HEADER[p]) - { - p++; - } - // Reset if not. - else - { - p = 0; - } - } - - // Sync with header after success. - else - { - // Put the byte read to a particular address of this object which depends on the carriage position. - if (p < (this->size + 2)) - { - ((unsigned char *)(this))[p - 2 + this->offsetClassProperties] = c; - } - - // Move the carriage forward. - p++; - - // Carriage is at the first checksum byte, we can calculate our checksum, but not compare, because this byte - // is not read. - if (p == (this->size + 2)) - { - this->calculateChecksum(); - } - // Carriage is at the second checksum byte, but only the first byte of checksum read, check if it equals to - // ours. - else if (p == (this->size + 3)) - { - // Reset if not. - if (c != this->checksum[0]) - { - p = 0; - } - } - // Carriage is after the second checksum byte, which has been read, check if it equals to ours. - else if (p == (this->size + 4)) - { - // Reset the carriage. - p = 0; - - // The readings are correct and filled the object, return true. - if (c == this->checksum[1]) - { - this->carriagePosition = p; - return true; - } - } - // Reset the carriage if it is out of a packet. - else if (p > (this->size + 4)) - { - p = 0; - } - } - } - - this->carriagePosition = p; - - return false; -} diff --git a/src/UbxGps.h b/src/UbxGps.h index 0ea6afc..5d7ad9c 100644 --- a/src/UbxGps.h +++ b/src/UbxGps.h @@ -5,23 +5,126 @@ const unsigned char UBXGPS_HEADER[] = {0xB5, 0x62}; +template class UbxGps { public: - void begin(long); - boolean ready(); + void begin(long speed) + { + return this->serial.begin(speed); + }; + + boolean ready() + { + unsigned char p = this->carriagePosition; + + while (this->available()) + { + byte c = this->read(); + + // Carriage is at the first or the second sync byte, should be equals. + if (p < 2) + { + if (c == UBXGPS_HEADER[p]) + { + p++; + } + // Reset if not. + else + { + p = 0; + } + } + + // Sync with header after success. + else + { + // Put the byte read to a particular address of this object which depends on the carriage position. + if (p < (this->size + 2)) + { + ((unsigned char *)(this))[p - 2 + this->offsetClassProperties] = c; + } + + // Move the carriage forward. + p++; + + // Carriage is at the first checksum byte, we can calculate our checksum, but not compare, because this byte is + // not read. + if (p == (this->size + 2)) + { + this->calculateChecksum(); + } + // Carriage is at the second checksum byte, but only the first byte of checksum read, check if it equals to + // ours. + else if (p == (this->size + 3)) + { + // Reset if not. + if (c != this->checksum[0]) + { + p = 0; + } + } + // Carriage is after the second checksum byte, which has been read, check if it equals to ours. + else if (p == (this->size + 4)) + { + // Reset the carriage. + p = 0; + + // The readings are correct and filled the object, return true. + if (c == this->checksum[1]) + { + this->carriagePosition = p; + return true; + } + } + // Reset the carriage if it is out of a packet. + else if (p > (this->size + 4)) + { + p = 0; + } + } + } + + this->carriagePosition = p; + + return false; + }; protected: - UbxGps(HardwareSerial &); - void setLength(unsigned char); + UbxGps(T &serial) : serial(serial) + { + this->carriagePosition = 0; + }; + + void setLength(unsigned char length) + { + this->size = length + this->offsetHeaders; + }; private: - int available(); - byte read(); - void calculateChecksum(); + int available() + { + return this->serial.available(); + }; + + byte read() + { + return this->serial.read(); + }; + + void calculateChecksum() + { + memset(this->checksum, 0, 2); + + for (int i = 0; i < this->size; i++) + { + this->checksum[0] += ((unsigned char *)(this))[i + this->offsetClassProperties]; + this->checksum[1] += this->checksum[0]; + } + }; // Class properties. - HardwareSerial &serial; + T &serial; unsigned char offsetClassProperties = 8; unsigned char offsetHeaders = 4; unsigned char size; diff --git a/src/UbxGpsNavPosecef.h b/src/UbxGpsNavPosecef.h index 1d1f831..e34bf97 100644 --- a/src/UbxGpsNavPosecef.h +++ b/src/UbxGpsNavPosecef.h @@ -3,7 +3,8 @@ #include -class UbxGpsNavPosecef : public UbxGps +template +class UbxGpsNavPosecef : public UbxGps { public: // Type Name Unit Description (scaling) @@ -14,7 +15,7 @@ class UbxGpsNavPosecef : public UbxGps long ecefZ; // cm ECEF Z coordinate unsigned long pAcc; // cm Position Accuracy Estimate - UbxGpsNavPosecef(HardwareSerial &serial) : UbxGps(serial) + UbxGpsNavPosecef(T &serial) : UbxGps(serial) { this->setLength(20); } diff --git a/src/UbxGpsNavPosllh.h b/src/UbxGpsNavPosllh.h index 2c17eba..367efe7 100644 --- a/src/UbxGpsNavPosllh.h +++ b/src/UbxGpsNavPosllh.h @@ -3,7 +3,8 @@ #include -class UbxGpsNavPosllh : public UbxGps +template +class UbxGpsNavPosllh : public UbxGps { public: // Type Name Unit Description (scaling) @@ -16,7 +17,7 @@ class UbxGpsNavPosllh : public UbxGps unsigned long hAcc; // mm Horizontal accuracy estimate unsigned long vAcc; // mm Vertical accuracy estimate - UbxGpsNavPosllh(HardwareSerial &serial) : UbxGps(serial) + UbxGpsNavPosllh(T &serial) : UbxGps(serial) { this->setLength(28); } diff --git a/src/UbxGpsNavPvt.h b/src/UbxGpsNavPvt.h index f18831b..43522a1 100644 --- a/src/UbxGpsNavPvt.h +++ b/src/UbxGpsNavPvt.h @@ -3,7 +3,8 @@ #include -class UbxGpsNavPvt : public UbxGps +template +class UbxGpsNavPvt : public UbxGps { public: // Type Name Unit Description (scaling) @@ -39,7 +40,7 @@ class UbxGpsNavPvt : public UbxGps short reserved2; // - Reserved unsigned long reserved3; // - Reserved - UbxGpsNavPvt(HardwareSerial &serial) : UbxGps(serial) + UbxGpsNavPvt(T &serial) : UbxGps(serial) { this->setLength(84); } diff --git a/src/UbxGpsNavSol.h b/src/UbxGpsNavSol.h index f55f4d1..a7fa7c0 100644 --- a/src/UbxGpsNavSol.h +++ b/src/UbxGpsNavSol.h @@ -3,7 +3,8 @@ #include -class UbxGpsNavSol : public UbxGps +template +class UbxGpsNavSol : public UbxGps { public: // Type Name Unit Description (scaling) @@ -27,7 +28,7 @@ class UbxGpsNavSol : public UbxGps unsigned char numSV; // - Number of satellites used in Nav Solution unsigned long reserved2; // - Reserved - UbxGpsNavSol(HardwareSerial &serial) : UbxGps(serial) + UbxGpsNavSol(T &serial) : UbxGps(serial) { this->setLength(52); } From 65a17ca163451159a0a97496f0bd0b9c20a0d000 Mon Sep 17 00:00:00 2001 From: Danila Loginov Date: Mon, 3 Sep 2018 03:34:14 +0300 Subject: [PATCH 3/3] chore: v1.4.0, update readme --- README.md | 20 +++++++++----------- library.properties | 2 +- 2 files changed, 10 insertions(+), 12 deletions(-) diff --git a/README.md b/README.md index 5166f1a..53cf3f2 100644 --- a/README.md +++ b/README.md @@ -35,7 +35,7 @@ headingAcc, pDOP, reserved2, reserved3. *NAV-SOL (Navigation Solution Information):* iTOW, fTOW, week, gpsFix, flags, ecefX, ecefY, ecefZ, pAcc, ecefVX, ecefVY, ecefVZ, sAcc, pDOP, reserved1, numSV, reserved2. -## Quick Start +## Quick start Download `UbxGps` and place it to the Arduino libraries directory. Refer to [How to install Libraries](https://www.arduino.cc/en/Guide/Libraries) for details. @@ -51,7 +51,7 @@ After that you can use included examples or play with the following simple sketc ```cpp #include "UbxGpsNavPvt.h" -UbxGpsNavPvt gps(Serial3); +UbxGpsNavPvt gps(Serial3); void setup() { @@ -118,7 +118,7 @@ send some data. ### Step 3. Meet u-center For u-blox GPS module configuration we will use **u-center** program that you can find -[here](https://www.u-blox.com/en/product/u-center-windows). It parses data from GPS module and provides useful tools to +[here](https://www.u-blox.com/en/product/u-center). It parses data from GPS module and provides useful tools to work with it. Launch program, choose appropriate COM port and set baudrate, 9600 for default. It will start getting some data. @@ -185,17 +185,15 @@ in the [Docs](https://github.com/1oginov/UbxGps/tree/master/extras/Docs) directo ## Compatible GPS modules -* NEO-7M — tested -* Other u-blox GPS modules, which supports UBX protocol -* *Please, notice me if it works with your GPS module* +* NEO-7M +* Other u-blox GPS modules supporting UBX protocol +* *Please notice (create an issue) if it works with your GPS module* ## Contribution -Feel free to add something useful to this library :relaxed: For example new classes for UBX packets! +Please use the [dev](https://github.com/1oginov/UbxGps/tree/dev) branch and feel free to contribute! -Please, use the [dev](https://github.com/1oginov/UbxGps/tree/dev) branch for contribution. - -## Links +## Reference * [u-blox Website](https://www.u-blox.com) -* [u-center Download page](https://www.u-blox.com/en/product/u-center-windows) +* [u-center Download page](https://www.u-blox.com/en/product/u-center) diff --git a/library.properties b/library.properties index 1286995..e043434 100644 --- a/library.properties +++ b/library.properties @@ -1,5 +1,5 @@ name=UbxGps -version=1.3.0 +version=1.4.0 author=Danila Loginov maintainer=Danila Loginov sentence=A library for the fastest and simplest communication with u-blox GPS modules.