Adafruit_RGBLCDShield lcd = Adafruit_RGBLCDShield();
Moderators: adafruit_support_bill, adafruit

Adafruit_RGBLCDShield lcd = Adafruit_RGBLCDShield();

by jhyden on Wed May 23, 2012 12:28 pm

Adafruit_RGBLCDShield lcd = Adafruit_RGBLCDShield();

I am using a adafruit logging shield with a adafruit gps breakout board. They work great together! When I try to add an adafruilt rgb lcd shield, it stops working. Adding the #include <Adafruit_MCP23017.h> and
#include <Adafruit_RGBLCDShield.h> causes not problems but when this line in the sketch:
Adafruit_RGBLCDShield lcd = Adafruit_RGBLCDShield.h, the program freezes after the sd card is initialized and is ready for logging. There are no more gps nmea sentences read by the interrupt timer0.
jhyden
 
Posts: 19
Joined: Fri Apr 27, 2012 8:36 pm

Re: Adafruit_RGBLCDShield lcd = Adafruit_RGBLCDShield();

by adafruit_support_bill on Wed May 23, 2012 12:45 pm

There should be no pin conflicts since the i2c can be shared. It is possible you are running out of RAM. If you post your whole sketch we can take a closer look.
User avatar
adafruit_support_bill
 
Posts: 31701
Joined: Sat Feb 07, 2009 10:11 am

Re: Adafruit_RGBLCDShield lcd = Adafruit_RGBLCDShield();

by jhyden on Wed May 23, 2012 12:54 pm

here it is:

[Edit - moderator - use 'code' button when submitting code]

Code: Select all | TOGGLE FULL SIZE
// 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 2 and 3
#include <Wire.h>
#include <SD.h>
#include <Adafruit_MCP23017.h>
#include <Adafruit_RGBLCDShield.h>
#include <Adafruit_GPS.h>
//Adafruit_RGBLCDShield lcd = Adafruit_RGBLCDShield();
// If using Arduino IDE prior to 1.0,
// make sure to install newsoftserial from Mikal Hart
// http://arduiniana.org/libraries/NewSoftSerial/
#if ARDUINO >= 100
 #include <SoftwareSerial.h>
#else
 #include <NewSoftSerial.h>
#endif
#define OFF 0x0
#define ON 0x1
// power saving modes
#define SLEEPDELAY 0
#define TURNOFFGPS 0
#define LOG_RMC_FIXONLY 0
#define PMTK_ENABLE_WAAS       "$PMTK301,1*2E"
#define PMTK_SET_NMEA_OUTPUT_RMCGGA "$PMTK314,0,1,0,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0*28"
#define PMTK_SET_NMEA_OUTPUT_RMCONLY "$PMTK314,0,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0*29"
#define PMTK_SET_NMEA_UPDATE_1HZ  "$PMTK220,1000*1F"
// Use pins 2 and 3 to talk to the GPS. 2 is the TX pin, 3 is the RX pin
#if ARDUINO >= 100
 SoftwareSerial gpsSerial =  SoftwareSerial(7, 8);
#else
 NewSoftSerial gpsSerial =  NewSoftSerial(7, 8);
#endif
//Adafruit_GPS GPS(gpsSerial);
// Set the GPSRATE to the baud rate of the GPS module. Most are 4800
// but some are 38400 or other. Check the datasheet!
#define GPSRATE 9600
Adafruit_GPS GPS(&gpsSerial);
// Set the pins used
#define qualityPin 9
#define fixPin 3
#define writePin 4
#define chipSelect 10


#define BUFFSIZE 99
char buffer[BUFFSIZE];
uint8_t bufferidx = 0;
uint8_t fix = 0; // current fix data
uint8_t i;
int r;
char *pmtk;
File logfile;

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


void setup() {
  //WDTCSR |= (1 << WDCE) | (1 << WDE);
  //WDTCSR = 0;
  Serial.begin(9600);
  Serial.println("\r\nGPSlogger");
  pinMode(fixPin, OUTPUT);
  pinMode(writePin, OUTPUT);
  pinMode(qualityPin, OUTPUT);
  digitalWrite(qualityPin, HIGH);

  // make sure that the default chip select pin is set to
  // output, even if you don't use it:
  pinMode(10, OUTPUT);
 
  // see if the card is present and can be initialized:
  if (!SD.begin(chipSelect)) {
    Serial.println("Card init. failed!");
    //error(1);
  }

  strcpy(buffer, "GPSLOG00.TXT");
  for (i = 0; i < 100; i++) {
    Serial.print('0'+i-48);
    buffer[6] = '0' + i/10;
    buffer[7] = '0' + i%10;
    // create if does not exist, do not open existing, write, sync after write
    if (! SD.exists(buffer)) {
      break;
    }
  }
  Serial.println(">");
  logfile = SD.open(buffer, FILE_WRITE);
  if( ! logfile ) {
    Serial.print("Couldnt create "); Serial.println(buffer);
    //error(3);
  }
  Serial.print("Writing to "); Serial.println(buffer);
 
  // connect to the GPS at the desired rate
  gpsSerial.begin(GPSRATE);
 
  Serial.println("Ready!");
 

  delay(250);
  digitalWrite(qualityPin, LOW); 
  //delay(100);
  // uncomment this line to turn on RMC (recommended minimum) and GGA (fix data) including altitude
  GPS.sendCommand(PMTK_SET_NMEA_OUTPUT_RMCGGA);
  //delay(100);
  // uncomment this line to turn on only the "minimum recommended" data
  //GPS.sendCommand(PMTK_SET_NMEA_OUTPUT_RMCONLY);
  // For parsing data, we don't suggest using anything but either RMC only or RMC+GGA since
  // the parser doesn't care about other sentences at this time
 
  // Set the update rate
  GPS.sendCommand(PMTK_ENABLE_WAAS);   
  GPS.sendCommand(PMTK_SET_NMEA_UPDATE_1HZ);// 1 Hz update ratE
   //delay(100);   
}

void loop() {
  //Serial.println(Serial.available(), DEC);
  char c;
  uint8_t sum;

  // read one 'line'
  if (gpsSerial.available()) {
    c = gpsSerial.read();
#if ARDUINO >= 100
    //Serial.write(c);
#else
    //Serial.print(c, BYTE);
#endif
    if (bufferidx == 0) {
      while (c != '$')
        c = gpsSerial.read(); // wait till we get a $
    }
    buffer[bufferidx] = c;

#if ARDUINO >= 100
    //Serial.write(c);
#else
    //Serial.print(c, BYTE);
#endif
    if (c == '\n') {
      //putstring_nl("EOL");
      //Serial.print(buffer);
      buffer[bufferidx+1] = 0; // terminate it

      if (buffer[bufferidx-4] != '*') {
        // no checksum?
        Serial.print('*');
        bufferidx = 0;
        return;
      }
      // get checksum
    if (strstr(buffer, "GPRMC")) {
      sum = parseHex(buffer[bufferidx-3]) * 16;
      sum += parseHex(buffer[bufferidx-2]);
      //Serial.println(sum, HEX);
      // check checksum
      for (i=1; i < (bufferidx-4); i++) {
        //Serial.print(i);
        //Serial.print(",");
        //Serial.print(buffer[i]);
        sum ^= buffer[i];
      }
      //Serial.println(sum, HEX);
      if (sum != 0) {
        //putstring_nl("Cxsum mismatch");
        Serial.print('~');
        bufferidx = 0;
        return;
      }
    }
      // got good data!

        //
      if (strstr(buffer, "GPGGA")) {
        // find out QUALITY
        char *r = buffer;
        r = strchr(r, ',')+1;
        r = strchr(r, ',')+1;       // skip to 3rd item
        r = strchr(r, ',')+1;
        r = strchr(r, ',')+1;       // skip to 3rd item
        r = strchr(r, ',')+1;
        r = strchr(r, ',')+1;       // skip to 3rd item
        Serial.println(r[0]);
        //Serial.print(buffer);
        if (r[0] == '2') {
          digitalWrite(qualityPin, HIGH);

        } else {
          digitalWrite(qualityPin, LOW);

        }
      }

      //for (int t = 1;t<100;t++) Serial.print(">");
      //Serial.println("?");
      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(fixPin, LOW);
          fix = 0;
        } else {
          digitalWrite(fixPin, HIGH);
          fix = 1;
        }
      }
     

     
      if (LOG_RMC_FIXONLY) {
        if (!fix) {
          Serial.print('_');
          bufferidx = 0;
          return;
        }
      }

      // rad. lets log it!
      Serial.print(buffer);
      Serial.print('#');
           // sets the digital pin as output

      // Bill Greiman - need to write bufferidx + 1 bytes to getCR/LF
      bufferidx++;

     if (strstr(buffer, "GPRMC")) {
       digitalWrite(writePin, HIGH);
       logfile.write((uint8_t *) buffer, bufferidx);
       logfile.flush();
       delay(250);
      digitalWrite(writePin, LOW);
      }
     
      bufferidx = 0;
      //Serial.print("idx");
       //Serial.print(bufferidx);

    }
    bufferidx++;
    if (bufferidx == BUFFSIZE-1) {

       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 */
jhyden
 
Posts: 19
Joined: Fri Apr 27, 2012 8:36 pm

Re: Adafruit_RGBLCDShield lcd = Adafruit_RGBLCDShield();

by adafruit_support_bill on Wed May 23, 2012 1:15 pm

You have some good sized buffers and a lot of string-literals. I suspect that RAM is the problem. This article describes the memory limitations and some memory-saving techniques.http://itp.nyu.edu/~gpv206/2008/04/making_the_most_of_arduino_mem.html

I'd start with the strings. You can reduce the RAM footprint of any quoted strings by using the "F()" function to specify Flash-only storage - as in:

Code: Select all | TOGGLE FULL SIZE
        Serial.println(F("Card init. failed!"));
User avatar
adafruit_support_bill
 
Posts: 31701
Joined: Sat Feb 07, 2009 10:11 am

Re: Adafruit_RGBLCDShield lcd = Adafruit_RGBLCDShield();

by jhyden on Wed May 23, 2012 1:18 pm

my bad
I forgot, I am not reading in the interrupt but in the main loop. IN another sketch, I do read in the interrupt. But either way, I have problems.
jhyden
 
Posts: 19
Joined: Fri Apr 27, 2012 8:36 pm

Re: Adafruit_RGBLCDShield lcd = Adafruit_RGBLCDShield();

by jhyden on Wed May 23, 2012 1:35 pm

Will Serial.println(F()); also work lcd.println(F()); when I send to the lcd instead of the serial monitor?
jhyden
 
Posts: 19
Joined: Fri Apr 27, 2012 8:36 pm

Re: Adafruit_RGBLCDShield lcd = Adafruit_RGBLCDShield();

by adafruit_support_bill on Wed May 23, 2012 1:44 pm

It should work for all the quoted strings in the sketch.
User avatar
adafruit_support_bill
 
Posts: 31701
Joined: Sat Feb 07, 2009 10:11 am

Re: Adafruit_RGBLCDShield lcd = Adafruit_RGBLCDShield();

by jhyden on Wed May 23, 2012 4:14 pm

That was the problem, thanks! Just one question. Adafruit_GPS returns a latitude that is a float and the sd logger needs a char string. How do I change from one to other?
jhyden
 
Posts: 19
Joined: Fri Apr 27, 2012 8:36 pm

Re: Adafruit_RGBLCDShield lcd = Adafruit_RGBLCDShield();

by adafruit_support_bill on Wed May 23, 2012 8:45 pm

Here is one solution to printing floats:
http://arduino.cc/playground/Code/PrintFloats
User avatar
adafruit_support_bill
 
Posts: 31701
Joined: Sat Feb 07, 2009 10:11 am

Re: Adafruit_RGBLCDShield lcd = Adafruit_RGBLCDShield();

by jhyden on Wed May 23, 2012 10:32 pm

I pounded out a solution. It may not be elegant but it is simple. Since the latitude and longitude of the us is fairly consistent where I plan to use the GPS, it was easier to come up with function than trying to write one for anywhere on the earth.
Code: Select all | TOGGLE FULL SIZE
// Test code for Adafruit GPS modules using MTK3329/MTK3339 driver
//
// This code shows how to listen to the GPS module in an interrupt
// which allows the program to have more 'freedom' - just parse
// when a new NMEA sentence is available! Then access data when
// desired.
//
// Tested and works great with the Adafruit Ultimate GPS module
// using MTK33x9 chipset
//    ------> http://www.adafruit.com/products/746
// Pick one up today at the Adafruit electronics shop
// and help support open source hardware & software! -ada
#include <Wire.h>
#include <SD.h>
#include <Adafruit_MCP23017.h>
#include <Adafruit_RGBLCDShield.h>
#include <Adafruit_GPS.h>
Adafruit_RGBLCDShield lcd = Adafruit_RGBLCDShield();
 #include <SoftwareSerial.h>


// Connect the GPS Power pin to 5V
// Connect the GPS Ground pin to ground
// If using software serial (sketch example default):
//   Connect the GPS TX (transmit) pin to Digital 7
//   Connect the GPS RX (receive) pin to Digital 8
// If using hardware serial (e.g. Arduino Mega):
//   Connect the GPS TX (transmit) pin to Arduino RX1, RX2 or RX3
//   Connect the GPS RX (receive) pin to matching TX1, TX2 or TX3

// If using software serial, keep these lines enabled
// (you can change the pin numbers to match your wiring):

  SoftwareSerial mySerial(7, 8);

Adafruit_GPS GPS(&mySerial);
// If using hardware serial (e.g. Arduino Mega), comment
// out the above six lines and enable this line instead:
//Adafruit_GPS GPS(&Serial1);


// Set GPSECHO to 'false' to turn off echoing the GPS data to the Serial console
// Set to 'true' if you want to debug and listen to the raw GPS sentences
#define GPSECHO  false

// this keeps track of whether we're using the interrupt
// off by default!
boolean usingInterrupt = false;
void useInterrupt(boolean); // Func prototype keeps Arduino 0023 happy
#define qualityPin 3
#define fixPin 2
#define writePin 4
#define chipSelect 10


#define BUFFSIZE 12
char buffer[BUFFSIZE];
uint8_t bufferidx = 0;
File logfile;
uint8_t i;
uint8_t counter = 0;
char *floatToAscii(float);

void setup() 
{
  Serial.begin(9600);
  //
   pinMode(fixPin, OUTPUT);
  pinMode(writePin, OUTPUT);
  pinMode(qualityPin, OUTPUT);
  digitalWrite(qualityPin, HIGH);
  delay(500);
  digitalWrite(qualityPin, LOW);
  digitalWrite(fixPin, HIGH);
  delay(500); 
  digitalWrite(fixPin, LOW); 
  // connect at 115200 so we can read the GPS fast enough and echo without dropping chars
  // also spit it out
  lcd.begin(16, 2);
 
  // 9600 NMEA is the default baud rate for Adafruit MTK GPS's- some use 4800
  GPS.begin(9600);
 
  // uncomment this line to turn on RMC (recommended minimum) and GGA (fix data) including altitude
  GPS.sendCommand(PMTK_SET_NMEA_OUTPUT_RMCGGA);
 
  // Set the update rate
  GPS.sendCommand(PMTK_SET_NMEA_UPDATE_1HZ);   // 1 Hz update rate
  //GPS.sendCommand(PMTK_ENABLE_WAAS);    // ENABLE WAAS
  //GPS.sendCommand("$PMTK319,1*24");     // SBAS mode
 
 

  //Serial.println(F("\r\nGPSlogger"));
    // make sure that the default chip select pin is set to
  // output, even if you don't use it:
  pinMode(10, OUTPUT);
 
  // see if the card is present and can be initialized:
  if (!SD.begin(chipSelect)) {
    lcd.clear();
    lcd.setCursor(0,0);
    lcd.print(F("Card failed!"));
    //error(1);
  }

  strcpy(buffer, "LOG00.TXT");

  for (i = 0; i < 100; i++) {
    //Serial.print('0'+i-48);
    buffer[3] = '0' + i/10;
    buffer[4] = '0' + i%10;
    // create if does not exist, do not open existing, write, sync after write
    if (! SD.exists(buffer)) {
      break;
    }
  }
    buffer[9]=0;
  //Serial.println(F(">"));
  logfile = SD.open(buffer, FILE_WRITE);
  if( ! logfile ) {
    lcd.print(F("Couldnt create "));
    //Serial.println(buffer);
    //error(3);
  }   
  lcd.clear();
  lcd.setCursor(0,0);
  lcd.print(F("Write:"));
  //lcd.clear();

  lcd.print(buffer);
  lcd.setCursor(0,1);
  lcd.print(F("Ready!"));
 
 
  useInterrupt(true);

  delay(1000);
}


// Interrupt is called once a millisecond, looks for any new GPS data, and stores it
SIGNAL(TIMER0_COMPA_vect) {
  char c = GPS.read();
  // if you want to debug, this is a good time to do it!
  if (GPSECHO)
    if (c) UDR0 = c; 
    // writing direct to UDR0 is much much faster than Serial.print
    // but only one character can be written at a time.
}

void useInterrupt(boolean v) {
  if (v) {
    // Timer0 is already used for millis() - we'll just interrupt somewhere
    // in the middle and call the "Compare A" function above
    OCR0A = 0xAF;
    TIMSK0 |= _BV(OCIE0A);
    usingInterrupt = true;
  } else {
    // do not call the interrupt function COMPA anymore
    TIMSK0 &= ~_BV(OCIE0A);
    usingInterrupt = false;
  }
}

uint32_t timer = millis();
void loop()                     // run over and over again
{
  int CST;
  // in case you are not using the interrupt above, you'll
  // need to 'hand query' the GPS, not suggested :(
  if (! usingInterrupt) {
    // read data from the GPS in the 'main loop'
    char c = GPS.read();
    // if you want to debug, this is a good time to do it!
    if (GPSECHO)
      if (c) UDR0 = c;
      // writing direct to UDR0 is much much faster than Serial.print
      // but only one character can be written at a time.
  }
 
  // if a sentence is received, we can check the checksum, parse it...
  if (GPS.newNMEAreceived()) {
    // a tricky thing here is if we print the NMEA sentence, or data
    // we end up not listening and catching other sentences!
    // so be very wary if using OUTPUT_ALLDATA and trytng to print out data
    //Serial.println(GPS.lastNMEA());   // this also sets the newNMEAreceived() flag to false
 
    if (!GPS.parse(GPS.lastNMEA()))   // this also sets the newNMEAreceived() flag to false
      return;  // we can fail to parse a sentence in which case we should just wait for another
  }

  // if millis() or timer wraps around, we'll just reset it
  if (timer > millis())  timer = millis();

  // approximately every 2 seconds or so, print out the current stats
  if (millis() - timer > 6000) {
    timer = millis(); // reset the timer


    if (GPS.fix) {
    digitalWrite(fixPin, HIGH);     
    lcd.clear();
    lcd.setCursor(0,0);
      lcd.print(GPS.latitude, 4);
      lcd.print(F(" "));
      lcd.print(GPS.lat);
      lcd.setCursor(0,1);
      lcd.print(GPS.longitude, 4);
      lcd.print(F(" "));
      lcd.print(GPS.lon);
     
      delay(3000);
     
       lcd.clear();
      lcd.setCursor(0,0);
      //lcd.print("Sp");
      lcd.print(GPS.speed * 1.15078, 0);
      lcd.print(F("MPH"));
      lcd.print(F(" S:"));lcd.print(GPS.satellites);
      lcd.print(F(" Q:")); lcd.print((int)GPS.fixquality);
      //if (GPS.fixquality == 2) {  digitalWrite(qualityPin, HIGH);}
      //else {  digitalWrite(qualityPin, LOW);}
      lcd.setCursor(0,1);
      //lcd.print("An");
      lcd.print(GPS.angle, 0);
      lcd.print(F("Deg"));
      lcd.print(F(" A:"));lcd.print(GPS.altitude, 0);
      lcd.print(F("Ft"));
     
  digitalWrite(writePin, HIGH);
      bufferidx = 11;
      //Serial.println(GPS.latitude, 4);     
      char *buffer = floatToAscii(GPS.latitude);
      //strcpy(buffer, "00,testing\r\n");
      Serial.print(buffer);
      logfile.write((uint8_t *) buffer, bufferidx);
      logfile.flush();

 
  delay(250);
  digitalWrite(writePin, LOW);

    }
    else {lcd.print(F("Searching..."));}
  }
}

char *floatToAscii(float lat)
{
float temp =0;
int v1, val2, val3, v4, val5, val6, val7, val8;
  temp = lat*10000;
  //Serial.println(temp);
  v1 = (temp/10000000);
  buffer[0] = v1+48;
  temp = (temp-((float)v1*10000000));
  //Serial.println(v1);
  val2=(temp/1000000);
  buffer[1] = val2+48;
  temp = (temp-((float)val2*1000000));
  //Serial.println(val2);
  val3=(temp/100000);
  buffer[2] = val3+48;
  temp = (temp-((float)val3*100000));
  //Serial.println(val3);
  v4=(temp/10000);
  buffer[3] = v4+48;
  buffer[4] = '.';


  temp = (temp-((float)v4*10000));

 

 
  val5=(temp/1000);
  buffer[5] = val5+48;
  temp = (temp-((float)val5*1000));
  //Serial.println(val5);
  val6=(temp/100);
  buffer[6] = val6+48;
  temp = (temp-((float)val6*100));
  //Serial.println(val6);
  val7=(temp/10);
  buffer[7] = val7+48;
  temp = (temp-((float)val7*10));
  //Serial.println(val7);
  val8=(temp/1);
  buffer[8] = val8+48;
  buffer[9]='\r';
  buffer[10]='\n';
  buffer[11]=0;
 
  //Serial.print(buffer);
  return buffer;
}
jhyden
 
Posts: 19
Joined: Fri Apr 27, 2012 8:36 pm

Re: Adafruit_RGBLCDShield lcd = Adafruit_RGBLCDShield();

by jhyden on Fri Jun 01, 2012 9:06 am

My final sketch:
Code: Select all | TOGGLE FULL SIZE
    //John Hyden
    //June 1, 2012
    // Based on the test code for Adafruit GPS modules using MTK3329/MTK3339 driver
    //and the Adafruit lcd Shield test sketch and the Adafruit data logging test sketch
    // This code shows how to listen to the GPS module in an interrupt
    // which allows the program to have more 'freedom' - just parse
    // when a new NMEA sentence is available! Then access data when
    // desired.
    //
    // Tested and works great with the Adafruit Ultimate GPS module
    // using MTK33x9 chipset
    //    ------> http://www.adafruit.com/products/746
    // Pick one up today at the Adafruit electronics shop
    // and help support open source hardware & software! -ada
    #include <Wire.h>
    #include <SD.h>
    #include <Adafruit_MCP23017.h>
    #include <Adafruit_RGBLCDShield.h>
    #include <Adafruit_GPS.h>
    Adafruit_RGBLCDShield lcd = Adafruit_RGBLCDShield();
    #include <SoftwareSerial.h>


    // Connect the GPS Power pin to 5V
    // Connect the GPS Ground pin to ground
    // If using software serial (sketch example default):
    //   Connect the GPS TX (transmit) pin to Digital 7
    //   Connect the GPS RX (receive) pin to Digital 8
    // If using hardware serial (e.g. Arduino Mega):
    //   Connect the GPS TX (transmit) pin to Arduino RX1, RX2 or RX3
    //   Connect the GPS RX (receive) pin to matching TX1, TX2 or TX3

    // If using software serial, keep these lines enabled
    // (you can change the pin numbers to match your wiring):

      SoftwareSerial mySerial(7, 8);

    Adafruit_GPS GPS(&mySerial);
    // If using hardware serial (e.g. Arduino Mega), comment
    // out the above six lines and enable this line instead:
    //Adafruit_GPS GPS(&Serial1);


    // Set GPSECHO to 'false' to turn off echoing the GPS data to the Serial console
    // Set to 'true' if you want to debug and listen to the raw GPS sentences
    #define GPSECHO  false

    // this keeps track of whether we're using the interrupt
    // off by default!
    boolean usingInterrupt = false;
    void useInterrupt(boolean); // Func prototype keeps Arduino 0023 happy
    #define qualityPin 3
    #define fixPin 5
    #define writePin 4
    #define chipSelect 10


    #define BUFFSIZE 30
    char buffer[BUFFSIZE];
    uint8_t bufferidx = 0;
    File logfile;
    uint8_t i;
    uint8_t counter = 0;
    uint8_t counter2 = 0;
    char *floatToAscii(float);
   

    void setup()
    {
      Serial.begin(9600);
      //
       pinMode(fixPin, OUTPUT);
      pinMode(writePin, OUTPUT);
      pinMode(qualityPin, OUTPUT);
      digitalWrite(qualityPin, HIGH);
      delay(500);
      digitalWrite(qualityPin, LOW);
      digitalWrite(fixPin, HIGH);
      delay(500);
      digitalWrite(fixPin, LOW);
      // connect at 115200 so we can read the GPS fast enough and echo without dropping chars
      // also spit it out
      lcd.begin(16, 2);

      // 9600 NMEA is the default baud rate for Adafruit MTK GPS's- some use 4800
      GPS.begin(9600);
     
      // uncomment this line to turn on RMC (recommended minimum) and GGA (fix data) including altitude
      GPS.sendCommand(PMTK_SET_NMEA_OUTPUT_RMCGGA);
     
      // Set the update rate
      GPS.sendCommand(PMTK_SET_NMEA_UPDATE_1HZ);   // 1 Hz update rate
      //GPS.sendCommand(PMTK_ENABLE_WAAS);    // ENABLE WAAS
      //GPS.sendCommand("$PMTK319,1*24");     // SBAS mode
     
     

      //Serial.println(F("\r\nGPSlogger"));
        // make sure that the default chip select pin is set to
      // output, even if you don't use it:
      pinMode(10, OUTPUT);
     
      // see if the card is present and can be initialized:
      if (!SD.begin(chipSelect)) {
        lcd.clear();
        lcd.setCursor(0,0);
        lcd.print(F("Card failed!"));
        //error(1);
      }

      strcpy(buffer, "LOG00.TXT");

      for (i = 0; i < 100; i++) {
        //Serial.print('0'+i-48);
        buffer[3] = '0' + i/10;
        buffer[4] = '0' + i%10;
        // create if does not exist, do not open existing, write, sync after write
        if (! SD.exists(buffer)) {
          break;
        }
      }
        buffer[9]=0;
      //Serial.println(F(">"));
      logfile = SD.open(buffer, FILE_WRITE);
      if( ! logfile ) {
        lcd.print(F("Couldnt create "));
        //Serial.println(buffer);
        //error(3);
      }   
      lcd.clear();
      lcd.setCursor(0,0);
      lcd.print(F("Write:"));
      //lcd.clear();

      lcd.print(buffer);
      lcd.setCursor(0,1);
      lcd.print(F("Ready!"));
     
     
      useInterrupt(true);

      delay(1000);
    }


    // Interrupt is called once a millisecond, looks for any new GPS data, and stores it
    SIGNAL(TIMER0_COMPA_vect) {
      char c = GPS.read();
      // if you want to debug, this is a good time to do it!
      if (GPSECHO)
        if (c) UDR0 = c;
        // writing direct to UDR0 is much much faster than Serial.print
        // but only one character can be written at a time.
    }

    void useInterrupt(boolean v) {
      if (v) {
        // Timer0 is already used for millis() - we'll just interrupt somewhere
        // in the middle and call the "Compare A" function above
        OCR0A = 0xAF;
        TIMSK0 |= _BV(OCIE0A);
        usingInterrupt = true;
      } else {
        // do not call the interrupt function COMPA anymore
        TIMSK0 &= ~_BV(OCIE0A);
        usingInterrupt = false;
      }
    }

    uint32_t timer = millis();
    void loop()                     // run over and over again
    {
      int CST;
      // in case you are not using the interrupt above, you'll
      // need to 'hand query' the GPS, not suggested :(
      if (! usingInterrupt) {
        // read data from the GPS in the 'main loop'
        char c = GPS.read();
        // if you want to debug, this is a good time to do it!
        if (GPSECHO)
          if (c) UDR0 = c;
          // writing direct to UDR0 is much much faster than Serial.print
          // but only one character can be written at a time.
      }
     
      // if a sentence is received, we can check the checksum, parse it...
      if (GPS.newNMEAreceived()) {
        // a tricky thing here is if we print the NMEA sentence, or data
        // we end up not listening and catching other sentences!
        // so be very wary if using OUTPUT_ALLDATA and trytng to print out data
        //Serial.println(GPS.lastNMEA());   // this also sets the newNMEAreceived() flag to false
     
        if (!GPS.parse(GPS.lastNMEA()))   // this also sets the newNMEAreceived() flag to false
          return;  // we can fail to parse a sentence in which case we should just wait for another
      }

      // if millis() or timer wraps around, we'll just reset it
      if (timer > millis())  timer = millis();

      // approximately every 2 seconds or so, print out the current stats
      if (millis() - timer > 6000) {
        timer = millis(); // reset the timer


        if (GPS.fix) {
        digitalWrite(fixPin, HIGH);     
        lcd.clear();
        lcd.setCursor(0,0);
         
          if (counter >= 255) {counter2++;}
          counter++;
          if (counter == 0){counter = 1;}
          lcd.print(GPS.latitude, 4);
          lcd.print(F(" "));
          lcd.print(GPS.lat);
          lcd.print(F(" "));
          lcd.print(counter2);
          lcd.setCursor(0,1);
          lcd.print(GPS.longitude, 4);
          lcd.print(F(" "));
          lcd.print(GPS.lon);
          lcd.print(F(" "));
          lcd.print(counter);
         
          delay(3000);
         
           lcd.clear();
          lcd.setCursor(0,0);
          //lcd.print("Sp");
          lcd.print(GPS.speed * 1.15078, 0);
          lcd.print(F("MPH"));
          lcd.print(F(" S:"));lcd.print(GPS.satellites);
          lcd.print(F(" Q:")); lcd.print((int)GPS.fixquality);
          //if (GPS.fixquality == 2) {  digitalWrite(qualityPin, HIGH);}
          //else {  digitalWrite(qualityPin, LOW);}
          lcd.setCursor(0,1);
          //lcd.print("An");
          lcd.print(GPS.angle, 0);
          lcd.print(F("Deg"));
          lcd.print(F(" A:"));lcd.print(GPS.altitude*3.2808399, 0);
          lcd.print(F("Ft"));
         
      digitalWrite(writePin, HIGH);
          bufferidx = BUFFSIZE;
          //Serial.println(GPS.latitude, 4);     
          char *buffer = floatToAscii(GPS.latitude, GPS.longitude);
          //strcpy(buffer, "00,testing\r\n");
          Serial.print(buffer);
          logfile.write((uint8_t *) buffer, bufferidx);
          logfile.flush();

     
      delay(250);
      digitalWrite(writePin, LOW);

        }
        else {lcd.print(F("Searching..."));}
      }
    }

    char *floatToAscii(float lat, float lon)
    {
    float temp =0;
    int v1, val2, val3, v4, val5, val6, val7, val8, x=0;
      temp = lat*10000;
      v1 = (temp/10000000);
      buffer[0] = v1+48;
      temp = (temp-((float)v1*10000000));
      val2=(temp/1000000);
      buffer[1] = val2+48;
      buffer[2] = ',';
      temp = (temp-((float)val2*1000000));
      val3=(temp/100000);
      buffer[3] = val3+48;
      temp = (temp-((float)val3*100000));
      v4=(temp/10000);
      buffer[4] = v4+48;
      buffer[5] = '.';
      temp = (temp-((float)v4*10000));
      val5=(temp/1000);
      buffer[6] = val5+48;
      temp = (temp-((float)val5*1000));
      val6=(temp/100);
      buffer[7] = val6+48;
      temp = (temp-((float)val6*100));
      val7=(temp/10);
      buffer[8] = val7+48;
      temp = (temp-((float)val7*10));;
      val8=(temp/1);
      buffer[9] = val8+48;
      buffer[10]=',';
      buffer[11]='N';
      buffer[12]=',';
     
      temp = lon*10000;
      if (temp > 100000000){
        buffer[13] = '1';
        x=1;
        temp = temp - 100000000;
      }
      v1 = (temp/10000000);
      buffer[13+x] = v1+48;
      temp = (temp-((float)v1*10000000));
      val2=(temp/1000000);
      buffer[14+x] = val2+48;
      buffer[15+x] = ',';
      temp = (temp-((float)val2*1000000));
      val3=(temp/100000);
      buffer[16+x] = val3+48;
      temp = (temp-((float)val3*100000));
      v4=(temp/10000);
      buffer[17+x] = v4+48;
      buffer[18+x] = '.';
      temp = (temp-((float)v4*10000));
      val5=(temp/1000);
      buffer[19+x] = val5+48;
      temp = (temp-((float)val5*1000));
      val6=(temp/100);
      buffer[20+x] = val6+48;
      temp = (temp-((float)val6*100));
      val7=(temp/10);
      buffer[21+x] = val7+48;
      temp = (temp-((float)val7*10));
      val8=(temp/1);
      buffer[22+x] = val8+48;
      buffer[23+x]=',';
      buffer[24+x]='W';
      buffer[25+x]='\r';
      buffer[26+x]='\n';
      buffer[27+x]=0;

      return buffer;
    }
jhyden
 
Posts: 19
Joined: Fri Apr 27, 2012 8:36 pm

Re: Adafruit_RGBLCDShield lcd = Adafruit_RGBLCDShield();

by jhyden on Fri Jun 01, 2012 10:17 am

the gps lat and long format that i am writing to the logger looks like this:
42,58.2000,N,87,54.1104,W
42,58.2008,N,87,54.1104,W
42,58.2000,N,87,54.1104,W
42,58.2000,N,87,54.1104,W

I can then take the file into excel and easily create a decimal degree format for lat and long if I want or any number of other possibilities.
jhyden
 
Posts: 19
Joined: Fri Apr 27, 2012 8:36 pm