diff --git a/.travis.yml b/.travis.yml new file mode 100644 index 0000000..cd72901 --- /dev/null +++ b/.travis.yml @@ -0,0 +1,69 @@ +matrix: + include: + # compile example sketches + - name: 'Compile Examples' + language: minimal + env: + - CLI_VERSION=latest + - BOARD='arduino:samd:mkrzero' + + before_install: + - wget http://downloads.arduino.cc/arduino-cli/arduino-cli-$CLI_VERSION-linux64.tar.bz2 + - tar xf arduino-cli-$CLI_VERSION-linux64.tar.bz2 + - mkdir -p "$HOME/bin" + - mv arduino-cli-*-linux64 $HOME/bin/arduino-cli + - export PATH="$PATH:$HOME/bin" + + - arduino-cli core update-index + - arduino-cli core install arduino:samd + + - buildExampleSketch() { arduino-cli compile --verbose --warnings all --fqbn $BOARD "$PWD/examples/$1"; } + + install: + - mkdir -p "$HOME/Arduino/libraries" + - ln -s "$PWD" "$HOME/Arduino/libraries/." + + script: + - buildExampleSketch GPSLocation + - buildExampleSketch GPSLocationStandy + + + # check all code files for compliance with the Arduino code formatting style + - name: 'Code Formatting Check' + language: minimal + before_install: + # install Artistic Style code formatter tool: http://astyle.sourceforge.net + - | + mkdir "${HOME}/astyle"; + wget --no-verbose --output-document="${HOME}/astyle/astyle.tar.gz" "https://iweb.dl.sourceforge.net/project/astyle/astyle/astyle%203.1/astyle_3.1_linux.tar.gz"; + tar --extract --file="${HOME}/astyle/astyle.tar.gz" --directory="${HOME}/astyle"; + cd "${HOME}/astyle/astyle/build/gcc"; + make; + export PATH="$PWD/bin:$PATH"; + cd "$TRAVIS_BUILD_DIR" + # download Arduino's Artistic Style configuration file + - wget --directory-prefix="${HOME}/astyle" https://raw.githubusercontent.com/arduino/Arduino/master/build/shared/examples_formatter.conf + script: + # check code formatting + - find . -regextype posix-extended -path './.git' -prune -or -path './src/minmea' -prune -or \( -iregex '.*\.((ino)|(h)|(hpp)|(hh)|(hxx)|(h\+\+)|(cpp)|(cc)|(cxx)|(c\+\+)|(cp)|(c)|(ipp)|(ii)|(ixx)|(inl)|(tpp)|(txx)|(tpl))$' -and -type f \) -print0 | xargs -0 -L1 bash -c 'if ! diff "$0" <(astyle --options="${HOME}/astyle/examples_formatter.conf" --dry-run < "$0"); then echo "Non-compliant code formatting in $0"; false; fi' + + + # check all files for commonly misspelled words + - name: 'Spell Check' + language: python + python: 3.6 + before_install: + # https://github.com/codespell-project/codespell + - pip install codespell + script: + # codespell will ignore any words in extras/codespell-ignore-words-list.txt, which may be used to fix false positives + - codespell --skip="${TRAVIS_BUILD_DIR}/.git,${TRAVIS_BUILD_DIR}/src/minmea" --ignore-words="${TRAVIS_BUILD_DIR}/extras/codespell-ignore-words-list.txt" "${TRAVIS_BUILD_DIR}" + + +notifications: + webhooks: + # use TravisBuddy to comment on any pull request that results in a failed CI build + urls: + - https://www.travisbuddy.com/ + on_success: never + on_failure: always diff --git a/README.adoc b/README.adoc index c2b87e9..4a3fd9a 100644 --- a/README.adoc +++ b/README.adoc @@ -1,5 +1,7 @@ = MKRGPS Library for Arduino = +image:https://travis-ci.org/arduino-libraries/Arduino_MKRGPS.svg?branch=master[Build Status, link=https://travis-ci.org/arduino-libraries/Arduino_MKRGPS] + Allows you to read the location from the GPS on your MKR GPS shield. This library is based on https://github.com/kosma/minmea[minmea]. diff --git a/extras/codespell-ignore-words-list.txt b/extras/codespell-ignore-words-list.txt new file mode 100644 index 0000000..9acfe5c --- /dev/null +++ b/extras/codespell-ignore-words-list.txt @@ -0,0 +1 @@ +extint diff --git a/src/GPS.cpp b/src/GPS.cpp index 2c6af00..6de365d 100644 --- a/src/GPS.cpp +++ b/src/GPS.cpp @@ -20,7 +20,7 @@ // Useful info. on NMEA data: https://www.gpsinformation.org/dale/nmea.htm extern "C" { - #include "minmea/minmea.h" +#include "minmea/minmea.h" } // #define GPS_DEBUG @@ -35,16 +35,13 @@ GPSClass::GPSClass(HardwareSerial& serial, unsigned long baudrate, SerialDDC& se _baudrate(baudrate), _serialDDC(&serialDDC), _clockRate(clockrate), - _extintPin(extintPin) -{ + _extintPin(extintPin) { } -GPSClass::~GPSClass() -{ +GPSClass::~GPSClass() { } -int GPSClass::begin(int mode) -{ +int GPSClass::begin(int mode) { _mode = mode; pinMode(_extintPin, OUTPUT); @@ -70,8 +67,7 @@ int GPSClass::begin(int mode) return 1; } -void GPSClass::end() -{ +void GPSClass::end() { digitalWrite(_extintPin, LOW); pinMode(_extintPin, INPUT); @@ -82,8 +78,7 @@ void GPSClass::end() } } -int GPSClass::available() -{ +int GPSClass::available() { poll(); if (_available == (GPS_MASK_RMC | GPS_MASK_GGA)) { @@ -95,8 +90,7 @@ int GPSClass::available() return 0; } -float GPSClass::latitude() -{ +float GPSClass::latitude() { if (isnan(_latitude)) { return NAN; } @@ -104,8 +98,7 @@ float GPSClass::latitude() return toDegrees(_latitude); } -float GPSClass::longitude() -{ +float GPSClass::longitude() { if (isnan(_longitude)) { return NAN; } @@ -113,19 +106,16 @@ float GPSClass::longitude() return toDegrees(_longitude); } -float GPSClass::speed() -{ +float GPSClass::speed() { // convert speed from knots to kph return _speed * 1.852; } -float GPSClass::course() -{ +float GPSClass::course() { return _course; } -float GPSClass::variation() -{ +float GPSClass::variation() { if (isnan(_variation)) { return NAN; } @@ -133,23 +123,19 @@ float GPSClass::variation() return toDegrees(_variation); } -float GPSClass::altitude() -{ +float GPSClass::altitude() { return _altitude; } -int GPSClass::satellites() -{ +int GPSClass::satellites() { return _satellites; } -unsigned long GPSClass::getTime() -{ +unsigned long GPSClass::getTime() { return _ts.tv_sec; } -void GPSClass::standby() -{ +void GPSClass::standby() { byte payload[48]; memset(payload, 0x00, sizeof(payload)); @@ -158,7 +144,7 @@ void GPSClass::standby() // flags: // extintSel = EXTINT0 // extintWake = enabled, keep receiver awake as long as selected EXTINT pin is 'high' - // extintBackup = enabled, force receiver into BACKUP mode when selected EXTINT pin is 'low' + // extintBackup = enabled, force receiver into BACKUP mode when selected EXTINT pin is 'low' payload[4] = 0x60; sendUbx(0x06, 0x3b, payload, sizeof(payload)); @@ -175,8 +161,7 @@ void GPSClass::standby() _index = 0; } -void GPSClass::wakeup() -{ +void GPSClass::wakeup() { digitalWrite(_extintPin, HIGH); delay(100); // delay for GPS to wakeup @@ -190,14 +175,13 @@ void GPSClass::wakeup() _index = 0; } -void GPSClass::poll() -{ +void GPSClass::poll() { if (_stream->available()) { char c = _stream->read(); -#ifdef GPS_DEBUG + #ifdef GPS_DEBUG Serial.print(c); -#endif + #endif if (c == '$') { _index = 0; @@ -215,51 +199,49 @@ void GPSClass::poll() } } -void GPSClass::parseBuffer() -{ +void GPSClass::parseBuffer() { int sentenceId = minmea_sentence_id(_buffer, false); switch (sentenceId) { case MINMEA_SENTENCE_RMC: { - struct minmea_sentence_rmc frame; - - if (minmea_parse_rmc(&frame, _buffer) && frame.valid) { - _latitude = minmea_tofloat(&frame.latitude); - _longitude = minmea_tofloat(&frame.longitude); - _speed = minmea_tofloat(&frame.speed); - _course = minmea_tofloat(&frame.course); - _variation = minmea_tofloat(&frame.variation); - - minmea_gettime(&_ts, &frame.date, &frame.time); - - _available |= GPS_MASK_RMC; - } + struct minmea_sentence_rmc frame; - break; - } + if (minmea_parse_rmc(&frame, _buffer) && frame.valid) { + _latitude = minmea_tofloat(&frame.latitude); + _longitude = minmea_tofloat(&frame.longitude); + _speed = minmea_tofloat(&frame.speed); + _course = minmea_tofloat(&frame.course); + _variation = minmea_tofloat(&frame.variation); - case MINMEA_SENTENCE_GGA: { - struct minmea_sentence_gga frame; - - if (minmea_parse_gga(&frame, _buffer) && frame.fix_quality != 0) { - _latitude = minmea_tofloat(&frame.latitude); - _longitude = minmea_tofloat(&frame.longitude); - _altitude = minmea_tofloat(&frame.altitude); - _satellites = frame.satellites_tracked; - - _available |= GPS_MASK_GGA; + minmea_gettime(&_ts, &frame.date, &frame.time); + + _available |= GPS_MASK_RMC; + } + + break; } - break; - } + case MINMEA_SENTENCE_GGA: { + struct minmea_sentence_gga frame; + + if (minmea_parse_gga(&frame, _buffer) && frame.fix_quality != 0) { + _latitude = minmea_tofloat(&frame.latitude); + _longitude = minmea_tofloat(&frame.longitude); + _altitude = minmea_tofloat(&frame.altitude); + _satellites = frame.satellites_tracked; + + _available |= GPS_MASK_GGA; + } + + break; + } default: break; } } -void GPSClass::sendUbx(uint8_t cls, uint8_t id, uint8_t payload[], uint16_t length) -{ +void GPSClass::sendUbx(uint8_t cls, uint8_t id, uint8_t payload[], uint16_t length) { uint8_t ckA = 0; uint8_t ckB = 0; @@ -287,8 +269,7 @@ void GPSClass::sendUbx(uint8_t cls, uint8_t id, uint8_t payload[], uint16_t leng _stream->flush(); } -float GPSClass::toDegrees(float f) -{ +float GPSClass::toDegrees(float f) { float degrees = (int)(f / 100.0); float minutes = f - (100.0 * degrees); diff --git a/src/GPS.h b/src/GPS.h index b0231cc..6f87a9b 100644 --- a/src/GPS.h +++ b/src/GPS.h @@ -24,68 +24,67 @@ #include "utility/SerialDDC.h" -enum -{ +enum { GPS_MODE_UART, GPS_MODE_I2C, GPS_MODE_SHIELD = GPS_MODE_UART }; class GPSClass { -public: - GPSClass(HardwareSerial& serial, unsigned long baudrate, SerialDDC& serialDDC, unsigned long clockrate, int extintPin); - virtual ~GPSClass(); + public: + GPSClass(HardwareSerial& serial, unsigned long baudrate, SerialDDC& serialDDC, unsigned long clockrate, int extintPin); + virtual ~GPSClass(); - int begin(int mode = GPS_MODE_I2C); - void end(); + int begin(int mode = GPS_MODE_I2C); + void end(); - int available(); + int available(); - float latitude(); - float longitude(); - float speed(); // Speed over the ground in kph - float course(); // Track angle in degrees - float variation(); // Magnetic Variation - float altitude(); - int satellites(); + float latitude(); + float longitude(); + float speed(); // Speed over the ground in kph + float course(); // Track angle in degrees + float variation(); // Magnetic Variation + float altitude(); + int satellites(); - unsigned long getTime(); + unsigned long getTime(); - void standby(); - void wakeup(); + void standby(); + void wakeup(); -private: - void poll(); - void parseBuffer(); - void sendUbx(uint8_t cls, uint8_t id, uint8_t payload[], uint16_t length); + private: + void poll(); + void parseBuffer(); + void sendUbx(uint8_t cls, uint8_t id, uint8_t payload[], uint16_t length); - static float toDegrees(float f); + static float toDegrees(float f); -private: - HardwareSerial* _serial; - unsigned long _baudrate; + private: + HardwareSerial* _serial; + unsigned long _baudrate; - SerialDDC* _serialDDC; - unsigned long _clockRate; + SerialDDC* _serialDDC; + unsigned long _clockRate; - int _extintPin; + int _extintPin; - int _mode; - Stream* _stream; + int _mode; + Stream* _stream; - int _available; - char _buffer[82 + 1]; - int _index; + int _available; + char _buffer[82 + 1]; + int _index; - float _latitude; - float _longitude; - float _speed; - float _course; - float _variation; - float _altitude; - int _satellites; + float _latitude; + float _longitude; + float _speed; + float _course; + float _variation; + float _altitude; + int _satellites; - struct timespec _ts; + struct timespec _ts; }; extern GPSClass GPS; diff --git a/src/utility/SerialDDC.cpp b/src/utility/SerialDDC.cpp index edf9afe..9669a0e 100644 --- a/src/utility/SerialDDC.cpp +++ b/src/utility/SerialDDC.cpp @@ -23,16 +23,13 @@ SerialDDC::SerialDDC(TwoWire& wire, int address, uint8_t availableRegister, uint _wire(&wire), _address(address), _availableRegister(availableRegister), - _readRegister(readRegister) -{ + _readRegister(readRegister) { } -SerialDDC::~SerialDDC() -{ +SerialDDC::~SerialDDC() { } -int SerialDDC::begin(uint32_t clockFrequency) -{ +int SerialDDC::begin(uint32_t clockFrequency) { _wire->begin(); _wire->setClock(clockFrequency); @@ -47,13 +44,11 @@ int SerialDDC::begin(uint32_t clockFrequency) return 1; } -void SerialDDC::end() -{ +void SerialDDC::end() { _wire->end(); } -int SerialDDC::available() -{ +int SerialDDC::available() { int avail = _wire->available(); if (avail) { @@ -96,23 +91,19 @@ int SerialDDC::available() return _wire->available(); } -int SerialDDC::read() -{ +int SerialDDC::read() { return _wire->read(); } -int SerialDDC::peek() -{ +int SerialDDC::peek() { return _wire->peek(); } -size_t SerialDDC::write(uint8_t b) -{ +size_t SerialDDC::write(uint8_t b) { return write(&b, sizeof(b)); } -size_t SerialDDC::write(const uint8_t *buffer, size_t size) -{ +size_t SerialDDC::write(const uint8_t *buffer, size_t size) { if (size < 2) { return 0; } @@ -128,7 +119,6 @@ size_t SerialDDC::write(const uint8_t *buffer, size_t size) return result; } -void SerialDDC::flush() -{ +void SerialDDC::flush() { // no-op } \ No newline at end of file diff --git a/src/utility/SerialDDC.h b/src/utility/SerialDDC.h index c0a013c..6b90d69 100644 --- a/src/utility/SerialDDC.h +++ b/src/utility/SerialDDC.h @@ -25,28 +25,28 @@ #include class SerialDDC : public Stream { -public: - SerialDDC(TwoWire& wire, int address, uint8_t availableRegister, uint8_t readRegister); - virtual ~SerialDDC(); - - int begin(uint32_t clockFrequency); - void end(); - - // from Stream - virtual int available(); - virtual int read(); - virtual int peek(); - - // from Print - virtual size_t write(uint8_t); - virtual size_t write(const uint8_t *buffer, size_t size); - virtual void flush(); - -private: - TwoWire* _wire; - int _address; - uint8_t _availableRegister; - uint8_t _readRegister; + public: + SerialDDC(TwoWire& wire, int address, uint8_t availableRegister, uint8_t readRegister); + virtual ~SerialDDC(); + + int begin(uint32_t clockFrequency); + void end(); + + // from Stream + virtual int available(); + virtual int read(); + virtual int peek(); + + // from Print + virtual size_t write(uint8_t); + virtual size_t write(const uint8_t *buffer, size_t size); + virtual void flush(); + + private: + TwoWire* _wire; + int _address; + uint8_t _availableRegister; + uint8_t _readRegister; }; #endif