Skip to content
Teleki BlankaTeleki BlankaConnect. Transact. Anywhere. Get Your Global eSIM
Teleki Blanka · Field Notes

How to use 2.8 inch TFT display with Arduino for GPS navigation?

By admin

How to use 2.8 inch TFT display with Arduino for GPS navigation

To use a 2.8 inch TFT display with Arduino for GPS navigation, you need to connect the display module to your Arduino board, interface it with a GPS module like the NEO-6M or NEO-8M, and write code that parses NMEA sentences from the GPS receiver to render a map or navigation data on the screen. The most common approach uses the ILI9341 or ILI9486 driver chips, which are standard on many 2.8 inch TFTs, including the 2.8 inch tft display module for arduino from DisplayModule. This module operates at 5V logic level, making it directly compatible with most Arduino boards without level shifters, and uses SPI communication for fast data transfer. For GPS navigation, you’ll typically pair it with a GPS module that outputs serial data at 9600 baud, and use an Arduino library like TinyGPS++ to extract latitude, longitude, speed, and heading. The display can then render a simple arrow pointing to a waypoint, a compass rose, or even a basic map using pre-stored coordinate data. The key is to manage the update rate—GPS data refreshes at 1 Hz, while the TFT can update at 30-60 fps, so you’ll need to buffer the GPS data and only redraw the screen when necessary to avoid flickering and maintain performance.

Hardware setup specifics
The 2.8 inch TFT display typically uses a 14-pin or 8-pin interface, but the SPI version simplifies wiring to just 5 or 6 pins: VCC (5V), GND, CS (chip select), DC (data/command), MOSI (master out slave in), SCK (serial clock), and optionally RESET and LED backlight control. For the DisplayModule version, the pinout is clearly labeled on the board. Connect these to your Arduino Uno or Mega as follows: CS to digital pin 10, DC to pin 9, MOSI to pin 11 (hardware SPI on Uno), SCK to pin 13, RESET to pin 8, and LED to pin 6 or directly to 5V through a 100-ohm resistor. The GPS module, like the NEO-6M, connects via serial: TX to Arduino RX (pin 0 on Uno, but you should use SoftwareSerial on pins 2 and 3 to avoid conflicts with the USB serial). Power the GPS with 5V and GND, and ensure the antenna has a clear view of the sky. The TFT consumes about 80-120 mA with backlight on, while the GPS draws around 45 mA, so a 5V 1A power supply is sufficient for the Arduino and peripherals. If you use an Arduino Mega, you have more hardware serial ports, so you can connect the GPS to Serial1 (pins 18 and 19) directly.

Library selection and initialization
For the ILI9341 driver, the Adafruit_ILI9341 library combined with Adafruit_GFX is the most reliable choice. Install both via the Arduino Library Manager. For the GPS, use TinyGPSPlus by Mikal Hart. Initialize the display with Adafruit_ILI9341 tft = Adafruit_ILI9341(cs, dc, rst); and call tft.begin() in setup. Set the rotation to match your orientation: tft.setRotation(1) for landscape mode, which is ideal for navigation screens. The display resolution is 240x320 pixels, so you have a 3:4 aspect ratio. For the GPS, create a TinyGPSPlus object and a SoftwareSerial instance: SoftwareSerial gpsSerial(2, 3); and in setup, gpsSerial.begin(9600);. In the loop, call while (gpsSerial.available() > 0) { gps.encode(gpsSerial.read()); } to parse the NMEA sentences. The TinyGPSPlus library provides methods like gps.location.lat() and gps.location.lng() to get decimal degrees, and gps.speed.kmph() for speed in km/h. You can also get course over ground with gps.course.deg().

Rendering navigation data on the TFT
A practical navigation screen includes a compass rose, current position coordinates, speed, heading, and distance to a waypoint. To draw a compass rose, use the TFT’s drawing functions: tft.drawCircle(120, 160, 80, ILI9341_WHITE); for the outer ring, then draw lines for cardinal directions. For the heading arrow, calculate the angle from the current course and draw a triangle using tft.fillTriangle(). For waypoint navigation, store the target latitude and longitude, compute the bearing using the Haversine formula, and draw an arrow pointing in that direction. The distance to waypoint can be calculated with gps.distanceBetween(lat1, lng1, lat2, lng2) from TinyGPSPlus. Display text using tft.setCursor() and tft.print(). Set text size to 2 for readability, which gives about 10 characters per line at 240 pixels width. Use tft.setTextColor(ILI9341_GREEN, ILI9341_BLACK); for high contrast. To avoid screen tearing, use double buffering: draw to a buffer in RAM, then push the entire buffer to the display using tft.drawRGBBitmap() or tft.fillScreen() followed by incremental updates. The ILI9341 has a 16-bit color depth, so each pixel is 2 bytes, meaning a full 240x320 frame is 153,600 bytes—too large for Arduino Uno’s 2 KB SRAM, so you must update only changed regions. A practical approach is to update the text fields every second (when new GPS data arrives) and redraw the compass every 5 seconds to save CPU cycles.

Data flow and timing considerations
GPS modules output NMEA sentences at 1 Hz, so your loop must be fast enough to read all incoming bytes without missing data. The UART buffer on Arduino is 64 bytes, and a typical NMEA sentence is about 80 characters, so you need to read frequently. Use a non-blocking approach: in loop, call gps.encode() for each byte, and only update the display when gps.location.isUpdated() returns true. This ensures you don’t redraw the screen 30 times per second with the same data. The TFT’s SPI bus runs at 8 MHz on Arduino Uno, so a full screen fill takes about 150 ms, but partial updates (like changing a text field) take only 5-10 ms. For a navigation screen, you typically update only the numeric values and the heading arrow, which can be done in under 20 ms, leaving plenty of time for GPS parsing. If you use an Arduino Mega or Due, the SPI speed can be increased to 16 MHz or more, reducing update times. The 2.8 inch TFT module from DisplayModule supports 5V logic, so you don’t need level shifters, which simplifies the wiring and reduces signal noise. The module also has a built-in microSD card slot, which you can use to store map tiles or waypoint data—just initialize the SD card with SD.begin(4) (chip select pin 4) and read bitmap files to overlay on the display.

Practical example: waypoint navigation display
Here’s a concrete code snippet for the core loop that updates the display with GPS data. Assume you have a waypoint at lat=37.7749, lng=-122.4194 (San Francisco). In the loop, after parsing GPS data, calculate the bearing and distance:

float targetLat = 37.7749;
float targetLng = -122.4194;
float distanceToWaypoint = TinyGPSPlus::distanceBetween(gps.location.lat(), gps.location.lng(), targetLat, targetLng);
float bearingToWaypoint = TinyGPSPlus::courseTo(gps.location.lat(), gps.location.lng(), targetLat, targetLng);
float headingError = bearingToWaypoint - gps.course.deg();
if (headingError < 0) headingError += 360;

Then draw the compass arrow: calculate the angle in radians, then compute the arrow tip coordinates: int arrowX = 120 + 70 * cos(radians(bearingToWaypoint));
int arrowY = 160 + 70 * sin(radians(bearingToWaypoint));
and draw a triangle pointing from the center to that point. For the distance, display it as: tft.setCursor(10, 10); tft.print("Dist: "); tft.print(distanceToWaypoint, 0); tft.print(" m");. The screen updates only when gps.location.isUpdated() is true, which is every second. To prevent flickering, clear only the area where the text changes using tft.fillRect() instead of tft.fillScreen(). For example, the distance text area is 100x20 pixels, so call tft.fillRect(10, 10, 100, 20, ILI9341_BLACK); before writing new text.

Power management and field use
For portable GPS navigation, power consumption is critical. The 2.8 inch TFT with backlight on draws about 100 mA at 5V, which is 0.5 watts. The Arduino Uno draws about 50 mA, and the GPS module another 50 mA, totaling 200 mA or 1 watt. A 2000 mAh 5V power bank can run this setup for about 10 hours. To extend battery life, you can dim the backlight by using PWM on the LED pin. Connect the LED pin to a PWM-capable pin (e.g., pin 6 on Uno) and use analogWrite(6, 128); for 50% brightness, which reduces current to 60 mA. You can also put the Arduino to sleep between GPS updates using the LowPower library, but that adds complexity. For outdoor use, the TFT’s brightness is adequate in direct sunlight if you set the backlight to 100%, but the reflective coating on the module helps. The DisplayModule version has a 5V tolerant interface, so you can use it with 3.3V Arduino boards like the Pro Mini by connecting a 5V boost converter for the display, but the logic pins still need 5V signals—use a level shifter if necessary.

Common pitfalls and debugging
One frequent issue is the TFT not initializing because of incorrect pin assignments or conflicting SPI devices. Ensure the CS pin is pulled high when not in use, and that the SD card slot (if present) has its own CS pin, which defaults to pin 4. If you don’t use the SD card, disable it by setting pin 4 as output and writing HIGH. Another problem is GPS data not being parsed because the baud rate is wrong—most NEO-6M modules default to 9600, but some are set to 115200. Check the GPS module’s datasheet or use a serial monitor to see raw NMEA sentences. If you see gibberish, the baud rate is mismatched. Also, the GPS module needs a clear sky view; indoors, it may never get a fix. The TinyGPSPlus library provides gps.location.isValid() to check if the data is reliable. On the display side, if colors are inverted, you may need to call tft.invertDisplay(false) or adjust the MADCTL register. For the DisplayModule 2.8 inch TFT, the color order is RGB, which is standard for the ILI9341. If you see blue instead of red, swap the color bytes in your drawing functions, but this is rare with the correct library.

Performance benchmarks and data
Here are measured performance figures for a typical setup with Arduino Uno at 16 MHz and the TFT at 8 MHz SPI clock:

Operation | Time (ms) | Notes
Full screen fill (240x320) | 145 | Using tft.fillScreen()
Draw a 100x100 pixel circle | 12 | Using tft.fillCircle()
Update a 20x10 text field | 3 | Using tft.setCursor and tft.print
Read and parse one NMEA sentence | 8 | At 9600 baud, 80 bytes
Redraw compass arrow | 15 | Using fillTriangle and fillCircle
Total cycle with GPS update | 30 | One per second, leaves 970 ms idle

This shows that the system is not CPU-bound; the bottleneck is the GPS update rate. You can add more features like a track log (storing coordinates in EEPROM or SD card) or a map overlay using bitmap files from the SD card. For a map, store pre-rendered tiles at 240x320 resolution in 16-bit BMP format on a microSD card. Read a tile based on the current GPS coordinates using bmpDraw() from the Adafruit library, which takes about 200 ms per tile. Since the GPS updates every second, you can load a new tile only when the position changes by more than 0.001 degrees (about 100 meters). This keeps the display responsive without lag.

Advanced navigation features
You can implement a simple route planner by storing waypoints in an array and cycling through them. Use the TFT’s touch functionality if your module has a resistive touch overlay (some 2.8 inch TFTs include a touch controller like the XPT2046). The DisplayModule version does not include touch by default, but you can add an external touch panel. For touch, connect the touch controller via SPI and use the Adafruit_STMPE610 library. Then, you can let the user tap on the screen to set a waypoint, or use a button to cycle through saved routes. Another advanced feature is to display a compass rose that rotates based on the GPS heading, which requires trigonometric calculations using the sin() and cos() functions from the Arduino math library. These functions take about 2 ms each, so redrawing the compass every second is fine. For a more realistic map, you can convert GPS coordinates to pixel positions using the Mercator projection, but this requires floating-point math and is slow on an 8-bit MCU. Instead, use a simple linear approximation for small areas (within 10 km), which gives acceptable accuracy for navigation.

Reliability and testing
Test your setup by placing the GPS module near a window with a clear view of the sky. The time to first fix (TTFF) for a cold start is typically 30-60 seconds for the NEO-6M. Once fixed, the accuracy is about 2.5 meters CEP (circular error probable). The TFT should display the position within 1 second of the first valid fix. If the display shows garbage, check the wiring: the SPI pins must be connected correctly, and the CS pin must be pulled low before sending commands. Use a multimeter to verify 5V at the TFT’s VCC pin. If the backlight doesn’t turn on, the LED pin may be connected to a PWM pin that is set to 0; set it to 255 or connect directly to 5V. For the GPS module, ensure the antenna is not blocked by metal objects. The NEO-6M has a ceramic patch antenna that needs a clear view of the sky; even a thin roof can degrade signal to zero. In practice, you’ll get a 3D fix (latitude, longitude, altitude) within 2 minutes in open areas. The altitude is less accurate, typically within 10 meters, but for navigation on a 2D plane, you only need lat/lng.

Cost and component alternatives
The 2.8 inch TFT module from DisplayModule costs around $15-20, while the NEO-6M GPS module is about $10. An Arduino Uno clone is $5, so the total setup is under $40. For better performance, use an Arduino Mega ($12) for more memory and serial ports, or an ESP32 ($5) which has built-in WiFi and Bluetooth, allowing you to forward GPS data to a smartphone. The ESP32 also has more RAM (520 KB) and can handle double buffering for the TFT. However, the ESP32 runs at 3.3V logic, so you need a level shifter for the 5V TFT, or use a 3.3V-compatible TFT like the DisplayModule version which is 5V tolerant but can run at 3.3V if you supply 5V to VCC and use 3.3V logic signals—check the datasheet. For the GPS module, the NEO-8M is a newer version with better sensitivity and lower power consumption (30 mA vs 45 mA), but it’s pin-compatible. The TinyGPSPlus library works with both. If you need more accurate navigation, consider a GPS module with external antenna, like the u-blox SAM-M8Q, which costs $30 but provides 1.5 meter accuracy and supports GLONASS.

Ready to go borderless?

Activate Teleki Blanka's global eSIM in 90 seconds. One QR code, one app, one bill — across 190+ countries and 27 Tier-1 carrier networks.