#include #include "MorsePart.h" #define refreshDelay 1000 #define BTN_A 37 #define BTN_B 39 #define extenderPin 26 int currentlySelected = 1000; const int numCodes = 11; const String codes[] = { "bond", "swap", "call", "repo", "yield", "index", "asset", "bear", "bull", "gain", "loss"}; #define selectedDisplayLength 0 // Used for debug but not used for production bool isSelectionMode = false; long onSelectedTime = 0; int correctIndex; bool hasWon = false; void initRandomSeed() { M5.IMU.Init(); float accX, accY, accZ; delay(250); // Wait for imu init M5.IMU.getAccelData(&accX, &accY, &accZ); float accelSum = accX + accY + accZ; unsigned long seed = accelSum * 1000000; randomSeed(seed); } void setup() { M5.begin(); M5.Lcd.setRotation(1); M5.Lcd.fillScreen(BLACK); pinMode(BTN_A, INPUT_PULLDOWN); pinMode(BTN_B, INPUT_PULLDOWN); Serial.begin(115200); updateUI(); initRandomSeed(); //correctIndex = 1; correctIndex = random(0, 12); morseInit(correctIndex, 0, 0, 300, 100); } void updateUI() { Serial.println("Next correct: " + codes[correctIndex]); // Clear screen M5.Lcd.fillRect(0, 100, 300, 100, BLACK); if (hasWon) { M5.Lcd.fillScreen(GREEN); digitalWrite(extenderPin, LOW); delay(3000); // Wait for reset click while (digitalRead(BTN_A) == HIGH || digitalRead(BTN_B) == HIGH) { delay(10); } while (digitalRead(BTN_A) == HIGH || digitalRead(BTN_B) == HIGH) { delay(10); } digitalWrite(extenderPin, HIGH); hasWon = false; M5.Lcd.fillScreen(BLUE); correctIndex = random(0, 12); delay(1000); return; } if (!isSelectionMode) { // Draw divider M5.Lcd.drawLine(0, 100, 300, 100, WHITE); // Draw left text M5.Lcd.setTextSize(2); M5.Lcd.setCursor(20, 110); M5.Lcd.setTextColor(WHITE); M5.Lcd.print(codes[(currentlySelected - 1) % numCodes]); // Draw selected text M5.Lcd.fillRect(90, 110 - 5, 14 * 5, 25, WHITE); M5.Lcd.setTextSize(2); M5.Lcd.setCursor(95, 110); M5.Lcd.setTextColor(BLACK); M5.Lcd.print(codes[(currentlySelected) % numCodes]); // Draw right text M5.Lcd.setTextSize(2); M5.Lcd.setCursor(175, 110); M5.Lcd.setTextColor(WHITE); M5.Lcd.print(codes[(currentlySelected + 1) % numCodes]); } else { // Draw selected text M5.Lcd.setTextSize(4); M5.Lcd.setCursor(10, 20); M5.Lcd.setTextColor(WHITE); M5.Lcd.print(codes[(currentlySelected) % numCodes]); } } void onBothPressed() { isSelectionMode = true; Serial.println("Selected: " + codes[(currentlySelected) % numCodes]); updateUI(); if (correctIndex == (currentlySelected) % numCodes) hasWon = true; else { M5.Lcd.fillScreen(RED); delay(3000); morseDisplayIndex = 0; // Reset morse } onSelectedTime = millis(); } bool isButtonAPressed, isButtonBPressed = false; void loop() { morseUpdate(); if (millis() % refreshDelay < 100) updateUI(); if (!isButtonAPressed && digitalRead(BTN_A) == LOW) { isButtonAPressed = true; //Serial.println("A pressed"); if (isButtonBPressed) { onBothPressed(); return; } } else if (isButtonAPressed && digitalRead(BTN_A) == HIGH) { isButtonAPressed = false; //Serial.println("A released"); if (!isSelectionMode) { currentlySelected++; updateUI(); } } if (!isButtonBPressed && digitalRead(BTN_B) == LOW) { isButtonBPressed = true; //Serial.println("B pressed"); if (isButtonAPressed) { onBothPressed(); return; } } else if (isButtonBPressed && digitalRead(BTN_B) == HIGH) { isButtonBPressed = false; //Serial.println("B released"); if (!isSelectionMode) { currentlySelected--; updateUI(); } } if (isSelectionMode && onSelectedTime + selectedDisplayLength < millis()) { isSelectionMode = false; } }