Trying to write GPS time to SD card filename with sprintf

Hi all,

I’ve carefully gone through several posts on this topic but after hours of beating my head against the wall can’t figure out why this is not working.

Most of the code is NMEAGPS to get and parse GPS, then I use the ‘doSomeWork’ section to try and write the file and print lat and long in it. It will work fine if I specifically name the filename (e.g. File dataFile = SD.open(“filename.csv”, FILE_WRITE):wink: but when I try to use the filename char that sprintf creates it doenst write anything to the sd card. I have printed the filename and it creates something I’d expect (e.g. “04:40.csv”). I’m pretty amateur at this C++ stuff so I’m guessing it’s something simple. Thank you for your help!

#include <AltSoftSerial.h>

#include <NMEAGPS.h>

#include <SPI.h>

#include <SD.h>

//======================================================================
//  Program: NMEA.ino
//
//  Description:  This program uses the fix-oriented methods available() and
//    read() to handle complete fix structures.
//
//    When the last character of the LAST_SENTENCE_IN_INTERVAL (see NMEAGPS_cfg.h)
//    is decoded, a completed fix structure becomes available and is returned
//    from read().  The new fix is saved the 'fix' structure, and can be used
//    anywhere, at any time.
//
//    If no messages are enabled in NMEAGPS_cfg.h, or
//    no 'gps_fix' members are enabled in GPSfix_cfg.h, no information will be
//    parsed, copied or printed.
//
//  Prerequisites:
//     1) Your GPS device has been correctly powered.
//          Be careful when connecting 3.3V devices.
//     2) Your GPS device is correctly connected to an Arduino serial port.
//          See GPSport.h for the default connections.
//     3) You know the default baud rate of your GPS device.
//          If 9600 does not work, use NMEAdiagnostic.ino to
//          scan for the correct baud rate.
//     4) LAST_SENTENCE_IN_INTERVAL is defined to be the sentence that is
//          sent *last* in each update interval (usually once per second).
//          The default is NMEAGPS::NMEA_RMC (see NMEAGPS_cfg.h).  Other
//          programs may need to use the sentence identified by NMEAorder.ino.
//     5) NMEAGPS_RECOGNIZE_ALL is defined in NMEAGPS_cfg.h
//
//  'Serial' is for debug output to the Serial Monitor window.
//
//  License:
//    Copyright (C) 2014-2017, SlashDevin
//
//    This file is part of NeoGPS
//
//    NeoGPS is free software: you can redistribute it and/or modify
//    it under the terms of the GNU General Public License as published by
//    the Free Software Foundation, either version 3 of the License, or
//    (at your option) any later version.
//
//    NeoGPS is distributed in the hope that it will be useful,
//    but WITHOUT ANY WARRANTY; without even the implied warranty of
//    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
//    GNU General Public License for more details.
//
//    You should have received a copy of the GNU General Public License
//    along with NeoGPS.  If not, see <http://www.gnu.org/licenses/>.
//
//======================================================================

//-------------------------------------------------------------------------
//  The GPSport.h include file tries to choose a default serial port
//  for the GPS device.  If you know which serial port you want to use,
//  edit the GPSport.h file.

#include <GPSport.h>
#ifndef GPSport_h
#define GPSport_h
#define PMTK_SET_NMEA_UPDATE_10HZ "$PMTK220,100*2F" // this tells the gps to work at 10hz

#include <AltSoftSerial.h>
AltSoftSerial gpsPort;
#define GPS_PORT_NAME "AltSoftSerial"
#define DEBUG_PORT Serial

#endif
#define RX_PIN 8 //Green goes to pin 8
#define TX_PIN 9 //Yellow goes to pin 9
//------------------------------------------------------------
// For the NeoGPS example programs, "Streamers" is common set
//   of printing and formatting routines for GPS data, in a
//   Comma-Separated Values text format (aka CSV).  The CSV
//   data will be printed to the "debug output device".
// If you don't need these formatters, simply delete this section.

#include <Streamers.h>

//------------------------------------------------------------
// This object parses received characters
//   into the gps.fix() data structure

static NMEAGPS  gps;

//------------------------------------------------------------
//  Define a set of GPS fix information.  It will
//  hold on to the various pieces as they are received from
//  an RMC sentence.  It can be used anywhere in your sketch.

static gps_fix  fix;

//----------------------------------------------------------------
//  This function gets called about once per second, during the GPS
//  quiet time.  It's the best place to do anything that might take
//  a while: print a bunch of things, write to SD, send an SMS, etc.
//
//  By doing the "hard" work during the quiet time, the CPU can get back to
//  reading the GPS chars as they come in, so that no chars are lost.

char filename[] = "00000.csv";
int doonce;
  
static void doSomeWork()
{
  // Print all the things!
  // open the file. note that only one file can be open at a time,
  // so you have to close this one before opening another.
Serial.print(doonce);
  if (doonce == 0)
  
  {
  sprintf(filename,"%02d:%02d.csv", fix.dateTime.seconds, fix.dateTime.minutes);
    doonce++;
  }

  else 
  
  {    
  File dataFile = SD.open(filename, FILE_WRITE);
  
  if (dataFile)
  {
    dataFile.print(fix.longitudeL());
    dataFile.print(",");
    dataFile.println(fix.latitudeL());
    dataFile.close();
  }
  // if the file isn't open, pop up an error:
  
  else {
    Serial.println("error opening file");
  }
  }
  trace_all( DEBUG_PORT, gps, fix );
  Serial.println(filename);
} // doSomeWork

//------------------------------------
//  This is the main GPS parsing loop.

static void GPSloop()
{
  while (gps.available( gpsPort )) {
    fix = gps.read();
    doSomeWork();
  }

} // GPSloop

const int chipSelect = 4;

//--------------------------



void setup()
{
  doonce = 0;
  DEBUG_PORT.begin(9600);
  while (!DEBUG_PORT)
    ;

  // sd card initialization

  if (!SD.begin(chipSelect)) {
    DEBUG_PORT.println("Card failed, or not present");
    // don't do anything more:
    return;

  }
  Serial.println("card initialized.");

  DEBUG_PORT.print( F("NMEA.INO: started\n") );
  DEBUG_PORT.print( F("  fix object size = ") );
  DEBUG_PORT.println( sizeof(gps.fix()) );
  DEBUG_PORT.print( F("  gps object size = ") );
  DEBUG_PORT.println( sizeof(gps) );
  DEBUG_PORT.println( F("Looking for GPS device on " GPS_PORT_NAME) );

#ifndef NMEAGPS_RECOGNIZE_ALL
#error You must define NMEAGPS_RECOGNIZE_ALL in NMEAGPS_cfg.h!
#endif

#ifdef NMEAGPS_INTERRUPT_PROCESSING
#error You must *NOT* define NMEAGPS_INTERRUPT_PROCESSING in NMEAGPS_cfg.h!
#endif

#if !defined( NMEAGPS_PARSE_GGA ) & !defined( NMEAGPS_PARSE_GLL ) & \
      !defined( NMEAGPS_PARSE_GSA ) & !defined( NMEAGPS_PARSE_GSV ) & \
      !defined( NMEAGPS_PARSE_RMC ) & !defined( NMEAGPS_PARSE_VTG ) & \
      !defined( NMEAGPS_PARSE_ZDA ) & !defined( NMEAGPS_PARSE_GST )

  DEBUG_PORT.println( F("\nWARNING: No NMEA sentences are enabled: no fix data will be displayed.") );

#else
  if (gps.merging == NMEAGPS::NO_MERGING) {
    DEBUG_PORT.print  ( F("\nWARNING: displaying data from ") );
    DEBUG_PORT.print  ( gps.string_for( LAST_SENTENCE_IN_INTERVAL ) );
    DEBUG_PORT.print  ( F(" sentences ONLY, and only if ") );
    DEBUG_PORT.print  ( gps.string_for( LAST_SENTENCE_IN_INTERVAL ) );
    DEBUG_PORT.println( F(" is enabled.\n"
                          "  Other sentences may be parsed, but their data will not be displayed.") );
  }
#endif

  DEBUG_PORT.print  ( F("\nGPS quiet time is assumed to begin after a ") );
  DEBUG_PORT.print  ( gps.string_for( LAST_SENTENCE_IN_INTERVAL ) );
  DEBUG_PORT.println( F(" sentence is received.\n"
                        "  You should confirm this with NMEAorder.ino\n") );

  trace_header( DEBUG_PORT );
  DEBUG_PORT.flush();


  gpsPort.begin( 9600 );
  
}


//--------------------------

void loop()
{
  
  GPSloop();

}
  sprintf(filename,"%02d:%02d.csv", fix.dateTime.seconds, fix.dateTime.minutes);

Seconds then minutes? Weird...

  if (doonce == 0)

  {
  sprintf(filename,"%02d:%02d.csv", fix.dateTime.seconds, fix.dateTime.minutes);
    doonce++;
  }

  else

  {   
  File dataFile = SD.open(filename, FILE_WRITE);

  if (dataFile)
  {
    dataFile.print(fix.longitudeL());
    dataFile.print(",");
    dataFile.println(fix.latitudeL());
    dataFile.close();
  }
  // if the file isn't open, pop up an error:

  else {
    Serial.println("error opening file");
  }
  }
  trace_all( DEBUG_PORT, gps, fix );
  Serial.println(filename);

I always print the variables that I care about immediately after assigning the variable a value. Printing them later has the potential for all kinds of corruption to have happened. YMMV.

Is the : a supported character in a file name? Try constructing the file name without the : to know.

Bingo! Colon wasn't allowed. Also, appreciate the advice on printing right away. Thank you!