1

I have a GPS code that I need to run only once, but every different try gives me errors, including placing the whole code in void setup(). Is there any way that this code can be run just once? As of now, the code repeats itself, putting out data over and over again - I need just one set, right when the code is activated.

Here is the code:

#include <Adafruit_GPS.h>
#include <SoftwareSerial.h>

SoftwareSerial mySerial(3, 2);
Adafruit_GPS GPS(&mySerial);
#define GPSECHO  true
boolean usingInterrupt = false;
void useInterrupt(boolean); 

void setup() {
  Serial.begin(115200);
  Serial.println("Adafruit GPS library basic test!");
  GPS.begin(9600);
  GPS.sendCommand(PMTK_SET_NMEA_OUTPUT_RMCGGA);
  GPS.sendCommand(PMTK_SET_NMEA_UPDATE_1HZ);  
  GPS.sendCommand(PGCMD_ANTENNA);
  useInterrupt(true);
  delay(1000);
  mySerial.println(PMTK_Q_RELEASE);
}

SIGNAL(TIMER0_COMPA_vect) {
  char c = GPS.read();
#ifdef UDR0
  if (GPSECHO)
    if (c) UDR0 = c;  
#endif
}

void useInterrupt(boolean v) {
  if (v) {
    OCR0A = 0xAF;
    TIMSK0 |= _BV(OCIE0A);
    usingInterrupt = true;
  } else {
    TIMSK0 &= ~_BV(OCIE0A);
    usingInterrupt = false;
  }
}

uint32_t timer = millis();
void loop() {                  // run over and over again
  if (! usingInterrupt) {
    char c = GPS.read();
    if (GPSECHO)
      if (c) Serial.print(c);
  }
  if (GPS.newNMEAreceived()) {
    if (!GPS.parse(GPS.lastNMEA()))   
      return;

  if (timer > millis())
    timer = millis();

  if (millis() - timer > 2000) { 
    timer = millis(); // reset the timer
    Serial.print("\nTime: ");
    Serial.print(GPS.hour, DEC); Serial.print(':');
    Serial.print(GPS.minute, DEC); Serial.print(':');
    Serial.print(GPS.seconds, DEC); Serial.print('.');
    Serial.println(GPS.milliseconds);
    Serial.print("Date: ");
    Serial.print(GPS.day, DEC); Serial.print('/');
    Serial.print(GPS.month, DEC); Serial.print("/20");
    Serial.println(GPS.year, DEC);
    Serial.print("Fix: "); Serial.print((int)GPS.fix);
    Serial.print(" quality: "); Serial.println((int)GPS.fixquality); 
    if (GPS.fix) {
      Serial.print("Location: ");
      Serial.print(GPS.latitude, 4); Serial.print(GPS.lat);
      Serial.print(", "); 
      Serial.print(GPS.longitude, 4); Serial.println(GPS.lon);
      Serial.print("Location (in degrees, works with Google Maps): ");
      Serial.print(GPS.latitudeDegrees, 4);
      Serial.print(", "); 
      Serial.println(GPS.longitudeDegrees, 4);
      Serial.print("Speed (knots): "); Serial.println(GPS.speed);
      Serial.print("Angle: "); Serial.println(GPS.angle);
      Serial.print("Altitude: "); Serial.println(GPS.altitude);
      Serial.print("Satellites: "); Serial.println((int)GPS.satellites);
    }
  }
  }
}

I've been trying to get this for a while, and I'm new to programming!

  • How is the code 'activated'? – sa_leinad Nov 26 '16 at 2:10
0

Here's your sketch, modified to use my library, NeoGPS. It is smaller, faster, more reliable and more accurate than all other libraries.

I added a waitForFix routine that, well, waits for the GPS to get a fix. Then it calls printFix, just once:

#include <NMEAGPS.h>
#include <NeoSWSerial.h>

NeoSWSerial gpsSerial(3, 2);
NMEAGPS     GPS;
gps_fix     fix;

void setup()
{
  Serial.begin(115200);
  Serial.println( F("Run once!") ); // F macro saves RAM!

  gpsSerial.begin(9600);
  gpsSerial.println( F("$PMTK314,0,1,0,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0*28") ); // RMC & GGA only
  gpsSerial.println( F("$PMTK220,1000*1F") ); // 1Hz update rate

  waitForFix();
  printFix();
}

void loop()
{
}

void waitForFix()
{
  uint8_t fixes = 0;

  do {
    if (GPS.available( gpsSerial )) {
      fix = GPS.read();
      fixes++;
    }
  } while ((fixes < 2) && !fix.valid.location);

} // waitForFix

void printFix()
{
  Serial.print( F("Time: ") );
  if (fix.valid.time) {
    if (fix.dateTime.hours < 10)
      Serial.print( '0' );
    Serial.print(fix.dateTime.hours);
    Serial.print(':');
    if (fix.dateTime.hours < 10)
      Serial.print( '0' );
    Serial.print(fix.dateTime.minutes);
    Serial.print(':');
    if (fix.dateTime.hours < 10)
      Serial.print( '0' );
    Serial.print(fix.dateTime.seconds);
    Serial.print('.');
    if (fix.dateTime_cs < 10)
      Serial.print( '0' );
    Serial.print(fix.dateTime_cs);
  }
  Serial.println();

  Serial.print( F("Date: ") );
  if (fix.valid.date) {
    Serial.print(fix.dateTime.day);
    Serial.print('/');
    Serial.print(fix.dateTime.month);
    Serial.print('/');
    Serial.print( fix.dateTime.full_year() );
  }
  Serial.println();

  Serial.print( F("Fix status: ") );
  if (fix.valid.status)
    Serial.print( (int) fix.status );
  Serial.println();

  if (fix.valid.location) {
    Serial.print( F("Location: ") );
    Serial.print( fix.latitude(), 4 );
    Serial.print( F(", ") );
    Serial.println(fix.longitude(), 4);
  }

  if (fix.valid.speed) {
    Serial.print("Speed (knots): ");
    Serial.println( fix.speed() );
  }

  if (fix.valid.heading) {
    Serial.print( F("Angle: ") );
    Serial.println( fix.heading() );
  }

  if (fix.valid.altitude) {
    Serial.print( F("Altitude: ") );
    Serial.println( fix.altitude() );
  }

  if (fix.valid.satellites) {
    Serial.print( F("Satellites: ") );
    Serial.println( fix.satellites );
  }
}

The NeoGPS library waits for a complete batch of sentences, because the speed is in one sentence (RMC) and the altitude is in another sentence (see this table). NeoGPS provides complete "fixes", as assembled from all the sentences your GPS device sends. The fixes are available once per second, or whatever you have configured your device to provide.

You may also notice that I used another library I maintain, NeoSWSerial. SoftwareSerial is very inefficient because it disables interrupts for long periods of time. This can interfere with other parts of your sketch or other libraries.

If you can put the GPS on pins 8 & 9, AltSoftSerial would be even better. It only works on those two pins.

Your original sketch uses 12124 bytes of program space and 1031 bytes of RAM.

The NeoGPS version uses 10680 bytes of program space and 446 bytes of RAM. A significant savings!

  • But when trying to verify this sketch, I still get the same error, that the timer wasn't declared. – JMacris Nov 17 '16 at 20:25
  • Sorry, that wasnt the error, got mixed up. – JMacris Nov 17 '16 at 20:44
  • The error says; #include <NeoSWSerial.h> ^ compilation terminated. exit status 1 Error compiling for board Arduino/Genuino Uno. – JMacris Nov 17 '16 at 20:44
  • Did you download and install NeoSWSerial from the link? It's a standard Arduino library that you download, unzip, and copy the NeoSWSerial-master directory to a new Arduino/Libraries/NeoSWSerial subdirectory. – slash-dev Nov 17 '16 at 21:00
0

Put everything from your void loop() into your void setup. Put them AFTER the original setup and you should be good to go.

DO NOT DELETE THE VOID LOOP!! ONLY KEEP IT EMPTY!!

Here, try this:

#include <Adafruit_GPS.h>
#include <SoftwareSerial.h>


SoftwareSerial mySerial(3, 2);



Adafruit_GPS GPS(&mySerial);



#define GPSECHO  true


boolean usingInterrupt = false;
void useInterrupt(boolean);

void setup()
{


  Serial.begin(115200);
  Serial.println("Adafruit GPS library basic test!");


  GPS.begin(9600);


  GPS.sendCommand(PMTK_SET_NMEA_OUTPUT_RMCGGA);



  GPS.sendCommand(PMTK_SET_NMEA_UPDATE_1HZ);


  GPS.sendCommand(PGCMD_ANTENNA);


  useInterrupt(true);

  delay(1000);

  mySerial.println(PMTK_Q_RELEASE);

  if (! usingInterrupt) {

    char c = GPS.read();

    if (GPSECHO)
      if (c) Serial.print(c);
  }


  if (GPS.newNMEAreceived()) {


    if (!GPS.parse(GPS.lastNMEA()))
      return;


    if (timer > millis())  timer = millis();


    if (millis() - timer > 2000) {
      timer = millis(); // reset the timer

      Serial.print("\nTime: ");
      Serial.print(GPS.hour, DEC); Serial.print(':');
      Serial.print(GPS.minute, DEC); Serial.print(':');
      Serial.print(GPS.seconds, DEC); Serial.print('.');
      Serial.println(GPS.milliseconds);
      Serial.print("Date: ");
      Serial.print(GPS.day, DEC); Serial.print('/');
      Serial.print(GPS.month, DEC); Serial.print("/20");
      Serial.println(GPS.year, DEC);
      Serial.print("Fix: "); Serial.print((int)GPS.fix);
      Serial.print(" quality: "); Serial.println((int)GPS.fixquality);
      if (GPS.fix) {
        Serial.print("Location: ");
        Serial.print(GPS.latitude, 4); Serial.print(GPS.lat);
        Serial.print(", ");
        Serial.print(GPS.longitude, 4); Serial.println(GPS.lon);
        Serial.print("Location (in degrees, works with Google Maps): ");
        Serial.print(GPS.latitudeDegrees, 4);
        Serial.print(", ");
        Serial.println(GPS.longitudeDegrees, 4);

        Serial.print("Speed (knots): "); Serial.println(GPS.speed);
        Serial.print("Angle: "); Serial.println(GPS.angle);
        Serial.print("Altitude: "); Serial.println(GPS.altitude);
        Serial.print("Satellites: "); Serial.println((int)GPS.satellites);
      }
    }
  }
}



SIGNAL(TIMER0_COMPA_vect) {
  char c = GPS.read();

#ifdef UDR0
  if (GPSECHO)
    if (c) UDR0 = c;

#endif
}

void useInterrupt(boolean v) {
  if (v) {

    OCR0A = 0xAF;
    TIMSK0 |= _BV(OCIE0A);
    usingInterrupt = true;
  } else {

    TIMSK0 &= ~_BV(OCIE0A);
    usingInterrupt = false;
  }
}

uint32_t timer = millis();

void loop()                     // run over and over again
{
}
  • Dat Ha... After uploading this code, i recieved the error ' timer' was not declared in this scope, in this line if (millis() - timer > 2000) { – JMacris Nov 15 '16 at 21:08
  • Do you know what might be causing this?? – JMacris Nov 15 '16 at 21:08
  • void setup is a loop that run once. void loop is a code that runs and repeat. Open a blank sketch a see what happens. If it works, please consider accepting the answer to mark this question as resolved. – Dat Ha Nov 15 '16 at 21:11
  • 1
    Well, the error tells you that the variabele 'timer' was not declared... Which basically means you're missing your declaration of the timer variable: 'uint32_t timer = millis();' – Paul Nov 15 '16 at 21:12

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

Not the answer you're looking for? Browse other questions tagged or ask your own question.