Dear all,
We have developed a wireless GPS datalogger for use on wildlife. Several prototypes have been built, tested and even successfully deployed. Please see Wireless GPS Datalogger and Wireless GPS Datalogger - YouTube for details of construction.
The processor is a 3.3v Arduino Pro Mini mounted on a Fritzing PCB, a solid state relay turns the power ON/OFF for the GPS module, Xbee and the micro SD card.
Power is supplied by a 3.7v 400mAh lipo. Logging a location once every 15 mins and sleeping between will allow the datalogger to function for almost one week.
Once the datalogger gets a location it writes it to the micro SD card and the Xbee transmits the datalog wirelessly. A similar datalogger, loaded with the receiving code, listens for Xbee transmissions and writes them down to its own micro SD card. You can have one receiver listening for multiple dataloggers!
A 1mW Xbee provides a wireless range of about one hundred metres and the 60mW Xbee just over 1km but at the expense of battery life (only 2 days).
My problem is this: if the GPS doesn't get a location soon after it is turned on it keeps looking and drains the battery fast!
This seems to be more of a problem when deploying in the field, due to harsh environmental conditions. When tested under clear sky they work just fine.
Can any interested person please assist me by looking at the code and suggesting improvements, I would like the code to spend an small amount of time attempting to get a location (say no more than 30 secs). If the GPS can't get a location it transmits the existing datalog from the micro SD card, then sleeps for 15 mins. If the GPS can get a location it adds that location to the datalog on the micro SD card, transmits the datalog wirelessly and then sleeps for a period of 15 mins.
The code can already do most of this, it just needs improving.
Our goal is to have an open source DIY wireless GPS datalogger for use on wildlife. If your able to provide substantial assistance I could possibly provide you with one of our prototypes for your testing.
Thanks...
// Wireless GPS Datalogger, written using examples from the following libraries by smithcs
// Load the libraries
#include <LowPower.h> // http://www.rocketscream.com/blog/2011/07/04/lightweight-low-power-arduino-library/
#include <SdFat.h> // http://code.google.com/p/sdfatlib/
#include <SoftwareSerial.h> // http://arduino.cc/en/Reference/SoftwareSerial
#include <TinyGPS.h> // http://arduiniana.org/libraries/tinygps/
// Declare variables and objects
SdFat sd;
SdFile myFile;
SoftwareSerial SS_gps(8, 9); // Declare SoftwareSerial connection for GPS
SoftwareSerial SS_xbee(2, 3); // Declare SoftwareSerial connection for Xbee
TinyGPS gps;
void getgps(TinyGPS &gps); // Write the GPS message to the datalog
void slp(); // Loop sleep for 8S
void tx_datalog(); // Send the datalog wirelessly
void setup()
{
// Turn the relay ON
pinMode(7, OUTPUT);
digitalWrite(7, HIGH);
// Turn the Xbee ON
pinMode(2, INPUT);
pinMode(3, OUTPUT);
SS_xbee.begin(9600);
delay(500);
SS_xbee.println(" ");
// Send a message wirelessly
SS_xbee.println("Wireless GPS Datalogger 10.");
SS_xbee.println("Initializing SD card...");
// Initialize SdFat or print a detailed error message and halt
// Use half speed like the native library
// Change to SPI_FULL_SPEED for more performance
if (!sd.begin(10, SPI_HALF_SPEED)) sd.initErrorHalt();
// Open the datalog and write at end like the Native SD library
if (!myFile.open("Log_10.txt", O_RDWR | O_CREAT | O_AT_END))
{
sd.errorHalt();
}
// Create the datalog header
myFile.println("Datalogger,Date,Time,Latitude,Longitude");
// Close the datalog
myFile.close();
myFile.sync();
// Send a message wirelessly
SS_xbee.println("Card initialized.");
SS_xbee.println("Waiting for GPS lock...");
//Turn the GPS ON
SS_gps.begin(9600);
// Turn the Xbee OFF
delay(500);
SS_xbee.end();
pinMode(2, INPUT);
pinMode(3, INPUT);
}
void loop()
{
// Turn the relay ON
digitalWrite(7, HIGH);
//Turn the GPS ON
SS_gps.begin(9600);
// Wait until the GPS sends a message
while(SS_gps.available())
{
// Read the GPS message
int c = SS_gps.read();
if(gps.encode(c))
{
// Write the GPS message to the datalog
getgps(gps);
// Send the datalog wirelessly
tx_datalog();
// Turn the GPS OFF
SS_gps.end();
// Turn the relay OFF
digitalWrite(7, LOW);
// Loop sleep for 8S
slp();
}
}
}
// Write the GPS message to the datalog
void getgps(TinyGPS &gps)
{
//Declare variables and objects
float latitude, longitude;
char lat[12];
char lon[12];
// Get latitude and longitude from GPS message
gps.f_get_position(&latitude, &longitude);
// Convert longitude and latitude floats to lat and lon characters as floats cannot be added to a string
dtostrf(latitude,1,5,lat);
dtostrf(longitude,1,5,lon);
// Declare variables and objects
int year;
byte month, day, hour, minute, second;
// Get year, month, day, hour, minute and second from GPS message
gps.crack_datetime(&year, &month, &day, &hour, &minute, &second);
// Declare variables and objects
String dataString = "";
// Add GPS message to the datastring
dataString += "10,";
dataString += String(day, DEC) + "/" + String(month, DEC) + "/" + year + ",";
dataString += String(hour, DEC) + ":" + String(minute, DEC) + ":" + String(second, DEC) + ",";
dataString += String(lat) + "," + String(lon);
// Open the datalog and write at end like the Native SD library
if (!myFile.open("Log_10.txt", O_RDWR | O_AT_END))
{
sd.errorHalt();
}
// Add the dataString to the datalog
myFile.println(dataString);
// Close the datalog
myFile.close();
myFile.sync();
}
// Loop sleep for 8S
void slp()
{
int var = 0;
while(var < 112)
{
LowPower.powerDown(SLEEP_8S, ADC_OFF, BOD_OFF);
var++;
}
}
// Send the datalog wirelessly
void tx_datalog()
{
// Turn the Xbee ON
pinMode(2, INPUT);
pinMode(3, OUTPUT);
SS_xbee.begin(9600);
delay(500);
SS_xbee.println(" ");
delay(500);
SS_xbee.println(" ");
// Send a messeage wirelessly
SS_xbee.println("Begin transmission of Log_10.txt");
// Open the datalog for reading
if (!myFile.open("Log_10.txt", O_READ))
{
sd.errorHalt();
}
// Read and send the datalog wirelessly
char data;
while ((data = myFile.read()) >= 0)
{
SS_xbee.write(data);
delay(4);
}
// Send a messeage wirelessly
SS_xbee.println("End transmission of Log_10.txt");
// Close the datalog
myFile.close();
myFile.sync();
//Turn the Xbee OFF
delay(500);
SS_xbee.end();
pinMode(2, INPUT);
pinMode(3, INPUT);
}