// --- Libraries --- #include #include #include // --- OLED display configuration --- #define SCREEN_WIDTH 128 #define SCREEN_HEIGHT 64 #define OLED_RESET -1 #define SCREEN_ADDRESS 0x3C Adafruit_SSD1306 display(SCREEN_WIDTH, SCREEN_HEIGHT, &Wire, OLED_RESET); // --- Pin definitions --- #define RELE_RESISTOR1_PIN D0 #define RELE_PISTON_PIN D1 #define RELE_RESISTOR2_PIN D9 #define BUTTON_UP D2 #define BUTTON_DOWN D3 #define BUTTON_SELECT D6 #define SENSOR_BEGIN_PIN D7 #define SENSOR_END_PIN D8 // --- System states --- bool resistor1 = false; bool piston = false; bool resistor2 = false; int selectedOption = 0; const int NUM_OPTIONS = 3; String options[NUM_OPTIONS] = { "Resistor 1", "Resistor 2", "Piston" }; int animationFrame = 0; unsigned long lastAnimationTime = 0; // --- Setup --- void setup() { Wire.begin(); display.begin(SSD1306_SWITCHCAPVCC, SCREEN_ADDRESS); display.clearDisplay(); showStartupScreen(); // Output pins pinMode(RELE_RESISTOR1_PIN, OUTPUT); pinMode(RELE_PISTON_PIN, OUTPUT); pinMode(RELE_RESISTOR2_PIN, OUTPUT); digitalWrite(RELE_RESISTOR1_PIN, LOW); digitalWrite(RELE_PISTON_PIN, LOW); digitalWrite(RELE_RESISTOR2_PIN, LOW); // Input buttons pinMode(BUTTON_UP, INPUT_PULLUP); pinMode(BUTTON_DOWN, INPUT_PULLUP); pinMode(BUTTON_SELECT, INPUT_PULLUP); // Sensors pinMode(SENSOR_BEGIN_PIN, INPUT); pinMode(SENSOR_END_PIN, INPUT); drawMenu(); } // --- Main loop --- void loop() { static unsigned long lastDebounce = 0; if (millis() - lastDebounce > 200) { if (digitalRead(BUTTON_UP) == LOW) { selectedOption = (selectedOption - 1 + NUM_OPTIONS) % NUM_OPTIONS; lastDebounce = millis(); } else if (digitalRead(BUTTON_DOWN) == LOW) { selectedOption = (selectedOption + 1) % NUM_OPTIONS; lastDebounce = millis(); } else if (digitalRead(BUTTON_SELECT) == LOW) { switch (selectedOption) { case 0: resistor1 = !resistor1; digitalWrite(RELE_RESISTOR1_PIN, resistor1 ? HIGH : LOW); break; case 1: resistor2 = !resistor2; digitalWrite(RELE_RESISTOR2_PIN, resistor2 ? HIGH : LOW); break; case 2: piston = !piston; digitalWrite(RELE_PISTON_PIN, piston ? HIGH : LOW); break; } lastDebounce = millis(); } } // Animation update if (millis() - lastAnimationTime > 150) { animationFrame = (animationFrame + 1) % 3; lastAnimationTime = millis(); } drawMenu(); delay(50); } // --- Startup screen with logo and loading bar --- void showStartupScreen() { display.clearDisplay(); display.setTextSize(2); display.setTextColor(SSD1306_WHITE); display.setCursor(24, 0); display.println("Apolo's"); display.display(); delay(800); display.drawCircle(64, 28, 7, SSD1306_WHITE); // Head display.drawLine(48, 54, 64, 36, SSD1306_WHITE); // Left body display.drawLine(64, 36, 80, 54, SSD1306_WHITE); // Right body display.drawLine(54, 54, 74, 54, SSD1306_WHITE); // Base display.drawLine(64, 42, 64, 54, SSD1306_WHITE); // Inner line display.drawLine(48, 40, 34, 28, SSD1306_WHITE); // Left arm display.drawLine(80, 40, 94, 28, SSD1306_WHITE); // Right arm display.display(); for (int i = 0; i <= 100; i += 10) { display.drawRect(14, 58, 100, 4, SSD1306_WHITE); display.fillRect(16, 60, i, 2, SSD1306_WHITE); display.display(); delay(180); } delay(300); display.clearDisplay(); display.display(); } // --- Menu interface with state and animation --- void drawMenu() { display.clearDisplay(); display.setTextSize(1); display.setTextColor(SSD1306_WHITE); display.setCursor(0, 0); display.println("Interfaz de Control"); for (int i = 0; i < NUM_OPTIONS; i++) { display.setCursor(0, 12 + i * 10); display.print(i == selectedOption ? "> " : " "); display.setCursor(10, 12 + i * 10); display.print(options[i]); display.setCursor(80, 12 + i * 10); bool state = (i == 0) ? resistor1 : (i == 1) ? resistor2 : piston; display.print(state ? "ON" : "OFF"); if (state) { int cx = 110; int cy = 14 + i * 10; switch (animationFrame) { case 0: display.drawCircle(cx, cy, 2, SSD1306_WHITE); break; case 1: display.fillCircle(cx, cy, 2, SSD1306_WHITE); break; case 2: display.drawCircle(cx, cy, 2, SSD1306_WHITE); display.drawPixel(cx, cy, SSD1306_BLACK); break; } } } // Sensor indicators display.setCursor(0, 42); display.print("Begin: "); if (digitalRead(SENSOR_BEGIN_PIN) == LOW) display.fillCircle(60, 44, 3, SSD1306_WHITE); else display.drawCircle(60, 44, 3, SSD1306_WHITE); display.setCursor(0, 52); display.print("End: "); if (digitalRead(SENSOR_END_PIN) == LOW) display.fillCircle(60, 54, 3, SSD1306_WHITE); else display.drawCircle(60, 54, 3, SSD1306_WHITE); display.display(); }