BN-220/BN-880 GPS Module

From Squirrel's Lair


  • Cargo:


  • Categories:
  • Default form


The BN-220 and BN-880 both talk via UART. The BN-880 is almost the same as the BN-220 except for its physical size and it has two additional pins for I2C communications for a compass module that is not present in the BN-220. Both use the NMEA GPS protocol but defaults to 9600bps instead of the NMEA standard 4800bps.

The BN-220/880 GPS modules can use GPS, GLONASS, Galileo, BeiDou, and SBAS signals. When powered on, the module repeatedly sends comma-delimited output phrases one line at a time. Each line starts with a $ and ends with \r\n. The signal used and type of data is identified by a five character string, for example GPGGA. The first two characters define the system being used to get position (Talker ID): (GP=GPS, GA=Galileo, GB=BeiDou, GL=GLONASS, GN=GPS+GLONASS). The last three identify the kind of signal (GGA=GPS fix data, GLL=position data, GRS=GPS range residuals, GSA=GPS DOP and active satellites, GST=GPS PRN, GSV=GPS satellites in view, GGK=Time/position/position type/DOP, as well as some others)

If power is lost and there is a backup battery with enough charge, the module will use its onboard RTC to keep track of time until power is restored and a signal is received.

The following is a simple Micropython program that reads a BN-220/880 connected to UART0 on a Raspberry Pi Pico RP2040, and prints the GNGGA data (GPS+GLONASS position fix)

from machine import Pin, UART
import time
import gc


uart = UART(1, baudrate=9600, tx=Pin(4), rx=Pin(5))

rxData = bytes()
rxDataFull = bytearray()
rxDataConv = ""
rxDataString = ""
rxDataList = []

while True:
    while uart.any() > 0:
        rxData = uart.read(1)
        if(rxData == b'$'):
            rxDataFull = ([])
        if(rxData == b'\r'):
            dataStringCount = len(rxDataFull)
            for i in range(0, dataStringCount, 1):
                rxDataString = rxDataString + chr(rxDataFull[i])
            if((rxDataString[0:6]) == "$GNGGA"):
                rxDataList = rxDataString.split(',')
                # For GNGGA, time is in element 1, Lat: 2&3, Long: 4&5, Alt: 9&10
                try:
                    print("Time: {}:{}:{}".format((str(rxDataList[1])[0:2]), (str(rxDataList[1])[2:4]), (str(rxDataList[1])[4:6])))
                    print("Lat: {}d {}m {}".format((str(rxDataList[2])[0:2]), (str(rxDataList[2])[2:10]), rxDataList[3]))
                    print("Long: {}d {}m {}".format((str(rxDataList[4])[0:3]), (str(rxDataList[4])[3:11]), rxDataList[5]))
                    print("Altitude: {}{}".format(rxDataList[9], rxDataList[10]))
                except IndexError:
                    print("NO DATA")
                print("**********")
                gc.collect()
                print("Free heap: ",gc.mem_free())
                print("**********")
            rxDataString = ""
            rxDataList = []
            time.sleep(0.05)
        else:
            rxDataFull += rxData