You are here
Home > BBGW >

How To Interface GPS With BeagleBone Green

This post discuss on how to connect and test your BeagleBone Green wireless with NEO-6M GPS module. After reading this article you will know how to play with the u-blox NEO-6M global positioning system (GPS) module. These days NEO-6m is a very popular, cost-effective GPS module. So lets get started with How To Interface GPS With BeagleBone Green board.

Contents

Introduction To NEO-6M GPS Module

You can easily check all NMEA 0813-National Marine Electronics Association – statements using this module. NEO-6m module works well with a DC input from 3.3- to 5-V range. That means it can easily powered up from your Raspberry Pi, Arduino, ESP32, or Beaglebone board. NEO-6M GPS module comes up with UART interface.

You might have noticed that NEO-6M GPS antenna is different from normal antenna. This calls for special care while mounting NEO-6M GPS antenna. The GPS antenna is called as patch antenna, they are flat with ceramic and metal body. It is mounted on metal base plate. You have to place the antenna parallel to horizon. Make sure the antenna must have full view of the sky, ensuring a direct line of sight with as many visible satellites as possible. I had tried to make it work in my room, placing near to window, it did not worked. I have to come outside to make it work.

NEO-6M GPS Module Standalone Testing

You can test this GPS module using your laptop/PC. I have used USB-to-Serial converter module for this standalone testing. The hardware setup is very simple, make the connections as follows.

NEO-6M GPS ModuleUSB-to-Serial Converter
TXRX
RXTX
GNDGND
VCC5 V

Now, download the u-center GNSS evaluation software for Windows from u-blox website. After downloading go to “Receiver->Connection” and select your COM port. The u-center software will display the GPS data collected by NEO-6M GPS module. Following images shows when GPS receiver is receiving properly.

Also Note that, when NEO-6M GPS module is working its LED indicator starts blinking. This test confirms that your GPS module is working as expected. I had verified the lat, long using my mobile phone also there are online tools for GPS Reverse Geocoded Address method, you can try it out.

Interface GPS Module With BeagleBone Green Board

First make sure that you are running latest image on the BBGW – Debian Buster IoT Image 2020-04-06. Test UART is set properly and it is working. I am using UART4 from BBGW to communicate with NEO-6M GPS Module. UART-4 is on Pin 11 and Pin 13 of P9 header.

NEO-6M GPS ModuleBeagleBone Green Wireless
TXRX-P9-11
RXTX-P9-13
GNDGND-P9-1
VCC5 V-P9-5

You will have to enable UART 4 by adding following line in /boot/uEnv.txt file. You can add this line anywhere in the file.

# UART 4
uboot_overlay_addr2=/lib/firmware/BB-UART4-00A0.dtbo

In order to verify if UART is correctly configured, use “show pin-utils”, install this utility using following commands.

cd /usr/local/sbin
sudo wget -N https://raw.githubusercontent.com/mvduin/bbb-pin-utils/green-wireless/show-pins
sudo chmod a+x show-pins

Once you have show pin utility you can easily confirm your GPIO pin mappings.

sudo show-pins | sort	# sorted by expansion header pin
UART4- GPIO on BBGW

If you have not done the changes in /boot/uEnv.txt file then “show-pins” output will show UART as GPIO by default.

UART4- GPIO on BBGW

Once you are done with the configurations you can test your GPS module using command line form BeagleBone. Give following command and I get the output response with all the GPS NMEA statements, like $GPRMC, $GPVTG, $GPGGA, $GPGSA, $GPGSV.

$ stty -F /dev/ttyS4 ispeed 9600 && cat </dev/ttyS4
Test GPS Module From BeagleBone

Testing GPS Module With BeagleBone

For testing purpose I have used gpsd – a GPS service daemon. This utility responds to GPS queries with a format that meets NMEA 0183 standard. Install ‘gpsd’ on your BBGW and lets get started.

$sudo apt-get install scons libncurses5-dev python-dev pps-tools
$sudo apt-get install gpsd gpsd-clients

Once you have ‘gpsd’ you can run following command to verify the its working.

$gpsd -D 5 -N -n /dev/ttyS4

This will print GPS information on the terminal, but I like ‘gpsmon’ another utility to monitor GPS data. First I had to connect to host/port pair and run ‘gpsmon’

$ sudo gpsd /dev/ttyS4 -F /var/run/gpsd.sock
$ sudo gpsmon
gpsmon output on beaglebone

There is another utility like ‘gpsmon’ is ‘cgps’ – curses terminal client for gpsd, this will give formatted output including speed, latitude, longitude.

$sudo cgps -s
cgps output on beaglebone

Troubleshooting – Quick Fix For Issues

Address already in use error

debian@beaglebone:~/src$ gpsd -D 5 -N -n /dev/ttyS4
gpsd:INFO: launching (Version 3.17)
gpsd:IO: opening IPv4 socket
gpsd:ERROR: can't bind to IPv4 port gpsd, Address already in use
gpsd:ERROR: maybe gpsd is already running!
gpsd:IO: opening IPv6 socket
gpsd:ERROR: can't bind to IPv6 port gpsd, Address already in use
gpsd:ERROR: maybe gpsd is already running!
gpsd:INFO: command sockets creation failed, netlib errors -1, -1

To solve this error stop and start the gpsd service.

$sudo systemctl stop gpsd.socket
$sudo systemctl disable gpsd.socket

Verify if gpsd service is stopped.

$sudo systemctl status gpsd.socket
● gpsd.socket - GPS (Global Positioning System) Daemon Sockets
Loaded: loaded (/lib/systemd/system/gpsd.socket; enabled; vendor preset:
Active: active (running) since Sun 2021-08-08 11:54:22 UTC; 12min ago
Listen: /var/run/gpsd.sock (Stream)
[::1]:2947 (Stream)
127.0.0.1:2947 (Stream)
Tasks: 0 (limit: 1027)

If it doesn’t solve with this, reboot your beaglebone green wireless board and check again.

stty: /dev/ttyS4: Device or resource busy

Sometimes this error also pops us as – Failed to open /dev/ttyS4 (port busy), for this Install ‘fuser’ to check which process is using UART port.

$sudo apt-get install psmisc
$fuser -k /dev/ttyS4
/dev/ttyS4:           1965

$ kill -9 1965          //kill the process which is holding UART

$ stty -F /dev/ttyS4 speed 9600   //confirm if UART is available 

Error in the position shown on a gps receiver set into ‘2d’ or 3d fixing

Sometimes you will see the time shown from GPS module will be in minus, and reposes for sample gpsd program comes like below,

gpsd Fix mode: 3D (3) Time: -1505755136.1104692960 Fix mode: 3D

To solve this error – simply disable and enable gpsd, better to add this in shell script and run it whenever required.

sudo systemctl enable gpsd.socket
sudo systemctl start gpsd.socket

Sample GPS Client Program In C Language

There are lot of example programs written in Python, C and C++ to play around GPS module with Beaglebone green. Hope you have enjoyed playing around and reading this article on How To Interface GPS With BeagleBone Green Wireless board. This test program is little bit modified from original example program. This sample program is in ‘C’ language. You can get GPS time using gpsd/libgps.

// example  gpsd client
// compile this way:
//    gcc gpsd_client.c -o gpsclient -lgps -lm
#include <gps.h>
#include <math.h>        // for isfinite()
#include <unistd.h>      // for sleep()

#define MODE_STR_NUM 4
static char *mode_str[MODE_STR_NUM] = {
    "n/a",
    "None",
    "2D",
    "3D"
};

int main(int argc, char *argv[])
{
    struct gps_data_t gps_data;
    int my_gps_time;
    struct tm *ptm;

    if (0 != gps_open("localhost", "2947", &gps_data)) {
        printf("Open error.  Bye, bye\n");
        return 1;
    }

    (void)gps_stream(&gps_data, WATCH_ENABLE | WATCH_JSON, NULL);

    while (gps_waiting(&gps_data, 5000000)) {
        if (-1 == gps_read(&gps_data)) {
            printf("Read error.  Bye, bye\n");
            break;
        }
        if (MODE_SET != (MODE_SET & gps_data.set)) {
            // did not even get mode, nothing to see here
            continue;
        }
        if (0 > gps_data.fix.mode ||
            MODE_STR_NUM <= gps_data.fix.mode) {
            gps_data.fix.mode = 0;
        }
        printf("Fix mode: %s (%d) Time: ",
               mode_str[gps_data.fix.mode],
               gps_data.fix.mode);
        if (TIME_SET == (TIME_SET & gps_data.set)) {
	    my_gps_time = gps_data.fix.time;
	    ptm = localtime((time_t *)&my_gps_time);
	    printf("%04d/%02d/%02d,%02d:%02d:%02d",ptm->tm_year+1900,ptm->tm_mon+1,ptm->tm_mday,ptm->tm_hour,ptm->tm_min,ptm->tm_sec);
        } else {
            puts("n/a ");
        }
        if (isfinite(gps_data.fix.latitude) &&
            isfinite( gps_data.fix.longitude)) {
            // Display data from the GPS receiver if valid.
            printf(" Speed %f Lat %.6f Lon %.6f\n", gps_data.fix.speed,
                   gps_data.fix.latitude, gps_data.fix.longitude);
        }
    }

    // When you are done...
    (void)gps_stream(&gps_data, WATCH_DISABLE, NULL);
    (void)gps_close(&gps_data);
    return 0;
}

Compile this program and execute to see the output as follows. Make sure you bind the socket with respective ‘ttySx’ before you execute the program.

$sudo gpsd /dev/ttyS4 -F /var/run/gpsd.sock
$./gpsclient
example gpsd client
Top