#include #include #include #include #include #include #include #include // ---------------- CONFIGURACION ---------------- #define CANAL_WIFI 1 #define BTN_IZQ 4 #define BTN_DER 5 #define OLED_ANCHO 128 #define OLED_ALTO 64 #define OLED_RESET -1 #define OLED_DIR 0x3C Adafruit_SH1106G display( OLED_ANCHO, OLED_ALTO, &Wire, OLED_RESET ); uint8_t macReceptor[] = { 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF }; typedef struct { uint8_t comando; } Mensaje; Mensaje datosEnvio; unsigned long ultimoEnvio = 0; uint8_t comandoAnterior = 255; bool oledDisponible = false; // ---------------- TEXTO CENTRADO ---------------- void textoCentrado(const char* texto, int y, int tamano) { display.setTextSize(tamano); int ancho = strlen(texto) * 6 * tamano; int x = (OLED_ANCHO - ancho) / 2; display.setCursor(x, y); display.print(texto); } // ---------------- CONFIGURACION OLED ---------------- void iniciarOLED() { Wire.begin(21, 22); Wire.setClock(100000); // I2C a velocidad estándar y estable oledDisponible = display.begin(OLED_DIR, true); if (!oledDisponible) { Serial.println("ERROR: NO SE DETECTA LA OLED"); return; } // Limpiar memoria física de la pantalla display.clearDisplay(); display.display(); delay(50); // Configuracion de imagen display.setRotation(0); display.setTextColor(SH110X_WHITE, SH110X_BLACK); // Fondo negro display.setTextWrap(false); display.clearDisplay(); display.drawRect(0, 0, 128, 64, SH110X_WHITE); textoCentrado("INICIANDO", 19, 2); textoCentrado("ESP32 EMISOR", 43, 1); display.display(); delay(1200); } // ---------------- ACTUALIZAR PANTALLA ---------------- void actualizarPantalla(uint8_t comando) { if (!oledDisponible) return; display.clearDisplay(); // Marco exterior display.drawRect(0, 0, 128, 64, SH110X_WHITE); // Cabecera display.setTextSize(1); display.setCursor(7, 6); display.print(F("CONTROL ESP-NOW")); display.setCursor(105, 6); display.print(F("TX")); display.drawLine(5, 18, 122, 18, SH110X_WHITE); // Mensajes principales if (comando == 1) { textoCentrado("PULSADOR IZQ.", 26, 1); textoCentrado("IZQUIERDA", 39, 2); } else if (comando == 2) { textoCentrado("PULSADOR DER.", 26, 1); textoCentrado("DERECHA", 39, 2); } else { textoCentrado("SISTEMA ACTIVO", 26, 1); textoCentrado("ESPERANDO", 39, 2); } // Pie display.drawLine(5, 55, 122, 55, SH110X_WHITE); display.setTextSize(1); display.setCursor(26, 57); display.print(F("TRANSMISOR")); display.display(); } // ---------------- SETUP ---------------- void setup() { Serial.begin(115200); pinMode(BTN_IZQ, INPUT_PULLUP); pinMode(BTN_DER, INPUT_PULLUP); iniciarOLED(); // Iniciar WiFi WiFi.mode(WIFI_STA); WiFi.disconnect(); delay(100); Serial.println(); Serial.println("=== EMISOR ESP-NOW ==="); Serial.print("MAC: "); Serial.println(WiFi.macAddress()); // Configurar canal if (esp_wifi_set_channel( CANAL_WIFI, WIFI_SECOND_CHAN_NONE ) != ESP_OK) { Serial.println("ERROR CONFIGURANDO CANAL"); while (true) delay(1000); } // Iniciar ESP-NOW if (esp_now_init() != ESP_OK) { Serial.println("ERROR INICIANDO ESP-NOW"); while (true) delay(1000); } // Registrar receptor esp_now_peer_info_t peerInfo = {}; memcpy( peerInfo.peer_addr, macReceptor, 6 ); peerInfo.channel = CANAL_WIFI; peerInfo.encrypt = false; peerInfo.ifidx = WIFI_IF_STA; if (!esp_now_is_peer_exist(macReceptor)) { if (esp_now_add_peer(&peerInfo) != ESP_OK) { Serial.println("ERROR REGISTRANDO RECEPTOR"); while (true) delay(1000); } } Serial.println("EMISOR PREPARADO"); actualizarPantalla(0); } // ---------------- LOOP ---------------- void loop() { bool izquierda = digitalRead(BTN_IZQ) == LOW; bool derecha = digitalRead(BTN_DER) == LOW; uint8_t comando = 0; if (izquierda) { comando = 1; } else if (derecha) { comando = 2; } datosEnvio.comando = comando; // Enviar cada 100 ms if (millis() - ultimoEnvio >= 100) { esp_err_t resultado = esp_now_send( macReceptor, (uint8_t*)&datosEnvio, sizeof(datosEnvio) ); if (resultado != ESP_OK) { Serial.print("ERROR ENVIO: "); Serial.println(esp_err_to_name(resultado)); } ultimoEnvio = millis(); } // Actualizar pantalla cuando cambia el comando if (comando != comandoAnterior) { actualizarPantalla(comando); comandoAnterior = comando; } delay(10); }