I'm making a bike speedometer using a UNO, a NEO-6M GPS and a Adafruit 3.5 TFT display. I have most of it working including a way to log my position as I ride in a CSV file to the SD card that is on the display. Right now the logging starts as soon as I power the UNO up.
I'd like to be able to start and stop the logging using a button on the display. I want to toggle it on and off with the same button. I've tried to use the examples I have found that use a hardware pushbutton but obviously I can't get it to work or I wouldn't be here asking for help. Right now I'm just trying to work out the toggle function and turn a LED on and off.
Here's the code I have to toggle the LED
// Start/Stop logging file with Log PB
if ((p.x>=725) && (p.x<=890) && (p.y>=810) && (p.y<=890)) {
if(RunLogger == 0){
RunLogger = 1;
delay(500);
} // end RunLogger == 0
}
if ((p.x>=725) && (p.x<=890) && (p.y>=810) && (p.y<=890)) {
if(RunLogger == 1){
RunLogger = 0;
delay(500);
} // end RunLogger == 1
} // end Start/Stop logging
Serial.print("logger = ");
Serial.println(RunLogger);
if(RunLogger == 0){
digitalWrite(recLED, LOW);
}
else {
digitalWrite(recLED, HIGH);
}
And here is the main part of the code, I have the logging function on another tab but didn't think that would be useful. If you think it is I will send it on a later reply
/*
Changed to Uno
with Adafruit 3.5 TFT display
Rev 6 Added touch, made 2 pages for displaing info and separated logging to it's own tab
GPS Position Logger
code from
DroneBot Workshop 2021
https://dronebotworkshop.com
*/
// Include required libraries
#include <TinyGPS++.h>
#include <SoftwareSerial.h>
#include <SPI.h>
#include <SD.h>
#include <Adafruit_GFX.h> // Core graphics library
#include <Adafruit_HX8357.h> // Hardware-specific library
#include "TouchScreen.h"
// GPS Connections
static const int RXPin = 6, TXPin = 7;
// GPS Baud rate (change if required)
static const uint32_t GPSBaud = 9600;
// SD Card Select pin
const int chipSelect = 5;
// Write LED
const int recLED = 8;
// String to hold GPS data
String gpstext;
// GPS write delay counter variables
// Change gpsttlcount as required
int gpscount = 0;
int gpsttlcount = 30;
int fileMade = 0; // check to see if a new file was made on SD card
// TinyGPS++ object
TinyGPSPlus gps;
// SoftwareSerial connection to the GPS device
SoftwareSerial ss(RXPin, TXPin);
// display
#define TFT_CS 10
#define TFT_DC 9
Adafruit_HX8357 tft = Adafruit_HX8357(TFT_CS, TFT_DC);
// These are the four touchscreen analog pins
#define YP A2 // must be an analog pin, use "An" notation!
#define XM A3 // must be an analog pin, use "An" notation!
#define YM 3 // can be a digital pin
#define XP 4 // can be a digital pin
// 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
TouchScreen ts = TouchScreen(XP, YP, XM, YM, 300);
// 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
bool newData = false;
float distance = 0.0;
unsigned long int scan_time = millis();
int currentPage = 1;
int SD_Status = 0;
int GPS_Status = 0;
float Heading = 0.0;
String RideTime = "";
int RideHr = 0;
int RideMin = 0;
int RideSec = 0;
int StartHr = 0;
int StartMin = 0;
int StartSec = 0;
int readStartTime = 0;
char RideTm[80];
// the logging file
File logfile;
char logFileName[20] = " "; // current log file name
int errorNumb = 0; // system error number to display message
int RunLogger = 0; // run logging file
void setup()
{
// Set all chip selects high to avoid bus contention during initialisation of each peripheral
// digitalWrite(21, HIGH); // Touch controller chip select (if used)
digitalWrite(10, HIGH); // TFT screen chip select
digitalWrite( 5, HIGH); // SD card chips select, must use GPIO 5 (ESP32 SS)
// Set LED pin as output
pinMode(recLED, OUTPUT);
// Start Serial Monitor for debugging
Serial.begin(115200);
// Start SoftwareSerial
ss.begin(GPSBaud);
// start display driver
tft.begin(); // Initialize screen
//tft.fillScreen(BLACK); //clears screen, sets to Black
tft.setRotation(0); // rotates screen 90' for landscape mode
// 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);
// load Speedometer page
tft.fillScreen(BLACK); //clears screen, sets to Black
SpeedometerPage();
// Initialize SD card
if (!SD.begin(chipSelect)) {
Serial.println("Card failed, or not present");
//don't do anything more:
while (1);
}
Serial.println("card initialized.");
// Blink LED so we know we are ready
digitalWrite(recLED, HIGH);
delay(500);
digitalWrite(recLED, LOW);
delay(500);
digitalWrite(recLED, HIGH);
delay(500);
digitalWrite(recLED, LOW);
delay(500);
digitalWrite(recLED, HIGH);
delay(500);
digitalWrite(recLED, LOW);
scan_time = millis(); // reset scan time
} // end setup
void loop()
{
// Turn off LED
digitalWrite(recLED, LOW);
// Retrieve a point on touch screen
TSPoint p = ts.getPoint();
// See if GPS data available
while (ss.available() > 0)
if (gps.encode(ss.read()))
//Heading = (gps.course.deg(), gps.course.isValid(), 7, 2);
// If we press the Speedometer Button
if ((p.x>=130) && (p.x<=290) && (p.y>=810) && (p.y<=890)) {
currentPage = 1; // Indicates that we are the first example
tft.fillScreen(BLACK); //clears screen, sets to Black
Serial.println("Speed pressed");
SpeedometerPage(); // It is called only once, because in the next iteration of the loop, this above if statement will be false so this funtion won't be called. This function will draw the graphics of the first example.
} // end if for Speedometer button pressed
// If we press the GPS Info Button
if ((p.x>=420) && (p.x<=600) && (p.y>=810) && (p.y<=890)) {
currentPage = 2;
tft.fillScreen(BLACK); //clears screen, sets to Black
Serial.println("GPS Pressed");
GPS_Info_Page();
} // end if for GPS Info page
// Start/Stop logging file with Log PB
if ((p.x>=725) && (p.x<=890) && (p.y>=810) && (p.y<=890)) {
if(RunLogger == 0){
RunLogger = 1;
delay(500);
} // end RunLogger == 0
}
if ((p.x>=725) && (p.x<=890) && (p.y>=810) && (p.y<=890)) {
if(RunLogger == 1){
RunLogger = 0;
delay(500);
} // end RunLogger == 1
} // end Start/Stop logging
Serial.print("logger = ");
Serial.println(RunLogger);
if(RunLogger == 0){
digitalWrite(recLED, LOW);
}
else {
digitalWrite(recLED, HIGH);
}
// Update variables
// display GPS and SD card status
if(GPS_Status == 1){
tft.fillCircle(290, 30, 10, GREEN);
}
if(GPS_Status == 0) {
tft.fillCircle(290, 30, 10, RED);
}
newData = true;
if (((millis() - scan_time) > 1000)) {
//if (gps.location.isValid())
if(newData == true)
{
newData = false;
// ride start time
if(readStartTime == 0){
StartHr = gps.time.hour();
StartMin = gps.time.minute();
StartSec = gps.time.second();
readStartTime = 1;
} // end if(readStartTime == 0)
// calculate ride time
RideSec = (RideSec + 1);
if(RideHr >= 24){
RideHr = 0;
}
if(RideMin >= 60){
RideMin = 0;
RideHr = (RideHr + 1);
}
if(RideSec >= 60){
RideSec = 0;
RideMin = (RideMin + 1);
}
/*
RideHr = (gps.time.hour() - StartHr);
RideMin = (gps.time.minute() - StartMin);
RideSec = (gps.time.second() - StartSec);
RideTime = (String(RideHr) + ":" + String(RideMin) + ":" + String(RideSec));
*/
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)
Serial.print("Hour = ");
Serial.print(RideHr);
Serial.print(F("\t"));
Serial.print("Minute = ");
Serial.print(RideMin);
Serial.print(F("\t"));
Serial.print("Seconds = ");
Serial.println(RideSec);
Serial.print("Ride Time = ");
Serial.println(RideTime);
// Show green circle when GPS connected
// tft.setCursor(190, 25);
// tft.fillCircle(290, 30, 10, GREEN);
// calculate distance
if(gps.speed.mph() > 0.5){
distance = distance+(gps.speed.mph()/3600);
} // end if(GPS.speed.mph() > 0.5)
}
else
{
Serial.println(F("INVALID"));
// Show red circle when GPS disconnected
// tft.setCursor(185, 25);
// tft.fillCircle(290, 30, 10, RED);
}
// Update screen variables
if(currentPage == 1){
tft.setCursor(50, 120);
tft.setTextColor(WHITE, BLACK);
tft.setTextSize(6);
tft.print(gps.speed.mph(), 1);
// Display Distance
tft.setCursor(50, 230);
tft.setTextColor(WHITE, BLACK);
tft.setTextSize(6);
tft.print(distance, 1);
// Display Ride Time
tft.setCursor(50, 340);
tft.setTextColor(WHITE, BLACK);
tft.setTextSize(4);
//tft.print(RideHr);
//tft.setCursor(75, 340);
//tft.print(":");
//tft.setCursor(100, 340);
//tft.print(RideMin);
//tft.setCursor(125, 340);
//tft.print(":");
//tft.setCursor(150, 340);
sprintf(RideTm, "%02d:%02d:%02d", RideHr, RideMin, RideSec);
tft.print(RideTm);
} // end if current page =1
if(currentPage == 2){
tft.setCursor(50, 110);
tft.setTextColor(WHITE, BLACK);
tft.setTextSize(4);
tft.print(gps.location.lng(), 4);
// Display Latitude
tft.setCursor(50, 190);
tft.setTextColor(WHITE, BLACK);
tft.setTextSize(4);
tft.print(gps.location.lat(), 4);
} // end if current page = 2
if(millis() > 5000 && gps.charsProcessed() > 10){
GPS_Status = 1;
}
if (millis() > 5000 && gps.charsProcessed() < 10)
{
Serial.println(F("No GPS detected: check wiring."));
GPS_Status = 0;
//while(true);
}
scan_time = millis(); // reset scan time
} // end (((millis() - scan_time) > 1000)
} // end loop()
void SpeedometerPage(){
// Prints the title on the screen
tft.setCursor(65, 20);
tft.setTextColor(WHITE);
tft.setTextSize(3);
tft.print("Speedometer");
tft.drawFastHLine(10, 60, 320, RED);
// Display Speed
tft.setCursor(50, 90);
tft.setTextColor(WHITE);
tft.setTextSize(2);
tft.print("Speed");
// Display Distance
tft.setCursor(50, 190);
tft.setTextColor(WHITE);
tft.setTextSize(2);
tft.print("Distance");
// Display Distance
tft.setCursor(50, 300);
tft.setTextColor(WHITE);
tft.setTextSize(2);
tft.print("Time");
// Draw buttons
// fillRoundRect(X, Y, width, height, radius, color);
// Speedometer page select PB
tft.fillRoundRect(10, 410, 70, 50, 10, BLUE);
tft.setCursor(16, 427);
tft.setTextColor(WHITE, BLUE);
tft.setTextSize(2);
tft.print("Speed");
// GPS Info Page select PB
tft.fillRoundRect(126, 410, 70, 50, 10, MAGENTA);
tft.setCursor(143, 427);
tft.setTextColor(BLACK, MAGENTA);
tft.setTextSize(2);
tft.print("GPS");
// Data logger control PB
tft.fillRoundRect(240, 410, 70, 50, 10, RED);
tft.setCursor(257, 427);
tft.setTextColor(WHITE, RED);
tft.setTextSize(2);
tft.print("LOG");
} // end Speedometer page
void GPS_Info_Page(){
// Prints the title on the screen
tft.setCursor(65, 20);
tft.setTextColor(WHITE);
tft.setTextSize(3);
tft.print("GPS Info");
tft.drawFastHLine(10, 60, 320, RED);
// Display Longitude
tft.setCursor(50, 80);
tft.setTextColor(WHITE);
tft.setTextSize(2);
tft.print("Longitude");
// Display Latitude
tft.setCursor(50, 160);
tft.setTextColor(WHITE);
tft.setTextSize(2);
tft.print("Latitude");
// Draw buttons
// fillRoundRect(X, Y, width, height, radius, color);
// Speedometer page select PB
tft.fillRoundRect(10, 410, 70, 50, 10, BLUE);
tft.setCursor(16, 427);
tft.setTextColor(WHITE, BLUE);
tft.setTextSize(2);
tft.print("Speed");
// GPS Info Page select PB
tft.fillRoundRect(126, 410, 70, 50, 10, MAGENTA);
tft.setCursor(143, 427);
tft.setTextColor(BLACK, MAGENTA);
tft.setTextSize(2);
tft.print("GPS");
// Data logger control PB
tft.fillRoundRect(240, 410, 70, 50, 10, RED);
tft.setCursor(257, 427);
tft.setTextColor(WHITE, RED);
tft.setTextSize(2);
tft.print("LOG");
} // GPS_Info_Page
Thanks for all help, suggestions and comments
John