Adafruit Ultimate GPS Logger Shield on Arduino Mega

For other supported Arduino products from Adafruit: Shields, accessories, etc.

Moderators: adafruit_support_bill, adafruit

Please be positive and constructive with your questions and comments.
Locked
User avatar
michael chang
 
Posts: 36
Joined: Thu Jul 25, 2013 12:20 pm

Adafruit Ultimate GPS Logger Shield on Arduino Mega

Post by michael chang »

Hello all,

I have questions about using the Ultimate GPS Logger Shield on the Arduino Mega.

(1) Does the Adafruit library support the shield on Mega?
(2) Can other sensor wired on the shield log its dataset to the SD card?
(3) It seems like the shield come with the on-board RTC chip. It that correct?

Thanks,
Michael

User avatar
adafruit_support_rick
 
Posts: 35092
Joined: Tue Mar 15, 2011 11:42 am

Re: Adafruit Ultimate GPS Logger Shield on Arduino Mega

Post by adafruit_support_rick »

Yes, it will work with the Mega. You need to solder closed the SPI jumpers on the back of the shield.

Yes, it has an RTC

You can read the a sensor and write the data to SD.

User avatar
michael chang
 
Posts: 36
Joined: Thu Jul 25, 2013 12:20 pm

Re: Adafruit Ultimate GPS Logger Shield on Arduino Mega

Post by michael chang »

A further confirmation: does it and its library work on the Due board?

The product page indicates that "Assembled & tested shield for Arduino Uno/Duemilanove/Diecimila/Leonardo (not for use with Mega/ADK/Due)"


Thanks a lot.

User avatar
adafruit_support_rick
 
Posts: 35092
Joined: Tue Mar 15, 2011 11:42 am

Re: Adafruit Ultimate GPS Logger Shield on Arduino Mega

Post by adafruit_support_rick »

Oh, no! I gave you the wrong information!

I was thinking about the Logger Shield, not the *GPS* logger shield. Sorry!

You can make the actual GPS work on a Due or Mega, but the SD won't work. You need to connect to the ICSP header for SPI, and the GPS logger shield does not have an ICSP socket.

The RTC will work on the Mega. The RTC library needs a slight modification to work on the Due.

Again, I apologize for the wrong information. :(

User avatar
michael chang
 
Posts: 36
Joined: Thu Jul 25, 2013 12:20 pm

Re: Adafruit Ultimate GPS Logger Shield on Arduino Mega

Post by michael chang »

Thanks. I actually learn a lot from asking questions.

Could you please take a look this: http://www.instructables.com/id/Persona ... GPS-Shiel/

Is it something doable in order to make RTC, GPS and SD work on the Maga board?

Any suggestions? My main purpose is that I need the Mega for my project, but I also need to recored RTC, GPS and a data logger to record the time, location and sensor datasets.

User avatar
adafruit_support_rick
 
Posts: 35092
Joined: Tue Mar 15, 2011 11:42 am

Re: Adafruit Ultimate GPS Logger Shield on Arduino Mega

Post by adafruit_support_rick »

So, what that is doing is jumpering the GPS RX and TX pins to Serial1 on the Mega. This change to the sketch reflects that:
Then simply comment out:
//SoftwareSerial mySerial(8, 7);
And add:
HardwareSerial mySerial = Serial1;
Serial1 refers to TX1 and RX1
The other thing it's doing is to use software SPI for the SD card. The Adafruit fork of the SD library supports software SPI, but the official Arduino SD library does not. The problem is that the Adafruit SD library is very old, and hasn't kept up with the latest Arduino SD.
The adafruit library is here:
https://github.com/adafruit/SD
The Arduino SD library is built into Arduino

You can still use the Adafruit SD, but I recommend using the latest Arduino SD library instead. That means that you have to also jumper the CLK, DI, and DO pads over to the mega's SPI pins. CLK goes to pin 52, DI goes to 51, and DO goes to 50.
If you use the Arduino SD, use this for SD.begin:

Code: Select all

    if (!SD.begin(chipSelect)) {      // use hardware SPI 
Make sure chipSelect is #defined as 10.

User avatar
michael chang
 
Posts: 36
Joined: Thu Jul 25, 2013 12:20 pm

Re: Adafruit Ultimate GPS Logger Shield on Arduino Mega

Post by michael chang »

Hello -

I got the parts and put them altogether.

I followed instructions and here is what I did:

(1) stacking GPS logger shield on Mega.
(2) jumping these pins:
GPS RX --> MEGA TX1
GPS TX --> MEGA RX1
GPS CLK --> MEGA 52 SCK
GPS DI --> MEGA 51 MOSI
GPS DO --> MEGA 50 MISO
(3) modified these two line code:

HardwareSerial mySerial = Serial1;

if (!SD.begin(10)) {

(4) compile and upload the code to MEGA


I got the error message showing that "Card init. failed!"

Do I miss anything here?


Please help.

User avatar
adafruit_support_rick
 
Posts: 35092
Joined: Tue Mar 15, 2011 11:42 am

Re: Adafruit Ultimate GPS Logger Shield on Arduino Mega

Post by adafruit_support_rick »

Well, that should work.

Can you post some pictures showing your soldering and wiring?
Do you have a different SD card you can try? Are you sure the SD card is inserted and seated properly?

User avatar
michael chang
 
Posts: 36
Joined: Thu Jul 25, 2013 12:20 pm

Re: Adafruit Ultimate GPS Logger Shield on Arduino Mega

Post by michael chang »

Hello -

I went back to use the Adafruit SD library. Now, it's working.

Please see attached code.

Code: Select all

#include <SPI.h>
#include <Adafruit_GPS.h>
#include <SoftwareSerial.h>
// #include <SD.h>
#include <SDADA.h>
#include <avr/sleep.h>

// Connect to the GPS on the hardware port     
#define GPSSerial Serial1
Adafruit_GPS GPS(&GPSSerial);
     
// Set GPSECHO to 'false' to turn off echoing the GPS data to the Serial console
// Set to 'true' if you want to debug and listen to the raw GPS sentences
#define GPSECHO false

// This keeps track of whether we're using the interrupt off by default!
boolean usingInterrupt = false;
void useInterrupt(boolean);


// Set Adafruit SD Card pin
#define chipSelect 10

File logfile;

uint32_t timer = millis();


void setup()
{  
  Serial.begin(115200);
  pinMode(chipSelect, OUTPUT);
  SD.begin(chipSelect, 11, 12, 13);

  char filename[15];
  strcpy(filename, "GPSLOG00.csv");
  for (uint8_t i = 0; i < 100; i++) {
    filename[6] = '0' + i/10;
    filename[7] = '0' + i%10;
    if (! SD.exists(filename)) {
      break;
    }
  }
  
  logfile = SD.open(filename, FILE_WRITE);
  
     
  // 9600 NMEA is the default baud rate for Adafruit MTK GPS's- some use 4800
  GPS.begin(9600);
  // uncomment this line to turn on RMC (recommended minimum) and GGA (fix data) including altitude
  GPS.sendCommand(PMTK_SET_NMEA_OUTPUT_RMCGGA);
  // uncomment this line to turn on only the "minimum recommended" data
  //GPS.sendCommand(PMTK_SET_NMEA_OUTPUT_RMCONLY);
  // For parsing data, we don't suggest using anything but either RMC only or RMC+GGA since
  // the parser doesn't care about other sentences at this time
  // Set the update rate
  GPS.sendCommand(PMTK_SET_NMEA_UPDATE_10HZ); // 1 Hz update rate
  // For the parsing code to work nicely and have time to sort thru the data, and
  // print it out we don't suggest using anything higher than 1 Hz
     
  // Request updates on antenna status, comment out to keep quiet
  GPS.sendCommand(PGCMD_ANTENNA);

  // the nice thing about this code is you can have a timer0 interrupt go off
  // every 1 millisecond, and read data from the GPS for you. that makes the
  // loop code a heck of a lot easier!
  useInterrupt(true);  
}


// Interrupt is called once a millisecond, looks for any new GPS data, and stores it
SIGNAL(TIMER0_COMPA_vect) {
  char c = GPS.read();
}

void useInterrupt(boolean v) {
  if (v) {
    // Timer0 is already used for millis() - we'll just interrupt somewhere
    // in the middle and call the "Compare A" function above
    OCR0A = 0xAF;
    TIMSK0 |= _BV(OCIE0A);
    usingInterrupt = true;
  } 
  else {
    // do not call the interrupt function COMPA anymore
    TIMSK0 &= ~_BV(OCIE0A);
    usingInterrupt = false;
  }
}

void loop(){
  if (! usingInterrupt) {
  // read data from the GPS in the 'main loop'
  char c = GPS.read();
  }
  // if a sentence is received, we can check the checksum, parse it...
  if (GPS.newNMEAreceived()) {
    // a tricky thing here is if we print the NMEA sentence, or data
    // we end up not listening and catching other sentences!
    // so be very wary if using OUTPUT_ALLDATA and trytng to print out data
    Serial.println(GPS.lastNMEA()); // this also sets the newNMEAreceived() flag to false
    if (!GPS.parse(GPS.lastNMEA())) // this also sets the newNMEAreceived() flag to false
      return; // we can fail to parse a sentence in which case we should just wait for another
  }
  
  // if millis() or timer wraps around, we'll just reset it
  if (timer > millis()) timer = millis();
     
  // approximately every 2 seconds or so, print out the current stats
  if (millis() - timer > 100) {
    timer = millis(); // reset the timer
    logfile.print((int)GPS.fix);    
    logfile.print(", ");
    logfile.print(GPS.hour, DEC); logfile.print(':');
    logfile.print(GPS.minute, DEC); logfile.print(':');
    logfile.print(GPS.seconds, DEC); logfile.print('.');
    logfile.print(GPS.milliseconds);
    logfile.print(", ");
    logfile.print(GPS.day, DEC); logfile.print('/');
    logfile.print(GPS.month, DEC); logfile.print("/20");
    logfile.print(GPS.year, DEC);
    logfile.print(", ");      
    logfile.print(GPS.latitude, 4); logfile.print(GPS.lat);
    logfile.print(", ");
    logfile.print(GPS.longitude, 4); logfile.print(GPS.lon);
    logfile.print(", ");    
    logfile.print((int)GPS.fix);
    logfile.print(", ");    
    logfile.print((int)GPS.fixquality);
    logfile.print(", "); 
    logfile.println((int)GPS.satellites);      
    logfile.flush();
  }
}

Here is a part of the output. I noticed that the column of printing out time is still bit off.

Code: Select all

1	 15:42:20.0	 21/7/2017	 4331.6821N	 8013.6313W	1	1	6
1	 15:42:20.0	 21/7/2017	 4331.6821N	 8013.6313W	1	1	6
1	 15:42:20.0	 21/7/2017	 4331.6821N	 8013.6313W	1	1	6
1	 15:42:20.0	 21/7/2017	 4331.6821N	 8013.6313W	1	1	6
1	 15:42:20.0	 21/7/2017	 4331.6821N	 8013.6313W	1	1	6
1	 15:42:20.0	 21/7/2017	 4331.6821N	 8013.6313W	1	1	6
1	 15:42:20.0	 21/7/2017	 4331.6821N	 8013.6313W	1	1	6
1	 15:42:20.0	 21/7/2017	 4331.6821N	 8013.6313W	1	1	6
1	 15:42:20.0	 21/7/2017	 4331.6821N	 8013.6313W	1	1	6
1	 15:42:20.984	 21/7/2017	 4331.6816N	 8013.6293W	1	1	7
1	 15:42:20.984	 21/7/2017	 4331.6816N	 8013.6293W	1	1	7
1	 15:42:20.984	 21/7/2017	 4331.6816N	 8013.6293W	1	1	7
1	 15:42:20.984	 21/7/2017	 4331.6816N	 8013.6293W	1	1	7
1	 15:42:20.984	 21/7/2017	 4331.6816N	 8013.6293W	1	1	7
1	 15:42:20.984	 21/7/2017	 4331.6816N	 8013.6293W	1	1	7
1	 15:42:20.984	 21/7/2017	 4331.6816N	 8013.6293W	1	1	7
1	 15:42:20.984	 21/7/2017	 4331.6816N	 8013.6293W	1	1	7
1	 15:42:20.984	 21/7/2017	 4331.6816N	 8013.6293W	1	1	7
1	 15:42:20.984	 21/7/2017	 4331.6816N	 8013.6293W	1	1	7
For example, it should show "15:42:21.000" instead of " 15:42:20.984".

How can I resolve this issue?


Thanks again.

User avatar
adafruit_support_rick
 
Posts: 35092
Joined: Tue Mar 15, 2011 11:42 am

Re: Adafruit Ultimate GPS Logger Shield on Arduino Mega

Post by adafruit_support_rick »

Well, I'm glad to hear it's working. Although it should have worked with the Arduino SD library. Odd.

Arduino does not do print formatting very well. There's no way to tell it to pad out an integer with leading zeros. There are a couple of ways you can do it.
You could write a small function, let's call it padZero. It will take an integer argument of the value to be printed, and it will take an argument of the number of places in the format.
It will explicitly print the leading zeros. Haven't actually tried this, but I think it should work

Code: Select all

void padZero(int value, int places)
{
  int placeValue = 1;

  for (int i = 0; i < places-1; i++)
    placeValue = placeValue * 10;

  while (value < placeValue)
  {
    logFile.print("0");
    placeValue = placeValue / 10);
  }
  if (value > 0)
    logFile.print(value);
}
You would substitute padZero for logFile.print:

Code: Select all

    padZero(GPS.hour, 2); logfile.print(':');
    padZero(GPS.minute, 2); logfile.print(':');
    padZero(GPS.seconds, 2); logfile.print('.');
    padZero(GPS.milliseconds, 3);
    padZero(GPS.day, 2); logfile.print('/');
    padZero(GPS.month, 2); logfile.print("/20");
    padZero(GPS.year, 2);
. . .
    padZero(GPS.satellites, 2);
    logFile.println();

The other way is to use the snprintf function. You could do the entire output string with sprintf

Code: Select all

char buffer[80];
 snprintf(buffer, 79, "%1d     %02d:%02d:%02d.%03d         %02d/%02d/20%02d     %9.4f%c      %10.4f%c    %d    %d    %02d\r\n", GPS.fix, GPS.hour, GPS.minute, GPS.seconds, GPS.milliseconds, GPS.day, GPS.month, GPS.year, GPS.latitude, GPS.lat, GPS.longitude, GPS.lon, GPS.fix, GPS.fixquality, GPS.satellites);
  logFile.print(buffer);
snprintf documentation:
http://www.cplusplus.com/reference/cstdio/snprintf/

User avatar
C_3PO
 
Posts: 1
Joined: Tue Jan 23, 2018 5:38 am

Re: Adafruit Ultimate GPS Logger Shield on Arduino Mega

Post by C_3PO »

I have spent 2 weeks trying so many combinations of connections/ code/libraries I have lost the plot!

I have Mega R2 and cannot get the SD card on the GPS logger shield to work at all with the Mega R2! (GPS function works just fine)

The shield works fine on an UNO so I know card etc are OK

I have tried the SD and Adafruit SD library

I have edited library files to use soft SPI

I have Googled to death looking for a solution.

I have used jumpers to hardware SPI on Mega

The shield work fine on an UNO so I know card etc are OK

I must be doing something so obviusly wrong - but I just can't see it

Please could you identify what libraries/code/connections to use - the shield I have is new - date on package 2017-12-05

Please save my sanity - thank you in advance

Locked
Please be positive and constructive with your questions and comments.

Return to “Other Arduino products from Adafruit”