帮助文档

HS-S78P GPS定位模块

目 录 (点击目录列表可以跳转到相应位置)

  1. 介绍
  2. 原理图
  3. 模块参数
  4. 电路板尺寸
  5. 添加Arduino库文件
  6. 添加Micropython库文件
  7. ArduinoIDE 和Python语言示例程序
  8. 米思齐 Mixly 示例程序(图形化语言)
  9. Arduino测试环境搭建
  10. 视频教程
  11. 测试结论

1、介绍 点这里回到目录

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


2、原理图 点这里回到目录

HS-S78P GPS定位模块


3、模块参数 点这里回到目录

引脚名称 描述
G GND(电源输入负极)
V VCC(电源输入正极)
R 串口通信传输RX引脚
T 串口通信传输TX引脚

  • 供电电压: 3.3V-5V

  • 连接方式:PH2.0 4P端子线

  • 安装方式:螺丝固定


4、电路板尺寸 点这里回到目录

HS-S78P GPS定位模块


5、添加Arduino库文件

不会使用库文件的参考这里库文件安装使用

库文件下载:点击下载


6、添加MicroPython环境库文件 点这里回到目录

不会安装库文件的请点击这里:参考链接


7、Arduino IDE示例程序 点这里回到目录

示例程序(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('解析失败')

8、米思齐 Mixly 示例程序(图形化语言) 点这里回到目录

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

HS-S78P GPS定位模块

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

HS-S78P GPS定位模块


9、测试环境搭建 点这里回到目录

Arduino UNO 测试环境搭建

准备配件:

  • UNO-R3 开发板 *1
  • UNO-R3 EXP 扩展板 *1
  • USB type-c 数据线 *1
  • HS-S78P GPS模块*1
  • PH2.0 4P双头端子线 *1

电路接线图:

HS-S78P GPS定位模块

ESP32 Python 测试环境搭建


10、视频教程 点这里回到目录

Arduino UNO视频教程:点击查看

ESP32 Python视频教程:


11、测试结论 点这里回到目录

Arduino UNO测试结论:

下入代码,即可在电脑串口看到自己的经度和纬度。注意:室内可能因为天线信号原因没法打印显示不了经度和纬度,最好在室外开阔区域测试

HS-S78P GPS定位模块


点这里回到目录