Forum Rule: Always post complete source code & details to reproduce any issue!
Results 1 to 6 of 6

Thread: GPS Logging with Teensy 2

  1. #1
    Junior Member
    Join Date
    Feb 2013
    Posts
    4

    GPS Logging with Teensy 2

    Hello everybody,

    I have a Teensy 2, and i want to be able to log the NMEA message from a EM406 GPS

    I have take the sketch from http://www.ladyada.net/make/gpsshield/download.html
    and i want to use with HardwareSerial Uart for the serial btw gps and teensy

    The compilation seem to be good, the teensy run correctly (16 or 8mhz/sdcard), create the log file fine ... but log only ONE sequence in the file, or sometimes, nothing.

    If you have any suggestion ...

    Code:
    #include <SD.h>
    #include "GPSconfig.h"
    
    const int buttonPin = 17;     // Declare PIN 17 for USB mass-storage/charging control
    int buttonState = 0;          // State button int
    
    // what to log
    #define LOG_RMC 1 // RMC-Recommended Minimum Specific GNSS Data, message 103,04
    
    HardwareSerial Uart = HardwareSerial(); // Pin7 Rx Pin8 Tx
    
    // Set the pins used 
    #define led1Pin 15 // Green LED GPS valid position
    #define led2Pin 14 // Red LED Writing data on SDcard
    #define pin16 16 // USB and charging mode control
    #define chipSelect 0
    
    #define BUFFSIZE 90
    char buffer[BUFFSIZE];
    uint8_t bufferidx = 0;
    bool fix = false;
    bool gotGPRMC;
    uint8_t i;
    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;
    }
    
    // blink out an error code
    void error(uint8_t errno) {
    /*
      if (SD.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);
          delay(100);
          digitalWrite(led2Pin, HIGH);
          delay(100);
          digitalWrite(led1Pin, LOW);
          delay(100);
          digitalWrite(led2Pin, LOW);
          delay(100);
        }
        for (; i<10; i++) {
          delay(200);
        }
      }  
    }
    
    void setup() {
      pinMode(buttonPin, INPUT_PULLUP); // Set input button pin & pull-up on analog pin 17
      //Serial.begin(9600);
      //Serial.println("\r\nGPSlogger");
      pinMode(led1Pin, OUTPUT);
      pinMode(led2Pin, OUTPUT);
     
      // make sure that the default chip select pin is set to
      // output, even if you don't use it:
      pinMode(0, 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.LOG");
      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 (! SD.exists(buffer)) {
          break;
        }
      }
      logfile = SD.open(buffer, FILE_WRITE);
      if( ! logfile ) {
        //Serial.print("Couldnt create "); Serial.println(buffer);
        error(3);
      }
      //Serial.print("Writing to "); Serial.println(buffer); 
      //Serial.println("Ready!");
      
      Uart.begin(4800);
      delay(250);
    
    #if (LOG_RMC == 1)
        Serial.print(RMC_ON);
    #else
        Serial.print(RMC_OFF);
    #endif
      delay(250);
    }
    
    void loop() {
        char c;
        uint8_t sum;    
    
        buttonState = digitalRead(buttonPin); // Read button state
        if (buttonState == LOW) {
        digitalWrite(pin16, HIGH); // Enabling charging mode to LTC4054
        Serial.begin(9600);  // Start serial.begin, open SDCARD to get log
        delay(20000);
        } 
        else {
        Serial.end();  // Normal mode, disable USB for power saving (4ma off)
        }
      
      // read one 'line'
      if (Uart.available()) {
        c = Uart.read();
    #if ARDUINO >= 100
        //Serial.write(c);
    #else
        //Serial.print(c, BYTE);
    #endif
        if (bufferidx == 0) {
          while (c != '$')
            c = Uart.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
          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('~');
            bufferidx = 0;
            return;
          }
          // got good data!
          gotGPRMC = strstr(buffer, "GPRMC");
          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);
              delay(100);
              fix = false;
            } else {
              digitalWrite(led1Pin, HIGH);
              delay(100);
              digitalWrite(led1Pin, LOW);    // set the LED off
              delay(100);              // wait for a second
              fix = true;
            }
          }
          // rad. lets log it!
          //Serial.print(buffer);
          //Serial.print('#');
          
          if (gotGPRMC)      //If we have a GPRMC string
          {
            // Bill Greiman - need to write bufferidx + 1 bytes to getCR/LF
            bufferidx++;
            
          digitalWrite(led2Pin, HIGH);      // sets the digital pin as output
          delay(100);
                // Bill Greiman - need to write bufferidx + 1 bytes to getCR/LF
        
          logfile.write((uint8_t *) buffer, bufferidx);
          logfile.flush();
          /*
          if( != bufferidx) {
             putstring_nl("can't write!");
             error(4);
          }
          */
          digitalWrite(led2Pin, LOW);
          bufferidx = 0;
          }
           return;
          }
        }
        bufferidx++;
        if (bufferidx == BUFFSIZE-1) {
           Serial.print('!');
           bufferidx = 0;
        }
       }
    /* End code */

  2. #2
    Senior Member ZTiK.nl's Avatar
    Join Date
    Dec 2012
    Location
    Amsterdam
    Posts
    179
    Not sure if I can help, but I do have a suggestion you could try (its an easy one too).

    I use the Adafruit Ultimate GPS (MTK3339 not EM406) on a Teensy 3.0, and only I receive partial NMEA messages unless I set:
    Code:
    Serial.begin(115200);

  3. #3
    Junior Member
    Join Date
    Feb 2013
    Posts
    4
    Quote Originally Posted by ZTiK.nl View Post
    Not sure if I can help, but I do have a suggestion you could try (its an easy one too).

    I use the Adafruit Ultimate GPS (MTK3339 not EM406) on a Teensy 3.0, and only I receive partial NMEA messages unless I set:
    Code:
    Serial.begin(115200);
    thx ZTiK.nl

    the default baudrate of MTK3339 is 115200 ?
    because my EM406 use 4800 default u know

    u set it before receiving data ?

  4. #4
    Senior Member ZTiK.nl's Avatar
    Join Date
    Dec 2012
    Location
    Amsterdam
    Posts
    179
    Yeah I do, this is how I coded my setup() loop:
    Code:
    void setup()  
    {
      Serial.begin(115200); // connect at 115200 so we can read the GPS fast enough and echo without dropping chars
      Serial.println("Adafruit GPS library basic test!");
    
      // 9600 NMEA is the default baud rate for Adafruit MTK GPS's- some use 4800
      GPS.begin(9600);
      GPS.sendCommand(PMTK_SET_NMEA_OUTPUT_RMCGGA); // turn on RMC (recommended minimum)
      GPS.sendCommand(PMTK_SET_NMEA_UPDATE_1HZ); // Set the update rate
      Serial.println(PMTK_Q_RELEASE); // Ask for firmware version
    }

    This is straight out of the example ino file for my gps module.
    Not saying this HAS to work for you, but it would be a shame if this turned out to be the issue after many days troubleshooting :x

    Ow, my GPS module runs at 9600br as you can see above
    I have the GPS mod running at 9600br, but the Serial interface at 115200br
    Last edited by ZTiK.nl; 02-12-2013 at 05:40 PM. Reason: addition

  5. #5
    Junior Member
    Join Date
    Feb 2013
    Posts
    4
    finally rewrite the code with AltSerialSoft, and it work fine

    Code:
    #include <SD.h>
    #include <AltSoftSerial.h>
    
    const int buttonPin = 17;     // Declare PIN 17 for charging control
    int buttonState = 0;          // State button int
    
    // Set the pins used 
    #define led2Pin 15 //Get data from GPS
    #define pin16 16  //PILOT CHARGING
    ADCSRA = 0;   // shut off ADC
    
    AltSoftSerial gpsSerial;
    
    const int chipSelect = 0;
    
    #define BUFFSIZE 90
    char buffer[BUFFSIZE];
    uint8_t bufferidx = 0;
    bool fix = false; // current fix data
    bool gotGPRMC;    //true if current data is a GPRMC strinng
    //bool gotGPVTG;    //true if current data is a GPRMC strinng
    //bool gotGPGGA;    //true if current data is a GPRMC strinng
    uint8_t i;
    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;
    }
    
    // blink out an error code
    void error(uint8_t errno) {
    /*
      if (SD.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(led2Pin, HIGH);
          delay(100);
          digitalWrite(led2Pin, LOW);
          delay(100);
        }
        for (; i<10; i++) {
          delay(200);
        }
      }
    }
    
    void setup() {
      Serial.begin(9600);
      gpsSerial.begin(4800);
      gpsSerial.print("$PSRF103,04,00,255,01*25\r\n"); // 
      //gpsSerial.print("$PSRF103,00,01,60,00*25"); // 
        
      Serial.println("\r\nStarting...");
      pinMode(led2Pin, OUTPUT);
      pinMode(pin16, OUTPUT);
      // make sure that the default chip select pin is set to
      // output, even if you don't use it:
      pinMode(0, 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++) {
        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;
        }
      }
    
      logfile = SD.open(buffer, FILE_WRITE);
      if( ! logfile ) {
        Serial.print("Couldnt create"); 
        Serial.println(buffer);
        error(3);
      }
      Serial.print("Starting to log on ..."); 
      Serial.println(buffer);
      pinMode(buttonPin, INPUT_PULLUP); // Set input buttonpin & pull-up on analog pin 17
    }
    
    void loop() {
      //Serial.println(Serial.available(), DEC);
      char c;
      uint8_t sum;
    
      // read one 'line'
      if (gpsSerial.available()) {
        c = gpsSerial.read();
    
        if (bufferidx == 0) {
          while (c != '$')
            c = gpsSerial.read(); // wait till we get a $
        }
        buffer[bufferidx] = c;
    
        if (c == '\n') {
    
          buffer[bufferidx+1] = 0; // terminate it
    
          if (buffer[bufferidx-4] != '*') {
            // no checksum?
            Serial.print('*');
            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('~');
            bufferidx = 0;
            return;
          }
          // got good data!
    
          gotGPRMC = strstr(buffer, "GPRMC");
          if (gotGPRMC)
          {
            // 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] == 'A') {
              fix = false;
            } else {
              fix = true;
            }
          }      
          
          // rad. lets log it!
          
          Serial.print(buffer);    //first, write it to the serial monitor
          Serial.print('#');
          
          if (gotGPRMC)      //If we have a GPRMC string
          {
            // Bill Greiman - need to write bufferidx + 1 bytes to getCR/LF
            bufferidx++;
            delay(10000); //Write the sentence every 10 sec
            digitalWrite(led2Pin, HIGH);      // Turn on LED 2 (indicates write to SD)
    
            logfile.write((uint8_t *) buffer, bufferidx);    //write the string to the SD file
            logfile.flush();
            /*
            if( != bufferidx) {
               putstring_nl("can't write!");
               error(4);
            }
            */
    
            digitalWrite(led2Pin, LOW);    //turn off LED2 (write to SD is finished)
            bufferidx = 0;    //reset buffer pointer
            return;
          }//if (gotGPRMC)
          
        }
        bufferidx++;
        if (bufferidx == BUFFSIZE-1) {
           Serial.print('!');
           bufferidx = 0;
        }
      } else {
    
      }
      
        buttonState = digitalRead(buttonPin); // Read button state
        if (buttonState == LOW) {
        digitalWrite(pin16, HIGH); // Enabling charging mode to LTC4054
        }
    
    }
    /* End code */

  6. #6
    Junior Member
    Join Date
    Feb 2013
    Posts
    4
    finally work fine
    http://www.weirdlab.fr/?p=39

    thx everyone

Posting Permissions

  • You may not post new threads
  • You may not post replies
  • You may not post attachments
  • You may not edit your posts
  •