#include <PZEM004Tv30.h>
#include <Adafruit_GFX.h>
#include <Adafruit_ILI9341.h>
#include <SPI.h>

#define TFT_CS     10
#define TFT_RST    9
#define TFT_DC     8
#define TFT_MOSI   11
#define TFT_CLK    13
#define TFT_MISO   12

PZEM004Tv30 pzem(2, 3); // RX, TX
Adafruit_ILI9341 tft = Adafruit_ILI9341(TFT_CS, TFT_DC, TFT_RST);

// Definisikan warna
#define BLACK   0x0000
#define WHITE   0xFFFF
#define RED     0xF800
#define GREEN   0x07E0
#define YELLOW  0xFFE0

float maxVoltage = 250; // Rentang tegangan maksimum awal

void setup() {
  Serial.begin(9600);
  tft.begin();
  tft.setRotation(1); // Atur rotasi ke landscape
  tft.fillScreen(BLACK);
  tft.setTextColor(WHITE);
  tft.setTextSize(2);
}

void loop() {
  float voltage = pzem.voltage();
  float current = pzem.current();
  float power = pzem.power();
  float energy = pzem.energy();
  float frequency = pzem.frequency();
  float pf = pzem.pf();

  if (isnan(voltage) || isnan(current) || isnan(power) || isnan(energy) || isnan(frequency) || isnan(pf)) {
    Serial.println("Gagal membaca data!");
    return;
  }

  // Perbarui rentang tegangan maksimum jika diperlukan
  if (voltage > maxVoltage) {
    maxVoltage = voltage;
  }

  // Menggambar tampilan analog
  tft.fillScreen(BLACK);

  // Menggambar jarum analog
  int centerX = 0; // Disesuaikan untuk pojok kiri bawah
  int centerY = 260; // Disesuaikan untuk pojok kiri bawah
  int radius = 240; // Perbesar radius untuk gauge yang lebih besar
  float angle = map(voltage, 0, maxVoltage, -90, 90); // Sesuaikan rentang tegangan sesuai kebutuhan
  float radian = angle * PI / 180;
  int x = centerX + radius * cos(radian);
  int y = centerY + radius * sin(radian);

  // Menggambar setengah lingkaran dengan skala dan degradasi warna
  for (int i = -90; i <= 90; i++) {
    float rad = i * PI / 180;
    int x1 = centerX + radius * cos(rad);
    int y1 = centerY + radius * sin(rad);
    uint16_t color;
    if (i < -30) {
      color = GREEN;
    } else if (i < 30) {
      color = YELLOW;
    } else {
      color = RED;
    }
    for (int j = 0; j < 4; j++) { // Menebalkan garis
      tft.drawPixel(x1 + j, y1 + j, color);
    }
  }

  // Menggambar skala
  for (int i = 0; i <= 10; i++) {
    float scaleAngle = map(i, 0, 10, -90, 90);
    float scaleRadian = scaleAngle * PI / 180;
    int x1 = centerX + (radius - 20) * cos(scaleRadian); // Sesuaikan posisi skala
    int y1 = centerY + (radius - 20) * sin(scaleRadian); // Sesuaikan posisi skala
    int x2 = centerX + radius * cos(scaleRadian);
    int y2 = centerY + radius * sin(scaleRadian);
    tft.drawLine(x1, y1, x2, y2, WHITE);
    tft.setCursor(x1 - 10, y1 - 10);
    tft.print(i * 60); // Sesuaikan skala untuk tegangan
  }

  tft.drawLine(centerX, centerY, x, y, RED);

  // Menampilkan nilai tegangan di dalam gauge
  tft.setCursor(centerX + 50, centerY - 100);
  tft.setTextColor(WHITE);
  tft.setTextSize(3);
  tft.print(voltage);
  tft.print(" V");

  // Menampilkan nilai arus, daya aktif, energi, frekuensi, dan faktor daya
  tft.setCursor(210, 10);
  tft.setTextSize(1);
  tft.setTextColor(RED); // Ubah warna teks menjadi merah
  tft.print("Arus: ");
  tft.print(current);
  tft.print(" A");

  tft.setCursor(210, 30);
  tft.setTextSize(1);
  tft.setTextColor(YELLOW); // Ubah warna teks menjadi kuning
  tft.print("Daya: ");
  tft.print(power);
  tft.print(" W");

  tft.setCursor(210, 50);
  tft.setTextSize(1);
  tft.setTextColor(YELLOW); // Ubah warna teks menjadi kuning
  tft.print("Energi: ");
  tft.print(energy);
  tft.print(" kWh");

  tft.setCursor(210, 70);
  tft.setTextSize(1);
  tft.setTextColor(YELLOW); // Ubah warna teks menjadi kuning
  tft.print("Frekuensi: ");
  tft.print(frequency);
  tft.print(" Hz");

  tft.setCursor(210, 90);
  tft.setTextSize(1);
  tft.setTextColor(WHITE); // Ubah warna teks menjadi kuning
  tft.print("PF: ");
  tft.print(pf);

  delay(2000); // Tunggu 2 detik sebelum membaca lagi
}
uno:A5.2
uno:A4.2
uno:AREF
uno:GND.1
uno:13
uno:12
uno:11
uno:10
uno:9
uno:8
uno:7
uno:6
uno:5
uno:4
uno:3
uno:2
uno:1
uno:0
uno:IOREF
uno:RESET
uno:3.3V
uno:5V
uno:GND.2
uno:GND.3
uno:VIN
uno:A0
uno:A1
uno:A2
uno:A3
uno:A4
uno:A5
lcd1:VCC
lcd1:GND
lcd1:CS
lcd1:RST
lcd1:D/C
lcd1:MOSI
lcd1:SCK
lcd1:LED
lcd1:MISO