From 86da3aaa4d86ab2df6461b45fecd03854a52233b Mon Sep 17 00:00:00 2001 From: Balamurugan Kandan Date: Sun, 20 Dec 2020 15:30:12 +0530 Subject: [PATCH 1/9] Linux platform porting - Initial commit --- .gitignore | 8 +++++++- src/SparkFun_Ublox_Arduino_Library.h | 10 ++++++++++ 2 files changed, 17 insertions(+), 1 deletion(-) diff --git a/.gitignore b/.gitignore index 58b4bef..12be29c 100644 --- a/.gitignore +++ b/.gitignore @@ -55,4 +55,10 @@ Temporary Items *.swp # Zephyr build files -examples/Zephyr/*/build/* \ No newline at end of file +examples/Zephyr/*/build/* + +# Linux build files +linux/bin/* +linux/lib/* +linux/build/* + diff --git a/src/SparkFun_Ublox_Arduino_Library.h b/src/SparkFun_Ublox_Arduino_Library.h index 9a3e250..9808fbd 100644 --- a/src/SparkFun_Ublox_Arduino_Library.h +++ b/src/SparkFun_Ublox_Arduino_Library.h @@ -42,6 +42,14 @@ #ifndef SPARKFUN_UBLOX_ARDUINO_LIBRARY_H #define SPARKFUN_UBLOX_ARDUINO_LIBRARY_H +#ifdef LINUX_PLATFORM + +#include "Stream.h" +#include "Utils.h" +#include "Wire.h" + +#else + #if (ARDUINO >= 100) #include "Arduino.h" #else @@ -50,6 +58,8 @@ #include +#endif + #include "u-blox_config_keys.h" //-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-= From c42cec324ca6808d5fb367d1e8648e59dc5a12c8 Mon Sep 17 00:00:00 2001 From: Balamurugan Kandan Date: Sun, 20 Dec 2020 17:22:57 +0530 Subject: [PATCH 2/9] Linux files added. --- linux/CMakeLists.txt | 52 ++++++ linux/examples/ublox_f9p_test.cpp | 79 +++++++++ linux/inc/Print.h | 102 +++++++++++ linux/inc/Stream.h | 143 ++++++++++++++++ linux/inc/Utils.h | 37 ++++ linux/inc/Wire.h | 89 ++++++++++ linux/src/Print.cpp | 271 ++++++++++++++++++++++++++++++ 7 files changed, 773 insertions(+) create mode 100644 linux/CMakeLists.txt create mode 100644 linux/examples/ublox_f9p_test.cpp create mode 100644 linux/inc/Print.h create mode 100644 linux/inc/Stream.h create mode 100644 linux/inc/Utils.h create mode 100644 linux/inc/Wire.h create mode 100644 linux/src/Print.cpp diff --git a/linux/CMakeLists.txt b/linux/CMakeLists.txt new file mode 100644 index 0000000..904a6ee --- /dev/null +++ b/linux/CMakeLists.txt @@ -0,0 +1,52 @@ +project (ublox_linux) +cmake_minimum_required(VERSION 2.8) + +set( + CMAKE_RUNTIME_OUTPUT_DIRECTORY + ${CMAKE_HOME_DIRECTORY}/bin + ) + +set( + CMAKE_LIBRARY_OUTPUT_DIRECTORY + ${CMAKE_HOME_DIRECTORY}/lib + ) + +add_definitions( + -std=c++11 -Wno-deprecated -fconcepts -Wall -DLINUX_PLATFORM + ) + +link_directories( + /usr/local/lib + /usr/lib + ${CMAKE_HOME_DIRECTORY}/lib + ) + +include_directories( + ${CMAKE_HOME_DIRECTORY}/inc + ${CMAKE_HOME_DIRECTORY}/../src + ) + +set( + ublox_parser_src + ../src/SparkFun_Ublox_Arduino_Library.cpp + src/Print.cpp + ) + +add_library( + ublox_linux SHARED ${ublox_parser_src} + ) + +# +# Ublox f9p Test +# + +set( + ublox_f9p_test_src + examples/ublox_f9p_test.cpp + ) + +add_executable( + ublox_f9p_test ${ublox_f9p_test_src} + ) + +target_link_libraries(ublox_f9p_test ublox_linux util) diff --git a/linux/examples/ublox_f9p_test.cpp b/linux/examples/ublox_f9p_test.cpp new file mode 100644 index 0000000..cace024 --- /dev/null +++ b/linux/examples/ublox_f9p_test.cpp @@ -0,0 +1,79 @@ +/* +Copyright (c) 2020 Balamurugan Kandan + +Permission is hereby granted, free of charge, to any person obtaining a copy +of this software and associated documentation files (the "Software"), to deal +in the Software without restriction, including without limitation the rights +to use, copy, modify, merge, publish, distribute, sublicense, and/or sell +copies of the Software, and to permit persons to whom the Software is +furnished to do so, subject to the following conditions: + +The above copyright notice and this permission notice shall be included in all +copies or substantial portions of the Software. + +THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE +AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER +LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, +OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE +SOFTWARE. +*/ + +#include "SparkFun_Ublox_Arduino_Library.h" +SFE_UBLOX_GPS myGPS; + +int main(int argc, char** argv) +{ + if(argc == 1) { + printf("\nublox_f9p_test (ublox_f9p_test '/dev/ttyACM0' '/dev/pts/1')"); + return 0; + } else if (argc == 2) { + for(int counter=0;counter= 3) { + printf ("\nMore number of arguments..."); + return 0; + } + + Stream seriComm(argv[1]); + if (!seriComm.isConnected()) { + printf ("Ublox is not connected. Please connect ublox GNSS module and try again...\n"); + return 0; + } + myGPS.begin(seriComm); + myGPS.setNavigationFrequency(10); //Set output to 20 times a second + myGPS.saveConfiguration(); //Save the current settings to flash and BBR + + printf ("\n----------------------------------------\n"); + while(true) { + if (myGPS.getPVT()) { + printf ("%02d/%02d/%02d %02d:%02d:%02d %d:%d\n", myGPS.getDay(), myGPS.getMonth(), myGPS.getYear(), + myGPS.getHour(), myGPS.getMinute(), myGPS.getSecond(), + myGPS.getMillisecond(), myGPS.getNanosecond()); + printf("Latitude : %2.8f (deg)\n", myGPS.getLatitude() * 1e-7); + printf("Longitude : %2.8f (deg)\n", myGPS.getLongitude() * 1e-7); + printf("Altitude : %d (mm)\n", myGPS.getAltitude()); + printf("Altitude MSL : %d (mm)\n", myGPS.getAltitudeMSL()); + printf("SIV : %d\n", myGPS.getSIV()); + printf("PDOP : %f\n", myGPS.getPDOP() * 1e-2); + printf("Fix type : %d\n", myGPS.getFixType()); + printf ("Ground Speed : %d\n", myGPS.getGroundSpeed()); + printf ("VelN : %08d (mm/s)\n", myGPS.getNedNorthVel()); + printf ("VelE : %08d (mm/s)\n", myGPS.getNedEastVel()); + printf ("VelD : %08d (mm/s)\n", myGPS.getNedDownVel()); + printf ("VAcc : %08d (mm)\n", myGPS.getVerticalAccEst()); + printf ("HAcc : %08d (mm)\n", myGPS.getHorizontalAccEst()); + int solnType = myGPS.getCarrierSolutionType(); + if (solnType == 0) printf ("### No RTK Fix yet ###\n"); + else if (solnType == 1) printf ("&&& DGNSS/Float &&&\n"); + else if (solnType == 2) printf ("*** DGNSS/Fix ***\n"); + printf ("\n----------------------------------------\n"); + usleep(50); + } + + usleep(25); + } + + return 1; +} diff --git a/linux/inc/Print.h b/linux/inc/Print.h new file mode 100644 index 0000000..a440a03 --- /dev/null +++ b/linux/inc/Print.h @@ -0,0 +1,102 @@ +/* + Print.h - Base class that provides print() and println() + Copyright (c) 2008 David A. Mellis. All right reserved. + + This library is free software; you can redistribute it and/or + modify it under the terms of the GNU Lesser General Public + License as published by the Free Software Foundation; either + version 2.1 of the License, or (at your option) any later version. + + This library is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + Lesser General Public License for more details. + + You should have received a copy of the GNU Lesser General Public + License along with this library; if not, write to the Free Software + Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA +*/ + +#ifndef Print_h +#define Print_h + +#include +#include // for size_t + +//#include "WString.h" +//#include "Printable.h" + +#define DEC 10 +#define HEX 16 +#define OCT 8 +#ifdef BIN // Prevent warnings if BIN is previously defined in "iotnx4.h" or similar +#undef BIN +#endif +#define BIN 2 + +#include +typedef std::string String; + +#define PSTR(s) ((const char *)(s)) +#define PGM_P const char * + +class __FlashStringHelper; +#define F(string_literal) (reinterpret_cast(PSTR(string_literal))) + +class Print +{ + private: + int write_error; + size_t printNumber(unsigned long, uint8_t); + size_t printFloat(double, uint8_t); + protected: + void setWriteError(int err = 1) { write_error = err; } + public: + Print() : write_error(0) {} + + int getWriteError() { return write_error; } + void clearWriteError() { setWriteError(0); } + + virtual size_t write(uint8_t) = 0; + size_t write(const char *str) { + if (str == NULL) return 0; + return write((const uint8_t *)str, strlen(str)); + } + virtual size_t write(const uint8_t *buffer, size_t size); + size_t write(const char *buffer, size_t size) { + return write((const uint8_t *)buffer, size); + } + + // default to zero, meaning "a single write may block" + // should be overriden by subclasses with buffering + virtual int availableForWrite() { return 0; } + + size_t print(const __FlashStringHelper *); + size_t print(const String &); + size_t print(const char[]); + size_t print(char); + size_t print(unsigned char, int = DEC); + size_t print(int, int = DEC); + size_t print(unsigned int, int = DEC); + size_t print(long, int = DEC); + size_t print(unsigned long, int = DEC); + size_t print(double, int = 2); + //size_t print(const Printable&); + + size_t println(const __FlashStringHelper *); + size_t println(const String &s); + size_t println(const char[]); + size_t println(char); + size_t println(unsigned char, int = DEC); + size_t println(int, int = DEC); + size_t println(unsigned int, int = DEC); + size_t println(long, int = DEC); + size_t println(unsigned long, int = DEC); + size_t println(double, int = 2); + //size_t println(const Printable&); + size_t println(void); + + virtual void flush() { /* Empty implementation for backward compatibility */ } +}; + +#endif diff --git a/linux/inc/Stream.h b/linux/inc/Stream.h new file mode 100644 index 0000000..928ea40 --- /dev/null +++ b/linux/inc/Stream.h @@ -0,0 +1,143 @@ +/* +Copyright (c) 2020 Balamurugan Kandan + +Permission is hereby granted, free of charge, to any person obtaining a copy +of this software and associated documentation files (the "Software"), to deal +in the Software without restriction, including without limitation the rights +to use, copy, modify, merge, publish, distribute, sublicense, and/or sell +copies of the Software, and to permit persons to whom the Software is +furnished to do so, subject to the following conditions: + +The above copyright notice and this permission notice shall be included in all +copies or substantial portions of the Software. + +THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE +AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER +LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, +OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE +SOFTWARE. +*/ + +#ifndef STREAM_H__ +#define STREAM_H__ + +#include +#include +#include +#include +#include +#include +#include +#include +#include + +#include "Print.h" + +class Stream : public Print { +public: + Stream(char *devName) : m_IsAvailable(false), m_IsConnected(false), m_SerialFd(-1) { + OpenComm(devName); + m_recvdByte = '\0'; + } + + Stream() : m_IsAvailable(false), m_IsConnected(false), m_SerialFd(-1) { + OpenComm(create_pseudo_com()); + m_recvdByte = '\0'; + } + + virtual ~Stream() { + close(m_SerialFd); + m_IsAvailable = false; + m_IsConnected = false; + m_SerialFd = -1; + printf ("Stream : Closed\n"); + } + + bool OpenComm(char *devName) { + m_SerialFd = open(devName, O_NOCTTY|O_RDWR|O_NONBLOCK); + if (m_SerialFd != -1) { + printf ("%s is connected successfully!!!\n", devName); + // Get device info + struct termios newtio; + // Set device config, 115200baud for now. + memset(&newtio,0,sizeof(newtio)); + cfmakeraw(&newtio); + newtio.c_cflag|=B115200; + tcflush(m_SerialFd, TCIFLUSH); + tcsetattr(m_SerialFd,TCSANOW,&newtio); + m_IsConnected = true; + } else { + printf("Unable to open GNSS on: %s\n",devName); + } + return m_IsConnected; + } + + bool isConnected() { return m_IsConnected; } + bool available() { + int iRxLen = 0; + iRxLen = ::read(m_SerialFd, (void *)&m_recvdByte, sizeof(m_recvdByte)); + if (iRxLen > 0) { + m_IsAvailable = true; + // Debugging purpose + /* + int iPos = 0; + while (iPos < iRxLen) { + iPos++; + } + */ + } else { + m_IsAvailable = false; + } + return m_IsAvailable; + } + + size_t write(uint8_t byte) { + m_IsAvailable = false; + return ::write(m_SerialFd, (void *)&byte, sizeof(byte)); + } + + size_t write(uint8_t *byte, size_t num_of_bytes) { + m_IsAvailable = false; + return ::write(m_SerialFd, byte, num_of_bytes); + } + + uint8_t read() { + return m_recvdByte; + } + + int getFD() { + return m_SerialFd; + } + +private: + bool m_IsAvailable; + bool m_IsConnected; + int m_SerialFd; + uint8_t m_recvdByte; + + char* create_pseudo_com() { + static char name[256] = {'\0'}; + struct termios tt = {'\0'}; + int master = 0, slave = 0; + + if (tcgetattr (STDIN_FILENO, &tt) < 0) { + printf("Cannot get terminal attributes of stdin\n"); + } + cfmakeraw (&tt); + if (openpty (&master, &slave, name, &tt, NULL /*ws*/) < 0) { + printf("Cannot open pty\n"); + } + + return name; + } + +}; + +//typedef Stream Serial; +extern Stream Serial; +// Preinstantiate Objects ////////////////////////////////////////////////////// +Stream Serial = Stream(); + +#endif // STREAM__ \ No newline at end of file diff --git a/linux/inc/Utils.h b/linux/inc/Utils.h new file mode 100644 index 0000000..ad8ff16 --- /dev/null +++ b/linux/inc/Utils.h @@ -0,0 +1,37 @@ +#include +#include +using namespace std; + +typedef uint8_t byte; +typedef bool boolean; + +#define INPUT 0 +#define OUTPUT 1 +#define LOW 0 +#define HIGH 1 + +unsigned long millis() { + auto now = std::chrono::system_clock::now(); + auto now_ms = std::chrono::time_point_cast(now); + auto epoch = now_ms.time_since_epoch(); + auto value = std::chrono::duration_cast(epoch); + return (value.count()); +} + +void delay(int sec) { + int ms = 1000 * sec; + clock_t start_time = clock(); + while (clock() < start_time + ms); +} + +void delayMicroseconds(unsigned int us) { + usleep(us); +} + +void pinMode(uint8_t pin, uint8_t pinMode) { + printf ("Functionality yet to be implemented..."); +} + +void digitalWrite(uint8_t pin, uint8_t pinMode) { + printf ("Functionality yet to be implemented..."); +} \ No newline at end of file diff --git a/linux/inc/Wire.h b/linux/inc/Wire.h new file mode 100644 index 0000000..849a476 --- /dev/null +++ b/linux/inc/Wire.h @@ -0,0 +1,89 @@ +#ifndef Wire_h +#define Wire_h + +#include +#include +#include + +#define I2C_DEV "/dev/ublox_i2c" + +class TwoWire +{ +public: + TwoWire() : m_address(0x42), i2c_fd(0) { init(); } + ~TwoWire() { close(i2c_fd); } + + bool init() { + char filename[20] = I2C_DEV; + //snprintf(filename, sizeof(filename), "/dev/i2c-%u", bus_); + + if ((i2c_fd = open(filename, O_RDWR)) < 0) { + printf("I2C: Failed to open bus '%s': %i-%s", + filename, errno, strerror(errno)); + return false; + } + + printf("I2C: Successfully initialized with default address [%s 0x%02x]", filename, m_address); + return true; + } + + bool beginTransmission(uint8_t address) { + m_address = address; + if (ioctl(i2c_fd, I2C_SLAVE, m_address) < 0) { + printf("I2C: Failed to acquire bus access and/or talk to slave: %i-%s", + errno, strerror(errno)); + return false; + } + } + uint8_t endTransmission(void) { return 0; } + uint8_t endTransmission(bool stop) { return 0; } + + bool available() { + return (read(m_recvdByte)); + } + + size_t write(uint8_t byte) { + m_IsAvailable = false; + return ::write(i2c_fd, (void *)&byte, sizeof(byte)); + } + + size_t write(uint8_t *byte, size_t num_of_bytes) { + m_IsAvailable = false; + return ::write(i2c_fd, byte, num_of_bytes); + } + + uint8_t read() { + return m_recvdByte; + } + + uint8_t requestFrom(uint8_t address, uint8_t quantity) { + m_address = address; + m_quantity = quantity; + return (read(quantity)); + } + +private: + uint8_t m_address; + bool m_IsAvailable; + bool m_IsConnected; + uint8_t m_recvdByte; + uint8_t m_quantity; + int i2c_fd; + + size_t read(uint8_t byte) { + int iRxLen = 0; + iRxLen = ::read(i2c_fd, (void *)&byte, sizeof(byte)); + if (iRxLen > 0) { + m_IsAvailable = true; + } else { + m_IsAvailable = false; + } + return m_IsAvailable; + } +}; + +extern TwoWire Wire; +// Preinstantiate Objects ////////////////////////////////////////////////////// +TwoWire Wire = TwoWire(); + +#endif //Wire_h \ No newline at end of file diff --git a/linux/src/Print.cpp b/linux/src/Print.cpp new file mode 100644 index 0000000..bc33ee1 --- /dev/null +++ b/linux/src/Print.cpp @@ -0,0 +1,271 @@ +/* + Print.cpp - Base class that provides print() and println() + Copyright (c) 2008 David A. Mellis. All right reserved. + + This library is free software; you can redistribute it and/or + modify it under the terms of the GNU Lesser General Public + License as published by the Free Software Foundation; either + version 2.1 of the License, or (at your option) any later version. + + This library is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + Lesser General Public License for more details. + + You should have received a copy of the GNU Lesser General Public + License along with this library; if not, write to the Free Software + Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA + + Modified 23 November 2006 by David A. Mellis + Modified 03 August 2015 by Chuck Todd + */ + +#include +#include +#include +#include +/* +#include "Arduino.h" +*/ +#include "Print.h" + +// Public Methods ////////////////////////////////////////////////////////////// + +/* default implementation: may be overridden */ +size_t Print::write(const uint8_t *buffer, size_t size) +{ + size_t n = 0; + while (size--) { + if (write(*buffer++)) n++; + else break; + } + return n; +} + +size_t Print::print(const __FlashStringHelper *ifsh) +{ + PGM_P p = reinterpret_cast(ifsh); + size_t n = 0; + while (1) { + unsigned char c = (*p++); + if (c == 0) break; + if (write(c)) n++; + else break; + } + return n; +} + +size_t Print::print(const String &s) +{ + return write(s.c_str(), s.length()); +} + +size_t Print::print(const char str[]) +{ + return write(str); +} + +size_t Print::print(char c) +{ + return write(c); +} + +size_t Print::print(unsigned char b, int base) +{ + return print((unsigned long) b, base); +} + +size_t Print::print(int n, int base) +{ + return print((long) n, base); +} + +size_t Print::print(unsigned int n, int base) +{ + return print((unsigned long) n, base); +} + +size_t Print::print(long n, int base) +{ + if (base == 0) { + return write(n); + } else if (base == 10) { + if (n < 0) { + int t = print('-'); + n = -n; + return printNumber(n, 10) + t; + } + return printNumber(n, 10); + } else { + return printNumber(n, base); + } +} + +size_t Print::print(unsigned long n, int base) +{ + if (base == 0) return write(n); + else return printNumber(n, base); +} + +size_t Print::print(double n, int digits) +{ + return printFloat(n, digits); +} + +size_t Print::println(const __FlashStringHelper *ifsh) +{ + size_t n = print(ifsh); + n += println(); + return n; +} + +/* +size_t Print::print(const Printable& x) +{ + return x.printTo(*this); +} +*/ + +size_t Print::println(void) +{ + return write("\r\n"); +} + +size_t Print::println(const String &s) +{ + size_t n = print(s); + n += println(); + return n; +} + +size_t Print::println(const char c[]) +{ + size_t n = print(c); + n += println(); + return n; +} + +size_t Print::println(char c) +{ + size_t n = print(c); + n += println(); + return n; +} + +size_t Print::println(unsigned char b, int base) +{ + size_t n = print(b, base); + n += println(); + return n; +} + +size_t Print::println(int num, int base) +{ + size_t n = print(num, base); + n += println(); + return n; +} + +size_t Print::println(unsigned int num, int base) +{ + size_t n = print(num, base); + n += println(); + return n; +} + +size_t Print::println(long num, int base) +{ + size_t n = print(num, base); + n += println(); + return n; +} + +size_t Print::println(unsigned long num, int base) +{ + size_t n = print(num, base); + n += println(); + return n; +} + +size_t Print::println(double num, int digits) +{ + size_t n = print(num, digits); + n += println(); + return n; +} + +/* +size_t Print::println(const Printable& x) +{ + size_t n = print(x); + n += println(); + return n; +} +*/ + +// Private Methods ///////////////////////////////////////////////////////////// + +size_t Print::printNumber(unsigned long n, uint8_t base) +{ + char buf[8 * sizeof(long) + 1]; // Assumes 8-bit chars plus zero byte. + char *str = &buf[sizeof(buf) - 1]; + + *str = '\0'; + + // prevent crash if called with base == 1 + if (base < 2) base = 10; + + do { + char c = n % base; + n /= base; + + *--str = c < 10 ? c + '0' : c + 'A' - 10; + } while(n); + + return write(str); +} + +size_t Print::printFloat(double number, uint8_t digits) +{ + size_t n = 0; + + if (isnan(number)) return print("nan"); + if (isinf(number)) return print("inf"); + if (number > 4294967040.0) return print ("ovf"); // constant determined empirically + if (number <-4294967040.0) return print ("ovf"); // constant determined empirically + + // Handle negative numbers + if (number < 0.0) + { + n += print('-'); + number = -number; + } + + // Round correctly so that print(1.999, 2) prints as "2.00" + double rounding = 0.5; + for (uint8_t i=0; i 0) { + n += print('.'); + } + + // Extract digits from the remainder one at a time + while (digits-- > 0) + { + remainder *= 10.0; + unsigned int toPrint = (unsigned int)(remainder); + n += print(toPrint); + remainder -= toPrint; + } + + return n; +} From b7b92d51915af1063bdb1204e326483e5e80bfa0 Mon Sep 17 00:00:00 2001 From: Balamurugan Kandan Date: Sun, 20 Dec 2020 15:47:40 +0000 Subject: [PATCH 3/9] Code refactoring --- linux/CMakeLists.txt | 1 + linux/examples/ublox_f9p_test.cpp | 29 +++++++++++++-------- linux/inc/Print.h | 3 --- linux/inc/Stream.h | 42 +++++++++++++++++++++++++----- linux/inc/Utils.h | 43 ++++++------------------------- linux/inc/Wire.h | 4 +-- 6 files changed, 63 insertions(+), 59 deletions(-) diff --git a/linux/CMakeLists.txt b/linux/CMakeLists.txt index 904a6ee..d4041de 100644 --- a/linux/CMakeLists.txt +++ b/linux/CMakeLists.txt @@ -30,6 +30,7 @@ set( ublox_parser_src ../src/SparkFun_Ublox_Arduino_Library.cpp src/Print.cpp + src/Utils.cpp ) add_library( diff --git a/linux/examples/ublox_f9p_test.cpp b/linux/examples/ublox_f9p_test.cpp index cace024..f53757f 100644 --- a/linux/examples/ublox_f9p_test.cpp +++ b/linux/examples/ublox_f9p_test.cpp @@ -26,9 +26,9 @@ SFE_UBLOX_GPS myGPS; int main(int argc, char** argv) { if(argc == 1) { - printf("\nublox_f9p_test (ublox_f9p_test '/dev/ttyACM0' '/dev/pts/1')"); + printf("\nublox_f9p_test (ublox_f9p_test '/dev/ttyACM0')"); return 0; - } else if (argc == 2) { + } else if (argc == 2) { for(int counter=0;counter= 3) { @@ -42,10 +42,10 @@ int main(int argc, char** argv) return 0; } myGPS.begin(seriComm); - myGPS.setNavigationFrequency(10); //Set output to 20 times a second + myGPS.setNavigationFrequency(8); //Set output to 8 times a second myGPS.saveConfiguration(); //Save the current settings to flash and BBR - printf ("\n----------------------------------------\n"); + printf ("\n--------------------------------------------------------\n"); while(true) { if (myGPS.getPVT()) { printf ("%02d/%02d/%02d %02d:%02d:%02d %d:%d\n", myGPS.getDay(), myGPS.getMonth(), myGPS.getYear(), @@ -58,17 +58,24 @@ int main(int argc, char** argv) printf("SIV : %d\n", myGPS.getSIV()); printf("PDOP : %f\n", myGPS.getPDOP() * 1e-2); printf("Fix type : %d\n", myGPS.getFixType()); - printf ("Ground Speed : %d\n", myGPS.getGroundSpeed()); - printf ("VelN : %08d (mm/s)\n", myGPS.getNedNorthVel()); - printf ("VelE : %08d (mm/s)\n", myGPS.getNedEastVel()); - printf ("VelD : %08d (mm/s)\n", myGPS.getNedDownVel()); - printf ("VAcc : %08d (mm)\n", myGPS.getVerticalAccEst()); - printf ("HAcc : %08d (mm)\n", myGPS.getHorizontalAccEst()); + printf("Ground Speed : %d\n", myGPS.getGroundSpeed()); + printf("VelN : %08d (mm/s)\n", myGPS.getNedNorthVel()); + printf("VelE : %08d (mm/s)\n", myGPS.getNedEastVel()); + printf("VelD : %08d (mm/s)\n", myGPS.getNedDownVel()); + printf("VAcc : %08d (mm)\n", myGPS.getVerticalAccEst()); + printf("HAcc : %08d (mm)\n", myGPS.getHorizontalAccEst()); + printf("SpeedAccEst : %08d (mm/s)\n", myGPS.getSpeedAccEst()); + printf("HeadAccEst : %08d (degrees * 10^-5)\n", myGPS.getHeadingAccEst()); + if (myGPS.getHeadVehValid() == true) { + printf("HeadVeh : %08d (degrees * 10^-5)\n", myGPS.getHeadVeh()); + printf("MagDec : %08d (degrees * 10^-2)\n", myGPS.getMagDec()); + printf("MagAcc : %08d (degrees * 10^-2)\n", myGPS.getMagAcc()); + } int solnType = myGPS.getCarrierSolutionType(); if (solnType == 0) printf ("### No RTK Fix yet ###\n"); else if (solnType == 1) printf ("&&& DGNSS/Float &&&\n"); else if (solnType == 2) printf ("*** DGNSS/Fix ***\n"); - printf ("\n----------------------------------------\n"); + printf ("\n--------------------------------------------------------\n"); usleep(50); } diff --git a/linux/inc/Print.h b/linux/inc/Print.h index a440a03..4f10908 100644 --- a/linux/inc/Print.h +++ b/linux/inc/Print.h @@ -23,9 +23,6 @@ #include #include // for size_t -//#include "WString.h" -//#include "Printable.h" - #define DEC 10 #define HEX 16 #define OCT 8 diff --git a/linux/inc/Stream.h b/linux/inc/Stream.h index 928ea40..b006382 100644 --- a/linux/inc/Stream.h +++ b/linux/inc/Stream.h @@ -37,7 +37,7 @@ SOFTWARE. class Stream : public Print { public: - Stream(char *devName) : m_IsAvailable(false), m_IsConnected(false), m_SerialFd(-1) { + Stream(char *devName) : m_IsAvailable(false), m_IsConnected(false), m_SerialFd(-1), m_baudRate(115200) { OpenComm(devName); m_recvdByte = '\0'; } @@ -55,16 +55,46 @@ class Stream : public Print { printf ("Stream : Closed\n"); } + int get_baud(int baud) + { + switch (baud) { + case 1200: + return B1200; + case 2400: + return B2400; + case 4800: + return B4800; + case 9600: + return B9600; + case 19200: + return B19200; + case 38400: + return B38400; + case 57600: + return B57600; + case 115200: + return B115200; + case 230400: + return B230400; + case 460800: + return B460800; + case 921600: + return B921600; + default: + return B115200; + } + } + bool OpenComm(char *devName) { - m_SerialFd = open(devName, O_NOCTTY|O_RDWR|O_NONBLOCK); + m_SerialFd = open(devName, O_NOCTTY|O_RDWR|O_NONBLOCK);C if (m_SerialFd != -1) { - printf ("%s is connected successfully!!!\n", devName); + printf ("\n%s is connected successfully!!!\n", devName); // Get device info struct termios newtio; // Set device config, 115200baud for now. memset(&newtio,0,sizeof(newtio)); cfmakeraw(&newtio); - newtio.c_cflag|=B115200; + newtio.c_cflag|=get_baud(m_baudRate); tcflush(m_SerialFd, TCIFLUSH); tcsetattr(m_SerialFd,TCSANOW,&newtio); m_IsConnected = true; @@ -116,6 +146,7 @@ class Stream : public Print { bool m_IsConnected; int m_SerialFd; uint8_t m_recvdByte; + uint16_t m_baudRate; char* create_pseudo_com() { static char name[256] = {'\0'}; @@ -132,12 +163,9 @@ class Stream : public Print { return name; } - }; //typedef Stream Serial; extern Stream Serial; -// Preinstantiate Objects ////////////////////////////////////////////////////// -Stream Serial = Stream(); #endif // STREAM__ \ No newline at end of file diff --git a/linux/inc/Utils.h b/linux/inc/Utils.h index ad8ff16..c8e908e 100644 --- a/linux/inc/Utils.h +++ b/linux/inc/Utils.h @@ -1,37 +1,10 @@ -#include -#include -using namespace std; +#ifndef UTILS_H__ +#define UTILS_H__ -typedef uint8_t byte; -typedef bool boolean; +unsigned long millis(); +void delay(int sec); +void delayMicroseconds(unsigned int us); +void pinMode(uint8_t pin, uint8_t pinMode); +void digitalWrite(uint8_t pin, uint8_t pinMode); -#define INPUT 0 -#define OUTPUT 1 -#define LOW 0 -#define HIGH 1 - -unsigned long millis() { - auto now = std::chrono::system_clock::now(); - auto now_ms = std::chrono::time_point_cast(now); - auto epoch = now_ms.time_since_epoch(); - auto value = std::chrono::duration_cast(epoch); - return (value.count()); -} - -void delay(int sec) { - int ms = 1000 * sec; - clock_t start_time = clock(); - while (clock() < start_time + ms); -} - -void delayMicroseconds(unsigned int us) { - usleep(us); -} - -void pinMode(uint8_t pin, uint8_t pinMode) { - printf ("Functionality yet to be implemented..."); -} - -void digitalWrite(uint8_t pin, uint8_t pinMode) { - printf ("Functionality yet to be implemented..."); -} \ No newline at end of file +#endif // UTILS_H__ \ No newline at end of file diff --git a/linux/inc/Wire.h b/linux/inc/Wire.h index 849a476..d1a3800 100644 --- a/linux/inc/Wire.h +++ b/linux/inc/Wire.h @@ -5,7 +5,7 @@ #include #include -#define I2C_DEV "/dev/ublox_i2c" +#include "Common.h" class TwoWire { @@ -83,7 +83,5 @@ class TwoWire }; extern TwoWire Wire; -// Preinstantiate Objects ////////////////////////////////////////////////////// -TwoWire Wire = TwoWire(); #endif //Wire_h \ No newline at end of file From 8d574af984e63e19e8393dab6abdfc4264365847 Mon Sep 17 00:00:00 2001 From: Balamurugan Kandan Date: Sun, 20 Dec 2020 16:09:53 +0000 Subject: [PATCH 4/9] Code refactoring --- linux/examples/ublox_f9p_test.cpp | 2 ++ linux/inc/Stream.h | 28 ++++++++++++++++++++-------- 2 files changed, 22 insertions(+), 8 deletions(-) diff --git a/linux/examples/ublox_f9p_test.cpp b/linux/examples/ublox_f9p_test.cpp index f53757f..2468b4b 100644 --- a/linux/examples/ublox_f9p_test.cpp +++ b/linux/examples/ublox_f9p_test.cpp @@ -37,10 +37,12 @@ int main(int argc, char** argv) } Stream seriComm(argv[1]); + seriComm.begin(115200); if (!seriComm.isConnected()) { printf ("Ublox is not connected. Please connect ublox GNSS module and try again...\n"); return 0; } + myGPS.begin(seriComm); myGPS.setNavigationFrequency(8); //Set output to 8 times a second myGPS.saveConfiguration(); //Save the current settings to flash and BBR diff --git a/linux/inc/Stream.h b/linux/inc/Stream.h index b006382..d153aec 100644 --- a/linux/inc/Stream.h +++ b/linux/inc/Stream.h @@ -33,21 +33,27 @@ SOFTWARE. #include #include +#include "Common.h" #include "Print.h" class Stream : public Print { public: - Stream(char *devName) : m_IsAvailable(false), m_IsConnected(false), m_SerialFd(-1), m_baudRate(115200) { - OpenComm(devName); + Stream(char *devName) : m_IsAvailable(false), m_IsConnected(false), m_SerialFd(-1), m_baudRate(115200), m_devName({'\0'}) { + strcpy(m_devName, devName); + open_comm(devName); m_recvdByte = '\0'; } Stream() : m_IsAvailable(false), m_IsConnected(false), m_SerialFd(-1) { - OpenComm(create_pseudo_com()); + open_comm(create_pseudo_com()); m_recvdByte = '\0'; } virtual ~Stream() { + close_comm(); + } + + void close_comm() { close(m_SerialFd); m_IsAvailable = false; m_IsConnected = false; @@ -85,16 +91,15 @@ class Stream : public Print { } } - bool OpenComm(char *devName) { - m_SerialFd = open(devName, O_NOCTTY|O_RDWR|O_NONBLOCK);C + bool open_comm(char *devName) { + m_SerialFd = open(devName, O_NOCTTY|O_RDWR|O_NONBLOCK); if (m_SerialFd != -1) { printf ("\n%s is connected successfully!!!\n", devName); // Get device info struct termios newtio; - // Set device config, 115200baud for now. memset(&newtio,0,sizeof(newtio)); cfmakeraw(&newtio); - newtio.c_cflag|=get_baud(m_baudRate); + newtio.c_cflag |= get_baud(m_baudRate); tcflush(m_SerialFd, TCIFLUSH); tcsetattr(m_SerialFd,TCSANOW,&newtio); m_IsConnected = true; @@ -141,15 +146,22 @@ class Stream : public Print { return m_SerialFd; } + void begin(uint16_t baud_rate) { + m_baudRate = baud_rate; + close_comm(); + open_comm(m_devName); + } + private: bool m_IsAvailable; bool m_IsConnected; int m_SerialFd; uint8_t m_recvdByte; uint16_t m_baudRate; + char m_devName[SHORT_BUFF]; char* create_pseudo_com() { - static char name[256] = {'\0'}; + static char name[SHORT_BUFF] = {'\0'}; struct termios tt = {'\0'}; int master = 0, slave = 0; From 3064fa8ce13a6b76bac7cb22278f7c97a759f036 Mon Sep 17 00:00:00 2001 From: Balamurugan Kandan Date: Sun, 20 Dec 2020 17:37:22 +0000 Subject: [PATCH 5/9] Example changed. --- linux/examples/ublox_f9p_test.cpp | 9 ++++----- 1 file changed, 4 insertions(+), 5 deletions(-) diff --git a/linux/examples/ublox_f9p_test.cpp b/linux/examples/ublox_f9p_test.cpp index 2468b4b..be0caa5 100644 --- a/linux/examples/ublox_f9p_test.cpp +++ b/linux/examples/ublox_f9p_test.cpp @@ -68,11 +68,10 @@ int main(int argc, char** argv) printf("HAcc : %08d (mm)\n", myGPS.getHorizontalAccEst()); printf("SpeedAccEst : %08d (mm/s)\n", myGPS.getSpeedAccEst()); printf("HeadAccEst : %08d (degrees * 10^-5)\n", myGPS.getHeadingAccEst()); - if (myGPS.getHeadVehValid() == true) { - printf("HeadVeh : %08d (degrees * 10^-5)\n", myGPS.getHeadVeh()); - printf("MagDec : %08d (degrees * 10^-2)\n", myGPS.getMagDec()); - printf("MagAcc : %08d (degrees * 10^-2)\n", myGPS.getMagAcc()); - } + printf("HeadVehValid : %s\n", myGPS.getHeadVehValid() ? "true" : "false"); + printf("HeadVeh : %08d (degrees * 10^-5)\n", myGPS.getHeadVeh()); + printf("MagDec : %08d (degrees * 10^-2)\n", myGPS.getMagDec()); + printf("MagAcc : %08d (degrees * 10^-2)\n", myGPS.getMagAcc()); int solnType = myGPS.getCarrierSolutionType(); if (solnType == 0) printf ("### No RTK Fix yet ###\n"); else if (solnType == 1) printf ("&&& DGNSS/Float &&&\n"); From 7750abeafe1b0f13069a6db8fea1f8a315fd17c7 Mon Sep 17 00:00:00 2001 From: Balamurugan Kandan Date: Sat, 2 Jan 2021 19:18:34 +0000 Subject: [PATCH 6/9] Create README.md --- linux/README.md | 11 +++++++++++ 1 file changed, 11 insertions(+) create mode 100644 linux/README.md diff --git a/linux/README.md b/linux/README.md new file mode 100644 index 0000000..115e4ac --- /dev/null +++ b/linux/README.md @@ -0,0 +1,11 @@ +# SparkFun_Ublox_Linux_Library + +## How to compile +* mkdir build +* cd build +* cmake .. +* make + +## How to execute test +* cd ../bin (Assuming the current directorty is build directory, created above) +* ./ublox_f9p_test (Ublox library calls) From 413bc6b278e98b441a2d09f9e149c81efe6ede0f Mon Sep 17 00:00:00 2001 From: Balamurugan Kandan Date: Sun, 3 Jan 2021 12:17:21 +0000 Subject: [PATCH 7/9] Update CMakeLists.txt --- linux/CMakeLists.txt | 1 - 1 file changed, 1 deletion(-) diff --git a/linux/CMakeLists.txt b/linux/CMakeLists.txt index d4041de..904a6ee 100644 --- a/linux/CMakeLists.txt +++ b/linux/CMakeLists.txt @@ -30,7 +30,6 @@ set( ublox_parser_src ../src/SparkFun_Ublox_Arduino_Library.cpp src/Print.cpp - src/Utils.cpp ) add_library( From b8cb72cc38ac8905c991e622ae0523a10999f110 Mon Sep 17 00:00:00 2001 From: Balamurugan Kandan Date: Sun, 3 Jan 2021 13:01:29 +0000 Subject: [PATCH 8/9] Added Common.h and Utils.cpp files. --- linux/examples/ublox_f9p_test.cpp | 2 +- linux/inc/Common.h | 16 +++++++++++++ linux/src/Utils.cpp | 38 +++++++++++++++++++++++++++++++ 3 files changed, 55 insertions(+), 1 deletion(-) create mode 100644 linux/inc/Common.h create mode 100644 linux/src/Utils.cpp diff --git a/linux/examples/ublox_f9p_test.cpp b/linux/examples/ublox_f9p_test.cpp index be0caa5..63663b4 100644 --- a/linux/examples/ublox_f9p_test.cpp +++ b/linux/examples/ublox_f9p_test.cpp @@ -37,7 +37,7 @@ int main(int argc, char** argv) } Stream seriComm(argv[1]); - seriComm.begin(115200); + seriComm.begin(38400); if (!seriComm.isConnected()) { printf ("Ublox is not connected. Please connect ublox GNSS module and try again...\n"); return 0; diff --git a/linux/inc/Common.h b/linux/inc/Common.h new file mode 100644 index 0000000..0b46147 --- /dev/null +++ b/linux/inc/Common.h @@ -0,0 +1,16 @@ +#ifndef COMMON_H__ +#define COMMON_H__ + +typedef uint8_t byte; +typedef bool boolean; + +#define INPUT 0 +#define OUTPUT 1 +#define LOW 0 +#define HIGH 1 + +#define SHORT_BUFF 256 + +#define I2C_DEV "/dev/ublox_i2c" + +#endif // COMMON_H__ \ No newline at end of file diff --git a/linux/src/Utils.cpp b/linux/src/Utils.cpp new file mode 100644 index 0000000..d969e04 --- /dev/null +++ b/linux/src/Utils.cpp @@ -0,0 +1,38 @@ +#include +#include +using namespace std; + +#include "Stream.h" +#include "Wire.h" + +// Preinstantiate Objects ////////////////////////////////////////////////////// +Stream Serial = Stream(); + +// Preinstantiate Objects ////////////////////////////////////////////////////// +TwoWire Wire = TwoWire(); + +unsigned long millis() { + auto now = std::chrono::system_clock::now(); + auto now_ms = std::chrono::time_point_cast(now); + auto epoch = now_ms.time_since_epoch(); + auto value = std::chrono::duration_cast(epoch); + return (value.count()); +} + +void delay(int sec) { + int ms = 1000 * sec; + clock_t start_time = clock(); + while (clock() < start_time + ms); +} + +void delayMicroseconds(unsigned int us) { + usleep(us); +} + +void pinMode(uint8_t pin, uint8_t pinMode) { + printf ("Functionality yet to be implemented..."); +} + +void digitalWrite(uint8_t pin, uint8_t pinMode) { + printf ("Functionality yet to be implemented..."); +} \ No newline at end of file From 890ba025bb3ebd830c90174619b689e6986ca5c6 Mon Sep 17 00:00:00 2001 From: Balamurugan Kandan Date: Sun, 3 Jan 2021 13:04:36 +0000 Subject: [PATCH 9/9] Code refactoring --- linux/CMakeLists.txt | 1 + 1 file changed, 1 insertion(+) diff --git a/linux/CMakeLists.txt b/linux/CMakeLists.txt index 904a6ee..d4041de 100644 --- a/linux/CMakeLists.txt +++ b/linux/CMakeLists.txt @@ -30,6 +30,7 @@ set( ublox_parser_src ../src/SparkFun_Ublox_Arduino_Library.cpp src/Print.cpp + src/Utils.cpp ) add_library(