Ir al contenido

← Todas las funcionalidades

Piso móvil hidráulico (app BLE)ESP32 PLC 38RBLEInfraestructura

Sincronizar el reloj en tiempo real del PLC desde una app móvil por BLE

Una máquina sin internet no puede consultar NTP, pero su registro de eventos sigue necesitando fechas reales. El truco de este despliegue real en una máquina hidráulica móvil: el smartphone del operario siempre sabe la hora, así que la app móvil la envía. Este ejemplo de sincronización del RTC del ESP32 recibe una trama [D]timestamp_ms* por BLE UART y ajusta el reloj del PLC con settimeofday() — desde ese momento cada contador, alarma y registro lleva un timestamp verdadero.

El teléfono como fuente de hora

En cada conexión, la app móvil escribe el epoch Unix actual en milisegundos en la característica RX de BLE como una trama [D]timestamp_ms*. Como los operarios y técnicos se conectan al menos una vez por sesión de trabajo, el reloj se refresca mucho más a menudo de lo que deriva, y el RTC interno del ESP32 sigue contando entre visitas. Sin módulo GPS, sin servidor NTP, sin módem celular — cero hardware extra en la lista de materiales.

Parsear el timestamp con seguridad

Los milisegundos de epoch superan los 32 bits, así que la trama se parsea con strtoull a un entero de 64 bits — usar toInt() aquí es un clásico bug de desbordamiento silencioso. Una comprobación de cordura rechaza cualquier valor anterior a 2020, protegiendo el reloj frente a una trama malformada o una build defectuosa de la app. Una vez validado, settimeofday() actualiza el reloj del sistema y todas las llamadas estándar a time() y strftime() del firmware simplemente funcionan.

Pruébalo antes de que exista la app

Como el protocolo es ASCII plano sobre el servicio Nordic UART, puedes sincronizar el reloj desde nRF Connect escribiendo la trama a mano. El ejemplo notifica la hora actual del PLC cada cinco segundos, así que ves de inmediato el salto de "RTC SIN SYNC" a una fecha correcta — el mismo patrón que usa el firmware completo de control de máquina de esta serie.

Un fragmento de la implementación

Tal cual del ejemplo desplegado en el ESP32 PLC 38R — cópialo libremente:

void setup() {
  Serial.begin(115200);

  BLEDevice::init("PLC-HIDRAULICO");
  BLEServer *server = BLEDevice::createServer();
  server->setCallbacks(new ServerCB());

  BLEService *svc = server->createService(SERVICE_UUID);
  txChar = svc->createCharacteristic(CHAR_TX_UUID, BLECharacteristic::PROPERTY_NOTIFY);
  txChar->addDescriptor(new BLE2902());
  BLECharacteristic *rxChar =
      svc->createCharacteristic(CHAR_RX_UUID, BLECharacteristic::PROPERTY_WRITE);
  rxChar->setCallbacks(new RxCB());

  svc->start();
  server->getAdvertising()->start();
  Serial.println("BLE advertising. Waiting for [D]timestamp_ms* frame ...");
}

El ejemplo completo es un programa entero — cabecera de conexionado, setup y bucle principal — listo para adaptar a tu aplicación.

Preguntas frecuentes

¿Conserva el ESP32 la hora tras un corte de alimentación?

No, el reloj interno se reinicia al quitar la alimentación salvo que añadas un chip RTC externo con batería. En la práctica la app resincroniza en cada conexión, lo que cubre la mayoría de los escenarios de máquina móvil.

¿Por qué enviar milisegundos en lugar de segundos?

Las API de los teléfonos producen de forma nativa milisegundos de epoch, y la resolución extra permite al PLC ordenar eventos que ocurren dentro del mismo segundo. El firmware divide entre 1000 para el campo de segundos de todos modos.

¿Cómo gestiono las zonas horarias?

Envía UTC desde la app y guarda UTC en el PLC. Convierte a hora local solo para la visualización, ya sea en la app o con la variable de entorno TZ en el ESP32.

Funcionalidades relacionadas