Question for gps and interrupts

I have bought the Arduino Uno and the gps EM406A(GNSS Receiver - EM-506N5 - GPS-19629 - SparkFun Electronics) with this shield(GPS Shield Retail - RTL-09898 - SparkFun Electronics). The gps has 1Hz update rate. The gps is connected with the Arduino at pins 0,1 (UART) or pins 2,3 (DLINE) (GPS Shield Hookup Guide - SparkFun Learn). Is there any way in which I will be able to activate any interruption when I receive data? Where should I connect the gps? DLINE or UART? Is it possible for you to give me a code to correspond to the function mentioned above?

From: GPS Shield Hookup Guide - SparkFun Learn

If DLINE is selected, the GPS will be connected to digital pins 2 and 3 (default) or potentially any other digital pin.

So, it does not lock you into using pins 2 and 3, but does require using NewSoftSerial to read from the GPS.

Where should I connect the gps? DLINE or UART?

Where do you want to connect it? Connect it to UART if you aren't planning to use the Serial port for anything else, including debugging. Connect to DLINE if you need the Serial port for anything else.

Is it possible for you to give me a code to correspond to the function mentioned above?

Why? What's wrong with the code Sparkfun posted?

My problem is that I want to activate the interrupt every time that receive data from the gps. The code from the sparkfun only reads the gps. However, my program performs more function and has to read the gps only when it has data. How can I do it?

On every pass through loop, call the NewSoftSerial::available() function. If there is data to read, read it. No interrupts required.

When data from the gps comes is it saved in the serial until we read it?
With follow code do I have to read data only the moment it comes or when the half data has come?

  .  
  .
  .
if(uart_gps.available())
{
  Gps_read();
} 
 .
 .
 .
   

Gps_read();
{
while(uart_gps.available())     // While there is data on the RX 
  {
      int c = uart_gps.read();    // load the data into a variable...
      if(gps.encode(c))      // if there is a new valid sentence...
      {
        getgps(gps);         // then grab the data.
      }
  }

}

When data from the gps comes is it saved in the serial until we read it?

Yes. There is a buffer where incoming serial data is stored until you read it.

With follow code do I have to read data only the moment it comes or when the half data has come?

You read the data when you are ready to read it. The gps.encode() function will return true when the end of packet marker has arrived. Otherwise, the data is simply accumulated.

If the GPS is connected to a software serial port, then usart_gps is a really lousy name. If it is connected to the UART serial port, it already has a name - Serial.

I have connected the gps to the pins 2,3 (DLINE)
What should “if ” control, so that I can read the data from the gps just when they ready?

if(uart_gps.available())
{
  Gps_read();
}

or

int c = uart_gps.read();   
 if(gps.encode(c))
{
Gps_read();
}
Gps_read();
{
while(uart_gps.available())     // While there is data on the RX 
  {
      int c = uart_gps.read();    // load the data into a variable...
      if(gps.encode(c))      // if there is a new valid sentence...
      {
        getgps(gps);         // then grab the data.
      }
  }

}

I have connected the gps to the pins 2,3 (DLINE)

So, it is not connected to the UART. So, why is uart part of the name?

The first code snippet calls the Gps_read() function when there is data to read. This is good.

The second snippet has stuff all out of order. There may be nothing to read when the read() function is called. The next line of code expects that something useful was read. When the string is not complete, it calls the Gps_read function. This snippet deserves to meet the delete key.

The next snippet appears to be the Gps_read function, but is has problems. No return type is defined for the function, and the semicolon on the end forms the body of the function. Probably not a very useful function that way.

        getgps(gps);         // then grab the data.

This function, whatever it does, is called AFTER a complete sentence has been read from the GPS. It is not going to grab any data, unless you plan on throwing away the sentence that was just completed.

This function, whatever it does, is called AFTER a complete sentence has been read from the GPS. It is not going to grab any data, unless you plan on throwing away the sentence that was just completed.

The function getgps(gps) there is at sparkfun.

void getgps(TinyGPS &gps)
{
  
 
  float latitude, longitude;
  
  gps.f_get_position(&latitude, &longitude);
  
  Serial.print("Lat/Long: "); 
  Serial.print(latitude,5); 
  Serial.print(", "); 
  Serial.println(longitude,5);

}

Do I have to make any ckecks before I grab the data from the gps

 .
 . 
 .
while(uart_gps.available()) 
int c = uart_gps.read();   
if(gps.encode(c))
 {
       getgps(gps);         
  }
 .
 .
 .

do I have an immediate access to the latitude and longitude of what is stored in the buffer by using only this function [gps.f_get_position(&latitude, &longitude);] without above checks?

The initial question that I had asked you was if I can activate the interrupt so as to get immediately the data when these arrive. The gps is connected at pins 2,3 (DLINE).

The initial question that I had asked you was if I can activate the interrupt so as to get immediately the data when these arrive.

The GPS doesn't generate an interrupt when it has data to send. It simply sends it. So, no, you can't activate an interrupt handler to be called when there is data.

Do I have to make any ckecks before I grab the data from the gps

Yes. You need to make sure that a complete sentence has arrived. That is done by the gps.encode() function.

do I have an immediate access to the latitude and longitude of what is stored in the buffer by using only this function [gps.f_get_position(&latitude, &longitude);] without above checks?

You would not know whether the portion of the data containing the lat/lon values had arrived yet, so, no, you can't skip the checks.

Okay, I understand now.
Thanks for the answers!

In the original code example in TinyGPS library by Mikal Hart, there is a function called feed_gps, which he calls every time he loops to keep gps info up to date.

The GPS doesn't generate an interrupt when it has data to send. It simply sends it. So, no, you can't activate an interrupt handler to be called when there is data.

If GPS module is connected to pins 0 and 1, is there any possibility to activate an interrupt in order to get as fast as I can the incoming data?

If GPS module is connected to pins 0 and 1, is there any possibility to activate an interrupt in order to get as fast as I can the incoming data?

No. The GPS does not generate an interrupt. You need to make sure your code is checking for the presence of serial data often enough.

It's not like the GPS will be sending data all that often, or that the end of a packet will arrive all that often.

My GPS module gives pulse every 1s (PPS), I added interrupt for that. Maybe that is what you are talking about?
Then you can read the serial port until nothing is coming, and wait for next pulse from PPS?

Cheers,
Kari

The GPS does not generate an interrupt.

Ok I got this.
The problem is that the GPS routine must be running all the time -> using the sparkfun code. On Arduino board will be connected 4 ultrasonic sensors, one digital compass, tow servo and some leds. So I have no time to lose.

Does the buffer (serial port) generate an interrupt??? I mean, when the incoming date is stored, can the buffer generate an interrupt???

Alternative1….
Does the GPS send data all the time??? If not, can I start a timer that will interrupt the main program and will jump to GPS routine just before the incoming data arrives?

Alternative2…
If I connect the GPS to pins 2 and 3, and activate the external interrupt (pin 2 or 3, don’t know yet) what is going to happen? Will the CPU interrupt (when the firs pulse arrives) the main program and will jump to GPS routine and wait there till data transfer is completed??

My GPS module gives pulse every 1s (PPS), I added interrupt for that.

How did you do that? Can you please give me an example?

krew88:
Ok I got this.
The problem is that the GPS routine must be running all the time -> using the sparkfun code. On Arduino board will be connected 4 ultrasonic sensors, one digital compass, tow servo and some leds. So I have no time to lose.

I think you're underestimating how fast the Arduino is. It should easily be able to keep up with the GPS, read your sensors and drive a few servos. And have 90% of it's CPU time still available to solve chess problems :wink:

Note also that the serial input is buffered - 128 bytes I think, so there's no issue with having to read it as it arrives. You will just want to avoid the use of the delay() function in your code - make your code look like the blink without delay tutorial example.

krew88:

My GPS module gives pulse every 1s (PPS), I added interrupt for that.

How did you do that? Can you please give me an example?

Goto Arduino - Home and look for "attachInterrupt()" . Define a free pin your arduino has for external interrupt. Create serial reading routine inside your own function.

Does your GPS have PPS out signal?

Cheers,
Kari

wildbill:
I think you're underestimating how fast the Arduino is. It should easily be able to keep up with the GPS, read your sensors and drive a few servos. And have 90% of it's CPU time still available to solve chess problems :wink:

I disagree. These days I am working with kostas_koz on a project that records a few waypoints and after that it tries to find each waypoint. To do that I use a GPS and a digital Compass which gives me the angle of the next waypoint. In order to see the angle, longitude, latitude etc. I use the serial monitor. So in my code I have a lot of Serial.print() functions. I noticed that when I use Serial.print it delays to update the variables longitude and latitude (some times take about 30sec to update). But when I delete all Serial.print functions it updates about every second.
We also tried to use a timer and interrupt in order to get long and lat every 500ms, every 100ms and 50ms but the long and lat didn’t update not even once.

GaryP:
Does your GPS have PPS out signal?

According to manual it does.

krew88:
Alternative1….
Does the GPS send data all the time??? If not, can I start a timer that will interrupt the main program and will jump to GPS routine just before the incoming data arrives?

Alternative2…
If I connect the GPS to pins 2 and 3, and activate the external interrupt (pin 2 or 3, don’t know yet) what is going to happen? Will the CPU interrupt (when the firs pulse arrives) the main program and will jump to GPS routine and wait there till data transfer is completed??

What about alternative 1 and 2? Some help?

Serial.print() is the problem - as you have noted - I don't believe it returns until the string is sent, which is an age & an age in Arduino clock cycles. Is this debug code or something you'll need in the final application? Also, how fast are you moving - as in how often are you going to need to read the GPS? Do you need to capture position data every time it sends it?