//Incluindo as bibliotecas
#include <Wire.h>
#include <Adafruit_GFX.h>
#include <Adafruit_SSD1306.h>
//Configurando o display
#define SCREEN_WIDTH 128
#define SCREEN_HEIGHT 64
#define OLED_RESET -1
Adafruit_SSD1306 display(SCREEN_WIDTH, SCREEN_HEIGHT, &Wire, OLED_RESET);
//Configurando os botões
#define BUTTON_NEXT 2
#define BUTTON_HIGHLIGHT 3
#define BUTTON_PREV 4
//Definindo variáveis
#define NUM_ITEMS 12
String elementos[NUM_ITEMS];
int selectedIndex = 0;
int highlightedIndex = -1;
//Configurando o debounce
unsigned long lastButtonPressNext = 0;
unsigned long lastButtonPressHighlight = 0;
unsigned long lastButtonPressPrev = 0;
unsigned long debounceDelay = 200;
//Outras variáveis
int scrollOffset = 0;
unsigned long lastScroll = 0;
unsigned long scrollInterval = 30;
void setup() {
//Configurando os INPUT's
pinMode(BUTTON_NEXT, INPUT_PULLUP);
pinMode(BUTTON_HIGHLIGHT, INPUT_PULLUP);
pinMode(BUTTON_PREV, INPUT_PULLUP); // Novo botão configurado
//Configura os elementos
for (int i = 0; i < NUM_ITEMS; i++) {
elementos[i] = "elemento" + String(i + 1);
}
//Configura e inicializa o display
if (!display.begin(SSD1306_SWITCHCAPVCC, 0x3C)) {
while (true);
}
//Mostra a animação de inicialização
StartupAnimation();
//Inicia a comunicação serial
Serial.begin(9600);
}
void loop() {
if (digitalRead(BUTTON_NEXT) == LOW) {
if (millis() - lastButtonPressNext > debounceDelay) {
selectedIndex = (selectedIndex + 1) % NUM_ITEMS;
scrollOffset = 0;
lastButtonPressNext = millis();
}
}
// Botão para voltar ao item anterior
if (digitalRead(BUTTON_PREV) == LOW) {
if (millis() - lastButtonPressPrev > debounceDelay) {
selectedIndex = (selectedIndex - 1 + NUM_ITEMS) % NUM_ITEMS;
scrollOffset = 0;
lastButtonPressPrev = millis();
}
}
if (digitalRead(BUTTON_HIGHLIGHT) == LOW) {
if (millis() - lastButtonPressHighlight > debounceDelay) {
if (highlightedIndex == selectedIndex) {
highlightedIndex = -1; // Desativa o grifo
} else {
highlightedIndex = selectedIndex; // Ativa o grifo
}
lastButtonPressHighlight = millis();
}
}
if (millis() - lastScroll > scrollInterval) {
scrollOffset++;
lastScroll = millis();
}
display.clearDisplay();
int itemsVisible = 4;
int lineHeight = 16;
int charWidth = 12;
display.setTextSize(2);
int start = selectedIndex - itemsVisible / 2;
if (start < 0) start = 0;
if (start + itemsVisible > NUM_ITEMS) start = NUM_ITEMS - itemsVisible;
for (int i = 0; i < itemsVisible; i++) {
int index = start + i;
int y = i * lineHeight;
String txt = elementos[index];
bool isSelected = (index == selectedIndex);
bool isHighlighted = (index == highlightedIndex);
// Prepara área limpa
display.fillRect(0, y, SCREEN_WIDTH, lineHeight, isHighlighted ? SSD1306_WHITE : SSD1306_BLACK);
display.setTextColor(isHighlighted ? SSD1306_BLACK : SSD1306_WHITE);
if (isSelected) {
int textWidth = txt.length() * charWidth;
if (scrollOffset > textWidth + SCREEN_WIDTH) {
scrollOffset = 0;
}
int x1 = -scrollOffset;
int x2 = textWidth - scrollOffset + SCREEN_WIDTH;
if (x1 + textWidth > 0) {
display.setCursor(x1, y);
display.print(txt);
}
if (x2 < SCREEN_WIDTH) {
display.setCursor(x2, y);
display.print(txt);
}
} else {
display.setCursor(0, y);
display.print(txt);
}
display.setTextColor(SSD1306_WHITE); // Reset cor
}
display.display();
static int lastReported = -2; // -2 garante que a mensagem inicial seja impressa
if (highlightedIndex != -1 && highlightedIndex != lastReported) {
Serial.print("tocando ");
Serial.println(elementos[highlightedIndex]);
lastReported = highlightedIndex;
} else if (highlightedIndex == -1 && lastReported != -1) {
Serial.println("pause");
lastReported = -1;
}
delay(10);
}
void StartupAnimation() {
//Configura o display
display.clearDisplay();
display.setTextSize(3);
display.setTextColor(SSD1306_WHITE);
//Configura o primeiro "frame" da animação (juntamente com o tamanho das barras)
const int len = 6;
char sequence[len + 1] = "//////";
int charWidth = 18;
//Centraliza
int startX = (SCREEN_WIDTH - (charWidth * len)) / 2; //Horizontalmente
int y = (SCREEN_HEIGHT - 24) / 2; //Verticalmente
// Etapas de rotação: | → \ → - → / → | → \ → - (7 ciclos)
char rotations[7] = {'|', '\\', '-','/','|','\\','-'};
for (int r = 0; r < 7; r++) {
for (int i = 0; i < len; i++) {
sequence[i] = rotations[r];
}
display.clearDisplay();
display.setCursor(startX, y);
display.print(sequence);
display.display();
delay(100);
}
// Etapa final: transformar uma a uma nas letras de CASTRO
const char* word = "CASTRO";
for (int i = 0; i < len; i++) {
sequence[i] = word[i];
display.clearDisplay();
display.setCursor(startX, y);
display.print(sequence);
display.display();
delay(200);
}
delay(1000); // pausa final antes de iniciar o menu
}