This class provides an API to communicate with a u-blox GNSS chip. The files here were originally part of the C027_Support library (https://developer.mbed.org/teams/ublox/code/C027_Support/ at revision 138:dafbbf31bf76) but have been separated out, primarily for use on the u-blox C030 board where the cellular interace portion of the C027_Support library will instead be provided through the new mbed Cellular API.
Dependents: example-ublox-at-cellular-interface-ext example-low-power-sleep example-C030-out-of-box-demo example-C030-out-of-box-demo ... more
main.cpp
00001 #include "mbed.h" 00002 #include "greentea-client/test_env.h" 00003 #include "unity.h" 00004 #include "utest.h" 00005 #include "gnss.h" 00006 00007 using namespace utest::v1; 00008 00009 // ---------------------------------------------------------------- 00010 // COMPILE-TIME MACROS 00011 // ---------------------------------------------------------------- 00012 00013 // How long to wait for a GNSS result 00014 #define GNSS_WAIT_SECONDS 120 00015 00016 // ---------------------------------------------------------------- 00017 // PRIVATE VARIABLES 00018 // ---------------------------------------------------------------- 00019 00020 // ---------------------------------------------------------------- 00021 // PRIVATE FUNCTIONS 00022 // ---------------------------------------------------------------- 00023 00024 static void printHex (char * pData, uint32_t lenData) 00025 { 00026 char * pEnd = pData + lenData; 00027 uint8_t x; 00028 00029 printf (" 0 1 2 3 4 5 6 7 8 9 A B C D E F\n"); 00030 while (pData < pEnd) { 00031 for (x = 1; (x <= 32) && (pData < pEnd); x++) { 00032 if (x % 16 == 8) { 00033 printf ("%02x ", *pData); 00034 } else if (x % 16 == 0) { 00035 printf ("%02x\n", *pData); 00036 } else { 00037 printf ("%02x-", *pData); 00038 } 00039 pData++; 00040 } 00041 00042 00043 if (x % 16 != 1) { 00044 printf("\n"); 00045 } 00046 } 00047 } 00048 00049 // ---------------------------------------------------------------- 00050 // TESTS 00051 // ---------------------------------------------------------------- 00052 00053 // Test sending a u-blox command over serial 00054 void test_serial_ubx() { 00055 char buffer[64]; 00056 int responseLength = 0; 00057 int returnCode; 00058 bool gotAck = false; 00059 Timer timer; 00060 00061 GnssSerial *pGnss = new GnssSerial(); 00062 00063 // Initialise the GNSS chip 00064 pGnss->init(NC); 00065 00066 // Try this a few times as we might get no response 00067 // if the GNSS chip is busy 00068 for (int x = 0; (x < 3) && !gotAck; x++) { 00069 // See ublox7-V14_ReceiverDescrProtSpec section 30.11.15 (CFG-NAV5) 00070 // Set automotive mode, which should be acknowledged 00071 memset (buffer, 0, sizeof (buffer)); 00072 buffer[0] = 0x00; 00073 buffer[1] = 0x01; // Mask: set dynamic config only 00074 buffer[2] = 0x04; // Dynamic platform model: automotive 00075 // Send length is 32 bytes of payload + 6 bytes header + 2 bytes CRC 00076 TEST_ASSERT_EQUAL_INT (40, pGnss->sendUbx(0x06, 0x24, buffer, 32)); 00077 printf ("CFG_NAV5 command sent, try %d.\n", x); 00078 timer.start(); 00079 while ((!gotAck) && (timer.read_ms() < 1000)) { 00080 // Wait for the required Ack 00081 returnCode = pGnss->getMessage(buffer, sizeof(buffer)); 00082 if ((returnCode != GnssSerial::WAIT) && (returnCode != GnssSerial::NOT_FOUND)) { 00083 responseLength = LENGTH(returnCode); 00084 if ((PROTOCOL(returnCode) == GnssSerial::UBX)) { 00085 printHex(buffer, responseLength); 00086 // Ack is 0xb5-62-05-00-02-00-msgclass-msgid-crcA-crcB 00087 // Nack is 0xb5-62-05-01-02-00-msgclass-msgid-crcA-crcB 00088 TEST_ASSERT_EQUAL_UINT8(0xb5, buffer[0]); 00089 TEST_ASSERT_EQUAL_UINT8(0x62, buffer[1]); 00090 TEST_ASSERT_EQUAL_UINT8(0x05, buffer[2]); 00091 TEST_ASSERT_EQUAL_UINT8(0x00, buffer[3]); 00092 TEST_ASSERT_EQUAL_UINT8(0x02, buffer[4]); 00093 TEST_ASSERT_EQUAL_UINT8(0x00, buffer[5]); 00094 TEST_ASSERT_EQUAL_UINT8(0x06, buffer[6]); 00095 TEST_ASSERT_EQUAL_UINT8(0x24, buffer[7]); 00096 gotAck = true; 00097 } else if ((PROTOCOL(returnCode) == GnssSerial::NMEA)) { 00098 printf ("%.*s", responseLength, buffer); 00099 } else { 00100 printHex(buffer, responseLength); 00101 } 00102 } 00103 wait_ms (100); 00104 } 00105 timer.stop(); 00106 timer.reset(); 00107 } 00108 } 00109 00110 // Test getting a response from GNSS using the serial interface 00111 void test_serial_time() { 00112 GnssSerial *pGnss = new GnssSerial(); 00113 00114 bool gotLatLong = false; 00115 bool gotElevation = false; 00116 bool gotSpeed = false; 00117 bool gotTime = false; 00118 char buffer[256]; 00119 int returnCode; 00120 double latitude; 00121 double longitude; 00122 double elevation; 00123 double speed; 00124 00125 printf("GNSS: powering up and waiting up to %d second(s) for something to happen.\n", GNSS_WAIT_SECONDS); 00126 pGnss->init(); 00127 00128 memset(buffer, 0, sizeof(buffer)); 00129 for (uint32_t x = 0; (x < GNSS_WAIT_SECONDS) && !gotTime; x++) 00130 { 00131 while (((returnCode = pGnss->getMessage(buffer, sizeof(buffer))) > 0) && 00132 !(gotLatLong && gotElevation && gotSpeed && gotTime)) 00133 { 00134 int32_t length = LENGTH(returnCode); 00135 00136 if ((PROTOCOL(returnCode) == GnssParser::NMEA) && (length > 6)) 00137 { 00138 printf("."); 00139 00140 // talker is $GA=Galileo $GB=Beidou $GL=Glonass $GN=Combined $GP=GNSS 00141 if ((buffer[0] == '$') || buffer[1] == 'G') 00142 { 00143 #define _CHECK_TALKER(s) ((buffer[3] == s[0]) && (buffer[4] == s[1]) && (buffer[5] == s[2])) 00144 if (_CHECK_TALKER("GLL")) 00145 { 00146 char ch; 00147 00148 if (pGnss->getNmeaAngle(1, buffer, length, latitude) && 00149 pGnss->getNmeaAngle(3, buffer, length, longitude) && 00150 pGnss->getNmeaItem(6, buffer, length, ch) && 00151 ch == 'A') 00152 { 00153 gotLatLong = true; 00154 latitude *= 60000; 00155 longitude *= 60000; 00156 printf("\nGNSS: location %.5f %.5f %c.\n", latitude, longitude, ch); 00157 } 00158 } 00159 else if (_CHECK_TALKER("GGA") || _CHECK_TALKER("GNS")) 00160 { 00161 const char *pTimeString = NULL; 00162 00163 // Retrieve the time 00164 pTimeString = pGnss->findNmeaItemPos(1, buffer, buffer + length); 00165 if (pTimeString != NULL) 00166 { 00167 gotTime = true; 00168 printf("\nGNSS: time is %.6s.", pTimeString); 00169 } 00170 00171 if (pGnss->getNmeaItem(9, buffer, length, elevation)) // altitude msl [m] 00172 { 00173 gotElevation = true; 00174 printf("\nGNSS: elevation: %.1f.", elevation); 00175 } 00176 } 00177 else if (_CHECK_TALKER("VTG")) 00178 { 00179 if (pGnss->getNmeaItem(7, buffer, length, speed)) // speed [km/h] 00180 { 00181 gotSpeed = true; 00182 printf("\nGNSS: speed: %.1f.", speed); 00183 } 00184 } 00185 } 00186 } 00187 } 00188 00189 wait_ms(1000); 00190 } 00191 00192 printf("\n"); 00193 00194 // Depending on antenna positioning we may not be able to get a GNSS fix but we 00195 // should at least be able to receive the time from a satellite 00196 TEST_ASSERT(gotTime); 00197 } 00198 00199 // ---------------------------------------------------------------- 00200 // TEST ENVIRONMENT 00201 // ---------------------------------------------------------------- 00202 00203 // Setup the test environment 00204 utest::v1::status_t test_setup(const size_t number_of_cases) { 00205 // Setup Greentea with a timeout 00206 GREENTEA_SETUP(120, "default_auto"); 00207 return verbose_test_setup_handler(number_of_cases); 00208 } 00209 00210 // Test cases 00211 Case cases[] = { 00212 Case("Ubx command", test_serial_ubx), 00213 Case("Get time", test_serial_time), 00214 }; 00215 00216 Specification specification(test_setup, cases); 00217 00218 // ---------------------------------------------------------------- 00219 // MAIN 00220 // ---------------------------------------------------------------- 00221 00222 int main() { 00223 00224 return !Harness::run(specification); 00225 } 00226 00227 // End Of File
Generated on Tue Jul 12 2022 14:18:20 by 1.7.2