GPS (Neo 6M) with STM32
This tutorial will cover the Interfacing of the GPS Module (Neo 6M) with the STM32. We will see how we can get the location, time, date, speed, altitude etc.
As we are going to use the UART for the data transmission, also the length of the data is unknown, This tutorial is going to use the UART Ring Buffer from one of my previous Posts. It is recommended that you first go through that tutorial, and make it work.
The GPS module Transmits the data via the UART in the NMEA format. In this tutorial, we will see how to decode it and extract the useful information from this data. The sample data in the NMEA format is shown below.
I am using STM32F103C8T6 (BluePill) for this tutorial.
- As shown above, I have enabled the UART1 for communicating with the GPS Module
- Also the I2C1 is enabled , so that we can connect the LCD and display the results on it.
The Settings for the UART and I2C are shown below.
- As shown above, the UART Baud Rate is configured at 9600 bps. This is according to the Neo 6M
- We also need to enable the UART interrupt for the ring buffer to work.
- Everything is set to default in the I2C Configuration.
- As shown above, The Tx Pin of the Module (Neo 6M) is connected with the PB7 (Rx Pin) of the Controller.
- We only need to receive data, and hence one pin is enough.
- The PB8 and PB9 of the controller are connected to the SCL and SDA Pins of the LCD1602.
- The Module and the LCD must be powered with the external 5V supply, as the Bluepill’s 5V won’t be enough for both of them.
As I have mentioned before, we need to use the UART Ring Buffer Library inorder to receive the data of unknown length. That is why the Ring Buffer Library will be included in the code.
Along with the Ring buffer, I have also written a Library to decode the NMEA Data and we need to include it in our project. The project structure is as shown below.
Let’s Take a look at the NMEA.c File
First we are going to look at the Function to decode the GGA
decodeGGAfunction can be used to decode the GGA String.
- The first parameter is the GGA Buffer, where the GGA string is saved, and the second parameter is the pointer to the GGA Structure, which is defined in the NMEA.h file.
Let’s see how the decoding actually works
Checking the Fix
- Here First we will try to find if the fix on the signal is valid or not.
- This can be done by checking the number, that comes after 6 commas (,) as shown in the picture below.
- If the number is 1, 2 or 6, indicating the fix is valid, we will reset the
inxvariable to 0, and start collecting data from the beginning.
- On the other hand, if the number is 0, indicating the fix is invalid, we will return from here.
Get the TIME
- Here we first copy the time into our buffer. The time data is as shown below.
- This data is still in the character format, and we need to change it to the numerical format.
- This can be done by using the
atoifunction, which is defined in the
stdlib.hfile, and can be used to convert the string into the number.
- This can be done by using the
- Then we extract the Hours (first 2 numbers), Minutes (the next 2 numbers) and seconds (the last 2 numbers) from the numerical time data.
- The later part of the code is to adjust according to the GMT offset defined in the beginning of the file.
- Finally we save this data into the
timelement of the GGA Structure.
Get the Latitude
- Here we first extract the Latitude data from the GGA Buffer as shown below.
if (strlen(buffer) < 6) return 2;is used to check if we have received any data, or if the buffer is empty return with error.
- Then we convert the buffer into the numerical format.
atoifunction will only convert the string upto the decimal point, so in above case, the
numvariable will only have the 3015
- In order to convert the data after the decimal point, we will first find the position of the decimal in the buffer. And then use the
atoifunction after that position.
- The next part is to convert the number we obtained, into the proper coordinates. For eg 1234 and 56789 should be converted to 12.3456789
- Then save the latitude data into the
lcationelement of the GGA Structure.
- The increment the inx variable and look for the N/S character to indicate the North/South.
- And save this into the the Structure again.
The rest of the data like Longitudes, Altitude, and the number of satellites is also obtained in the similar way. The code is commented properly at each step, and you can look at it to understand the process.
The main function
- First we define the
GGA and RMC bufferswhich can store the GGA and RMC string data.
- I have only used these 2 as they give enough information required. If you want more information, you can use others as well.
- Next we have defined the GPS structure to store all the results from the GGA Structure, and RMC Structure.
- GGA and RMC flags will be later used to confirm if the data received is valid or not.
lcdBufferwill store the data, which needs to be transmitted to the LCD
VCCTimeoutwill be used to verify if we are receiving any data or not.
- In the while loop, we wait for the “GGA” in the incoming buffer.
- The Wait_for function have timeout feature in it. So incase if the string is not detected after some time, the function will return error and the control goes to the next statement.
- If the “GGA” or “RMC” string gets detected in the incoming data, we will copy upto the “*” and save this data in the respective array.
- This data is processed in the decode function, and if the result is a success the flag will be set to 2, indicating the success.
- Otherwise the flag is set to 1, indicating that the string was received, but the decoding wasn’t successful.
- we also reset the VCC Timeout here, to indicate that the string was received, and there is no issue with the connection.
- Here we check if the GGA and RMC flags are set to 2, indicating that the decoding as success.
- If it is, then we send the time, date and location data to the LCD.
sprintffunction is used to convert the numerical data into the characters.
- If the GGA and RMC flags are set to 1, indicating that the GGA and RMC strings were received but the decoding wasn’t successful, we will print the relative information on the display indicating that we haven’t got the fix yet.
- If the
VCC Timeoutis 0, means that the GGA and RMC strings were not detected in the incoming buffer.
- This could only mean that either the voltage supply is insufficient, or the connection between the module and controller is faulty.
- We print the relative information on the display again.
Below are the Pictures of the display in all three cases:
- The VCC provided is 3.3 volts
- The fix is not valid
- Everything is fine
- STM32 Ethernet #10 HTTP Server (Basic) using LWIP NETCONN (RTOS) May 18, 2022
- STM32 Ethernet #9 TCP Server and Client using LWIP NETCONN (RTOS) April 26, 2022
- STM32 Ethernet #8 UDP Client using LWIP NETCONN (RTOS) April 16, 2022
- STM32 Ethernet #7 UDP Server using LWIP NETCONN (RTOS) April 9, 2022
- GPS (Neo 6M) with STM32 March 9, 2022
- BME280 with STM32 January 8, 2022