I'm working on a bike speedometer using a Arduino Nano Every, the Adafruit Ultimate GPS breakout board and a 3.5" TFT display. I have a preliminary version breadboarded that will display latitude, longitude and speed. I took it for a ride in my truck to check it out, stopped a couple of places on the way and the latitude and longitude were right on. My problem, or question any ways, is the refresh rate of the speed. Although it was relatively accurate it was slow to update. I didn't expect instantaneous reading but it seems to update about every 15 seconds so I'm reading more of an average. The updated speed seems to coincided with the blinking of the GPS connected LED but not sure if that has anything to do with it.
Here is how things are connected to the Nano
GPS -- Nano
Vin -- +5v
GND -- GND
RX -- DI7 (I'm using SoftwareSerial)
TX -- DI8
TFT -- Nano
GND -- GND
Vin -- +5v
CLK -- DI13
MISO -- DI12
MOSI -- DI11
CS -- DI10
D/C -- DI9
My code, see below, is scanning for data from the GPS every 1.5 seconds. So is the delay a code problem or the GPS update rate? If the GPS can I modify that to 5 seconds, or would that be to fast for the GPS?
Thanks for any help, comments or suggestions
John
// Bike Speedometer using GPS
// Arduino Nano Every
#include <TinyGPS++.h>
#include <SoftwareSerial.h>
#include <SPI.h>
#include <Adafruit_GFX.h> // Core graphics library
#include "Adafruit_HX8357.h"
//#include "TouchScreen.h"
// Connect the GPS Power pin to 5V
// Connect the GPS Ground pin to ground
// Connect the GPS TX (transmit) pin to Digital 8
// Connect the GPS RX (receive) pin to Digital 7
// You can change the pin numbers to match your wiring:
SoftwareSerial mySerial(8, 7);
TinyGPSPlus GPS;
// GPS Variables
String NMEA1; //Variable for first NMEA sentence
String NMEA2; //Variable for second NMEA sentence
char c; //to read characters coming from the GPS
float deg; //Will hold positin data in simple degree format
float degWhole; //Variable for the whole part of position
float degDec; //Variable for the decimal part of degree
float GPS_Lon = 00;
float GPS_Lat = 00;
float Latitude = 0.0;
float Longitude = 0.0;
unsigned long int scan_time = millis();
int GPS_Scanned = 0;
/*
// for TFT display
// These are the four touchscreen analog pins
#define YP A5 // must be an analog pin, use "An" notation!
#define XM A6 // must be an analog pin, use "An" notation!
#define YM 5 // can be a digital pin
#define XP 6 // can be a digital pin
// For better pressure precision, we need to know the resistance
// between X+ and X- Use any multimeter to read it
// For the one we're using, its 300 ohms across the X plate
TouchScreen ts = TouchScreen(XP, YP, XM, YM, 300);
// This is calibration data for the raw touch data to the screen coordinates
#define TS_MINX 110
#define TS_MINY 80
#define TS_MAXX 900
#define TS_MAXY 940
#define MINPRESSURE 10
#define MAXPRESSURE 1000
*/
// Color definitions
#define BLACK 0x0000
#define BLUE 0x001F
#define RED 0xF800
#define GREEN 0x07E0
#define CYAN 0x07FF
#define MAGENTA 0xF81F
#define YELLOW 0xFFE0
#define WHITE 0xFFFF
// These are 'flexible' lines that can be changed
#define TFT_CS 10
#define TFT_DC 9
#define TFT_RST -1 // dont use a reset pin, tie to arduino RST if you like
// Use hardware SPI (on Nano Every, #13, #12, #11) and the above for CS/DC
Adafruit_HX8357 tft = Adafruit_HX8357(TFT_CS, TFT_DC, TFT_RST);
void setup() {
// connect at 115200 so we can read the GPS fast enough and echo without dropping chars
// also spit it out
Serial.begin(115200);
delay(5000);
Serial.println("Start GPS");
// GPS
mySerial.begin(9600); //Turn on GPS at 9600 baud
tft.begin();
tft.fillScreen(BLACK); //clears screen, sets to Black
tft.setRotation(0); // rotates screen 90' for landscape mode
// Sets the background color of the screen to black
tft.fillScreen(BLACK);
// Back to Home button
/*
tft.fillRoundRect(30, 20, 50, 30, 10, BLUE);
tft.drawRoundRect(30, 20, 50, 30, 10, WHITE);
tft.setCursor(40, 27);
tft.setTextColor(WHITE);
tft.setTextSize(2);
tft.print("<-");
tft.setCursor(100, 30);
tft.setTextColor(WHITE);
tft.setTextSize(1);
tft.print("Back to Main Menu");
*/
// Prints the title on the screen
tft.setCursor(65, 20);
tft.setTextColor(WHITE);
tft.setTextSize(3);
tft.print("GPS Status");
// Draws the red line under the title
tft.drawFastHLine(10, 60, 320, RED);
} // end setup()
void loop() {
// read GPS
if (((millis() - scan_time) > 1500) && !GPS_Scanned) {
// readGPS();
// Serial.println("read GPS");
// displays information every time a new sentence is correctly encoded.
while (mySerial.available() > 0)
if (GPS.encode(mySerial.read()))
// Serial.print(F("Location: "));
if (GPS.location.isValid())
{
Serial.println(F("VALID"));
Serial.print("Lat = ");
Serial.print(GPS.location.lat(), 4);
Serial.print(F("\t"));
Serial.print("Lon = ");
Serial.print(GPS.location.lng(), 4);
Serial.print(F("\t"));
Serial.print("Speed = ");
Serial.println(GPS.speed.mph()); // Speed in miles per hour (double)
// Show green circle when GPS connected
// tft.setCursor(190, 25);
// tft.setTextColor(WHITE);
// tft.setTextSize(1);
// tft.print("GPS Online");
tft.fillCircle(290, 30, 10, GREEN);
}
else
{
Serial.println(F("INVALID"));
// Show red circle when GPS disconnected
// tft.setCursor(185, 25);
// tft.setTextColor(WHITE);
// tft.setTextSize(1);
// tft.print("GPS Offline");
tft.fillCircle(290, 30, 10, RED);
}
if (millis() > 5000 && GPS.charsProcessed() < 10)
{
Serial.println(F("No GPS detected: check wiring."));
while(true);
}
} // end (millis()- scan_time) > GPS
if ((millis() - scan_time ) > 3000) {
scan_time = millis();
Serial.println("reset");
GPS_Scanned = 0;
// Update screen variables
// Display Longitude
tft.setCursor(50, 130);
tft.setTextColor(WHITE);
tft.setTextSize(2);
tft.print("Longitude");
tft.setCursor(50, 160);
tft.setTextColor(WHITE, BLACK);
tft.setTextSize(4);
tft.print(GPS.location.lng(), 4);
// Display Latitude
tft.setCursor(50, 200);
tft.setTextColor(WHITE);
tft.setTextSize(2);
tft.print("Latitude");
tft.setCursor(50, 230);
tft.setTextColor(WHITE, BLACK);
tft.setTextSize(4);
tft.print(GPS.location.lat(), 4);
// Display Speed
tft.setCursor(50, 290);
tft.setTextColor(WHITE);
tft.setTextSize(2);
tft.print("Speed");
tft.setCursor(50, 320);
tft.setTextColor(WHITE, BLACK);
tft.setTextSize(6);
tft.print(GPS.speed.mph(), 1);
} // end (millis() - scan_time > 1500)
}