/*
  Wokwi | questions
  Arduino Drag Race Tree Project, Please help

  Wolfish — December 14, 2024 at 10:29 PM
  //Drag Race Tree For Andrew
*/

#include <Wire.h>
#include <Adafruit_Sensor.h>
#include <Adafruit_MPU6050.h>
#include <LiquidCrystal_I2C.h>

const int STAGE_DELAYS[] = {0, 1000, 1000, 1000, 1000, 5000};
// pin constants
const int BUTTON_PIN = 12;
const int STAGE1_LED_PIN = 11;
const int STAGE2_LED_PIN = 10;
const int YEL1_LED_PIN = 9;
const int YEL2_LED_PIN = 8;
const int YEL3_LED_PIN = 7;
const int GRN_LED_PIN = 6;
const int RED_LED_PIN = 5;
const int BUZZER_PIN = 4;

// global variables
bool isRunning = false;
int stage = 0;
unsigned long prevMillis = 0;

// create objects
Adafruit_MPU6050 mpu;
LiquidCrystal_I2C lcd(0x27, 16, 2);

bool checkMotion()  {
  bool didMove = false;

  sensors_event_t event;
  mpu.getAccelerometerSensor()->getEvent(&event);

  // for test
  /*
    Serial.print("X: ");
    Serial.println(event.acceleration.x, 3);
    Serial.print("Y: ");
    Serial.println(event.acceleration.y, 3);
    Serial.print("Z: ");
    Serial.println(event.acceleration.z, 3);
    delay(1000);
  */

  if ((event.acceleration.x <= -0.5 || event.acceleration.x >= 0.5) ||
      (event.acceleration.y <= -0.5 || event.acceleration.y >= 0.5) ||
      (event.acceleration.z <=  9.3 || event.acceleration.z >= 10.3)) {
    didMove = true;
  }

  return didMove;
}

bool checkStartBtn() {
  static int lastBtnState = HIGH;
  bool isPressed = false;

  int btnState = digitalRead(BUTTON_PIN);
  if (btnState != lastBtnState) {
    lastBtnState = btnState;
    if (btnState == LOW) {
      isPressed = true;
    }
    delay(20);  // debounce
  }
  return isPressed;
}

void setup() {
  Serial.begin(9600);
  if (!mpu.begin()) {
    Serial.println("MPU6050 not detected, check wiring.");
  }
  lcd.init();
  lcd.backlight();
  pinMode(BUTTON_PIN, INPUT_PULLUP);
  pinMode(STAGE1_LED_PIN, OUTPUT);
  pinMode(STAGE2_LED_PIN, OUTPUT);
  pinMode(YEL1_LED_PIN, OUTPUT);
  pinMode(YEL2_LED_PIN, OUTPUT);
  pinMode(YEL3_LED_PIN, OUTPUT);
  pinMode(GRN_LED_PIN, OUTPUT);
  pinMode(RED_LED_PIN, OUTPUT);
  pinMode(BUZZER_PIN, OUTPUT);
  // initialize
  digitalWrite(STAGE1_LED_PIN, HIGH);
  digitalWrite(STAGE2_LED_PIN, LOW);
  digitalWrite(YEL1_LED_PIN, LOW);
  digitalWrite(YEL2_LED_PIN, LOW);
  digitalWrite(YEL3_LED_PIN, LOW);
  digitalWrite(GRN_LED_PIN, LOW);
  digitalWrite(RED_LED_PIN, LOW);
  lcd.setCursor(1, 0);
  lcd.print("Practice Tree");
  lcd.setCursor(5, 1);
  lcd.print("V1.00");
  delay(1000);
  lcd.clear();
  lcd.setCursor(3, 0);
  lcd.print("Pre-stage");
  Serial.println("System ready!\n");
  Serial.println("Pre-stage");
}

void loop() {
  bool start = checkStartBtn();

  if (start && !isRunning)  {
    stage = 0;
    isRunning = true;
    prevMillis = millis();
  }

  if (isRunning)  {
    bool didMove = checkMotion();
    if (didMove && (stage != 0 || stage != 5))  {
      //isRunning = false;
      stage = 5;
      digitalWrite(STAGE1_LED_PIN, LOW);
      digitalWrite(STAGE2_LED_PIN, LOW);
      digitalWrite(YEL1_LED_PIN, LOW);
      digitalWrite(YEL2_LED_PIN, LOW);
      digitalWrite(YEL3_LED_PIN, LOW);
      digitalWrite(GRN_LED_PIN, LOW);
      digitalWrite(RED_LED_PIN, HIGH);
      //lcd.clear();
      lcd.setCursor(3, 0);
      lcd.print("   FOUL  ");
    } else if (stage == 5)  {
      // start timer
      lcd.setCursor(0, 1);
      lcd.print("Start: ");
      lcd.print(millis());///////////////////////////////////////////////////////////
    }
    if (millis() - prevMillis >= STAGE_DELAYS[stage]) {
      prevMillis = millis();
      stage++;
      if (stage == 6) {
        stage = 0;
        isRunning = false;
      }
      if (stage == 0) {
        Serial.println("Pre-Stage");
        lcd.clear();
        lcd.setCursor(3, 0);
        lcd.print("Pre-Stage");
      } else if (stage == 5) {
        Serial.println("GO !!!\n");
        lcd.clear();
        lcd.setCursor(5, 0);
        lcd.print("GO !!!");
      } else {
        Serial.print("Stage: ");
        Serial.println(stage);
        lcd.clear();
        lcd.setCursor(4, 0);
        lcd.print("Stage: ");
        lcd.print(stage);
      }
      //}
      switch (stage)  {
        case 0:
          digitalWrite(STAGE1_LED_PIN, HIGH);
          digitalWrite(STAGE2_LED_PIN, LOW);
          digitalWrite(YEL1_LED_PIN, LOW);
          digitalWrite(YEL2_LED_PIN, LOW);
          digitalWrite(YEL3_LED_PIN, LOW);
          digitalWrite(GRN_LED_PIN, LOW);
          digitalWrite(RED_LED_PIN, LOW);
          break;
        case 1:
          digitalWrite(STAGE2_LED_PIN, HIGH);
          tone(BUZZER_PIN, 220, 100);
          break;
        case 2:
          digitalWrite(YEL1_LED_PIN, HIGH);
          tone(BUZZER_PIN, 440, 100);
          break;
        case 3:
          digitalWrite(YEL2_LED_PIN, HIGH);
          tone(BUZZER_PIN, 440, 100);
          break;
        case 4:
          digitalWrite(YEL3_LED_PIN, HIGH);
          tone(BUZZER_PIN, 440, 100);
          break;
        case 5:
          digitalWrite(GRN_LED_PIN, HIGH);
          tone(BUZZER_PIN, 880, 100);
          break;
        default:
          break;
      }
    }
  }
}
$abcdeabcde151015202530354045505560fghijfghij