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

#define TFT_CS 10
#define TFT_RST 8
#define TFT_DC 9

Adafruit_ILI9341 tft = Adafruit_ILI9341(TFT_CS, TFT_DC, TFT_RST);

const int numSamples = 240;
int samples[numSamples];
const int screenWidth = 320;
const int screenHeight = 240;
const int voltageDisplayHeight = 20;

void drawAxes() {
  tft.fillScreen(ILI9341_BLACK);

  // Draw Y axis
  tft.drawLine(0, voltageDisplayHeight, 0, screenHeight, ILI9341_WHITE);

  // Draw X axis
  tft.drawLine(0, screenHeight - 1, screenWidth, screenHeight - 1, ILI9341_WHITE);

  // Draw axis labels
  tft.setTextColor(ILI9341_WHITE);
  tft.setTextSize(1);
  tft.setCursor(5, voltageDisplayHeight + 5);
  tft.print("5V");
  tft.setCursor(5, screenHeight - 10);
  tft.print("0V");

  // Add grid lines
  tft.setTextColor(ILI9341_DARKGREY); // Use a lighter color for grid lines
  for (int y = voltageDisplayHeight + 20; y < screenHeight; y += 20) {
    tft.drawLine(0, y, screenWidth, y, ILI9341_DARKGREY);
  }
}

void setup() {
  Serial.begin(9600);
  tft.begin();
  tft.setRotation(3);
  drawAxes();
}

void loop() {
  static int previousSamples[numSamples] = {0};

  for (int i = 0; i < numSamples; i++) {
    samples[i] = analogRead(A0);
    delay(1);
  }

  for (int i = 0; i < numSamples - 1; i++) {
    int x1 = map(i, 0, numSamples - 1, 0, tft.width());
    int y1 = map(previousSamples[i], 0, 1023, tft.height(), voltageDisplayHeight);
    int x2 = map(i + 1, 0, numSamples - 1, 0, tft.width());
    int y2 = map(previousSamples[i + 1], 0, 1023, tft.height(), voltageDisplayHeight);

    tft.drawLine(x1, y1, x2, y2, ILI9341_BLACK);

    y1 = map(samples[i], 0, 1023, tft.height(), voltageDisplayHeight);
    y2 = map(samples[i + 1], 0, 1023, tft.height(), voltageDisplayHeight);
    tft.drawLine(x1, y1, x2, y2, ILI9341_GREEN);
  }

  for (int i = 0; i < numSamples; i++) {
    previousSamples[i] = samples[i];
  }

  tft.fillRect(screenWidth - 100, 0, 100, voltageDisplayHeight, ILI9341_BLACK);
  tft.setTextColor(ILI9341_WHITE);
  tft.setTextSize(2);
  tft.setCursor(screenWidth - 100 + 10, 2);
  float voltage = map(samples[numSamples - 1], 0, 1023, 0, 5000) / 1000.0;
  tft.print(voltage, 2);
  tft.print("V");

  delay(100);
}