SparkFun Forums 

Where electronics enthusiasts find answers.

Have questions about a SparkFun product or board? This is the place to be.
By joan
#199332
Hi,

I recently bought some GPSlogger shields. I want to collect GPS + baromètric pressure to measure altitude.

GPS logger shield works fine alone, collects correct data on the SD

Octopus bmp180 baròmetre, orks fine with SFE BMP180 library.

When I try to read pressure data and write into the SD, it fails.

I send the sketch below, where I simply add pressure readings into the CSV_Logger_TinyGPSPlus.ino exemple. The exemple works fine alone, but fails when adding

pressure.begin(); in the setup

I really would appreciate if you could help me to solve this problema. Thanks!

joan





#include <Wire.h>
#include <SFE_BMP180.h>
SFE_BMP180 pressure;
/******************************************************************************
CSV_Logger_TinyGPSPlus.ino
Log GPS data to a CSV file on a uSD card
By Jim Lindblom @ SparkFun Electronics
February 9, 2016
https://github.com/sparkfun/GPS_Shield

This example uses SoftwareSerial to communicate with the GPS module on
pins 8 and 9, 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 - https://github.com/mikalhart/TinyGPSPlus/releases
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, 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 1000 // 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, RedBoard, or any board that uses the
// 0/1 UART for programming/Serial monitor-ing, use SoftwareSerial:
#include <SoftwareSerial.h>
#define ARDUINO_GPS_RX 9 // GPS TX, Arduino RX pin
#define ARDUINO_GPS_TX 8 // 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, and Leonardo this is 'Serial'
// on other boards this may be 'SerialUSB'
#define SerialMonitor Serial

void setup()
{

pressure.begin(); //this instruction causes the sketch to fail!!

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()
{

/* double P;

// Get a new pressure reading:

P = getPressure();
*/

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
} //LOOP


double getPressure()
{
char status;
double T,P,p0,a;

// You must first get a temperature measurement to perform a pressure reading.

// Start a temperature measurement:
// If request is successful, the number of ms to wait is returned.
// If request is unsuccessful, 0 is returned.

status = pressure.startTemperature();
if (status != 0)
{
// Wait for the measurement to complete:

delay(status);

// Retrieve the completed temperature measurement:
// Note that the measurement is stored in the variable T.
// Use '&T' to provide the address of T to the function.
// Function returns 1 if successful, 0 if failure.

status = pressure.getTemperature(T);
if (status != 0)
{
// Start a pressure measurement:
// The parameter is the oversampling setting, from 0 to 3 (highest res, longest wait).
// If request is successful, the number of ms to wait is returned.
// If request is unsuccessful, 0 is returned.

status = pressure.startPressure(3);
if (status != 0)
{
// Wait for the measurement to complete:
delay(status);

// Retrieve the completed pressure measurement:
// Note that the measurement is stored in the variable P.
// Use '&P' to provide the address of P.
// Note also that the function requires the previous temperature measurement (T).
// (If temperature is stable, you can do one temperature measurement for a number of pressure measurements.)
// Function returns 1 if successful, 0 if failure.

status = pressure.getPressure(P,T);
if (status != 0)
{
return(P);
}
else Serial.println("error retrieving pressure measurement\n");
}
else Serial.println("error starting pressure measurement\n");
}
else Serial.println("error retrieving temperature measurement\n");
}
else Serial.println("error starting temperature measurement\n");
}
By joan
#199333
Hi,

I recently bought some GPSlogger shields. I want to collect GPS + barometric pressure to measure altitude on a walk. It is a scolar project involving several schools.

GPS logger shield works fine alone, collects correct data on the SD

Octopus bmp180 barometre, works fine with SFE BMP180 library.

When I try to read pressure data and write into the SD, it fails.

I send the sketch where I simply add pressure readings into the CSV_Logger_TinyGPSPlus.ino exemple. The exemple works fine alone, but fails when adding pressure.begin(); in the setup

I really would appreciate if you could help me to solve this problem. Thanks!

joan
You do not have the required permissions to view the files attached to this post.
By paulvha
#199334
when you say "but fails when adding pressure.begin(); in the setup" what fails ? do you get an error message or does it just hang or what ?
By joan
#199335
It shows the message "Failed to log new GPS data." every time it attempts to write a log. The sketch correctly opens and writes the file header in the setup, but it fails when writing to it.
By paulvha
#199339
3 aspects come to mind to check:
1. The power consumption. Creating a file takes less current than writing. That combined with active reading and GPS and BMP180 could cause issues
2. The amount of RAM bytes left after compile. The sketch (and libraries) needs enough RAM during running for stack etc. etc.
3. The card format is mentioned in other articles as a cause and should be FAT16 only (even though specification indicate differently)
By Valen
#199383
Why didn't you provide the error statements in the compilation log (as a result of adding the pressure.begin)? That might explain that there is something missing/wrong in your code. And if that is al ok, how exactly did you determine that the program failed?

BTW, please enclose your code in [ code] Arduino code goes here [ /code] tags. (remove the spaces after the [-bracket to make it work) It makes it easier to read and copy.
By Valen
#199384
Double thread: https://forum.sparkfun.com/viewtopic.php?f=14&t=48221

Joan, please don't do that. It creates more confusion to have multiple answered threads. Many frequent repliers/support volunteers use the new reply/unanswered filters of the forum. Don't worry, your question will be viewed if placed in a single forum section. And most likely answered if properly asked/needed information is provided by you. Which you did.