#include "Arduino.h" // includes for LCD #include #include "Adafruit_GFX.h" #include "Adafruit_HX8357.h" #include "LCD_Graphics.h" // includes for audio #include #include #include "Audio.h" #include "SPIFFS_tasks.h" #define FORMAT_SPIFFS_IF_FAILED true // includes for motors #include "Motors.h" // includes for lighting #include "Lighting.h" // includes for 7 segment #include // Enable this line if using Arduino Uno, Mega, etc. #include "Adafruit_LEDBackpack.h" #include "Adafruit_GFX.h" Adafruit_7segment matrix = Adafruit_7segment(); // Use hardware SPI (on Uno, #13, #12, #11) and the above for CS/DC Adafruit_HX8357 tft = Adafruit_HX8357(TFT_CS, TFT_DC, TFT_RST); // SoftSPI - note that on some processors this might be *faster* than hardware SPI! //Adafruit_HX8357 tft = Adafruit_HX8357(TFT_CS, TFT_DC, MOSI, SCK, TFT_RST, MISO); char initials1[4] = {'T','M','B','\0'}; char initials2[4] = {'X','X','X','\0'}; char initials3[4] = {'L','L','L','\0'}; char tempInitials[4] = {'A','A','A','\0'}; char letters[28] = {'A','B','C','D','E','F','G','H','I','J','K','L','M','N','O','P','Q','R','S','T','U','V','W','X','Y','Z','-','\0'}; enum State {IDLE, EDITING, GAMEPLAY}; State currentState = IDLE; int letterIndex = 0; // Current letter being edited int charPos = 0; // Current position in initials (0-2) bool lastButton1State = HIGH; bool lastButton2State = HIGH; bool button1State = HIGH; bool button2State = HIGH; bool lastIRState = HIGH; volatile bool targetHit = false; unsigned long lastDebounceTime1 = 0; unsigned long lastDebounceTime2 = 0; const unsigned long debounceDelay = 50; // cursors to write highscores int score1_cursorY; int score2_cursorY; int score3_cursorY; int letterUnderlineX; int letterUnderlineY; int motorCounter = 0; // high scores (change to be empty values) int score1 = 500; int score2 = 300; int score3 = 0; int currentScore = 0; // most recent score int scoreToEdit; // housekeeping int graphicsCounter = 0; bool buttonsPressedAndReleased = false; // Add this as a global variable void highScore(){ unsigned long start = micros(); tft.setCursor(0, 0); tft.setTextSize(7); tft.setTextColor(HX8357_GREEN); tft.println("Welcome to Pinball!"); tft.setTextSize(3); tft.println(); tft.setTextColor(HX8357_RED); tft.setTextSize(5); tft.println("High Scores:"); tft.setTextColor(HX8357_WHITE); tft.setTextSize(3); tft.println(); score1_cursorY = tft.getCursorY(); // tft.fillRect(0, score1_cursorY, 200, 30, HX8357_BLACK); // Adjust width/height as needed tft.setCursor(0, score1_cursorY); // Move cursor back tft.print("1: "); tft.print(initials1); tft.print(" - "); tft.println(score1); tft.setTextSize(2); tft.println(); tft.setTextSize(3); score2_cursorY = tft.getCursorY(); // tft.fillRect(0, score2_cursorY, 200, 30, HX8357_BLACK); // Adjust width/height as needed tft.setCursor(0, score2_cursorY); // Move cursor back tft.print("2: "); tft.print(initials2); tft.print(" - "); tft.println(score2); tft.setTextSize(2); tft.println(); tft.setTextSize(3); score3_cursorY = tft.getCursorY(); // tft.fillRect(0, score3_cursorY, 200, 30, HX8357_BLACK); // Adjust width/height as needed tft.setCursor(0, score3_cursorY); // Move cursor back tft.print("3: "); tft.print(initials3); tft.print(" - "); tft.println(score3); } // Button 1 - Cycle through letters void handleButton1Press(int initial) { if (currentState == EDITING) { letterIndex = (letterIndex + 1) % 27; // Wrap around A-Z and '-' if (initial == 1){ initials1[charPos] = letters[letterIndex]; tft.setCursor(0, score1_cursorY); // Move cursor tft.fillRect(0, score1_cursorY, 150, 25, HX8357_BLACK); // Adjust width/height as needed tft.setCursor(0, score1_cursorY); // Move cursor back tft.print("1: "); tft.println(initials1); // tft.fillRect(letterUnderlineX, letterUnderlineY, 20, 3, HX8357_WHITE); // White underline Serial.print("Updated Initials: "); Serial.println(initials1); } else if (initial == 2){ initials2[charPos] = letters[letterIndex]; tft.setCursor(0, score2_cursorY); // Move cursor tft.fillRect(0, score2_cursorY, 150, 25, HX8357_BLACK); // Adjust width/height as needed tft.setCursor(0, score2_cursorY); // Move cursor back tft.print("2: "); tft.println(initials2); Serial.print("Updated Initials: "); Serial.println(initials2); } else if (initial == 3){ initials3[charPos] = letters[letterIndex]; tft.setCursor(0, score3_cursorY); // Move cursor tft.fillRect(0, score3_cursorY, 150, 25, HX8357_BLACK); // Adjust width/height as needed tft.setCursor(0, score3_cursorY); // Move cursor back tft.print("3: "); tft.println(initials3); Serial.print("Updated Initials: "); Serial.println(initials3); } } } // Button 2 - Move to next letter void handleButton2Press(int initial) { if (currentState == EDITING) { // Erase the previous underline if (initial == 1) { tft.fillRect(50, letterUnderlineY, 60, 3, HX8357_BLACK); // Clears all 3 positions } else if (initial == 2) { tft.fillRect(50, letterUnderlineY, 60, 3, HX8357_BLACK); } else if (initial == 3) { tft.fillRect(50, letterUnderlineY, 60, 3, HX8357_BLACK); // Fix incorrect score reference } charPos++; // Move to next letter if (charPos > 2) { Serial.println("Initials Set! Returning to IDLE mode."); currentState = IDLE; // Exit editing mode charPos = 0; } else { letterIndex = 0; // Reset letter choice // Update the underline position for the next character letterUnderlineX = 50 + (charPos * 20); // Draw the new white underline tft.fillRect(letterUnderlineX, letterUnderlineY, 20, 3, HX8357_WHITE); } } } // tasks void IRAM_ATTR targetISR() { targetHit = true; // Set flag when target is hit digitalWrite(LED_BUILTIN,HIGH); Serial.println("DETECTED"); } void setup() { Serial.begin(115200); // 115200 delay(1000); pinMode (LED_BUILTIN, OUTPUT); pinMode (buttonPin1, INPUT_PULLDOWN); pinMode (buttonPin2, INPUT_PULLDOWN); pinMode (IRPin1, INPUT); pinMode (targetPin1, INPUT_PULLDOWN); pinMode (targetPin2, INPUT_PULLDOWN); pinMode (IRPin2, INPUT); // begin 7 segment matrix.begin(0x70); matrix.println(currentScore); matrix.writeDisplay(); // begin lighting SetupLights(); // begin LCD display tft.begin(8000000); tft.fillScreen(HX8357_BLACK); tft.setRotation(3); highScore(); Serial.println("Motors check begin"); //begin motors MotorsSetup(); Serial.println("Motors check end"); } void loop() { highScore(); switchLights(); if(currentScore%2==0){ turnMotorsBackward(); } else{ turnMotorsForward(); } currentScore+=1; matrix.println(currentScore); matrix.writeDisplay(); }