🌍 oledGPS - ATGM336H-5N Project

20250820_110911-ezgif.com-optimize

This project utilizes a 128x64 OLED display and a GPS+BDS Beidou dual mode module. Yes, that blinking circle is my location on the map. The information shown is rough enough, not to be doxed. This GPS GUI is meant to be used for educational purposes and definitely not to be used for navigation. Unless, you are dropped on a random continent or you are Ferdinand Magellan :grinning_face:. This project displays the current time in 12 hour increments with “AM“ and “PM“, longitude, latitude without decimals, altitude in meters, number of satellites, and a blinking cursor on a scaled world map with your GPS location.

Required items:
Arduino of your choice… (i.e. MEGA, NANO, Micro…)
Small breadboard and jumpers
128x64 display (SH1106 used in this example)
GPS+BDS Beidou module with antenna (ATGM336H-5N used in this example)
Power source (9V lithium ion used in this example)

Also required, is the ability to add libraries to Arduino IDE. This project requires six libraries:

TinyGPS++.h at: https://github.com/mikalhart/TinyGPSPlus/tree/master/src
Adafruit_GFX.h at: https://github.com/adafruit/Adafruit-GFX-Library
Adafruit_SH1106.h: https://github.com/wonho-maker/Adafruit_SH1106
SoftwareSerial.h, Wire.h, and SPI.h are included with Arduino IDE.

More information about the GPS module used:

ATGM336H-5N series modules are small-sized, high-performance BDS/GNSS full constellation navigation modules. These modules are based on ZTE Micro's fourth-generation, low-power GNSS SOC chip - AT6558, which supports a wide range of satellite navigation systems, including China's BDS (BeiDou), the U.S. GPS, Russia's GLONASS, the EU's GALILEO, Japan's QZSS, and the satellite-based augmentation systems SBAS (WAAS, EGNOS, GAGAN, MSAS). The AT6558 is a true 6-in-1 multimode satellite navigation and positioning chip with 32 tracking channels that can simultaneously receive GNSS signals from six satellite navigation systems and realize joint positioning, navigation and timing. ATGM336H-5N modules have the advantages of high sensitivity, low power consumption, low cost, etc. They are suitable for in-vehicle navigation, handheld positioning, wearable devices, and can directly replace Ublox MAX series modules.

The build:
On the GPS use RX→PIN D3 and TX→PIN D4 on the Arduino.
On the OLED use SCK→SCL and SCA→SCA on the Arduino.
** On the GPS use VCC→5V and the OLED VDD→3.3V on the Arduino.
On both GPS and OLED GND→GND on the Arduino.

** you can use 5V on the OLED… extends OLED life on 3.3V.

Note from author: I tried several locations manually without travelling to other continents. The cursor on the map was scaled to land on the right place. Please try your own GPS with the provided code and check my accuracy.

Arduino code:
oledGPS.ino (11.8 KB)

3 OLEDgps

Video of this code at work:

3 Likes

#include <Adafruit_GFX.h>
#include <Adafruit_SSD1306.h>

#define SCREEN_WIDTH     128
#define SCREEN_HEIGHT    64
#define OLED_RESET       -1
#define SCREEN_ADDRESS   0x3C
Adafruit_SSD1306 display (SCREEN_WIDTH, SCREEN_HEIGHT, &Wire, OLED_RESET);

const unsigned char bitmap_105x64 [] PROGMEM = {
	// 'canvas, 128x64px
	0x00, 0x00, 0x00, 0x00, 0x3e, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 
	0x00, 0x00, 0x00, 0x7c, 0x22, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 
	0x00, 0x00, 0x03, 0x82, 0x46, 0x70, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 
	0x00, 0x00, 0x06, 0x02, 0x81, 0xd8, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 
	0x00, 0x00, 0x0a, 0x01, 0x00, 0x10, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 
	0x00, 0x00, 0x0a, 0x02, 0x00, 0x20, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 
	0x00, 0x00, 0x16, 0x04, 0x00, 0x40, 0x08, 0x00, 0x00, 0x0c, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 
	0x00, 0x00, 0x92, 0x28, 0x00, 0x80, 0x34, 0x00, 0x00, 0x0a, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 
	0x00, 0x00, 0x14, 0xd8, 0x00, 0x80, 0x34, 0x00, 0x00, 0x04, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 
	0x00, 0x00, 0x89, 0x88, 0x00, 0x80, 0x08, 0x00, 0x00, 0x02, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 
	0x00, 0x00, 0x8d, 0x04, 0x00, 0x40, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 
	0x00, 0x00, 0x22, 0x06, 0x00, 0x20, 0x00, 0x00, 0x40, 0x61, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 
	0x00, 0x01, 0x32, 0x02, 0x00, 0x20, 0x00, 0x00, 0x80, 0x5e, 0x80, 0x80, 0x00, 0x00, 0x00, 0x00, 
	0x00, 0x1c, 0x04, 0x01, 0x00, 0x20, 0x00, 0x01, 0x01, 0x80, 0x78, 0x00, 0x00, 0x00, 0x00, 0x00, 
	0x00, 0x12, 0x4a, 0x01, 0x00, 0x40, 0x00, 0x01, 0x16, 0x00, 0x04, 0xe0, 0x00, 0x00, 0x00, 0x00, 
	0x00, 0x07, 0x93, 0xe0, 0x80, 0x40, 0x00, 0x01, 0x29, 0x00, 0x03, 0x18, 0x00, 0x00, 0x00, 0x00, 
	0x1e, 0x39, 0x28, 0x30, 0x80, 0x80, 0x07, 0xe1, 0x20, 0x00, 0x00, 0x07, 0x70, 0x00, 0x00, 0x00, 
	0x21, 0x46, 0x47, 0x18, 0x81, 0x00, 0x08, 0x12, 0xc0, 0x00, 0x00, 0x00, 0x8c, 0x00, 0x00, 0x00, 
	0x40, 0x83, 0x80, 0x84, 0x82, 0x00, 0x10, 0x0c, 0x00, 0x00, 0x00, 0x00, 0x02, 0x80, 0x00, 0x00, 
	0x40, 0x00, 0x00, 0xc4, 0x8c, 0x30, 0x10, 0x10, 0x00, 0x00, 0x00, 0x00, 0x04, 0x00, 0x00, 0x00, 
	0x40, 0x00, 0x01, 0x38, 0x50, 0x00, 0x23, 0x00, 0x00, 0x00, 0x00, 0x00, 0x08, 0x00, 0x00, 0x00, 
	0x40, 0x00, 0x02, 0x00, 0x20, 0x00, 0x24, 0x80, 0x00, 0x00, 0x00, 0x00, 0x30, 0x00, 0x00, 0x00, 
	0x46, 0x00, 0x04, 0x20, 0x00, 0x00, 0x44, 0x80, 0x00, 0x00, 0x00, 0x79, 0xc0, 0x00, 0x00, 0x00, 
	0x39, 0x00, 0x04, 0x70, 0x00, 0x00, 0x29, 0x00, 0x00, 0x00, 0x00, 0x86, 0x00, 0x00, 0x00, 0x00, 
	0x41, 0xc0, 0x02, 0x88, 0x00, 0x02, 0x12, 0x00, 0x00, 0x00, 0x01, 0x02, 0x00, 0x00, 0x00, 0x00, 
	0x80, 0x60, 0x01, 0x84, 0x00, 0x00, 0x04, 0x00, 0x00, 0x00, 0x01, 0x02, 0x00, 0x00, 0x00, 0x00, 
	0x00, 0x60, 0x00, 0x02, 0x00, 0x00, 0x78, 0x00, 0x00, 0x00, 0x00, 0x84, 0x00, 0x00, 0x00, 0x00, 
	0x00, 0x30, 0x00, 0x0d, 0x00, 0x03, 0x80, 0x00, 0x00, 0x00, 0x00, 0x40, 0x00, 0x00, 0x00, 0x00, 
	0x00, 0x10, 0x00, 0x08, 0x00, 0x04, 0x00, 0x00, 0x00, 0x00, 0x00, 0x40, 0x00, 0x00, 0x00, 0x00, 
	0x00, 0x10, 0x00, 0x08, 0x00, 0x04, 0x30, 0x00, 0x00, 0x00, 0x01, 0x80, 0x00, 0x00, 0x00, 0x00, 
	0x00, 0x10, 0x00, 0x10, 0x00, 0x03, 0xc8, 0x00, 0x00, 0x00, 0x02, 0x00, 0x00, 0x00, 0x00, 0x00, 
	0x00, 0x10, 0x00, 0x20, 0x00, 0x01, 0x1e, 0x00, 0x00, 0x00, 0x0c, 0x80, 0x00, 0x00, 0x00, 0x00, 
	0x00, 0x08, 0x00, 0x20, 0x00, 0x01, 0xe1, 0x80, 0x00, 0x00, 0x3d, 0x80, 0x00, 0x00, 0x00, 0x00, 
	0x00, 0x08, 0x00, 0x40, 0x00, 0x02, 0x00, 0xc0, 0x00, 0x00, 0x30, 0x00, 0x00, 0x00, 0x00, 0x00, 
	0x00, 0x0c, 0x03, 0x40, 0x00, 0x04, 0x00, 0xa1, 0x00, 0x00, 0x32, 0x00, 0x00, 0x00, 0x00, 0x00, 
	0x00, 0x0e, 0x04, 0xc0, 0x00, 0x08, 0x00, 0x50, 0xc0, 0x00, 0x20, 0x00, 0x00, 0x00, 0x00, 0x00, 
	0x00, 0x05, 0x08, 0x40, 0x00, 0x10, 0x00, 0x28, 0xb0, 0x00, 0x40, 0x00, 0x00, 0x00, 0x00, 0x00, 
	0xa0, 0x02, 0x90, 0x20, 0x00, 0x20, 0x00, 0x17, 0x08, 0x10, 0x80, 0x00, 0x00, 0x00, 0x00, 0x00, 
	0x10, 0x00, 0x48, 0x10, 0x00, 0x20, 0x00, 0x08, 0x8c, 0x59, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 
	0x00, 0x00, 0x3e, 0x00, 0x00, 0x10, 0x00, 0x05, 0x04, 0x49, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 
	0x00, 0x00, 0x07, 0x3f, 0x00, 0x08, 0x00, 0x02, 0x03, 0x46, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 
	0x00, 0x00, 0x00, 0xc0, 0x80, 0x07, 0x80, 0x02, 0x01, 0x80, 0xc0, 0x00, 0x00, 0x00, 0x00, 0x00, 
	0x00, 0x00, 0x01, 0x00, 0x40, 0x00, 0x40, 0x04, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 
	0x00, 0x00, 0x01, 0x00, 0x38, 0x00, 0x20, 0x08, 0x00, 0x06, 0x81, 0x80, 0x00, 0x00, 0x00, 0x00, 
	0x00, 0x00, 0x00, 0x80, 0x04, 0x00, 0x10, 0x10, 0x00, 0x01, 0x80, 0xc0, 0x08, 0x00, 0x00, 0x00, 
	0x00, 0x00, 0x00, 0x40, 0x04, 0x00, 0x10, 0x10, 0x00, 0x00, 0x83, 0x06, 0x00, 0x00, 0x00, 0x00, 
	0x00, 0x00, 0x00, 0x20, 0x08, 0x00, 0x10, 0x14, 0x00, 0x00, 0x04, 0xe1, 0x20, 0x00, 0x00, 0x00, 
	0x00, 0x00, 0x00, 0x30, 0x08, 0x00, 0x10, 0x2a, 0x00, 0x00, 0x18, 0x10, 0x88, 0x00, 0x00, 0x00, 
	0x00, 0x00, 0x00, 0x10, 0x10, 0x00, 0x10, 0x2a, 0x00, 0x00, 0x60, 0x10, 0x00, 0x00, 0x00, 0x00, 
	0x00, 0x00, 0x00, 0x08, 0x10, 0x00, 0x08, 0x2c, 0x00, 0x00, 0xc0, 0x08, 0x00, 0x00, 0x00, 0x00, 
	0x00, 0x00, 0x00, 0x08, 0x20, 0x00, 0x08, 0x44, 0x00, 0x00, 0x40, 0x08, 0x00, 0x00, 0x00, 0x00, 
	0x00, 0x00, 0x00, 0x08, 0x40, 0x00, 0x08, 0xc0, 0x00, 0x00, 0x32, 0x08, 0x00, 0x00, 0x00, 0x00, 
	0x00, 0x00, 0x00, 0x10, 0x40, 0x00, 0x04, 0x80, 0x00, 0x00, 0x1d, 0x08, 0x00, 0x00, 0x00, 0x00, 
	0x00, 0x00, 0x00, 0x10, 0x80, 0x00, 0x03, 0x00, 0x00, 0x00, 0x00, 0x90, 0x00, 0x00, 0x00, 0x00, 
	0x00, 0x00, 0x00, 0x11, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x60, 0x60, 0x00, 0x00, 0x00, 
	0x00, 0x00, 0x00, 0x12, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x20, 0x40, 0x00, 0x00, 0x00, 
	0x00, 0x00, 0x00, 0x14, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xc0, 0x00, 0x00, 0x00, 
	0x00, 0x00, 0x00, 0x14, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 
	0x00, 0x00, 0x00, 0x14, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 
	0x00, 0x00, 0x00, 0x18, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 
	0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 
	0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 
	0x00, 0x00, 0x00, 0x02, 0x00, 0x00, 0x00, 0x00, 0x00, 0x0f, 0xff, 0x80, 0x00, 0x00, 0x00, 0x00, 
	0x00, 0x00, 0x00, 0x0c, 0x00, 0x00, 0x00, 0x03, 0xff, 0xf0, 0x00, 0x70, 0x00, 0x00, 0x00, 0x00
};

void setup () {
  display.begin(SSD1306_SWITCHCAPVCC, SCREEN_ADDRESS);
  display.clearDisplay();
  display.drawBitmap(0, 0, bitmap_105x64, 128, 64, WHITE);
  display.display();
}

void loop() {}

I had to find my SSD1306 and load the Adafruit library. Your code works…

I like your idea of reducing the image size to save memory. I didn’t do it cause I am lazy.

After removing half of Antarctica and reducing the image size to 105x64 to preserve scale, leaving room for data on the right, I removed all the "alias" pixels (caused by shrinking the image) in MSPaint to make one-pixel-wide outline.

The GPS coordinates start from Greenwich and the Equator (0,0). Europe is +,+ or NE, North America is +,- or NW, South America -,- or SW, and Australia is -,+ or SE.

Duemilanova with 1.54 I2C display on A4 and A5. :+1:

1 Like

I had 4 satellites earlier today and wondered just exactly how many satellites it took to "trianglulate" my position. I always assumed three satellites... I was wrong.

So, if you have less than four satellites. Your position is not going to display.

Nine was normal in early 2000s.

I also assumed GPS Satellites were in stationary orbits. I was wrong again. :frowning:

GPS_Animation

This explains why the number of satellites is constantly changing. :man_facepalming:

I wrote another version of the oledGPS for the NANO Every with the ATMega4809 chip. I used the Adafruit SH110X display library. But, now it is not reverse capable with the ATMega328 chips. The SoftwareSerial library has a conflict with the new Adafruit SH110X display library.

NANO Every running oledGPS_4809:

ATMega4809: oledGPS_4809.ino (12.4 KB)

ATMega328: oledGPS.ino (11.8 KB) (same as original post)

Until I figure out why Adafruit SH110X library has a conflict with SoftwareSerial library, there will be two versions.

Note that there is no need for SoftwareSerial on the Nano Every, the Rx and Tx pins are on a 2nd hardware serial port (Serial1). The atmega4809 actually has four hardware serial ports.

Does not look like you are using Serial at all, if you wanted to allow for disconnecting the GPS while uploading code then you could use the hardware Serial Rx for the GPS.

Looking at the GPS_4809 code compiled for an UNO, seems like you are going to be low on dynamic memory (ram), instead of having a conflict with the SoftwareSerial library, although writing to the display will take so long when SoftwareSerial is running that you can overrun the receive buffer if you are not careful.

If I get time I'll try the code using the U8g2 library with a page buffer, that can greatly decrease the ram requirements.

1 Like

I like what you are thinking. I would like to think that we can make a reverse capable version that works on both ATMEGA328s and 4809s. Getting the U8g2 library working on both, does have a possibility of working on both.