#include <Wire.h>
#include <LiquidCrystal_I2C.h>
#include <TinyGPS++.h>

#define LCD_ADDRESS 0x27
#define LCD_COLUMNS 16
#define LCD_ROWS 2

LiquidCrystal_I2C lcd(LCD_ADDRESS, LCD_COLUMNS, LCD_ROWS);
TinyGPSPlus gps;

unsigned long previousMillis = 0;
unsigned long interval = 1000;

// Assume average heart rate during cycling
int averageHeartRate = 120; // Adjust this value based on your assumption

void setup() {
  Serial.begin(9600);
  Wire.begin();
  lcd.init();
  lcd.backlight();
}

void loop() {
  while (Serial.available() > 0) {
    gps.encode(Serial.read());
  }

  // Update GPS data every second
  unsigned long currentMillis = millis();
  if (currentMillis - previousMillis >= interval) {
    previousMillis = currentMillis;

    // Calculate speed (in km/h) from GPS data
    float speedKmh = gps.speed.kmph();

    // Display speed on LCD
    lcd.clear();
    lcd.setCursor(0, 0);
    lcd.print("Speed: ");
    lcd.print(speedKmh);
    lcd.print(" km/h");

    // Calculate distance traveled (in meters)
   double distanceKm = gps.distanceBetween(gps.location.lat(), gps.location.lng(), 0, 0) / 1000.0;

    // Display distance on LCD
    lcd.setCursor(0, 1);
    lcd.print("Distance: ");
    lcd.print(distanceKm, 4);
    lcd.print(" km");

    // Simulate heart rate estimation based on time spent cycling
    // Calculate time spent cycling in minutes (for example)
    unsigned long timeCycling = currentMillis / 60000; // Convert milliseconds to minutes

    // Estimate heart rate based on time spent cycling
    int estimatedHeartRate = averageHeartRate + (timeCycling / 10); // Adjust this formula based on your assumption

    // Display estimated heart rate on LCD
    lcd.setCursor(0, 2);
    lcd.print("Est. Heart Rate:");
    lcd.setCursor(0, 3);
    lcd.print(estimatedHeartRate);
    lcd.print(" BPM");
  }
}