In the previous article, I explained how to use your Arduino to read GPS data from a u-blox 6 GPS, and visualize it on the PC using serial communication.
In this article, I will show you how to log the GPS data on an SD card, inside Arduino Ethernet, and then export it to your PC using serial communication. After exporting the binary file to the PC, it is possible to convert it to a CSV file and visualize it in Excel. It is also possible to analyze the data using more advanced tools such as Matlab, and so on. The complete Arduino sketch code can be downloaded here: GPS_serial_test GPS_serial_v2_20160402.
As explained in the u-blox6 Receiver Description Protocol Specification official guide, it is possible to use the proprietary UBX protocol to read ECEF position (X, Y, Z position in cm), time and speed (X, Y, Z speed in cm/s). I used the service NAV-SOL (0x01 0x06) for this purpose. The payload of this message is quite big (52 bytes) but it contains a lot of useful data. By using the Tempo library (tempo_library_v1) which I made for Arduino, I managed to poll this message once a second (the time can be calibrated), and log the messages on the Arduino Ethernet SD Card (file "capture.log").
In order to be able to send and receive correctly the UBX messages, I implemented a checksum check as below.
1 2 3 4 5 6 7 8 9 10 |
// CALCULATES THE UBX CHECKSUM OF A CHAR ARRAY void UBX_calculate_checksum(uint8_t* array, unsigned int array_start, unsigned int array_length){ CK_A = 0; CK_B = 0; unsigned int i; for (i=0;i<array_length;i++){ CK_A = CK_A + array[array_start+i]; CK_B = CK_B + CK_A; } } |
The following code parses the data received from the GPS (UBX 0x01 0x06 message).
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 |
// PARSES THE 0x01 0x06 MESSAGE RECEIVED FROM GPS void NAV_SOL_message_parse(){ time_GPS_recv = millis(); // records message receiving time GPS_recv_buffer[GPS_recv_char_count]=(byte)(time_GPS_recv & 0xff); // Little Endian LSB GPS_recv_buffer[GPS_recv_char_count+1]=(byte)((time_GPS_recv >> 8) & 0xff); GPS_recv_buffer[GPS_recv_char_count+2]=(byte)((time_GPS_recv >> 16) & 0xff); GPS_recv_buffer[GPS_recv_char_count+3]=(byte)((time_GPS_recv >> 24) & 0xff); // Little Endian MSB File dataFile = SD.open("capture.log", FILE_WRITE); // opens the SD card file if (dataFile) { dataFile.write(GPS_recv_buffer, GPS_recv_char_count+4); // logs data to the SD card dataFile.close(); // closes the SD card file } // SHOWS WRITTEN DATA ON THE PC TERMINAL (in case flag is enabled) if (gateway_enable == true){ // forwards the message to PC unsigned int i; for (i=0; i<GPS_recv_char_count+4; i++){ // 64 characters in total (including reception time stamp, 4 bytes) Serial.write(GPS_recv_buffer[i]); // writes the message to the PC once it has been completely received } } } |
After logging the file, it is possible to transfer the content to the PC by removing the SD card and connecting it to the PC. Since this procedure is troublesome if you want to transfer the files many times, I also implemented a part of software (on both Arduino and PC) which handles the file transfer via Serial.
The file transfer to the PC via Serial (57600 bps) requires a long time (10.9 seconds for 13696 bytes) due to the fact that the Arduino has to read data from the SD before sending it to the PC.
Finally, the binary data is converted from binary format to a CSV file, which can be opened using Excel. The important info which are included in the NAV-SOL (0x01 0x06) message payload is the following:
- iTOW: GPS Millisecond Time of Week (ms)
- fTOW: Fractional Nanoseconds remainder (ns)
- week: GPS week (GPS time)
- ecefX, ecefY, ecefZ: ECEF X Y Z coordinates (cm)
- pAcc: 3D position accuracy estimate (cm)
- ecefVX, ecefVY, ecefVZ: ECEF X Y Z velocity (cm/s)
- sAcc: Speed Accuracy Estimate
Hi Davide,
I am testing a ublox NEO M8P with teh above GPS_serial example however i am getting a compile error "In function 'void PC_message_parse()':
GPS_serial:80: error: 'class Tempo' has no member named 'reset'
Timer1.reset();
I had a look in the header files for the tempo library and there is no function reset() in the tempo class.
Is there a work around for this?
Any help is much appreciated.