I am making a GPS SD card data logger. To write the GPS data to the SD card I have to sprintf it, unless there is another way. I looked at a tutorial for the GPS which showed me how to sprintf the elevation data, but nothing else. Would someone explain to me how to write a sprintf function and what the %02d part means. I know it replaces that with the GPS data, but I don't understand why it has to be %02d.
Hardware: Arduino Uno with Seeed SD card shield and Adafruit Ultimate GPS.
Code:
// SD card location logger
// Hardware: Seeed SD Card Shield v3.0, Sparkfun Ultimate GPS Breakout, and Arduino Uno
#include <SD.h>
#include <SoftwareSerial.h>
#include <TinyGPS++.h>
// RX and TX pins for Software Serial library
#define RXPin 2
#define TXPin 3
// The serial connections to the GPS device.
SoftwareSerial ss(RXPin, TXPin);
// GPS Baud Rate
#define GPSBaud 4800
// The TinyGPS++ object
TinyGPSPlus gps;
// On the Seeed SD Card Shield, the CS is pin 10. No matter what pin is used as CS on your shield,
// the hardware CS pin (10 on most Arduino board's, 53 on Arduino Mega) must be left as an output
const int chipSelect = 10;
// Prepare SD card file.
File GPSlog;
// Warning light (LED)
const int fail = 13;
void setup() {
Serial.begin(GPSBaud);
// IMPORTANT: Set the hardware CS pin to output mode
pinMode(10, OUTPUT);
// Warning LED is an output
pinMode(fail, OUTPUT);
// Turn warning light off
digitalWrite(fail, LOW);
// Make sure the card is present and can be initialized.
if(!SD.begin(chipSelect))
{
// Turn on the SD warning light.
digitalWrite(fail, HIGH);
// Don't do anything more.
return;
}
// Make and open a new plain text (.txt) file called "GPSdata.txt"
File GPSlog = SD.open("GPSdata.txt", FILE_WRITE);
// If the file opened, write to it.
if(GPSlog)
{
GPSlog.println("GPS Data Log File");
GPSlog.println("lattitude, longitude, altitude, time");
// Close the file.
GPSlog.close();
}
// If the file was not able to be opened
else
{
// Turn on the SD warning light.
digitalWrite(fail, HIGH);
// Don't do anything more.
return;
}
}
void loop() {
// If any characters have arrived from the GPS,
// send them to the TinyGPS++ object.
while(Serial.available() > 0)
{
gps.encode(Serial.read());
}
// Record our new locaation and altitude when
// they have been updated.
if(gps.location.isUpdated() || gps.altitude.isUpdated())
{
}
}
void recordGPS() {
// Open the GPSdata.txt file in write mode.
GPSlog = SD.open("GPSdata.txt", FILE_WRITE);
// If the file opened, write to it.
if(GPSlog)
{
// Make a char called emit and sprintf it.
char emit[80]; //Time backwards since naming stuff time causes compiler issues
sprintf(emit, "%02d:%02d:%02d ~ ", gps.time.hour(), gps.time.minute(), gps.time.second());
// Make a char called here and sprintf it.
char here[80];
sprintf(here, "?????????", gps.location.lat(), gps.location.long(), gps.altitude.meters());
// Print the time to GPSdata.txt.
GPSlog.print(emit);
// Print the lattitude and longitude to GPSdata.txt.
GPSlog.print(here);
}
}
Thanks, but do you know if you have to specify where to put the decimal on floats like you have to for Serial.print()ing floats. ex.
myFloat = 3.14;
Serial.print(myFloat, 2); //Decimal 2 points in from right
// SD card location logger
// Hardware: Seeed SD Card Shield v3.0, Sparkfun Ultimate GPS Breakout, and Arduino Uno
#include <SPI.h>
#include <SD.h>
#include <SoftwareSerial.h>
#include <TinyGPS++.h>
// RX and TX pins for Software Serial library
#define RXPin 2
#define TXPin 3
// The serial connections to the GPS device.
SoftwareSerial ss(RXPin, TXPin);
// GPS Baud Rate
#define GPSBaud 4800
// The TinyGPS++ object
TinyGPSPlus gps;
// On the Seeed SD Card Shield, the CS is pin 10. No matter what pin is used as CS on your shield,
// the hardware CS pin (10 on most Arduino board's, 53 on Arduino Mega) must be left as an output
const int chipSelect = 10;
// Prepare SD card file.
File GPSlog;
// Warning light (LED)
const int fail = 13;
void setup() {
Serial.begin(GPSBaud);
// IMPORTANT: Set the hardware CS pin to output mode
pinMode(10, OUTPUT);
// Warning LED is an output
pinMode(fail, OUTPUT);
// Turn warning light off
digitalWrite(fail, LOW);
// Make sure the card is present and can be initialized.
if (!SD.begin(chipSelect))
{
// Turn on the SD warning light.
digitalWrite(fail, HIGH);
// Don't do anything more.
return;
}
// Make and open a new plain text (.txt) file called "GPSdata.txt"
File GPSlog = SD.open("GPSdata.txt", FILE_WRITE);
// If the file opened, write to it.
if (GPSlog)
{
GPSlog.println("GPS Data Log File");
GPSlog.println("lattitude, longitude, altitude, time");
// Close the file.
GPSlog.close();
}
// If the file was not able to be opened
else
{
// Turn on the SD warning light.
digitalWrite(fail, HIGH);
// Don't do anything more.
return;
}
}
void loop() {
// If any characters have arrived from the GPS,
// send them to the TinyGPS++ object.
while (Serial.available() > 0)
{
gps.encode(Serial.read());
}
// Record our new locaation and altitude when
// they have been updated.
if (gps.location.isUpdated() || gps.altitude.isUpdated())
{
}
}
void recordGPS() {
// Open the GPSdata.txt file in write mode.
GPSlog = SD.open("GPSdata.txt", FILE_WRITE);
// If the file opened, write to it.
if (GPSlog)
{
// Make a char called emit and sprintf it.
char emit[80]; //Time backwards since naming stuff time causes compiler issues
sprintf(emit, "%02d:%02d:%02d ~ ", gps.time.hour(), gps.time.minute(), gps.time.second());
// Print the time to GPSdata.txt.
GPSlog.print(emit);
// Print the latitude and longitude to GPSdata.txt.
GPSlog.print(gps.location.lat());
GPSlog.print(", ");
GPSlog.print(gps.location.lng());
//Print the altitude to GPSdata.txt.
GPSlog.print(gps.altitude.meters());
}
else
{
// Turn on the SD warning light.
digitalWrite(fail, HIGH);
// Don't do anything more.
return;
}
}
KeithRB:
sprintf() on the arduino does not handle floats, so I guess the answer to your question is 42.
Yes it does.
To save space, avr libC has a library without floating point sprintf() support that is used by default.
The IDE uses this default library so the sprintf() linked in doesn't have it.
With Arduino 1.5x you can go in and modify the linker options down in the avr platform.txt
file to use the "normal" full version of sprintf() library instead.
You change this:
This is a one time "fix".
It does come with the cost of using additional code in flash - about 1.8k or so that you use
even if not using floating point.
bperrybap:
This is a one time "fix".
It does come with the cost of using additional code in flash - about 1.8k or so that you use
even if not using floating point.
--- bill
I added that as an option to the IDE 1.0.5 (I don't use 1.5.x).
bperrybap:
This is a one time "fix".
It does come with the cost of using additional code in flash - about 1.8k or so that you use
even if not using floating point.
--- bill
I added that as an option to the IDE 1.0.5 (I don't use 1.5.x).
That sounds really great. However, It didn't work for me.
On my linux Mint 13 machine I get:
Exception in thread "main" java.lang.UnsupportedClassVersionError: processing/app/Base : Unsupported major.minor version 51.0
at java.lang.ClassLoader.defineClass1(Native Method)
at java.lang.ClassLoader.defineClass(ClassLoader.java:643)
at java.security.SecureClassLoader.defineClass(SecureClassLoader.java:142)
at java.net.URLClassLoader.defineClass(URLClassLoader.java:277)
at java.net.URLClassLoader.access$000(URLClassLoader.java:73)
at java.net.URLClassLoader$1.run(URLClassLoader.java:212)
at java.security.AccessController.doPrivileged(Native Method)
at java.net.URLClassLoader.findClass(URLClassLoader.java:205)
at java.lang.ClassLoader.loadClass(ClassLoader.java:323)
at sun.misc.Launcher$AppClassLoader.loadClass(Launcher.java:294)
at java.lang.ClassLoader.loadClass(ClassLoader.java:268)
Could not find the main class: processing.app.Base. Program will exit.
What am I missing?
Note that 1.0.5-r2 was only released for Windows as it supposedly only
fixed issues that were windows specific.
Krupski,
apparently it needs jdk7 and that isn't there on Linux mint 13.
Seems a bit odd and restrictive to require a newer version than the jar file it is replacing.
Does it really need jdk7?