mirror of
https://github.com/esp8266/Arduino.git
synced 2025-07-30 16:24:09 +03:00
Combining MemoryCard and SdFat libraries into SD library.
Defaulting to CS pin 4 (for Arduino Ethernet Shield). Holding the SS pin high (for disabling W5100 on the Ethernet Shield).
This commit is contained in:
340
libraries/SD/utility/examples/SdFatGPSLogger_v3/SdFatGPSLogger_v3.pde
Executable file
340
libraries/SD/utility/examples/SdFatGPSLogger_v3/SdFatGPSLogger_v3.pde
Executable file
@ -0,0 +1,340 @@
|
||||
// Ladyada's logger modified by Bill Greiman to use the SdFat library
|
||||
|
||||
// this is a generic logger that does checksum testing so the data written should be always good
|
||||
// Assumes a sirf III chipset logger attached to pin 0 and 1
|
||||
|
||||
#include <SdFat.h>
|
||||
#include <SdFatUtil.h>
|
||||
#include <avr/sleep.h>
|
||||
|
||||
// macros to use PSTR
|
||||
#define putstring(str) SerialPrint_P(PSTR(str))
|
||||
#define putstring_nl(str) SerialPrintln_P(PSTR(str))
|
||||
|
||||
// power saving modes
|
||||
#define SLEEPDELAY 0
|
||||
#define TURNOFFGPS 0
|
||||
#define LOG_RMC_FIXONLY 1
|
||||
|
||||
Sd2Card card;
|
||||
SdVolume volume;
|
||||
SdFile root;
|
||||
SdFile f;
|
||||
|
||||
#define led1Pin 4
|
||||
#define led2Pin 3
|
||||
#define powerPin 2
|
||||
|
||||
#define BUFFSIZE 75
|
||||
char buffer[BUFFSIZE];
|
||||
uint8_t bufferidx = 0;
|
||||
uint8_t fix = 0; // current fix data
|
||||
uint8_t i;
|
||||
|
||||
/* EXAMPLE
|
||||
|
||||
$PSRF103,<msg>,<mode>,<rate>,<cksumEnable>*CKSUM<CR><LF>
|
||||
|
||||
<msg> 00=GGA,01=GLL,02=GSA,03=GSV,04=RMC,05=VTG
|
||||
<mode> 00=SetRate,01=Query
|
||||
<rate> Output every <rate>seconds, off=00,max=255
|
||||
<cksumEnable> 00=disable Checksum,01=Enable checksum for specified message
|
||||
Note: checksum is required
|
||||
|
||||
Example 1: Query the GGA message with checksum enabled
|
||||
$PSRF103,00,01,00,01*25
|
||||
|
||||
Example 2: Enable VTG message for a 1Hz constant output with checksum enabled
|
||||
$PSRF103,05,00,01,01*20
|
||||
|
||||
Example 3: Disable VTG message
|
||||
$PSRF103,05,00,00,01*21
|
||||
|
||||
*/
|
||||
|
||||
#define SERIAL_SET "$PSRF100,01,4800,08,01,00*0E\r\n"
|
||||
|
||||
// GGA-Global Positioning System Fixed Data, message 103,00
|
||||
#define LOG_GGA 0
|
||||
#define GGA_ON "$PSRF103,00,00,01,01*25\r\n"
|
||||
#define GGA_OFF "$PSRF103,00,00,00,01*24\r\n"
|
||||
|
||||
// GLL-Geographic Position-Latitude/Longitude, message 103,01
|
||||
#define LOG_GLL 0
|
||||
#define GLL_ON "$PSRF103,01,00,01,01*26\r\n"
|
||||
#define GLL_OFF "$PSRF103,01,00,00,01*27\r\n"
|
||||
|
||||
// GSA-GNSS DOP and Active Satellites, message 103,02
|
||||
#define LOG_GSA 0
|
||||
#define GSA_ON "$PSRF103,02,00,01,01*27\r\n"
|
||||
#define GSA_OFF "$PSRF103,02,00,00,01*26\r\n"
|
||||
|
||||
// GSV-GNSS Satellites in View, message 103,03
|
||||
#define LOG_GSV 0
|
||||
#define GSV_ON "$PSRF103,03,00,01,01*26\r\n"
|
||||
#define GSV_OFF "$PSRF103,03,00,00,01*27\r\n"
|
||||
|
||||
// RMC-Recommended Minimum Specific GNSS Data, message 103,04
|
||||
#define LOG_RMC 1
|
||||
#define RMC_ON "$PSRF103,04,00,01,01*21\r\n"
|
||||
#define RMC_OFF "$PSRF103,04,00,00,01*20\r\n"
|
||||
|
||||
// VTG-Course Over Ground and Ground Speed, message 103,05
|
||||
#define LOG_VTG 0
|
||||
#define VTG_ON "$PSRF103,05,00,01,01*20\r\n"
|
||||
#define VTG_OFF "$PSRF103,05,00,00,01*21\r\n"
|
||||
|
||||
// Switch Development Data Messages On/Off, message 105
|
||||
#define LOG_DDM 1
|
||||
#define DDM_ON "$PSRF105,01*3E\r\n"
|
||||
#define DDM_OFF "$PSRF105,00*3F\r\n"
|
||||
|
||||
#define USE_WAAS 0 // useful in US, but slower fix
|
||||
#define WAAS_ON "$PSRF151,01*3F\r\n" // the command for turning on WAAS
|
||||
#define WAAS_OFF "$PSRF151,00*3E\r\n" // the command for turning off WAAS
|
||||
|
||||
// read a Hex value and return the decimal equivalent
|
||||
uint8_t parseHex(char c) {
|
||||
if (c < '0')
|
||||
return 0;
|
||||
if (c <= '9')
|
||||
return c - '0';
|
||||
if (c < 'A')
|
||||
return 0;
|
||||
if (c <= 'F')
|
||||
return (c - 'A')+10;
|
||||
}
|
||||
|
||||
// blink out an error code
|
||||
void error(uint8_t errno) {
|
||||
if (card.errorCode()) {
|
||||
putstring("SD error: ");
|
||||
Serial.print(card.errorCode(), HEX);
|
||||
Serial.print(',');
|
||||
Serial.println(card.errorData(), HEX);
|
||||
}
|
||||
while(1) {
|
||||
for (i=0; i<errno; i++) {
|
||||
digitalWrite(led1Pin, HIGH);
|
||||
digitalWrite(led2Pin, HIGH);
|
||||
delay(100);
|
||||
digitalWrite(led1Pin, LOW);
|
||||
digitalWrite(led2Pin, LOW);
|
||||
delay(100);
|
||||
}
|
||||
for (; i<10; i++) {
|
||||
delay(200);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void setup() {
|
||||
WDTCSR |= (1 << WDCE) | (1 << WDE);
|
||||
WDTCSR = 0;
|
||||
Serial.begin(4800);
|
||||
putstring_nl("\r\nGPSlogger");
|
||||
pinMode(led1Pin, OUTPUT);
|
||||
pinMode(led2Pin, OUTPUT);
|
||||
pinMode(powerPin, OUTPUT);
|
||||
digitalWrite(powerPin, LOW);
|
||||
|
||||
// initialize the SD card at SPI_HALF_SPEED to avoid bus errors with
|
||||
// breadboards. use SPI_FULL_SPEED for better performance.
|
||||
if (!card.init(SPI_HALF_SPEED)) {
|
||||
putstring_nl("Card init. failed!");
|
||||
error(1);
|
||||
}
|
||||
if (!volume.init(&card)) {
|
||||
putstring_nl("No partition!");
|
||||
error(2);
|
||||
}
|
||||
if(!root.openRoot(&volume)) {
|
||||
putstring_nl("Can't! open root dir");
|
||||
error(3);
|
||||
}
|
||||
strcpy(buffer, "GPSLOG00.TXT");
|
||||
for (i = 0; i < 100; i++) {
|
||||
buffer[6] = '0' + i/10;
|
||||
buffer[7] = '0' + i%10;
|
||||
// create if does not exist, do not open existing, write, sync after write
|
||||
if (f.open(&root, buffer, O_CREAT | O_EXCL | O_WRITE | O_SYNC)) break;
|
||||
}
|
||||
|
||||
if(!f.isOpen()) {
|
||||
putstring("couldnt create "); Serial.println(buffer);
|
||||
error(3);
|
||||
}
|
||||
putstring("writing to "); Serial.println(buffer);
|
||||
putstring_nl("ready!");
|
||||
|
||||
putstring(SERIAL_SET);
|
||||
delay(250);
|
||||
|
||||
if (LOG_DDM)
|
||||
putstring(DDM_ON);
|
||||
else
|
||||
putstring(DDM_OFF);
|
||||
delay(250);
|
||||
|
||||
if (LOG_GGA)
|
||||
putstring(GGA_ON);
|
||||
else
|
||||
putstring(GGA_OFF);
|
||||
delay(250);
|
||||
|
||||
if (LOG_GLL)
|
||||
putstring(GLL_ON);
|
||||
else
|
||||
putstring(GLL_OFF);
|
||||
delay(250);
|
||||
|
||||
if (LOG_GSA)
|
||||
putstring(GSA_ON);
|
||||
else
|
||||
putstring(GSA_OFF);
|
||||
delay(250);
|
||||
|
||||
if (LOG_GSV)
|
||||
putstring(GSV_ON);
|
||||
else
|
||||
putstring(GSV_OFF);
|
||||
delay(250);
|
||||
|
||||
if (LOG_RMC)
|
||||
putstring(RMC_ON);
|
||||
else
|
||||
putstring(RMC_OFF);
|
||||
delay(250);
|
||||
|
||||
if (LOG_VTG)
|
||||
putstring(VTG_ON);
|
||||
else
|
||||
putstring(VTG_OFF);
|
||||
delay(250);
|
||||
|
||||
if (USE_WAAS)
|
||||
putstring(WAAS_ON);
|
||||
else
|
||||
putstring(WAAS_OFF);
|
||||
}
|
||||
|
||||
void loop() {
|
||||
//Serial.println(Serial.available(), DEC);
|
||||
char c;
|
||||
uint8_t sum;
|
||||
|
||||
// read one 'line'
|
||||
if (Serial.available()) {
|
||||
c = Serial.read();
|
||||
//Serial.print(c, BYTE);
|
||||
if (bufferidx == 0) {
|
||||
while (c != '$')
|
||||
c = Serial.read(); // wait till we get a $
|
||||
}
|
||||
buffer[bufferidx] = c;
|
||||
|
||||
//Serial.print(c, BYTE);
|
||||
if (c == '\n') {
|
||||
//putstring_nl("EOL");
|
||||
//Serial.print(buffer);
|
||||
buffer[bufferidx+1] = 0; // terminate it
|
||||
|
||||
if (buffer[bufferidx-4] != '*') {
|
||||
// no checksum?
|
||||
Serial.print('*', BYTE);
|
||||
bufferidx = 0;
|
||||
return;
|
||||
}
|
||||
// get checksum
|
||||
sum = parseHex(buffer[bufferidx-3]) * 16;
|
||||
sum += parseHex(buffer[bufferidx-2]);
|
||||
|
||||
// check checksum
|
||||
for (i=1; i < (bufferidx-4); i++) {
|
||||
sum ^= buffer[i];
|
||||
}
|
||||
if (sum != 0) {
|
||||
//putstring_nl("Cxsum mismatch");
|
||||
Serial.print('~', BYTE);
|
||||
bufferidx = 0;
|
||||
return;
|
||||
}
|
||||
// got good data!
|
||||
|
||||
if (strstr(buffer, "GPRMC")) {
|
||||
// find out if we got a fix
|
||||
char *p = buffer;
|
||||
p = strchr(p, ',')+1;
|
||||
p = strchr(p, ',')+1; // skip to 3rd item
|
||||
|
||||
if (p[0] == 'V') {
|
||||
digitalWrite(led1Pin, LOW);
|
||||
fix = 0;
|
||||
} else {
|
||||
digitalWrite(led1Pin, HIGH);
|
||||
fix = 1;
|
||||
}
|
||||
}
|
||||
if (LOG_RMC_FIXONLY) {
|
||||
if (!fix) {
|
||||
Serial.print('_', BYTE);
|
||||
bufferidx = 0;
|
||||
return;
|
||||
}
|
||||
}
|
||||
// rad. lets log it!
|
||||
Serial.print(buffer);
|
||||
Serial.print('#', BYTE);
|
||||
digitalWrite(led2Pin, HIGH); // sets the digital pin as output
|
||||
|
||||
// Bill Greiman - need to write bufferidx + 1 bytes to getCR/LF
|
||||
bufferidx++;
|
||||
|
||||
if(f.write((uint8_t *) buffer, bufferidx) != bufferidx) {
|
||||
putstring_nl("can't write!");
|
||||
error(4);
|
||||
}
|
||||
|
||||
digitalWrite(led2Pin, LOW);
|
||||
|
||||
bufferidx = 0;
|
||||
|
||||
// turn off GPS module?
|
||||
if (TURNOFFGPS) {
|
||||
digitalWrite(powerPin, HIGH);
|
||||
}
|
||||
|
||||
sleep_sec(SLEEPDELAY);
|
||||
digitalWrite(powerPin, LOW);
|
||||
return;
|
||||
}
|
||||
bufferidx++;
|
||||
if (bufferidx == BUFFSIZE-1) {
|
||||
Serial.print('!', BYTE);
|
||||
bufferidx = 0;
|
||||
}
|
||||
} else {
|
||||
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
void sleep_sec(uint8_t x) {
|
||||
while (x--) {
|
||||
// set the WDT to wake us up!
|
||||
WDTCSR |= (1 << WDCE) | (1 << WDE); // enable watchdog & enable changing it
|
||||
WDTCSR = (1<< WDE) | (1 <<WDP2) | (1 << WDP1);
|
||||
WDTCSR |= (1<< WDIE);
|
||||
set_sleep_mode(SLEEP_MODE_PWR_DOWN);
|
||||
sleep_enable();
|
||||
sleep_mode();
|
||||
sleep_disable();
|
||||
}
|
||||
}
|
||||
|
||||
SIGNAL(WDT_vect) {
|
||||
WDTCSR |= (1 << WDCE) | (1 << WDE);
|
||||
WDTCSR = 0;
|
||||
}
|
||||
|
||||
/* End code */
|
Reference in New Issue
Block a user