Help with Arduino Software serial Serial communication

Hello to all Members !

This is my very first post here so please excuse me for making mistakes :slight_smile: .

I am a hobbyist electronics technician and i recently started learning C language in order to be able to materialise small projects with Arduino.

I need guidance concerning a project im working on.

The project involves an arduino uno and two gps receiver units.

What i want to do is use the arduino to read the serial output of the two gps units then do some calculations and then turn on or off some leds.

The gps units transmit serial data NMEA.

The data string on Hyperterminal looks like this :

$GPGGA,123519,4807.038,N,01131.000,E,1,08,0.9,545.4,M,46.9,M,,47
$GPGSA,A,3,04,05,,09,12,,,24,,,,,2.5,1.3,2.1
39
$GPGSV,2,1,08,01,40,083,46,02,17,308,41,12,07,344,39,14,22,228,45*75

Just for the record here is a link that explains in detail what the above strings are about:
https://www.gpsinformation.org/dale/nmea.htm

what i want the arduino to do is read the below string (sentence) and ignore the rest.
$GPGSA,A,3,04,05,,09,12,,,24,,,,,2.5,1.3,2.1*39

Before i decide to turn to Arduino i used Pixace a little bit and i was able to do this by using these bits ( GSA ) as a qualifier and store all rest bits for later calculations ,A,3,04,05,,09,12,,,24,,,,,2.5,1.3,2.1*39

further more i need the serial to "timeout" if this ( GSA ) string is not transmitted for a period longer than 1 second.

The reason for the above is that first i only need the GSA sentence while i dont want my Microcontroller to "hang" waiting to receive this sentence (or any other) if the GPS unit is not connected.

After doing some research i came up empty about the "qualifier" while i found something about the timeouts and that was Stream.setTimeout() and Serial.readBytesUntil()

THANK YOU !!!

If you want to work with two gps receivers on the same Arduino then you need to use a Mega which has 3 spare HardwareSerial ports.

It is only practical to use one instance of Software Serial on an Uno or Nano as only one instance can listen at any one time.

...R
Serial Input Basics - simple reliable ways to receive data.

Thank you for taking time to write.

Yes i am aware of that. In my case i only need it to listen to one receiver at a time so the use of software serial is not a problem for me.

i also forgo to mention that i was able to receive all the gps data and echo them to the pc using this software serial example code:

If you want to ignore some messages you will still have to receive them so as to be able to identify those that you are interested in.

Have you looked at the parse example in the link I gave you?

...R

Robin2:
...R
Serial Input Basics - simple reliable ways to receive data.

Thank you ! this looks very helpful. ill read it !

Thow i have to admit 90% of the codes written there, i dont understand.

I am only a noob when it comes to programming. ive only started reading C like a month ago. :stuck_out_tongue:
I sure want to try though.

Robin2:
Have you looked at the parse example in the link I gave you?
...R

Well i actually just did... i do not understand the code :frowning:

The obvious question is, why are you trying to read the $GPGSA from two seperate GPSs at the same time, with the addition of a very specific timeout ?

HellasT:
Well i actually just did... i do not understand the code :frowning:

Unless you are more specific I don't know how to help.

I find that difficult things start to make sense after the 14th reading :slight_smile:

...R

srnet:
The obvious question is, why are you trying to read the $GPGSA from two seperate GPSs at the same time, with the addition of a very specific timeout ?

Not at the same time but in fact one after the other. That is what enables me to use the software serial.

The timeout is used because i want the arduino to warn me through a led if the devices are sending the GSA sentence or not. I do not want the arduino to wait indefinetly for the GSA to arrive because obviously that will not happen if for example some gps receiver is turned off or not set up properly.

Robin2:
Unless you are more specific I don't know how to help.

I find that difficult things start to make sense after the 14th reading :slight_smile:

...R

ill keep trying and get back for help !

$GPGGA,123519,4807.038,N,01131.000,E,1,08,0.9,545.4,M,46.9,M,,47
$GPGSA,A,3,04,05,,09,12,,,24,,,,,2.5,1.3,2.1
39
$GPGSV,2,1,08,01,40,083,46,02,17,308,41,12,07,344,39,14,22,228,45*75

So you read a line of text, and check whether it begins with $GPGSA. If so, you proceed with additional code.
Since SoftwareSerial is inherently blocking "I need to watch this pin really carefully and noone else can do much" code, I don't know if Robin2's tutorial will be of much use :frowning: You should be able to use the standard stream functions like setTimeout() and readStringUntil() (and anything coming in on the other softwareserial port at the same time will be lost.)

HellasT:
The timeout is used because i want the arduino to warn me through a led if the devices are sending the GSA sentence or not. I do not want the arduino to wait indefinetly for the GSA to arrive because obviously that will not happen if for example some gps receiver is turned off or not set up properly.

You can check if the GPS is connected and working by using a standard library function to see if the GPS fix is updating.

westfw:
So you read a line of text, and check whether it begins with $GPGSA. If so, you proceed with additional code.

Would it be practical to tell SoftwareSerial to stop listening after the desired text is found?

And then tell it to start again when the program is ready for more data.

...R

Robin2:
Would it be practical to tell SoftwareSerial to stop listening after the desired text is found?

Yes, I do exactly that in my tracker software; start software serial, wait X seconds for an updated fix , update location if a new fix is obtained, stop softwareserial.

NeoSWSerial is more reliable, especially if your sending commands to the GPS.

I found it necessary to stop softwareserial anyway, leaving it running intefered with access the LoRa device over SPI.

westfw:
So you read a line of text, and check whether it begins with $GPGSA. If so, you proceed with additional code.
Since SoftwareSerial is inherently blocking "I need to watch this pin really carefully and noone else can do much" code, I don't know if Robin2's tutorial will be of much use :frowning: You should be able to use the standard stream functions like setTimeout() and readStringUntil() (and anything coming in on the other softwareserial port at the same time will be lost.)

Exactly !!!

I do not need to monitor both GPS outputs at the same time.

I will explain further.

srnet:
You can check if the GPS is connected and working by using a standard library function to see if the GPS fix is updating.

I had no idea i can do that.

Robin2:
Would it be practical to tell SoftwareSerial to stop listening after the desired text is found?
And then tell it to start again when the program is ready for more data.
...R

After the desiredtext (what i call "qualifier") is found, (the "GSA" in my case) i need to sotre the bits that follow into variables (or string).
$GPGSA,A,3,04,05,,09,12,,,24,,,,,2.5,1.3,2.1*39
|--||--------bits to be stored----------|
I dont really need the serial to be "listening" after i get the bits i need.

srnet:
Yes, I do exactly that in my tracker software; start software serial, wait X seconds for an updated fix , update location if a new fix is obtained, stop softwareserial.
NeoSWSerial is more reliable, especially if your sending commands to the GPS.
I found it necessary to stop softwareserial anyway, leaving it running intefered with access the LoRa device over SPI.

I am not sending anything back to the GPS receiver units. so i am nit sure if closing the softwareserial will have any impact.

HellasT:
I dont really need the serial to be "listening" after i get the bits i need.

I think you now have all the ideas you need so time to start coding :slight_smile:

...R

I need to explain more to you... I should have done that in post #1. sorry for that.

About 4 years ago i came up with the idea of creating a circuit that would be used as a safety feature in a computer that requires GPS at all times (the reason for that is not important now).

the protocols involved here are RS-232 or RS-422 at baud rate 4.800.

I noticed that the receivers on their internal screen indicate an error estimation and it was then that i started thinking how to upgrade the above circuit in order to make it monitor not only the signal presence but also siglan quality.

I know that the GPS receivers use NMEA sentences. Each NMEA sentence provides different information. So the error estimation must have something to do with the receiver utilising some NMEA sentence to calculate error [DOP (dilution of precision)].

After googling for NMEA sentence i came up with this :
http://www.gpsinformation.org/dale/nmea.htm

GSA - GPS DOP and active satellites. This sentence provides details on the nature of the fix. It includes the numbers of the satellites being used in the current solution and the DOP. DOP (dilution of precision) is an indication of the effect of satellite geometry on the accuracy of the fix. It is a unitless number where smaller is better. For 3D fixes using 4 satellites a 1.0 would be considered to be a perfect number, however for overdetermined solutions it is possible to see numbers below 1.0.

Then i thought i can build a circuit that will read each GPS DOP value and select the best for me.

Then after working with a friend since i had no idea about programming at that time (not that i am much better now :p)

we found this article online:
http://www.husstechlabs.com/Introduction%20to%20GPS%20and%20PICAXE.pdf

and we structed a code (picaxe basic) based on that pdf (specially page 14)

Long story short is that we used the $GPGSA part of the gps string as a "qualifier" and dumped the rest bit into variables that later in our code we could process and figure out which gpsreceiver unit is more accurate.
If you take a look at the attached picture youll probably understand better what i say.

Now that i want to complete the same task with arduino, i think i probably dont need to save each individual bit into its own variable. Instead i might be able to get and save the whole NMEA sentence into a string, provided that i will later be able to process the parts of it that indicate the DOP of each receiver.
I hope i now make more sense :stuck_out_tongue:

HellasT:
I hope i now make more sense :stuck_out_tongue:

To me. all that condenses to "I need to identify the GPS message containing $GPGSA and ignore the other messages".

Have I missed something important (which I could easily have done)?

If I have got the right idea then I see no reason to change from the comment I made in Reply #15.

...R

HellasT:
I need to explain more to you... I should have done that in post #1. sorry for that.

Yes, your first post should have decribed your project, it saves everyones time.

If you had, I would have said you can probably do all you want with a few lines of code and the TinyGPSplus library.

srnet:
Yes, your first post should have decribed your project, it saves everyones time.

If you had, I would have said you can probably do all you want with a few lines of code and the TinyGPSplus library.

I apologise for that. wasnt done in purpose. I klnow that when asking for help you have to be clear about that you are asking.

I need to google about TinyGPSplus library.

Like i know almost nothing about programming and C language.

I definetly need to continue my C lessons.

Thank you again for helping me out. All people here. and ofcource im still open to any suggestions or ideas that you may come up with.