NEO-6M GPS Module
The NEO-6M/7M GPS module features high sensitivity, low power consumption, miniaturization, and high tracking sensitivity, greatly expanding its positioning coverage. In places where ordinary GPS receiver modules cannot perform positioning, such as under narrow urban skylines and in dense jungle environments, the NEO-6M can achieve high-precision positioning. The high sensitivity, small static drift, low power consumption, and lightweight volume of the module make it suitable for vehicle-mounted and handheld devices such as PDAs, vehicle monitoring, mobile phones, cameras, and other mobile positioning system applications, making it a good choice for GPS product applications.
Module Source
Purchase link: https://detail.tmall.com/item.htm?_u=52t4uge5db42&id=631125558647&skuId=5034971487695&spm=a1z09.2.0.0.47582e8dqqFD4i
Materials download: https://pan.baidu.com/s/1QvwMg9JbkzFauYmwExWcnQ Extraction code: 8888
Specifications
Operating voltage: 3.3V-5V Operating current: 10-26mA Control method: SPI
View Materials
Note: After the main power is disconnected, the backup battery can maintain the storage of GPS ephemeris data for about half an hour to support warm start or hot start, thereby achieving fast positioning. The first positioning takes a long time, so please ensure that positioning is performed outdoors.
Porting Process
Pin Selection
Port to Project
Our goal is to port the example to the ESP32-S3 dev board. Complete driver code has been provided for you. Follow the steps below to complete the porting. For detailed instructions on creating folders and new .c and .h files, refer to section 1.4.2 in the [DHT11 Temperature and Humidity Sensor] chapter; we will not repeat it here. However, here we replace the file names bsp_dht11.c and bsp_dht11.h with bsp_gps.c and bsp_gps.h, and change the folder name to GPS.
Write Code
In the file bsp_gps.c, write the following code.
/*
* LCSC-Openkits (LCKFB) software and hardware materials and related expansion board software and hardware materials are all open source on the official website.
* Dev board official website: www.lckfb.com
* Technical support resides on the forum; any technical questions are welcome for exchange and learning at any time.
* LCKFB Forum: club.szlcsc.com
* Follow our Bilibili account: [LCSC-Openkits (LCKFB)] to keep up with our latest updates!
* We do not make money by selling boards; we take cultivating engineers as our mission.
* Change Logs:
* Date Author Notes
* 2024-01-10 LCKFB-lp first version
*/
#include "bsp_gps.h"
#include "stdio.h"
#include "stdlib.h"
#include "string.h"
#define GPSRX_LEN_MAX 512
unsigned char GPSRX_BUFF[GPSRX_LEN_MAX];
unsigned int GPSRX_LEN = 0;
_SaveData Save_Data;
static void delay_ms(unsigned int ms)
{
vTaskDelay(ms / portTICK_PERIOD_MS);
}
static void delay_us(unsigned int us)
{
ets_delay_us(us);
}
static void delay_1ms(unsigned int ms)
{
vTaskDelay(ms / portTICK_PERIOD_MS);
}
static void delay_1us(unsigned int us)
{
ets_delay_us(us);
}
/******************************************************************
* Function Name: GPS_GPIO_Init
* Function Description: GPS pin initialization
* Function Parameters: band_rate GPS communication baud rate
* Function Return: None
* Author: LC
* Notes: Default baud rate is 9600
******************************************************************/
void GPS_GPIO_Init(uint32_t band_rate)
{
//Define UART configuration structure, must be initialized, otherwise it cannot work
uart_config_t uart_config={0};
uart_config.baud_rate = band_rate; //Configure baud rate
uart_config.data_bits = UART_DATA_8_BITS; //Configure data bits to 8
uart_config.parity = UART_PARITY_DISABLE; //Configure parity to none
uart_config.stop_bits = UART_STOP_BITS_1; //Configure stop bits to 1
uart_config.flow_ctrl = UART_HW_FLOWCTRL_DISABLE; //Disable hardware flow control
//Load the above parameters into the UART1 registers
uart_param_config(BSP_GPS_USART, &uart_config);
//Bind pins TX RX RTS=Not used CTS=Not used
uart_set_pin(BSP_GPS_USART, BSP_GPS_TX_PIN, BSP_GPS_RX_PIN, UART_PIN_NO_CHANGE, UART_PIN_NO_CHANGE);
//Install UART driver
uart_driver_install(BSP_GPS_USART, GPSRX_LEN_MAX, GPSRX_LEN_MAX, 0, NULL, 0);
//Create UART receive task
xTaskCreate(BSP_GPS_Handler, "BSP_GPS_Handler", 1024*2, NULL, configMAX_PRIORITIES, NULL);
}
/******************************************************************
* Function Name: GPS_Send_Bit
* Function Description: Send a single character to GPS
* Function Parameters: ch character to send
* Function Return: None
* Author: LC
* Notes: None
******************************************************************/
void GPS_Send_Bit(unsigned char ch)
{
uart_write_bytes(BSP_GPS_USART, (const char*)&ch, 1);
}
/******************************************************************
* Function Name: GPS_send_String
* Function Description: GPS sends a string
* Function Parameters: str string to send
* Function Return: None
* Author: LC
* Notes: None
******************************************************************/
void GPS_send_String(unsigned char *str)
{
uart_write_bytes(BSP_GPS_USART, (const char*)&str, strlen((const char*)str));
}
/******************************************************************
* Function Name: Hand
* Function Description: Identify whether there is a desired UART command in GPS data
* Function Parameters: command to identify
* Function Return: 1 identification successful 0 identification failed
* Author: LC
* Notes: None
******************************************************************/
uint8_t Hand(char *a)
{
if(strstr((const char*)GPSRX_BUFF,a)!=NULL)
{
return 1;
}
else
{
return 0;
}
}
/******************************************************************
* Function Name: CLR_Buf
* Function Description: Clear data received by UART
* Function Parameters: None
* Function Return: None
* Author: LC
* Notes: None
******************************************************************/
void CLR_Buf(void)
{
memset(GPSRX_BUFF, 0, GPSRX_LEN_MAX); //Clear
GPSRX_LEN = 0;
}
/******************************************************************
* Function Name: clrStruct
* Function Description: Clear GPS structure data
* Function Parameters: None
* Function Return: None
* Author: LC
* Notes: None
******************************************************************/
void clrStruct(void)
{
Save_Data.isGetData = 0;
Save_Data.isParseData = 0;
Save_Data.isUsefull = 0;
memset(Save_Data.GPS_Buffer, 0, GPS_Buffer_Length); //Clear
memset(Save_Data.UTCTime, 0, UTCTime_Length);
memset(Save_Data.latitude, 0, latitude_Length);
memset(Save_Data.N_S, 0, N_S_Length);
memset(Save_Data.longitude, 0, longitude_Length);
memset(Save_Data.E_W, 0, E_W_Length);
}
/******************************************************************
* Function Name: BSP_GPS_Handler
* Function Description:
* Function Parameters: None
* Function Return: None
* Author: LC
* Notes: None
******************************************************************/
void BSP_GPS_Handler(void)
{
while(1)
{
GPSRX_LEN = uart_read_bytes(BSP_GPS_USART, GPSRX_BUFF, GPSRX_LEN_MAX-1, 1000 / portTICK_PERIOD_MS);
if(GPSRX_LEN > 0) // Receive buffer is not empty
{
GPSRX_BUFF[GPSRX_LEN] = '\0';
printf("BUFF: %s\r\n",GPSRX_BUFF);
puts("");
if(GPSRX_BUFF[0] == '$' && GPSRX_BUFF[4] == 'M' && GPSRX_BUFF[5] == 'C')//Confirm whether the "GPRMC/GNRMC" frame data was received
{
memset(Save_Data.GPS_Buffer, 0, GPS_Buffer_Length); //Clear
memcpy(Save_Data.GPS_Buffer, GPSRX_BUFF, GPSRX_LEN); //Save data
Save_Data.isGetData = 1;
GPSRX_LEN = 0;
memset(GPSRX_BUFF, 0, GPSRX_LEN_MAX); //Clear
}
}
uart_flush(BSP_GPS_USART);
delay_ms(500);
}
}2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
In the file bsp_gps.h, write the following code.
/*
* LCSC-Openkits (LCKFB) software and hardware materials and related expansion board software and hardware materials are all open source on the official website.
* Dev board official website: www.lckfb.com
* Technical support resides on the forum; any technical questions are welcome for exchange and learning at any time.
* LCKFB Forum: club.szlcsc.com
* Follow our Bilibili account: [LCSC-Openkits (LCKFB)] to keep up with our latest updates!
* We do not make money by selling boards; we take cultivating engineers as our mission.
* Change Logs:
* Date Author Notes
* 2024-01-10 LCKFB-lp first version
*/
#ifndef _BSP_GPS_H
#define _BSP_GPS_H
#include <stdio.h>
#include "esp_log.h"
#include "freertos/FreeRTOS.h"
#include "freertos/task.h"
#include "driver/uart.h"
#include "driver/gpio.h"
#include "driver/i2c.h"
#include "sdkconfig.h"
#include "freertos/FreeRTOS.h"
#include "freertos/task.h"
#include "esp_log.h"
#include "freertos/queue.h"
#include <inttypes.h>
#include "sdkconfig.h"
#include "driver/gpio.h"
#include "esp_log.h"
#include "rom/ets_sys.h"
#include "esp_system.h"
#include "driver/gpio.h"
#include "driver/spi_master.h"
#include "driver/spi_common.h"
#include "hal/gpio_types.h"
#define BSP_GPS_TX_PIN 2 // UART TX pin
#define BSP_GPS_RX_PIN 1 // UART RX pin
#define BSP_GPS_USART UART_NUM_2 // UART2
//Define array lengths
#define GPS_Buffer_Length 255
#define UTCTime_Length 11
#define latitude_Length 11
#define N_S_Length 2
#define longitude_Length 12
#define E_W_Length 2
typedef struct SaveData
{
char GPS_Buffer[GPS_Buffer_Length];
char isGetData; //Whether GPS data was obtained
char isParseData; //Whether parsing is complete
char UTCTime[UTCTime_Length]; //UTC time
char latitude[latitude_Length]; //Latitude
char N_S[N_S_Length]; //N/S
char longitude[longitude_Length]; //Longitude
char E_W[E_W_Length]; //E/W
char isUsefull; //Whether positioning information is valid
} _SaveData;
extern _SaveData Save_Data;
void GPS_GPIO_Init(uint32_t band_rate);
void CLR_Buf(void);
uint8_t Hand(char *a);
void clrStruct(void);
void BSP_GPS_Handler(void);
#endif2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
Porting Verification
In the main function of your own project, write the following code.
/*
* LCSC-Openkits (LCKFB) software and hardware materials and related expansion board software and hardware materials are all open source on the official website.
* Dev board official website: www.lckfb.com
* Technical support resides on the forum; any technical questions are welcome for exchange and learning at any time.
* LCKFB Forum: club.szlcsc.com
* Follow our Bilibili account: [LCSC-Openkits (LCKFB)] to keep up with our latest updates!
* We do not make money by selling boards; we take cultivating engineers as our mission.
* Change Logs:
* Date Author Notes
* 2024-01-10 LCKFB-lp first version
*/
#include <stdio.h>
#include "GPS/bsp_gps.h"
#include "OLED/oled.h"
#include "string.h"
#include "esp_task_wdt.h"
void parseGpsBuffer(void);
void printGpsBuffer(void);
int app_main(void)
{
esp_task_wdt_deinit();
GPS_GPIO_Init(9600);
clrStruct();
OLED_Init(); //Initialize OLED
OLED_Clear();
printf("Start.......\r\n");
while(1)
{
parseGpsBuffer();
printGpsBuffer();
vTaskDelay(500 / portTICK_PERIOD_MS);
}
}
/******************************************************************
* Function Name: errorLog
* Function Description: Error log printing
* Function Parameters: num error code to output
* Function Return: None
* Author: LC
* Notes: None
******************************************************************/
void errorLog(int num)
{
while (1)
{
printf("ERROR%d\r\n",num);
vTaskDelay(1000 / portTICK_PERIOD_MS);
}
}
/******************************************************************
* Function Name: parseGpsBuffer
* Function Description: Parse the data sent by GPS
* Function Parameters: None
* Function Return: None
* Author: LC
* Notes: None
******************************************************************/
void parseGpsBuffer(void)
{
char *subString = NULL;
char *subStringNext = NULL;
char i = 0;
if (Save_Data.isGetData == 1)
{
Save_Data.isGetData = 0;
printf("**************\r\n");
printf("%s\r\n",Save_Data.GPS_Buffer);
for (i = 0 ; i <= 6 ; i++)
{
if (i == 0)
{
if ((subString = strstr(Save_Data.GPS_Buffer, ",")) == NULL)
errorLog(1); //Parse error
}
else
{
subString++;
if ((subStringNext = strstr(subString, ",")) != NULL)
{
char usefullBuffer[2];
switch(i)
{
case 1:memcpy(Save_Data.UTCTime, subString, subStringNext - subString);break; //Get UTC time
case 2:memcpy(usefullBuffer, subString, subStringNext - subString);break; //Get UTC time
case 3:memcpy(Save_Data.latitude, subString, subStringNext - subString);break; //Get latitude information
case 4:memcpy(Save_Data.N_S, subString, subStringNext - subString);break; //Get N/S
case 5:memcpy(Save_Data.longitude, subString, subStringNext - subString);break; //Get longitude information
case 6:memcpy(Save_Data.E_W, subString, subStringNext - subString);break; //Get E/W
default:break;
}
subString = subStringNext;
Save_Data.isParseData = 1;
if(usefullBuffer[0] == 'A')
Save_Data.isUsefull = 1;
else if(usefullBuffer[0] == 'V')
Save_Data.isUsefull = 0;
}
else
{
errorLog(2); //Parse error
}
}
}
}
}
/******************************************************************
* Function Name: printGpsBuffer
* Function Description: Output parsed data
* Function Parameters: None
* Function Return: None
* Author: LC
* Notes: None
******************************************************************/
void printGpsBuffer(void)
{
unsigned buff[100]={0};
if (Save_Data.isParseData)
{
Save_Data.isParseData = 0;
//Measured in Guangdong Shenzhen, found that UTC time has an 8-hour error
printf("Save_Data.UTCTime = ");
printf("%s",Save_Data.UTCTime);
printf("\r\n");
sprintf(buff,"T=\"%s\"",Save_Data.UTCTime);
OLED_ShowString(0,2,(unsigned char *)buff,8,1);
OLED_Refresh();
if(Save_Data.isUsefull)
{
Save_Data.isUsefull = 0;
//UART displays latitude
printf("Save_Data.latitude = ");
printf("%s",Save_Data.latitude);
//Screen displays latitude
sprintf(buff,"lat=\"%s\"",Save_Data.latitude);
OLED_ShowString(0,2+(8*1),(unsigned char *)buff,8,1);
OLED_Refresh();
//UART display
printf("Save_Data.N_S = ");
printf("%s\r\n",Save_Data.N_S);
//Screen display
sprintf(buff,"NS=\"%s\"",Save_Data.N_S);
OLED_ShowString(0,2+(8*2),(unsigned char *)buff,8,1);
OLED_Refresh();
//UART displays longitude
printf("Save_Data.longitude = ");
printf("%s",Save_Data.longitude);
printf("\r\n");
//Screen displays longitude
sprintf(buff,"lon=\"%s\"",Save_Data.longitude);
OLED_ShowString(0,2+(8*3),(unsigned char *)buff,8,1);
OLED_Refresh();
//UART display
printf("Save_Data.E_W = ");
printf("%s",Save_Data.E_W);
printf("\r\n");
//Screen display
sprintf(buff,"EW=\"%s\"",Save_Data.E_W);
OLED_ShowString(0,2+(8*4),(unsigned char *)buff,8,1);
OLED_Refresh();
//Overwrite the previous "not usefull" content
OLED_ShowString(0,64-8,(unsigned char *)" ",8,1);
OLED_Refresh();
}
else
{
OLED_ShowString(0,64-8,(unsigned char *)"not usefull",8,1);
OLED_Refresh();
printf("GPS DATA is not usefull!\r\n");
}
}
}2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
Because positioning is not possible indoors, the GPS is placed outdoors and a [0.96 inch IIC monochrome screen] is used to display positioning information. GPS driver code:
File Download
📌 Materials Download Center (click to jump)
📌 In the Materials Download Center -> Module Porting Materials Download, inside the compressed package of this chapter.