#pragma once #include #include #include // Guard RAII: toma el mutex al entrar al alcance y lo libera al salir. // Garantiza emparejamiento lock/unlock incluso con return/early-exit. // No copiable: un handle tomado debe liberarse exactamente una vez. struct ScopedMutexGuard { SemaphoreHandle_t _m = nullptr; ScopedMutexGuard(SemaphoreHandle_t m) : _m(m) { if (_m && xSemaphoreTake(_m, portMAX_DELAY) != pdTRUE) { Serial.println("[FATAL] xSemaphoreTake fallo (mutex destruido?)"); _m = nullptr; // no liberar lo que no se tomo } } ~ScopedMutexGuard() { if (_m && xSemaphoreGive(_m) != pdTRUE) { Serial.println("[FATAL] xSemaphoreGive fallo (mutex no tomado?)"); } } ScopedMutexGuard(const ScopedMutexGuard&) = delete; ScopedMutexGuard& operator=(const ScopedMutexGuard&) = delete; // Move: transfiere la posesion (evita doble liberacion). ScopedMutexGuard(ScopedMutexGuard&& other) : _m(other._m) { other._m = nullptr; } }; // Maximo de bytes de log copiados fuera de PSRAM hacia el heap interno // (String no usa PSRAM; el heap interno es ~320KB). constexpr size_t LOG_SEND_CHUNK = 60 * 1024; // ============================================================================== // CONFIGURACIÓN GENERAL Y HARDWARE (Waveshare ESP32-S3-Nano) // ============================================================================== #define VERBO 0 // --- Version de PCB: seleccionada mediante build_flags --- #ifndef PCB_VERSION #error "Define PCB_VERSION=1 o PCB_VERSION=2 en platformio.ini" #endif // --- Pines Motores Paso a Paso (GPIO nativos ESP32-S3) --- #if PCB_VERSION == 1 constexpr int MOTOR_X_STEP_PIN = 48; constexpr int MOTOR_X_DIRECTION_PIN = 47; #elif PCB_VERSION == 2 constexpr int MOTOR_X_STEP_PIN = 8; constexpr int MOTOR_X_DIRECTION_PIN = 7; #else #error "PCB_VERSION no soportada: utiliza 1 o 2" #endif constexpr int MOTOR_Y_STEP_PIN = 6; constexpr int MOTOR_Y_DIRECTION_PIN = 5; constexpr int PIN_MOTOR_EN = 21; constexpr int PIN_VOC = 18; // --- Pines I2C (ADS122C04) --- constexpr int SDA_PIN = 11; constexpr int SCL_PIN = 12; // --- Parámetros de UART para TMC2209 --- constexpr long TMC_SERIAL_BAUD_RATE = 250000; constexpr uint8_t TMC_REPLY_DELAY = 15; // Configuración Driver X (Motor 0) constexpr uint8_t RUN_CURRENT_PERCENT0 = 29; constexpr int32_t VELOCITY0 = 4200; constexpr uint8_t STALL_GUARD_THRESHOLD0 = 200; // Configuración Driver Y (Motor 1) constexpr uint8_t RUN_CURRENT_PERCENT1 = 29; constexpr int32_t VELOCITY1 = 4200; constexpr uint8_t STALL_GUARD_THRESHOLD1 = 200; // Límites de carrera mecánicos constexpr int32_t LIMITX = -120000; constexpr int32_t LIMITY = -116000; constexpr int32_t HIST_VAL = 100; // Velocidades de operación normal constexpr float MOTOR_MAX_SPEED = 6200.0f; constexpr float MOTOR_ACCELERATION = 9000.0f; // --- Red WiFi y NTP (WPA2-Enterprise / PEAP) --- extern const char* WIFI_SSID; extern const char* WIFI_EAP_IDENTITY; extern const char* WIFI_EAP_USERNAME; extern const char* WIFI_EAP_PASSWORD; constexpr const char* NTP_SERVER = "pool.ntp.org"; constexpr long GMT_OFFSET_SEC = -6 * 3600; // UTC-6 (Aguascalientes) constexpr int DAYLIGHT_OFFSET_SEC = 0; // --- Coordenadas Geográficas (Aguascalientes) --- constexpr float SITE_LATITUDE = 21.88f; // °N constexpr float SITE_LONGITUDE = -102.29f; // °E (negativo = Oeste) // --- Capacidad de Log en PSRAM --- constexpr size_t PSRAM_LOG_CAPACITY = 2 * 1024 * 1024; // 2 MB // --- NVS (Persistencia de coordenadas) --- constexpr int32_t NVS_THRESHOLD = 1000; constexpr unsigned long NVS_CHECK_PERIOD_MS = 500; // --- Servidor Cloud / Docker Hub (WebSocket Inverso) --- constexpr bool CLOUD_SYNC_ENABLED = true; extern const char* CLOUD_SERVER_HOST; // Definido en main.cpp constexpr uint16_t CLOUD_SERVER_PORT = 443; constexpr const char* CLOUD_SERVER_PATH = "/ws/esp32"; // --- F5: Re-alineación astronómica periódica -------------------------------- constexpr uint32_t F5_DRIFT_PERIOD_MS = 300000UL; // 5 min entre chequeos de deriva constexpr int32_t F5_DRIFT_THRESHOLD = 2000; // Pasos máx. de deriva antes de re-alinear // --- OTA / version de firmware --------------------------------------------- // Se reporta al hub al (re)conectar como linea "VER:". El hub la // compara con la imagen subida; cuando hay diferencia (o auto-update ON) manda // "OTA:" por el canal WSS para que el dispositivo descargue + flashee + // se reinicie con la nueva firmware. Sube esta version antes de cada build. #define FIRMWARE_VERSION "1.1.5-ws" // 1.1.4: corrige dC, rampa cerca del pico y escape de la zona muerta. // 1.1.3: corrige el terminador duplicado del encabezado de autenticacion WebSocket. // 1.1.2: PCB_ID configurable, identidad/token por tarjeta y TLS validado para cloud/OTA. // la 1.0.1 cambie valores de control del tuning engine para mejorar la estabilidad y evitar sobrepasos. // la 1.0.2 agrega soporte OTA y comandos remotos desde el hub (Fine-Tune, Set Coords, etc.) // la 1.0.3 corrige el orden de los ejes en la visualización del canvas y en el log de posición enviada al hub. // la 1.1.0: F1 reset CmaxN, F2 auto-arranque, F3 anti-oscilación, F4 filtro picos, F5 re-alineación, F6 telemetría // la 1.1.1: mutex en buffer de log y movimiento (evita corrupción por acceso concurrente), // elimina objetos FlexyStepper/TMC2209 duplicados y aplica extensión de signo // (24 bits) a los canales del ADC: V/P/C ya no se leen como ~2^24 de noche.