I recently purchased one of those U-blox GPS modules from Ebay for $20 and after downloading the TinyGPS library for the Arduino, it works well once it has valid GPS data (I had to have mine close to the window) plus there’s an LED on the module itself which blinks every second to tell you this, it’s set to 1 PPS by default.
The GPS module outputs it’s data in NMEA format which starts off with a $ dollar sign, has commas in-between values and ends with a line break. At the moment I’m only interested in the longitude and latitude which is in the GPRMC line. My GPS gave 10 bytes for the latitude and 11 bytes for the longitude. If you were travelling all over the world, it’s important to note the N(and S) and W (and E) which indicate whether the number should be positive or negative relative to the equator and prime meridian respectively.
It’s time to compact the size from the Arduino to the ATtiny2313A as it has USART which we’ve used before for sending, receiving is very similar. All we have to do is connect the GPS’s TX to the ATtiny RX, just listen for incoming data, parse that and then I’m logging this to an I2C EEPROM. I’m using a 3.7V Li-poly to power it.
.
The Code
uint8_t rxData = USART_Receive(); if (rxData == '$') { // Start of frame read_usart_to_comma(); // Read next chars // Check if GPRMC if (memcmp(tempBuffer, "GPRMC", 5) == 0) { read_usart_to_comma(); // Timestamp (ignore) read_usart_to_comma(); // Validity // If valid GPS data if (tempBuffer[0] == 'A') { if (gpsLogdelaycounter >= gpsLogdelay && dataCount < (EEPROM_END_ADDR - GPS_LONG_LAT_SIZE)) { uint8_t bytesReadLatitude = read_usart_to_comma(); // Latitude memcpy(gpsLatitude, tempBuffer, bytesReadLatitude); read_usart_to_comma(); // N or S (ignore because I know what it's going to be, you should check this) uint8_t bytesReadLongitude = read_usart_to_comma(); // Longitude memcpy(gpsLongitude, tempBuffer, bytesReadLongitude); // Write to I2C EEPROM for (int z = 0; z < bytesReadLatitude; z++) { //USART_Transmit(gpsLatitude[z]); soft_i2c_eeprom_write_byte(EEPROM_ADDR, dataCount, gpsLatitude[z]); dataCount++; } for (int z = 0; z < bytesReadLongitude; z++) { //USART_Transmit(gpsLongitude[z]); soft_i2c_eeprom_write_byte(EEPROM_ADDR, dataCount, gpsLongitude[z]); dataCount++; } gpsLogdelaycounter = 0; } else { gpsLogdelaycounter++; }
We firstly wait for the $ dollar sign and then read the next 5 characters after that. If they match “GPRMC” then we read the timestamp, ignore it and then look at the validity of the GPS data to see if it has GPS “lock”. Next I added in a GPS log delay, basically because I don’t need to log the GPS at the 1 PPS rate, so we can log every 2nd, 3rd, etc PPS as suits. If the GPS has lock, then we read out the latitude, ignore the N/S bearing and read out the longitude then write both of these on the EEPROM. As you can see I’m not checking the checksum and not doing much else with the data, download ATtiny_GPS_LongLat_Logger_v0.1
.
Using the logged data
In order to produce the longitude and latitude which we can use on Google maps, you have to convert the NMEA data to decimal by taking the 2 digits before the decimal point along with the digits after it and divide that by 60 and then add the number that we didn’t use to it. For example for 2415.18575, we take 15.18575 and divide by 60 to give 0.25309583 and then add the 24 back on to it to give 24.25309583.
The way I’m doing this all is a bit long and could be improved, I’m just using an Arduino sketch to read and print the EEPROM data (Download i2c_read_eeprom) to the serial monitor. I copy that data and save to a file then I run my C parsing program to change it into decimal and format it for us (Download parse_gps_longlat). If you don’t mind using more space, you could do all this conversion on the ATtiny which is what I’ll need to do in the future.
Once we have the decimal data, we can use GPS Visualiser to plot this on Google maps. I struggled trying to figure out how to connect one point to another, but it turns out that you shouldn’t include any “name” or other fields apart from the longitude and latitude.
Just paste in the output to the text box, hit draw the map and you’ll get the above points connected together, it works well.
My idea for this module in the future is to be placed in a car, have an accelerometer to detect car movement, activates the GPS and if it’s reached a certain area, it will send an SMS to you, but that will come together later.
[…] had previous experience with his GPS logger, so recently he decided to build another project called GPS alerter which would send SMS when […]