#include   <Adafruit_GFX.
h>     // Core graphics library
#include   <TouchScreen.h>
#include   "pitches.h"
#include   <MCUFRIEND_kbv.h>
// Triangle properties
const int centerX = 120; //    Center of rotation X
const int centerY = 160; //    Center of rotation Y
const int radius = 50;   //    Radius of rotation
const float rotationSpeed =    1; // Rotation speed in degrees per frame
// Current rotation angle
float currentAngle = 0;
#define LS1 35
#define LS2 37
#define   THERMISTOR_PIN A15 // Thermistor connected to A15
#define   THERMISTOR_NOMINAL_RESISTANCE 10000 // 10k ohm at 25 degrees C
#define   THERMISTOR_NOMINAL_TEMPERATURE 25   // 25 degrees C
#define   BETA_CONSTANT 3734.36                  // Beta constant
#define   SERIES_RESISTOR 10000               // 10k ohm series resistor
#define THERMISTOR_RESISTANCE 10000 // Assumed series resistance value (10K ohm)
#define THERMISTOR_BETA 3734.36 // Beta value calculated earlier
#define   LDR1 41
#define   LASER 43
#define   MOTOR_IN1   51
#define   MOTOR_IN2   49
#define   MOTOR_IN3   47
#define   MOTOR_IN4   45
#define   BUZZER 31
#define   IR_SENSOR   33
#define   BLACK    0x0000
#define   BLUE     0x001F
#define   RED      0xF800
#define   GREEN    0x07E0
#define   CYAN     0x07FF
#define   MAGENTA 0xF81F
#define   YELLOW 0xFFE0
#define   WHITE    0xFFFF
#define   DARK_BLUE 0x00008B // Dark blue color
#define   DARK_RED    0x8B0000 // Dark red color
#define   PRIMARY_COLOR 0x4A11
#define   PRIMARY_LIGHT_COLOR 0x7A17
#define   PRIMARY_DARK_COLOR 0x4016
#define   PRIMARY_TEXT_COLOR 0x7FFF
bool inWelcomeScreen = true; // Initialize to true if the welcome screen is the
first screen shown
bool   stopRequested = false;
bool   pauseRequested = false;
bool   isPaused = false;
bool   showingKeypad = false; // Add this line at the top of your sketch
bool manualModeStarted = false;
const char* keys[12] = {"1", "2", "3", "4", "5", "6", "7", "8", "9", "*", "0",
"#"};
// Button dimensions and positions
int screen_width = 400;
int screen_height = 240;
// At the beginning of your sketch, where you declare global variables
int startYEdit = 20; // You can adjust this value as per your screen layout
int button2Width = 200; // Width for button2
int button2Height = 100; // Height for button2
int manualButtonWidth = 200; // Width for manual screen buttons
int manualButtonHeight = 40; // Shorter height for manual screen buttons
int buttonWidth = 200; // Smaller button width
int buttonHeight = 60; // Smaller button height
int screen_width_rotated = 240; // Width after rotation
// Center horizontally for rotated orientation
int startX = (screen_width_rotated - buttonWidth) / 2;
int startYAuto = 20; // Starting Y position for Auto Mode button
int startYManual = startYAuto + buttonHeight + 20; // Below Auto Mode button
int startYReturn = startYManual + buttonHeight + 20; // Adjust as necessary
// Text positioning for buttons (adjust as needed)
int textPosXAuto = startX + (buttonWidth - 9 * 6) / 2; // Center for "Auto Mode"
int textPosYAuto = startYAuto + (buttonHeight - 16) / 2; // Center vertically in
button
int textPosXManual = startX + (buttonWidth - 12 * 6) / 2; // Center for "Manual
Mode"
int textPosYManual = startYManual + (buttonHeight - 16) / 2;
const int keyWidth = 60;
const int keyHeight = 40;
const int keysInRow = 3;
const int keyPadding = 10;
int keypadStartX = (screen_width_rotated - (keysInRow * keyWidth + (keysInRow - 1)
* keyPadding)) / 2;
int keypadStartY = 100; // Adjust this value as needed
const float maxTemperatureRange = 100; // Global declaration
MCUFRIEND_kbv tft;
#define LOWFLASH (defined(__AVR_ATmega328P__) && defined(MCUFRIEND_KBV_H_))
// Touch screen pressure threshold
#define MINPRESSURE 40
#define MAXPRESSURE 1000
// Touch screen calibration
const int16_t XP = 8, XM = 56, YP = 57, YM = 9; //400x240
const int16_t TS_LEFT = 197, TS_RT = 854, TS_TOP = 904, TS_BOT = 101;
const TouchScreen ts = TouchScreen(XP, YP, XM, YM, 300);
// Global variables to keep track of the current mode
bool inAutoMode = false;
bool inManualMode = false;
int itemCount = 0; // For manual mode item count
bool motor1Running = false;
void startMotor1() {
    digitalWrite(MOTOR_IN1, HIGH);
    digitalWrite(MOTOR_IN2, LOW);
    motor1Running = true;
}
void stopMotor1() {
    digitalWrite(MOTOR_IN1, LOW);
    digitalWrite(MOTOR_IN2, LOW);
    motor1Running = false;
}
void rotateMotor2Clockwise() {
    digitalWrite(MOTOR_IN3, HIGH);
    digitalWrite(MOTOR_IN4, LOW);
    delay(3000); // Run motor for 3 seconds
    digitalWrite(MOTOR_IN3, LOW);
    digitalWrite(MOTOR_IN4, LOW);
}
void updateButton(int x, int y, const char* label, uint16_t bgColor, uint16_t
textColor, int btnWidth, int btnHeight) {
    tft.fillRect(x, y, btnWidth, btnHeight, bgColor);
    tft.setTextColor(textColor);
    // Center the text horizontally and vertically
    int textX = x + (btnWidth - strlen(label) * 6) / 2; // Assuming character width
of 6 pixels
    int textY = y + (btnHeight - 8) / 2; // Assuming character height of 8 pixels
    tft.setCursor(textX, textY);
    tft.println(label);
    delay(100); // Delay for button press effect
}
void drawKey(int x, int y, const char* label, uint16_t bgColor, uint16_t textColor)
{
    tft.fillRect(x, y, keyWidth, keyHeight, bgColor);
    tft.setTextColor(textColor);
    tft.setTextSize(2); // Adjust text size as needed
    tft.setCursor(x + (keyWidth - strlen(label) * 6) / 2, y + (keyHeight - 8) / 2);
// Adjust for text size
    tft.println(label);
}
void updateItemCountDisplay() {
    int startYNumber = 20; // Adjust as needed
    tft.fillRect(startX, startYNumber, buttonWidth, buttonHeight, BLACK);
    tft.drawRect(startX, startYNumber, buttonWidth, buttonHeight, WHITE);
    tft.setCursor(startX + (buttonWidth - 4 * 6) / 2, startYNumber + (buttonHeight
- 16) / 2);
    tft.setTextSize(2);
    tft.setTextColor(WHITE);
    char numStr[5];
    sprintf(numStr, "%04d", itemCount);
    tft.println(numStr);
}
void drawKeypad() {
    tft.fillScreen(BLACK);
    tft.setTextColor(WHITE);
    tft.setTextSize(2);
    const char *keys[12] = {"1", "2", "3", "4", "5", "6", "7", "8", "9", "*", "0",
"#"};
      for (int row = 0; row < 4; ++row) {
          for (int col = 0; col < 3; ++col) {
              int x = keypadStartX + col * (keyWidth + keyPadding);
              int y = keypadStartY + row * (keyHeight + keyPadding);
              tft.drawRect(x, y, keyWidth, keyHeight, WHITE);
              tft.setCursor(x + keyWidth / 2 - 6, y + keyHeight / 2 - 8);
              tft.println(keys[row * 3 + col]);
          }
      }
}
float readTemperature() {
    int analogValue = analogRead(THERMISTOR_PIN); // Read the analog value from
thermistor
    float resistance = (1023.0 / analogValue - 1.0) * THERMISTOR_RESISTANCE;
    float temperature = 1.0 / (log(resistance / THERMISTOR_RESISTANCE) /
THERMISTOR_BETA + 1.0 / 298.15) - 273.15;
    return temperature;
}
void enterEditMode() {
    itemCount = 0; // Reset the number to zero
    showingKeypad = true;
    displayNumericKeypad();
}
void setup() {
    tft.begin(/* Your display ID here */);
      tft.setRotation(1); // Adjust rotation as needed
 tft.begin(/* Your display ID here */);
  tft.setRotation(1); // Adjust rotation as needed
      uint16_t ID = tft.readID();
      tft.begin(ID);
      tft.setRotation(2); // Adjust as needed
    // Clear the screen
    tft.fillScreen(BLACK);
 // Draw rotating triangles
    drawRotatingTriangles();
    delay(2000);
    // Move to another screen
    inWelcomeScreen = false;
    displayMainMenu(); // Or whatever function you use to display the next screen
     // Set up the limit switches as inputs
    pinMode(LS1, INPUT);
    pinMode(LS2, INPUT);
    // Set up the thermometer module
    pinMode(THERMISTOR_PIN, INPUT);
    // Set up the LDR and laser modules
    pinMode(LDR1, INPUT);
    pinMode(LASER, OUTPUT);
    // Set up the motor controller pins as outputs
    pinMode(MOTOR_IN1, OUTPUT);
    pinMode(MOTOR_IN2, OUTPUT);
    pinMode(MOTOR_IN3, OUTPUT);
    pinMode(MOTOR_IN4, OUTPUT);
    // Set up the buzzer as an output
    pinMode(BUZZER, OUTPUT);
    pinMode(IR_SENSOR, INPUT);
 drawBarGraphFrame();
void drawBarGraphFrame() {
    const int barGraphX = 10;
    const int barGraphY = 380;
    const int barGraphWidth = 220;
    const int barGraphHeight = 10;
    tft.drawRect(barGraphX - 1, barGraphY - 1, barGraphWidth + 2, barGraphHeight +
2, WHITE); // Drawing frame
}
void displayMainMenu() {
    tft.fillScreen(BLACK);
    tft.setTextColor(WHITE);
    tft.setTextSize(2);
// Define the background color for the button
uint16_t backgroundColor = GREEN; // You can use any color like RED, BLUE, GREEN,
etc.
tft.setTextSize(2);
tft.setTextColor(YELLOW); // Set the text color (choose a color that contrasts well
with the background)
tft.setCursor(12, 10); // Position the text cursor
tft.println("--SUPER ITEMISER--");
tft.setCursor(25, 40); // Position the text cursor
tft.setTextSize(1);
tft.println("Designed by");
tft.setTextColor(MAGENTA);
tft.setCursor(97, 40); // Position the text cursor
tft.println("S0t0S");
tft.setTextColor(WHITE); // Set the text color (choose a color that contrasts well
with the background)
tft.setCursor(131, 40); // Position the text cursor
tft.println("for");
tft.setTextColor(GREEN); // Set the text color (choose a color that contrasts well
with the background)
tft.setCursor(153, 40); // Position the text cursor
tft.println("CBDOILSHOP");
tft.setTextSize(2);
tft.setTextColor(WHITE); // Set the text color (choose a color that contrasts well
with the background)
tft.setCursor(52, 82); // Position the text cursor
tft.println("CHOOSE MODE");
startYAuto = 120;
tft.setTextSize(3);
// Auto Mode Button (using button2 dimensions)
tft.fillRect(startX, startYAuto, button2Width, button2Height, backgroundColor); //
Fill the button with background color
tft.drawRect(startX, startYAuto, button2Width, button2Height, WHITE); // Draw the
button border
tft.setTextColor(BLACK); // Set the text color (choose a color that contrasts well
with the background)
tft.setCursor(startX + (button2Width - 8 * 9) / 2, startYAuto + (button2Height -
20) / 2); // Position the text cursor
tft.println("AUTO"); // Print the button label
 // Define the background color for the button
uint16_t manualButtonBackgroundColor = BLUE; // Blue background color for Manual
button
// Manual Mode Button (using button2 dimensions)
tft.fillRect(startX, startYAuto + button2Height + 20, button2Width, button2Height,
manualButtonBackgroundColor); // Fill the button with background color
tft.drawRect(startX, startYAuto + button2Height + 20, button2Width, button2Height,
WHITE); // Draw the button border
tft.setTextColor(WHITE); // Set the text color (choose a color that contrasts well
with the background)
tft.setCursor(startX + (button2Width - 11 * 9) / 2, startYAuto + button2Height + 20
+ (button2Height - 20) / 2); // Position the text cursor
tft.println("MANUAL"); // Print the button label
void displayAutoMode() {
    tft.fillScreen(BLACK);
    tft.setTextColor(WHITE);
    tft.setTextSize(2);
    int gap = 20; // Gap between buttons
    int startYStart = screen_height / 6; // Starting Y position for the Start
button
    // Start Button
    tft.drawRect(startX, startYStart, buttonWidth, buttonHeight, WHITE);
    tft.setCursor(startX + (buttonWidth - 6 * 5) / 2, startYStart + (buttonHeight -
16) / 2);
    tft.println("Start");
    // Stop Button
    int startYStop = startYStart + buttonHeight + gap;
    tft.drawRect(startX, startYStop, buttonWidth, buttonHeight, WHITE);
    tft.setCursor(startX + (buttonWidth - 6 * 4) / 2, startYStop + (buttonHeight -
16) / 2);
    tft.println("Stop");
    // Return to Main Menu Button
    int startYReturn = startYStop + buttonHeight + gap;
    tft.drawRect(startX, startYReturn, buttonWidth, buttonHeight, WHITE);
    tft.setCursor(startX + (buttonWidth - 6 * 4) / 2, startYReturn + (buttonHeight
- 16) / 2);
    tft.println("Back");
}
void displayManualMode() {
    tft.fillScreen(BLACK);
    tft.setTextColor(WHITE);
    tft.setTextSize(2);
 int gap = 10; // Gap between buttons
    // 0000 Indicator
    int startYIndicator = 20;
    tft.drawRect(startX, startYIndicator, manualButtonWidth, manualButtonHeight,
WHITE);
    updateItemCountDisplay(); // Update the 0000 display
    // Edit Button
    int startYEdit = startYIndicator + manualButtonHeight + 10;
    tft.drawRect(startX, startYEdit, manualButtonWidth, manualButtonHeight, WHITE);
    tft.setCursor(startX + (manualButtonWidth - 6 * 4) / 2, startYEdit +
(manualButtonHeight - 16) / 2);
    tft.println("Edit");
    // Start Button
    int startYStart = startYEdit + manualButtonHeight + 10;
    tft.drawRect(startX, startYStart, manualButtonWidth, manualButtonHeight,
WHITE);
    tft.setCursor(startX + (manualButtonWidth - 6 * 5) / 2, startYStart +
(manualButtonHeight - 16) / 2);
    tft.println("Start");
    // Pause/Continue Button
    int startYPause = startYStart + manualButtonHeight + 10;
    tft.drawRect(startX, startYPause, manualButtonWidth, manualButtonHeight,
WHITE);
    tft.setCursor(startX + (manualButtonWidth - 6 * (isPaused ? 8 : 5)) / 2,
startYPause + (manualButtonHeight - 16) / 2);
    tft.println(isPaused ? "Continue" : "Pause");
    // Stop Button
    int startYStop = startYPause + manualButtonHeight + 10;
    tft.drawRect(startX, startYStop, manualButtonWidth, manualButtonHeight, WHITE);
    tft.setCursor(startX + (manualButtonWidth - 6 * 4) / 2, startYStop +
(manualButtonHeight - 16) / 2);
    tft.println("Stop");
    // Return to Main Menu Button
    int startYReturn = startYStop + manualButtonHeight + 10;
    tft.drawRect(startX, startYReturn, manualButtonWidth, manualButtonHeight,
WHITE);
    tft.setCursor(startX + (manualButtonWidth - 6 * 4) / 2, startYReturn +
(manualButtonHeight - 16) / 2);
    tft.println("Back");
}
void displayNumericKeypad() {
    tft.fillScreen(BLACK); // Clear the screen
    tft.setTextColor(WHITE);
    tft.setTextSize(2);
    const char *keys[12] = {"1", "2", "3", "4", "5", "6", "7", "8", "9", "*", "0",
"#"};
    for (int row = 0; row < 4; ++row) {
        for (int col = 0; col < 3; ++col) {
            int x = keypadStartX + col * (keyWidth + keyPadding);
            int y = keypadStartY + row * (keyHeight + keyPadding);
            tft.drawRect(x, y, keyWidth, keyHeight, WHITE);
            tft.setCursor(x + (keyWidth - 6) / 2, y + (keyHeight - 8) / 2);
            tft.println(keys[row * 3 + col]);
        }
    }
    // Draw the OK button
    int startYOK = keypadStartY + 4 * (keyHeight + keyPadding); // Below the keypad
    tft.drawRect(startX, startYOK, buttonWidth, buttonHeight, WHITE);
    tft.setCursor(startX + (buttonWidth - 6 * 2) / 2, startYOK + (buttonHeight -
16) / 2);
    tft.println("OK");
}
void handleKeypadInput(int row, int col, TSPoint p) {
    // Check if the touch point is within the bounds of the numeric keys
    for (int r = 0; r < 4; ++r) {
        for (int c = 0; c < 3; ++c) {
            int x = keypadStartX + c * (keyWidth + keyPadding);
            int y = keypadStartY + r * (keyHeight + keyPadding);
            // Check if the touch is within this key
            if (p.x >= x && p.x < (x + keyWidth) && p.y >= y && p.y < (y +
keyHeight)) {
                int numKey = r * 3 + c;
                if (numKey < 9) { // Number keys 1-9
                    itemCount = (itemCount * 10) + (numKey + 1);
                } else if (numKey == 9) { // '*' key, you can define its function
                    // Custom function for '*' key
                } else if (numKey == 10) { // '0' key
                    itemCount = (itemCount * 10);
                } else if (numKey == 11) { // '#' key, you can define its function
                    // Custom function for '#' key
                }
                // Update the display or handle the input as needed
                updateItemCountDisplay();
            }
        }
    }
    // Handle the OK button separately
    int okButtonX = startX; // Adjust as needed
    int okButtonY = keypadStartY + 4 * (keyHeight + keyPadding); // Adjust as
needed
    if (p.x >= okButtonX && p.x < (okButtonX + buttonWidth) && p.y >= okButtonY &&
p.y < (okButtonY + buttonHeight)) {
        // OK button logic
        showingKeypad = false;
        displayManualMode();
    }
}
void runMotor2For3Seconds() {
    // Assuming MOTOR_IN3 and MOTOR_IN4 control the second motor
    digitalWrite(MOTOR_IN3, HIGH); // Start motor2 (adjust based on your setup)
    digitalWrite(MOTOR_IN4, LOW);
    delay(3000); // Run for 3 seconds
    digitalWrite(MOTOR_IN3, LOW); // Stop motor2
    digitalWrite(MOTOR_IN4, LOW);
}
void circle() {
    startMotor1(); // Start motor1
    // Wait for the light switch to be HIGH
    while (digitalRead(LDR1) == LOW) {
        if (stopRequested) break; // Break if stop is requested
        delay(10);
    }
    stopMotor1(); // Stop motor1 immediately
    // Start motor2
    digitalWrite(MOTOR_IN3, HIGH);
    digitalWrite(MOTOR_IN4, LOW);
    // Wait for the IR module switch to be HIGH
    while (digitalRead(IR_SENSOR) == LOW) {
        if (stopRequested) break; // Break if stop is requested
        delay(10);
    }
    // Stop motor2
    digitalWrite(MOTOR_IN3, LOW);
    digitalWrite(MOTOR_IN4, LOW);
}
 // Global variable to keep track of the previous bar length
int previousBarLength = 0;
void updateBarGraph(float temperature) {
    // Define bar graph parameters
    const int barGraphX = 10; // X position of the bar graph
    const int barGraphY = 380; // Y position of the bar graph
    const int barGraphWidth = 180; // Total width of the bar graph
    const int barGraphHeight = 10; // Height of the bar graph
    const float minTemp = -5; // Minimum temperature
    const float maxTemp = 100; // Maximum temperature
    // Calculate the length of the bar graph based on temperature
    float scaledTemp = constrain(temperature, minTemp, maxTemp); // Constrain
temperature within range
    int newBarLength = map(scaledTemp, minTemp, maxTemp, 0, barGraphWidth);
    // Update the bar graph only if there's a change
    if (newBarLength != previousBarLength) {
        if (newBarLength > previousBarLength) {
            // Temperature increased, draw additional bar
            tft.fillRect(barGraphX + previousBarLength, barGraphY, newBarLength -
previousBarLength, barGraphHeight, RED);
        } else {
            // Temperature decreased, clear reduced bar
            tft.fillRect(barGraphX + newBarLength, barGraphY, previousBarLength -
newBarLength, barGraphHeight, BLACK);
        }
        previousBarLength = newBarLength; // Update the previous bar length
    }
}
void drawRotatingTriangles() {
    // Clear the entire screen at the start of the animation
    tft.fillScreen(BLACK);
    const int centerX = tft.width() / 2;
    const int centerY = tft.height() / 2;
    const int radius = 30; // Radius from center where triangles are positioned
    const float angleIncrement = 30 * PI / 180; // 30 degrees per step, converted
to radians
    for (float currentAngle = 0; currentAngle < 2 * PI; currentAngle +=
angleIncrement) {
        // Calculate the bounding box for the triangles
        int minX = centerX - radius - 10;
        int minY = centerY - radius - 10;
        int boxWidth = 2 * radius + 20;
        int boxHeight = 2 * radius + 20;
        // Clear the area where the triangles will be drawn
        tft.fillRect(minX, minY, boxWidth, boxHeight, BLACK);
        // Draw each triangle
        drawTriangle(centerX, centerY, radius, currentAngle, RED);
        drawTriangle(centerX, centerY, radius, currentAngle + 2 * PI / 3,
GREEN); // 120 degrees
        drawTriangle(centerX, centerY, radius, currentAngle + 4 * PI / 3,
BLUE); // 240 degrees
        delay(20); // Reduced delay for faster animation
    }
}
void drawTriangle(int centerX, int centerY, int radius, float angle, uint16_t
color) {
    // Calculate the vertices of the triangle
    int x1 = centerX + radius * cos(angle);
    int y1 = centerY + radius * sin(angle);
    int x2 = centerX + radius * cos(angle + 2 * PI / 5);
    int y2 = centerY + radius * sin(angle + 2 * PI / 5);
    int x3 = centerX + radius * cos(angle + 4 * PI / 3);
    int y3 = centerY + radius * sin(angle + 4 * PI / 3);
    // Draw the triangle
    tft.fillTriangle(x1, y1, x2, y2, x3, y3, color);
}
void loop() {
  float temperature;
    digitalWrite(YP, HIGH);    //   Disable Pull-up
    digitalWrite(XM, HIGH);    //   Disable Pull-up
    TSPoint p = ts.getPoint();
    digitalWrite(YP, LOW);     //   Enable Pull-down
    digitalWrite(XM, LOW);     //   Enable Pull-down
    pinMode(XM, OUTPUT);
    pinMode(YP, OUTPUT);
        // Read the thermistor value
    int thermistorReading = analogRead(THERMISTOR_PIN);
    // Calculate resistance
    float resistance = SERIES_RESISTOR * ((1023.0 / thermistorReading) - 1);
    // Calculate temperature
    temperature = (BETA_CONSTANT / (log(resistance / THERMISTOR_NOMINAL_RESISTANCE)
+ BETA_CONSTANT / (THERMISTOR_NOMINAL_TEMPERATURE + 273.15))) - 273.15;
    temperature = maxTemperatureRange - temperature; // Invert the direction
    temperature -= 31; // Adjust by subtracting 31 degrees
    // Update the bar graph
    updateBarGraph(temperature);
    // Display the temperature on the screen
    if (!showingKeypad && !inWelcomeScreen) {
        tft.setCursor(10, 357); // Adjust position as needed
        tft.setTextColor(YELLOW, BLACK); // Set text color and background color
        tft.setTextSize(2);
        tft.print("Press Temp: ");
        tft.print(temperature, 1); // Display one decimal place
        tft.println(" C");
    }
// Display temperature text
    if (!showingKeypad && !inWelcomeScreen) {
        // ... display temperature code ...
        // Define bar graph parameters
        const int barGraphX = 10; // X position of the bar graph
        const int barGraphY = 380; // Y position of the bar graph
        const int barGraphWidth = 220; // Total width of the bar graph
        const int barGraphHeight = 10; // Height of the bar graph
        const float minTemp = -5; // Minimum temperature
        const float maxTemp = 100; // Maximum temperature
        // Calculate the length of the bar graph based on temperature
        float scaledTemp = constrain(temperature, minTemp, maxTemp); // Constrain
temperature within range
        float barLength = map(scaledTemp, minTemp, maxTemp, 0, barGraphWidth);
        // Draw the bar graph background
        tft.fillRect(barGraphX, barGraphY, barGraphWidth, barGraphHeight, BLACK);
        // Draw the temperature bar
        tft.fillRect(barGraphX, barGraphY, barLength, barGraphHeight, RED); // Use
a different color if you wish
    }
  // Check IR sensor state
    if (digitalRead(IR_SENSOR) == LOW) {
        // IR sensor detects an obstacle - Stop motor1
        stopMotor1();
        // Optionally, display a message or take other actions
    }
    if (p.z > MINPRESSURE && p.z < MAXPRESSURE) {
        p.x = map(p.x, TS_LEFT, TS_RT, 0, tft.width());
        p.y = map(p.y, TS_TOP, TS_BOT, 0, tft.height());
        if (!inAutoMode && !inManualMode) {
         // Auto Mode Button
if (p.x > startX && p.x < startX + button2Width && p.y > startYAuto && p.y <
startYAuto + button2Height) {
    // Fill the button with the press effect color
    tft.fillRect(startX, startYAuto, button2Width, button2Height, YELLOW);
    // Draw the button border
    tft.drawRect(startX, startYAuto, button2Width, button2Height, WHITE);
    // Set cursor for the text with new position
tft.setCursor(startX + (button2Width - 8 * 9) / 2, startYAuto + (button2Height -
20) / 2); // Position the text cursor
    // Set the font color and background color for press effect
    tft.setTextColor(BLACK); // or any color you want for the text
tft.fillRect(startX, startYAuto, button2Width, button2Height, WHITE); // Fill the
button with background color
    // Print the text with new font and style
    tft.setTextSize(3);
    tft.print("AUTO");
    delay(100); // Delay for button press effect
    // Redraw the button with the original style
    tft.fillRect(startX, startYAuto, button2Width, button2Height, WHITE);
    tft.drawRect(startX, startYAuto, button2Width, button2Height, WHITE);
tft.setCursor(startX + (button2Width - 8 * 9) / 2, startYAuto + (button2Height -
20) / 2); // Position the text cursor
tft.setTextColor(BLACK); // Set the text color (choose a color that contrasts well
with the background)
    tft.print("AUTO");
    inAutoMode = true;
    displayAutoMode();
}
// Manual Mode Button
if (p.x > startX && p.x < startX + button2Width && p.y > startYAuto + button2Height
+ 20 && p.y < startYAuto + 2 * button2Height + 20) {
    // Fill the button with the press effect color
    tft.fillRect(startX, startYAuto + button2Height + 20, button2Width,
button2Height, YELLOW);
    // Draw the button border
    tft.drawRect(startX, startYAuto + button2Height + 20, button2Width,
button2Height, WHITE);
    // Set cursor for the text with new position
    tft.setCursor(startX + (button2Width - 11 * 9) / 2, startYAuto + button2Height
+ 20 + (button2Height - 20) / 2); // Position the text cursor
    // Set the font color and background color for press effect
    tft.setTextColor(BLACK); // or any color you want for the text
    tft.fillRect(startX, startYAuto + button2Height + 20, button2Width,
button2Height, WHITE); // Fill the button with background color
    // Print the text with new font and style
    tft.setTextSize(3);
    tft.print("MANUAL");
    delay(100); // Delay for button press effect
    // Redraw the button with the original style
    tft.fillRect(startX, startYAuto + button2Height + 20, button2Width,
button2Height, WHITE);
    tft.drawRect(startX, startYAuto + button2Height + 20, button2Width,
button2Height, WHITE);
    tft.setCursor(startX + (button2Width - 11 * 9) / 2, startYAuto + button2Height
+ 20 + (button2Height - 20) / 2); // Position the text cursor
    tft.setTextColor(BLACK); // Set the text color (choose a color that contrasts
well with the background)
    tft.print("MANUAL");
    inManualMode = true;
    displayManualMode();
}
        } else if (inAutoMode) {
                        // Start Button
                      int startYStart = screen_height / 6;
                      if (p.x > startX && p.x < startX + buttonWidth && p.y >
startYStart && p.y < startYStart + buttonHeight) {
                          updateButton(startX, startYStart, "Start", WHITE, BLACK,
buttonWidth, buttonHeight);
                          circle(); // Perform one circle
                      digitalWrite(LASER, HIGH); // Turn on the laser
                          delay(100);
                          displayAutoMode();
                      }
                      // Stop Button
                      int startYStop = startYStart + buttonHeight + 20;
                      if (p.x > startX && p.x < startX + buttonWidth && p.y >
startYStop && p.y < startYStop + buttonHeight) {
                          updateButton(startX, startYStop, "Stop", WHITE, BLACK,
buttonWidth, buttonHeight);
                           stopRequested = true;
                        pauseRequested = false; // Reset pause state if stop is
requested
                      digitalWrite(LASER, LOW); // Turn on the laser
                          delay(100);
                          displayAutoMode();
                      }
                      // Return to Main Menu Button
                      int startYReturn = startYStop + buttonHeight + 20;
                      if (p.x > startX && p.x < startX + buttonWidth && p.y >
startYReturn && p.y < startYReturn + buttonHeight) {
                          updateButton(startX, startYReturn, "Back", WHITE, BLACK,
buttonWidth, buttonHeight);
                          displayMainMenu();
                          inAutoMode = false;
                        }
            } else if (inManualMode) {
             int startYEdit = 20 + manualButtonHeight + 10;
        int startYStart = startYEdit + manualButtonHeight + 10;
        int startYPause = startYStart + manualButtonHeight + 10;
            static int lastPressedKeyX = -1;
            static int lastPressedKeyY = -1;
               if (showingKeypad) {
              // Numeric keypad buttons
                       for (int row = 0; row < 4; ++row) {
                       for (int col = 0; col < 3; ++col) {
                       int x = keypadStartX + col * (keyWidth + keyPadding);
                       int y = keypadStartY + row * (keyHeight + keyPadding);
                       if (p.x >= x && p.x < x + keyWidth && p.y >= y && p.y < y +
keyHeight) {
                             int numKey = row * 3 + col + 1;
                             if (numKey <= 9) { // Keys 1-9
                                 itemCount = (itemCount % 1000) * 10 + numKey; //
Shift left and add new digit
                             } else if (numKey == 10) { // Key 0
                                 itemCount = (itemCount % 1000) * 10;
                             } else if (numKey == 11) { // Clear or other function
                                 itemCount = 0;
                             }
                             updateItemCountDisplay();
                             delay(100); // Debounce delay
                         }
                     }
                }
                   // OK Button
                int startYOK = keypadStartY + 4 * (keyHeight + keyPadding);
                if (p.x > startX && p.x < startX + buttonWidth && p.y > startYOK &&
p.y < startYOK + buttonHeight) {
                     updateButton(startX, startYOK, "OK", DARK_RED, WHITE,
buttonWidth, buttonHeight);
                     delay(100); // Delay for button press effect
                     showingKeypad = false;
                     displayManualMode();
             }
            } else {
               // Edit Button
             int startYEdit = 20 + manualButtonHeight + 10;
             if (p.x > startX && p.x < startX + manualButtonWidth && p.y >
startYEdit && p.y < startYEdit + manualButtonHeight) {
                  updateButton(startX, startYEdit, "Edit", WHITE, BLACK,
manualButtonWidth, manualButtonHeight);
                  delay(100); // Delay for button press effect
                  enterEditMode(); // Enter edit mode and reset number
             }
             // Start Button
             int startYStart = startYEdit + manualButtonHeight + 10;
             if (p.x > startX && p.x < startX + manualButtonWidth && p.y >
startYStart && p.y < startYStart + manualButtonHeight) {
    updateButton(startX, startYStart, "Start", WHITE, BLACK, manualButtonWidth,
manualButtonHeight);
     circle(); // Perform one circle
    digitalWrite(LASER, HIGH); // Turn off the laser
    manualModeStarted = true; // Set the flag here
    delay(100);
}
             // In Manual Mode - Pause/Continue Button
if (inManualMode && p.x > startX && p.x < startX + manualButtonWidth && p.y >
startYPause && p.y < startYPause + manualButtonHeight) {
    isPaused = !isPaused; // Toggle the pause state
    updateButton(startX, startYPause, isPaused ? "Continue" : "Pause", WHITE,
BLACK, manualButtonWidth, manualButtonHeight);
    delay(100); // Delay for button press effect
     pauseRequested = !pauseRequested;
}
             // Stop Button
             int startYStop = startYPause + manualButtonHeight + 10;
             if (p.x > startX && p.x < startX + manualButtonWidth && p.y >
startYStop && p.y < startYStop + manualButtonHeight) {
                 updateButton(startX, startYStop, "Stop", WHITE, BLACK,
manualButtonWidth, manualButtonHeight);
                 stopMotor1();
               digitalWrite(LASER, LOW); // Turn off the laser
                 delay(100); // Delay for button press effect
             }
             // Return to Main Menu Button
             int startYReturn = startYStop + manualButtonHeight + 10;
             if (p.x > startX && p.x < startX + manualButtonWidth && p.y >
startYReturn && p.y < startYReturn + manualButtonHeight) {
                 updateButton(startX, startYReturn, "Back", WHITE, BLACK,
manualButtonWidth, manualButtonHeight);
                 inManualMode = false;
                 showingKeypad = false;
                 displayMainMenu();
             }
          }
    // Handle motor and sensor logic
    if (inAutoMode && !isPaused) {
        // Auto Mode specific motor and sensor logic
        // For example, checking LDR sensor, starting and stopping motors, etc.
    }
    if (inManualMode && !isPaused) {
        if (itemCount > 0 && motor1Running && digitalRead(LDR1) == HIGH) {
            stopMotor1();
            runMotor2For3Seconds();
            itemCount--;
            updateItemCountDisplay();
            // Check if pause was activated during the cycle
            if (isPaused) {
                // Wait here for the user to press continue
                while (isPaused) {
                    delay(100); // Small delay to prevent CPU hogging
                }
            }
        }
        // Other Manual Mode specific logic, if needed
    }
        if (inAutoMode && digitalRead(LS1) == HIGH) {
         // LS1 triggered: Stop motor1 and run it counterclockwise until LS2 is on
            stopMotor1();
            // Start motor1 counterclockwise
            digitalWrite(MOTOR_IN1, LOW);
            digitalWrite(MOTOR_IN2, HIGH);
            // Wait here until LS2 is triggered
            while (digitalRead(LS2) == LOW) {
                // Add a delay here to reduce CPU usage
                delay(10);
            }
            // Once LS2 is triggered, stop motor1
            stopMotor1();
            // Return to the main menu or update the status on the screen
            displayMainMenu();
            inAutoMode = false;
        }
  // Additional logic for Manual Mode
        if (inManualMode && itemCount > 0 && motor1Running && digitalRead(LDR1) ==
HIGH) {
          stopMotor1();
          runMotor2For3Seconds();
          itemCount--;
          updateItemCountDisplay();
        }
        // Additional Auto Mode logic
        if (inAutoMode) {
            if (motor1Running && digitalRead(LDR1) == HIGH) {
                 // ... (Code for Motor1 and LDR1 Logic)
            }
            if (digitalRead(LS1) == HIGH) {
                 // ... (Code for LS1 Logic)
                 // Note: Ensure that all loops and conditions inside this block are
closed properly.
            }
        }
                 // Additional logic for Manual Mode
        if (inManualMode && manualModeStarted && itemCount <= 0) {
    stopMotor1();
    tft.fillScreen(BLACK);
    tft.setTextColor(WHITE);
    tft.setTextSize(2);
    tft.setCursor(50, 100);
    tft.println("Process Complete");
    delay(2000);
    displayMainMenu();
    inManualMode = false;
    manualModeStarted = false; // Reset the flag
}
    }
} // Closing brace for the main loop function