Explorar el Código

ublox6: Initial implementation

jrvandr: removed unnecessary mraa_init() and mraa_deinit()

The module implements support for the ublox-6 GPS sensor.  It was
tested on a Grove GPS device.

This module simply allows data to be retrieved from the device in the
form of NMEA sentences, and provides a method to write commands to the
device for configuration purposes.

It does not attempt to parse NMEA data -- that is a project in itself.
There are libraries available on the Internet, such as tinyGPS++ that
can handle that for you.

Signed-off-by: Jon Trulson <jtrulson@ics.com>
Signed-off-by: Zion Orent <zorent@ics.com>
Signed-off-by: John Van Drasek <john.r.van.drasek@intel.com>
Jon Trulson hace 10 años
padre
commit
f53fab80fd

+ 3
- 0
examples/CMakeLists.txt Ver fichero

@@ -66,6 +66,7 @@ add_executable (grovewater-example grovewater.cxx)
66 66
 add_executable (guvas12d-example guvas12d.cxx)
67 67
 add_executable (groveloudness-example groveloudness.cxx)
68 68
 add_executable (mpr121-example mpr121.cxx)
69
+add_executable (ublox6-example ublox6.cxx)
69 70
 
70 71
 include_directories (${PROJECT_SOURCE_DIR}/src/hmc5883l)
71 72
 include_directories (${PROJECT_SOURCE_DIR}/src/grove)
@@ -119,6 +120,7 @@ include_directories (${PROJECT_SOURCE_DIR}/src/grovewater)
119 120
 include_directories (${PROJECT_SOURCE_DIR}/src/guvas12d)
120 121
 include_directories (${PROJECT_SOURCE_DIR}/src/groveloudness)
121 122
 include_directories (${PROJECT_SOURCE_DIR}/src/mpr121)
123
+include_directories (${PROJECT_SOURCE_DIR}/src/ublox6)
122 124
 
123 125
 target_link_libraries (hmc5883l-example hmc5883l ${CMAKE_THREAD_LIBS_INIT})
124 126
 target_link_libraries (groveled-example grove ${CMAKE_THREAD_LIBS_INIT})
@@ -188,3 +190,4 @@ target_link_libraries (grovewater-example grovewater ${CMAKE_THREAD_LIBS_INIT})
188 190
 target_link_libraries (guvas12d-example guvas12d ${CMAKE_THREAD_LIBS_INIT})
189 191
 target_link_libraries (groveloudness-example groveloudness ${CMAKE_THREAD_LIBS_INIT})
190 192
 target_link_libraries (mpr121-example mpr121 ${CMAKE_THREAD_LIBS_INIT})
193
+target_link_libraries (ublox6-example ublox6 ${CMAKE_THREAD_LIBS_INIT})

+ 99
- 0
examples/javascript/ublox6.js Ver fichero

@@ -0,0 +1,99 @@
1
+/*jslint node:true, vars:true, bitwise:true, unparam:true */
2
+/*jshint unused:true */
3
+/*global */
4
+/*
5
+* Author: Zion Orent <zorent@ics.com>
6
+* Copyright (c) 2014 Intel Corporation.
7
+*
8
+* Permission is hereby granted, free of charge, to any person obtaining
9
+* a copy of this software and associated documentation files (the
10
+* "Software"), to deal in the Software without restriction, including
11
+* without limitation the rights to use, copy, modify, merge, publish,
12
+* distribute, sublicense, and/or sell copies of the Software, and to
13
+* permit persons to whom the Software is furnished to do so, subject to
14
+* the following conditions:
15
+*
16
+* The above copyright notice and this permission notice shall be
17
+* included in all copies or substantial portions of the Software.
18
+*
19
+* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
20
+* EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
21
+* MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
22
+* NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE
23
+* LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION
24
+* OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
25
+* WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
26
+*/
27
+
28
+var GPSSensor = require('jsupm_ublox6');
29
+
30
+// Instantiate a Ublox6 GPS device on uart 0 (/dev/ttyS0).  This
31
+// works for the galileo G2.  
32
+
33
+// The Edison uses a different serial port, /dev/ttyMFD1, so if you
34
+// are using this example on an Edison board, specify the proper
35
+// port on the command line, eg: 'node ublox6.js /dev/ttyMFD1'
36
+// process.argv.length contains all command-line strings
37
+// argument 0 is "node"
38
+// argument 1 is "ublox6.js"
39
+// argument 2, if it exists, will be the override port,
40
+//    such as /dev/ttyMFD1 on Edison
41
+
42
+var defaultPort = "/dev/ttyS0";
43
+if (process.argv.length > 2)
44
+	defaultPort = process.argv[2];
45
+
46
+var myGPSSensor = new GPSSensor.Ublox6(0, defaultPort);
47
+
48
+if (!myGPSSensor.setupTty(GPSSensor.int_B9600))
49
+{
50
+	console.log("Failed to setup tty port parameters");
51
+	process.exit(0);
52
+}
53
+
54
+// Collect and output NMEA data.
55
+
56
+// This device also supports numerous configuration options, which
57
+// you can set with writeData().  Please refer to the Ublox-6 data
58
+// sheet for further information on the formats of the data sent and
59
+// received, and the various operating modes available.
60
+
61
+var bufferLength = 256;
62
+var nmeaBuffer  = new GPSSensor.charArray(bufferLength);
63
+
64
+function getGPSInfo()
65
+{
66
+	// we don't want the read to block in this example, so always
67
+	// check to see if data is available first.
68
+	if (myGPSSensor.dataAvailable())
69
+	{
70
+		var rv = myGPSSensor.readData(nmeaBuffer, bufferLength);
71
+
72
+		var GPSData, dataCharCode, isNewLine, lastNewLine;
73
+		var numlines= 0;
74
+		if (rv > 0)
75
+		{
76
+			GPSData = "";
77
+			// read only the number of characters
78
+			// specified by myGPSSensor.readData
79
+			for (var x = 0; x < rv; x++)
80
+				GPSData += nmeaBuffer.getitem(x);
81
+			process.stdout.write(GPSData)
82
+		}
83
+
84
+		if (rv < 0) // some sort of read error occured
85
+		{
86
+			console.log("Port read error.");
87
+			process.exit(0);
88
+		}
89
+	}
90
+}
91
+
92
+setInterval(getGPSInfo, 100);
93
+
94
+// Print message when exiting
95
+process.on('SIGINT', function()
96
+{
97
+	console.log("Exiting...");
98
+	process.exit(0);
99
+});

+ 107
- 0
examples/ublox6.cxx Ver fichero

@@ -0,0 +1,107 @@
1
+/*
2
+ * Author: Jon Trulson <jtrulson@ics.com>
3
+ * Copyright (c) 2014 Intel Corporation.
4
+ *
5
+ * Permission is hereby granted, free of charge, to any person obtaining
6
+ * a copy of this software and associated documentation files (the
7
+ * "Software"), to deal in the Software without restriction, including
8
+ * without limitation the rights to use, copy, modify, merge, publish,
9
+ * distribute, sublicense, and/or sell copies of the Software, and to
10
+ * permit persons to whom the Software is furnished to do so, subject to
11
+ * the following conditions:
12
+ *
13
+ * The above copyright notice and this permission notice shall be
14
+ * included in all copies or substantial portions of the Software.
15
+ *
16
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
17
+ * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
18
+ * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
19
+ * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE
20
+ * LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION
21
+ * OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
22
+ * WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
23
+ */
24
+
25
+#include <unistd.h>
26
+#include <iostream>
27
+#include <signal.h>
28
+#include "ublox6.h"
29
+
30
+using namespace std;
31
+
32
+bool shouldRun = true;
33
+
34
+void sig_handler(int signo)
35
+{
36
+  if (signo == SIGINT)
37
+    shouldRun = false;
38
+}
39
+
40
+const size_t bufferLength = 256;
41
+
42
+int main (int argc, char **argv)
43
+{
44
+  signal(SIGINT, sig_handler);
45
+
46
+//! [Interesting]
47
+  // Instantiate a Ublox6 GPS device on uart 0 (/dev/ttyS0).  This
48
+  // works for the galileo G2.  
49
+
50
+  // The Edison uses a different serial port, /dev/ttyMFD1, so if you
51
+  // are using this example on an Edison board, specify the proper
52
+  // port on the command line, eg: './ublox6-example /dev/ttyMFD1' 
53
+
54
+  const char *defaultPort = "/dev/ttyS0";
55
+  if (argc > 1)
56
+    defaultPort = argv[1];
57
+
58
+  upm::Ublox6* nmea = new upm::Ublox6(0, defaultPort);
59
+
60
+  // make sure port is initialized properly.  9600 baud is the default.
61
+  if (!nmea->setupTty(B9600))
62
+    {
63
+      cerr << "Failed to setup tty port parameters" << endl;
64
+      return 1;
65
+    }
66
+
67
+  // Collect and output NMEA data.  There are various libraries out on
68
+  // the Internet, such as tinyGPS or tinyGPS++ that can handle
69
+  // decoding NMEA data and presenting it in a more easily accessable
70
+  // format.  This example will just check for, and read raw NMEA data
71
+  // from the device and output it on stdout.
72
+
73
+  // This device also supports numerous configuration options, which
74
+  // you can set with writeData().  Please refer to the Ublox-6 data
75
+  // sheet for further information on the formats of the data sent and
76
+  // received, and the various operating modes available.
77
+
78
+  char nmeaBuffer[bufferLength];
79
+  while (shouldRun)
80
+    {
81
+      // we don't want the read to block in this example, so always
82
+      // check to see if data is available first.
83
+      if (nmea->dataAvailable())
84
+        {
85
+          int rv = nmea->readData(nmeaBuffer, bufferLength);
86
+
87
+          if (rv > 0)
88
+            write(1, nmeaBuffer, rv);
89
+
90
+          if (rv < 0) // some sort of read error occured
91
+            {
92
+              cerr << "Port read error." << endl;
93
+              break;
94
+            }
95
+
96
+          continue;
97
+        }
98
+
99
+      usleep(100000); // 100ms
100
+    }
101
+//! [Interesting]
102
+
103
+  cout << "Exiting..." << endl;
104
+
105
+  delete nmea;
106
+  return 0;
107
+}

+ 5
- 0
src/ublox6/CMakeLists.txt Ver fichero

@@ -0,0 +1,5 @@
1
+set (libname "ublox6")
2
+set (libdescription "upm u-blox 6 GPS UART support module")
3
+set (module_src ${libname}.cxx)
4
+set (module_h ${libname}.h)
5
+upm_module_init()

+ 13
- 0
src/ublox6/jsupm_ublox6.i Ver fichero

@@ -0,0 +1,13 @@
1
+%module jsupm_ublox6
2
+%include "../upm.i"
3
+%include "stdint.i"
4
+%include "carrays.i"
5
+
6
+%{
7
+    #include "ublox6.h"
8
+    speed_t int_B9600 = B9600;
9
+%}
10
+
11
+%include "ublox6.h"
12
+speed_t int_B9600 = B9600;
13
+%array_class(char, charArray);

+ 9
- 0
src/ublox6/pyupm_ublox6.i Ver fichero

@@ -0,0 +1,9 @@
1
+%module pyupm_ublox6
2
+%include "../upm.i"
3
+
4
+%feature("autodoc", "3");
5
+
6
+%include "ublox6.h"
7
+%{
8
+    #include "ublox6.h"
9
+%}

+ 140
- 0
src/ublox6/ublox6.cxx Ver fichero

@@ -0,0 +1,140 @@
1
+/*
2
+ * Author: Jon Trulson <jtrulson@ics.com>
3
+ * Copyright (c) 2014 Intel Corporation.
4
+ *
5
+ * Permission is hereby granted, free of charge, to any person obtaining
6
+ * a copy of this software and associated documentation files (the
7
+ * "Software"), to deal in the Software without restriction, including
8
+ * without limitation the rights to use, copy, modify, merge, publish,
9
+ * distribute, sublicense, and/or sell copies of the Software, and to
10
+ * permit persons to whom the Software is furnished to do so, subject to
11
+ * the following conditions:
12
+ *
13
+ * The above copyright notice and this permission notice shall be
14
+ * included in all copies or substantial portions of the Software.
15
+ *
16
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
17
+ * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
18
+ * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
19
+ * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE
20
+ * LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION
21
+ * OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
22
+ * WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
23
+ */
24
+
25
+#include <iostream>
26
+
27
+#include "ublox6.h"
28
+
29
+using namespace upm;
30
+using namespace std;
31
+
32
+Ublox6::Ublox6(int uart, const char *tty) :
33
+  m_ttyFd(-1)
34
+{
35
+  mraa_init();
36
+
37
+  if ( !(m_uart = mraa_uart_init(uart)) )
38
+    {
39
+      cerr << __FUNCTION__ << ": mraa_uart_init() failed" << endl;
40
+      return;
41
+    }
42
+
43
+  // now open the tty
44
+  if ( (m_ttyFd = open(tty, O_RDWR)) == -1)
45
+    {
46
+      cerr << __FUNCTION__ << ": open of " << tty << " failed: " 
47
+           << strerror(errno) << endl;
48
+      return;
49
+    }
50
+}
51
+
52
+Ublox6::~Ublox6()
53
+{
54
+  if (m_ttyFd != -1)
55
+    close(m_ttyFd);
56
+}
57
+
58
+bool Ublox6::dataAvailable()
59
+{
60
+  if (m_ttyFd == -1)
61
+    return false;
62
+
63
+  struct timeval timeout;
64
+
65
+  // no waiting
66
+  timeout.tv_sec = 0;
67
+  timeout.tv_usec = 0;
68
+
69
+  int nfds;  
70
+  fd_set readfds;
71
+
72
+  FD_ZERO(&readfds);
73
+
74
+  FD_SET(m_ttyFd, &readfds);
75
+  
76
+  if (select(m_ttyFd + 1, &readfds, NULL, NULL, &timeout) > 0)
77
+    return true;                // data is ready
78
+  else
79
+    return false;
80
+}
81
+
82
+int Ublox6::readData(char *buffer, size_t len)
83
+{
84
+  if (m_ttyFd == -1)
85
+    return(-1);
86
+
87
+  int rv = read(m_ttyFd, buffer, len);
88
+
89
+  if (rv < 0)
90
+    cerr << __FUNCTION__ << ": read failed: " << strerror(errno) << endl;
91
+
92
+  return rv;
93
+}
94
+
95
+int Ublox6::writeData(char * buffer, size_t len)
96
+{
97
+  if (m_ttyFd == -1)
98
+    return(-1);
99
+
100
+  int rv = write(m_ttyFd, buffer, len);
101
+
102
+  if (rv < 0)
103
+    {
104
+      cerr << __FUNCTION__ << ": write failed: " << strerror(errno) << endl;
105
+      return rv;
106
+    }
107
+
108
+  tcdrain(m_ttyFd);
109
+
110
+  return rv;
111
+}
112
+
113
+bool Ublox6::setupTty(speed_t baud)
114
+{
115
+  if (m_ttyFd == -1)
116
+    return(false);
117
+  
118
+  struct termios termio;
119
+
120
+  // get current modes
121
+  tcgetattr(m_ttyFd, &termio);
122
+
123
+  // setup for a 'raw' mode.  81N, no echo or special character
124
+  // handling, such as flow control.
125
+  cfmakeraw(&termio);
126
+
127
+  // set our baud rates
128
+  cfsetispeed(&termio, baud);
129
+  cfsetospeed(&termio, baud);
130
+
131
+  // make it so
132
+  int rv;
133
+  if ( (rv = tcsetattr(m_ttyFd, TCSAFLUSH, &termio)) < 0)
134
+    {
135
+      cerr << __FUNCTION__ << ": tcsetattr failed: " << strerror(errno) << endl;
136
+      return false;
137
+    }
138
+
139
+  return true;
140
+}

+ 117
- 0
src/ublox6/ublox6.h Ver fichero

@@ -0,0 +1,117 @@
1
+/*
2
+ * Author: Jon Trulson <jtrulson@ics.com>
3
+ * Copyright (c) 2014 Intel Corporation.
4
+ *
5
+ * Permission is hereby granted, free of charge, to any person obtaining
6
+ * a copy of this software and associated documentation files (the
7
+ * "Software"), to deal in the Software without restriction, including
8
+ * without limitation the rights to use, copy, modify, merge, publish,
9
+ * distribute, sublicense, and/or sell copies of the Software, and to
10
+ * permit persons to whom the Software is furnished to do so, subject to
11
+ * the following conditions:
12
+ *
13
+ * The above copyright notice and this permission notice shall be
14
+ * included in all copies or substantial portions of the Software.
15
+ *
16
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
17
+ * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
18
+ * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
19
+ * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE
20
+ * LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION
21
+ * OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
22
+ * WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
23
+ */
24
+#pragma once
25
+
26
+#include <string>
27
+#include <iostream>
28
+
29
+#include <stdint.h>
30
+#include <stdlib.h>
31
+#include <unistd.h>
32
+#include <string.h>
33
+#include <fcntl.h>
34
+#include <errno.h>
35
+#include <termios.h>
36
+#include <sys/time.h>
37
+#include <sys/select.h>
38
+#include <sys/types.h>
39
+#include <sys/stat.h>
40
+
41
+#include <mraa/uart.h>
42
+
43
+const int  UBLOX6_DEFAULT_UART = 0;
44
+
45
+namespace upm {
46
+
47
+  /**
48
+   * @brief C++ API for the U-BLOX 6 GPS module
49
+   *
50
+   * UPM support for the U-BLOX 6 GPS Module
51
+   *
52
+   * @ingroup grove uart
53
+   * @snippet ublox6.cxx Interesting
54
+   */
55
+  class Ublox6 {
56
+  public:
57
+    /**
58
+     * U-BLOX 6 GPS module constructor
59
+     *
60
+     * @param uart defualt uart to use (0 or 1)
61
+     * @param tty tty device to use
62
+     */
63
+    Ublox6(int uart, const char *tty);
64
+
65
+    /**
66
+     * U-BLOX 6 GPS module Destructor
67
+     */
68
+    ~Ublox6();
69
+
70
+    /**
71
+     * Check to see if there is data available for reading
72
+     *
73
+     * @return true if there is data available to be read
74
+     */
75
+    bool dataAvailable();
76
+
77
+    /**
78
+     * read any available data into a user-supplied buffer.  Note, the
79
+     * call will block until data is available to be read.  Use
80
+     * dataAvailable() to determine whether there is data available
81
+     * beforehand, to avoid blocking.
82
+     *
83
+     * @param buffer the buffer to hold the data read
84
+     * @param len the length of the buffer
85
+     * @return the number of bytes read
86
+     */
87
+    int readData(char *buffer, size_t len);
88
+
89
+    /**
90
+     * write the data in buffer to the device
91
+     *
92
+     * @param buffer the buffer to hold the data read
93
+     * @param len the length of the buffer
94
+     * @return the number of bytes written
95
+     */
96
+    int writeData(char *buffer, size_t len);
97
+
98
+    /**
99
+     * setup the proper tty i/o modes and the baudrate.  The default
100
+     * baud rate is 9600 (B9600).
101
+     *
102
+     * @param baud the desired baud rate.  
103
+     * @return true if successful
104
+     */
105
+    bool setupTty(speed_t baud=B9600);
106
+
107
+  protected:
108
+    int ttyFd() { return m_ttyFd; };
109
+    int setTtyFd(int fd) { m_ttyFd = fd; };
110
+
111
+  private:
112
+    mraa_uart_context m_uart;
113
+    int m_ttyFd;
114
+  };
115
+}
116
+
117
+