
ATGM336H-5N 系列是小尺寸高性能 BDS/GNSS 全星座定位导航模块,基于中科微第四代低功耗 GNSS SOC 单芯片 AT6558,支持多卫星导航系统及卫星增强系统,有 32 个跟踪通道,可同时接收六系统 GNSS 信号并联合定位导航授时,具备高灵敏度、低功耗、低成本优势,适用于车载导航、手持定位、可穿戴设备,可直接替换 Ublox MAX 系列模块。

| 引脚名称 | 描述 |
|---|---|
| G | GND(电源输入负极) |
| V | VCC(电源输入正极) |
| R | 串口通信传输RX引脚 |
| T | 串口通信传输TX引脚 |
供电电压: 3.3V-5V
连接方式:PH2.0 4P端子线
安装方式:螺丝固定

不会使用库文件的参考这里:库文件安装使用
库文件下载:点击下载
不会安装库文件的请点击这里:参考链接
示例程序(UNO开发板):点击下载
#include <TinyGPS++.h>
#include <SoftwareSerial.h>
TinyGPSPlus gps;
SoftwareSerial gps_ss(A5, A4);
void setup(){
gps_ss.begin(9600);
Serial.begin(9600);
}
void loop(){
while (gps_ss.available()) {
if (gps.encode(gps_ss.read())) {
if (gps.location.isValid()) {
Serial.println(gps.location.lat());
Serial.println(gps.location.lng());
}
}
}
}
ESP32 Python 示例(适用于Mixly IDE /米思齐)
(开发板选择 Python ESP32 【ESP32 Generic(4MB)】切换为代码模式上传 ):
from machine import UART, Pin
import time
import machine
# 示例程序
class GPSNMEA:
def __init__(self):
self._buf = bytearray()
self._lat = None
self._lon = None
self._fix_ok = False
self._sats = 0
self._fix_quality = 0
self._hdop = None
self._rmc_valid = False
self._utc_time = None
self._date = None
def has_fix(self):
return bool(self._fix_ok)
def latitude(self):
return self._lat
def longitude(self):
return self._lon
def satellites(self):
return self._sats
def hdop(self):
return self._hdop
def beijing_time(self):
dt = self.beijing_datetime_tuple()
if dt:
y, mo, d, hh, mm, ss = dt
return f"{y:04d}-{mo:02d}-{d:02d} {hh:02d}:{mm:02d}:{ss:02d}"
return None
def beijing_datetime_tuple(self):
if not self._utc_time or not self._date:
return None
day, month, year_2 = self._date
year_full = 2000 + year_2 if year_2 < 80 else 1900 + year_2
h, m, s = self._utc_time
try:
epoch = time.mktime((year_full, month, day, h, m, s, 0, 0))
epoch += 8 * 3600
y, mo, d, hh, mm, ss, _, _ = time.localtime(epoch)
return (y, mo, d, hh, mm, ss)
except:
return None
def feed(self, data):
if data is None:
return
if isinstance(data, int):
data = bytes([data])
elif isinstance(data, memoryview):
data = bytes(data)
elif isinstance(data, str):
data = data.encode('ascii', 'ignore')
self._buf.extend(data)
while True:
idx = self._buf.find(b'\n')
if idx < 0:
break
line = self._buf[:idx + 1]
self._buf = self._buf[idx + 1:]
try:
s = bytes(line).decode('ascii', 'ignore').strip()
except:
continue
if s:
self._handle_sentence(s)
def _handle_sentence(self, s):
if not s.startswith('$') or len(s) < 7:
return
if not self._checksum_ok(s):
return
fields = s.split('*', 1)[0].split(',')
tag = fields[0][1:]
if tag.endswith('RMC'):
self._parse_rmc(fields)
elif tag.endswith('GGA'):
self._parse_gga(fields)
self._fix_ok = self._rmc_valid or (self._fix_quality > 0)
@staticmethod
def _checksum_ok(sentence):
if not sentence.startswith('$') or '*' not in sentence:
return False
try:
data, cshex = sentence[1:].split('*', 1)
except ValueError:
return False
calc = 0
for ch in data:
calc ^= ord(ch)
try:
given = int(cshex.strip()[:2], 16)
except ValueError:
return False
return calc == given
@staticmethod
def _dm_to_deg(dm, neg):
if not dm or '.' not in dm:
return None
i = dm.find('.')
head, tail = dm[:i], dm[i:]
if len(head) < 3:
return None
try:
minutes = float(head[-2:] + tail)
degrees = float(head[:-2]) if head[:-2] else 0.0
except ValueError:
return None
dec = degrees + minutes / 60.0
return -dec if neg else dec
def _parse_rmc(self, f):
if len(f) < 7:
self._rmc_valid = False
return
if len(f) > 1 and f[1]:
try:
hh = int(f[1][0:2]); mm = int(f[1][2:4]); ss = int(f[1][4:6])
self._utc_time = (hh, mm, ss)
except:
pass
if len(f) > 9 and f[9]:
try:
dd = int(f[9][0:2]); mo = int(f[9][2:4]); yy = int(f[9][4:6])
self._date = (dd, mo, yy)
except:
pass
status = f[2] if len(f) > 2 else 'V'
self._rmc_valid = (status == 'A')
if not self._rmc_valid:
return
lat = self._dm_to_deg(f[3] if len(f) > 3 else ', (f[4] if len(f) > 4 else ') == 'S')
lon = self._dm_to_deg(f[5] if len(f) > 5 else ', (f[6] if len(f) > 6 else ') == 'W')
if (lat is not None) and (lon is not None):
self._lat, self._lon = lat, lon
def _parse_gga(self, f):
if len(f) < 10:
return
try:
self._fix_quality = int(f[6]) if f[6] else 0
except ValueError:
self._fix_quality = 0
try:
self._sats = int(f[7]) if f[7] else 0
except ValueError:
self._sats = 0
try:
self._hdop = float(f[8]) if f[8] else None
except ValueError:
self._hdop = None
if self._fix_quality > 0:
lat = self._dm_to_deg(f[2], f[3] == 'S') if len(f) > 4 else None
lon = self._dm_to_deg(f[4], f[5] == 'W') if len(f) > 6 else None
if (lat is not None) and (lon is not None):
self._lat, self._lon = lat, lon
uart = UART(1, baudrate=9600, tx=Pin(17), rx=Pin(16), timeout=1000)
gps = GPSNMEA()
def get_latitude():
return gps.latitude()
def get_longitude():
return gps.longitude()
def get_beijing_time():
return gps.beijing_time()
def get_beijing_datetime_tuple():
return gps.beijing_datetime_tuple()
def has_fix():
return gps.has_fix()
buf = bytearray(256)
# 这个变量必须有,获取时间块使用的这个变量
dt = (0,0,0,0,0,0)
while True:
# -----------------------串口数据切片处理------------------------------------
n = uart.any() # 检查 UART 缓冲区中是否有可读取的字节数量
if n:
# 防止读取的数据超过缓冲区长度
n = min(n, len(buf))
# 从 UART 中读取 n 个字节到 buf 数组中
read_bytes = uart.readinto(buf, n)
if read_bytes:
# 将实际读取的字节切片,并转换成 bytes 类型,传给 GPS 解析器
gps.feed(bytes(buf[:read_bytes]))
#-------------------------------------------------------------------------
if has_fix():
WeiDu = get_latitude()
JingDu = get_longitude()
dt = get_beijing_datetime_tuple()
print(('纬度:' + str(WeiDu)))
print(('经度:' + str(JingDu)))
time.sleep(1)
# 需先让GPS获取时间
if dt:
print('时间:',end ="")
print((str(dt[3]) + ' : '),end ="")
print((str(dt[4]) + ' : '),end ="")
print(str(dt[5]))
else:
print('解析失败')
示例程序(UNO开发板):点击下载

示例程序(ESP32开发板):点击下载

Arduino UNO 测试环境搭建
准备配件:
电路接线图:

ESP32 Python 测试环境搭建
Arduino UNO视频教程:点击查看
ESP32 Python视频教程:
Arduino UNO测试结论:
下入代码,即可在电脑串口看到自己的经度和纬度。注意:室内可能因为天线信号原因没法打印显示不了经度和纬度,最好在室外开阔区域测试
