New GPS + Datalogger Shield uses D0 and D1 to communicate with uBlox 6M

I purchased this new GPS Shield with SD data logger from a Chinese distributor on eBay.

The shield arrived with no instructions however, the vendor did email me a datasheet for the uBlox 6M and some example code from ladyada which used pins D2 and D3 to communicate using SoftwareSerial.h, so that example didn’t work. There is no manufacturer indicated on the shield pcb. The only screen print is on the bottom that says “GPS Shield for Arduino V 2.0” See attached photo. I have studied the traces on the pcb and the TX and RX from the uBlox M6 connect correctly to the RX and TX pins on the Arduino UNO I am using. I can load a sketch which has formatted output to the serial monitor and that part of the sketch works. However, I get error messages that the Arduino fails to sync with the uBlox 6M.
The board has a set of pins which appear to require jumpers to enable or disable interrupt0 and interrupt1.

Does anyone have experience with this shield?
Does anyone have instructions, a working sketch?

“eschew obfuscation”

GPS Shield.jpg

GPSLOG3.pdf (709 KB)

UPDATE: I found a photo from one of the distributers of this shield that indicates the shield is not “stackable”. The distributer also provided an example sketch that directs GPS TX to Arduino D2 and connects power from the Arduino 5V and Ground to the Shield 5V and Ground with jumpers. I connected a jumper to Arduino D3 to the GPS Shield RX and jumpers between D10, D11, D12, and D13, respectively and ran a sketch called “GPS_datalogger”. The setup worked. At startup, the sketch did not recognize the SD card. While power was still on, I removed and then reinserted the SD card and the sketch recognized the SD card and began to record GPS data to a .csv file.
I believe the shield could be stackable if the TX and RX pins are bent or removed from the shield.
I have tried several times to run the project outside with a 9V battery for power, but have only succeeded in getting one datalog file.
While connected via USB and using the Serial Monitor, the sketch works perfectly. Here’s the sketch I’m using:
/******************************************************************************
This example uses SoftwareSerial to communicate with the GPS module on
pins 2 and 3, then communicates over SPI to log that data to a uSD card.

It uses the TinyGPS++ library to parse the NMEA strings sent by the GPS module,
and prints interesting GPS information - comma separated - to a newly created
file on the SD card.

Resources:
TinyGPS++ Library - Releases · mikalhart/TinyGPSPlus · GitHub
SD Library (Built-in)
SoftwareSerial Library (Built-in)

Development/hardware environment specifics:
Arduino IDE 1.6.7
GPS Logger Shield v2.0 - Make sure the UART switch is set to SW-UART
Arduino Uno, RedBoard, Pro, Mega, etc.
******************************************************************************/

#include <SPI.h>
#include <SD.h>
#include <TinyGPS++.h>

#define ARDUINO_USD_CS 10 // uSD card CS pin (pin 10 on SparkFun GPS Logger Shield)

/////////////////////////
// Log File Defintions //
/////////////////////////
// Keep in mind, the SD library has max file name lengths of 8.3 - 8 char prefix,
// and a 3 char suffix.
// Our log files are called "gpslogXX.csv, so “gpslog99.csv” is our max file.
#define LOG_FILE_PREFIX “gpslog” // Name of the log file.
#define MAX_LOG_FILES 100 // Number of log files that can be made
#define LOG_FILE_SUFFIX “csv” // Suffix of the log file
char logFileName[13]; // Char string to store the log file name
// Data to be logged:
#define LOG_COLUMN_COUNT 8
char * log_col_names[LOG_COLUMN_COUNT] = {
“longitude”, “latitude”, “altitude”, “speed”, “course”, “date”, “time”, “satellites”
}; // log_col_names is printed at the top of the file.

//////////////////////
// Log Rate Control //
//////////////////////
#define LOG_RATE 5000 // Log every 5 seconds
unsigned long lastLog = 0; // Global var to keep of last time we logged

/////////////////////////
// TinyGPS Definitions //
/////////////////////////
TinyGPSPlus tinyGPS; // tinyGPSPlus object to be used throughout
#define GPS_BAUD 9600 // GPS module’s default baud rate

/////////////////////////////////
// GPS Serial Port Definitions //
/////////////////////////////////
// If you’re using an Arduino Uno, Mega, RedBoard, or any board that uses the
// 0/1 UART for programming/Serial monitor-ing, use SoftwareSerial:
#include <SoftwareSerial.h>
#define ARDUINO_GPS_RX 3 // GPS TX, Arduino RX pin
#define ARDUINO_GPS_TX 2 // GPS RX, Arduino TX pin
SoftwareSerial ssGPS(ARDUINO_GPS_TX, ARDUINO_GPS_RX); // Create a SoftwareSerial

// Set gpsPort to either ssGPS if using SoftwareSerial or Serial1 if using an
// Arduino with a dedicated hardware serial port
#define gpsPort ssGPS // Alternatively, use Serial1 on the Leonardo

// Define the serial monitor port. On the Uno, Mega, and Leonardo this is ‘Serial’
// on other boards this may be ‘SerialUSB’
#define SerialMonitor Serial

void setup()
{
SerialMonitor.begin(9600);
gpsPort.begin(GPS_BAUD);

SerialMonitor.println(“Setting up SD card.”);
// see if the card is present and can be initialized:
if (!SD.begin(ARDUINO_USD_CS))
{
SerialMonitor.println(“Error initializing SD card.”);
}
updateFileName(); // Each time we start, create a new file, increment the number
printHeader(); // Print a header at the top of the new file
}

void loop()
{
if ((lastLog + LOG_RATE) <= millis())
{ // If it’s been LOG_RATE milliseconds since the last log:
if (tinyGPS.location.isUpdated()) // If the GPS data is vaild
{
if (logGPSData()) // Log the GPS data
{
SerialMonitor.println(“GPS logged.”); // Print a debug message
lastLog = millis(); // Update the lastLog variable
}
else // If we failed to log GPS
{ // Print an error, don’t update lastLog
SerialMonitor.println(“Failed to log new GPS data.”);
}
}
else // If GPS data isn’t valid
{
// Print a debug message. Maybe we don’t have enough satellites yet.
SerialMonitor.print("No GPS data. Sats: ");
SerialMonitor.println(tinyGPS.satellites.value());
}
}

// If we’re not logging, continue to “feed” the tinyGPS object:
while (gpsPort.available())
tinyGPS.encode(gpsPort.read());
}

byte logGPSData()
{
File logFile = SD.open(logFileName, FILE_WRITE); // Open the log file

if (logFile)
{ // Print longitude, latitude, altitude (in feet), speed (in mph), course
// in (degrees), date, time, and number of satellites.
logFile.print(tinyGPS.location.lng(), 6);
logFile.print(’,’);
logFile.print(tinyGPS.location.lat(), 6);
logFile.print(’,’);
logFile.print(tinyGPS.altitude.feet(), 1);
logFile.print(’,’);
logFile.print(tinyGPS.speed.mph(), 1);
logFile.print(’,’);
logFile.print(tinyGPS.course.deg(), 1);
logFile.print(’,’);
logFile.print(tinyGPS.date.value());
logFile.print(’,’);
logFile.print(tinyGPS.time.value());
logFile.print(’,’);
logFile.print(tinyGPS.satellites.value());
logFile.println();
logFile.close();

return 1; // Return success
}

return 0; // If we failed to open the file, return fail
}

// printHeader() - prints our eight column names to the top of our log file
void printHeader()
{
File logFile = SD.open(logFileName, FILE_WRITE); // Open the log file

if (logFile) // If the log file opened, print our column names to the file
{
int i = 0;
for (; i < LOG_COLUMN_COUNT; i++)
{
logFile.print(log_col_names*);*

  • if (i < LOG_COLUMN_COUNT - 1) // If it’s anything but the last column*
  • logFile.print(’,’); // print a comma*
  • else // If it’s the last column*
  • logFile.println(); // print a new line*
  • }*
  • logFile.close(); // close the file*
  • }*
    }
    // updateFileName() - Looks through the log files already present on a card,
    // and creates a new file with an incremented file index.
    void updateFileName()
    {
  • int i = 0;*
  • for (; i < MAX_LOG_FILES; i++)*
  • {*
  • memset(logFileName, 0, strlen(logFileName)); // Clear logFileName string*
  • // Set logFileName to “gpslogXX.csv”:*
  • sprintf(logFileName, “%s%d.%s”, LOG_FILE_PREFIX, i, LOG_FILE_SUFFIX);*
  • if (!SD.exists(logFileName)) // If a file doesn’t exist*
  • {*
  • break; // Break out of this loop. We found our index*
  • }*
  • else // Otherwise:*
  • {*
  • SerialMonitor.print(logFileName);*
  • SerialMonitor.println(" exists"); // Print a debug statement*
  • }*
  • }*
  • SerialMonitor.print("File name: ");*
  • SerialMonitor.println(logFileName); // Debug print the file name*
    }