#include <Wire.h>
#include <LiquidCrystal_I2C.h>
#include <TinyGPSPlus.h>
#include <SoftwareSerial.h>
// LCD 2004
#define LCD2004_ADDRESS 0x3F // Sesuaikan dengan alamat I2C LCD Anda
#define LCD2004_COLUMNS 20   // Jumlah kolom pada LCD 2004
#define LCD2004_ROWS 4       // Jumlah baris pada LCD 2004
LiquidCrystal_I2C lcd2004(LCD2004_ADDRESS, LCD2004_COLUMNS, LCD2004_ROWS);

// LCD 1602
#define LCD1602_ADDRESS 0x27 // Sesuaikan dengan alamat I2C LCD Anda
#define LCD1602_COLUMNS 16   // Jumlah kolom pada LCD 1602
#define LCD1602_ROWS 2       // Jumlah baris pada LCD 1602
LiquidCrystal_I2C lcd1602(LCD1602_ADDRESS, LCD1602_COLUMNS, LCD1602_ROWS);

#define rxPin 4
#define txPin 3
int buzzerPin1 = 13; // uno 13 nano 7
int relayPin = 12;   // Sesuaikan pin relay
SoftwareSerial neogps(rxPin, txPin);
TinyGPSPlus gps;

unsigned long warningStartTime = 0; // Waktu dimulainya peringatan

void setup() {
  Serial.begin(115200);
  neogps.begin(9600);
  pinMode(buzzerPin1, OUTPUT);
  pinMode(relayPin, OUTPUT);

  lcd2004.begin(LCD2004_COLUMNS, LCD2004_ROWS);
  lcd1602.begin(LCD1602_COLUMNS, LCD1602_ROWS);

  lcd2004.backlight(); // Nyalakan backlight LCD 2004
  lcd1602.backlight(); // Nyalakan backlight LCD 1602

  lcd2004.clear();
  lcd1602.clear();

  lcd2004.setCursor(0, 0);
  lcd2004.print("GPS Speed Alarm");

  lcd1602.setCursor(0, 0);
  lcd1602.print("LCD 1602 Display");

  delay(2000);
}

void loop() {
  boolean newData = false;
  for (unsigned long start = millis(); millis() - start < 1000;)
  {
    while (neogps.available())
    {
      if (gps.encode(neogps.read()))
      {
        newData = true;
      }
    }
  }

  if (newData == true)
  {
    newData = false;
    print_speed();
  }
  else
  {
    lcd2004.clear();
    lcd1602.clear();

    lcd2004.setCursor(0, 0);
    lcd2004.print("No Data");

    lcd1602.setCursor(0, 0);
    lcd1602.print("No Data");
  }
}

void print_speed() {
  lcd2004.clear();
  lcd1602.clear();

  lcd2004.setCursor(0, 0);
  lcd2004.print("Speed: ");
  lcd2004.print(gps.speed.kmph());
  lcd2004.print(" km/h");

  lcd1602.setCursor(0, 0);
  lcd1602.print("Speed: ");
  lcd1602.print(gps.speed.kmph());
  lcd1602.print(" km/h");

  if (gps.speed.kmph() >= 50)
  {
    for (int i = 0; i < 2; i++) {
      digitalWrite(buzzerPin1, HIGH);
      delay(50); // Delay setengah detik
      digitalWrite(buzzerPin1, LOW);
      delay(50); // Delay setengah detik
    }

    lcd2004.setCursor(0, 3);
    lcd2004.print("Reduce Speed!");

    unsigned long elapsedTime = millis() - warningStartTime;

    if (elapsedTime < 5000)
    {
      lcd2004.setCursor(0, 2);
      lcd2004.print("Countdown: ");
      lcd2004.print((5000 - elapsedTime) / 1000);
      lcd2004.print("s");
    }
    else
    {
      warningStartTime = millis(); // Reset the warning start time
      digitalWrite(buzzerPin1, LOW);
      digitalWrite(relayPin, HIGH); // Nyalakan relay jika waktu countdown habis
    }
  }
  else
  {
    digitalWrite(buzzerPin1, LOW);
    digitalWrite(relayPin, LOW); // Matikan relay jika kecepatan sudah kurang dari 50 km/h
  }

  delay(1000);
}
nano:12
nano:11
nano:10
nano:9
nano:8
nano:7
nano:6
nano:5
nano:4
nano:3
nano:2
nano:GND.2
nano:RESET.2
nano:0
nano:1
nano:13
nano:3.3V
nano:AREF
nano:A0
nano:A1
nano:A2
nano:A3
nano:A4
nano:A5
nano:A6
nano:A7
nano:5V
nano:RESET
nano:GND.1
nano:VIN
nano:12.2
nano:5V.2
nano:13.2
nano:11.2
nano:RESET.3
nano:GND.3
lcd1:GND
lcd1:VCC
lcd1:SDA
lcd1:SCL
lcd2:GND
lcd2:VCC
lcd2:SDA
lcd2:SCL