|
| struct | SensorData |
| | Parámetros de configuración del sensor para descubrimiento Modbus. More...
|
|
|
#define | SLAVE_ID 1 |
| | Dirección Modbus del dispositivo esclavo.
|
|
#define | NUM_REGISTERS 18 |
| | Número total de registros Modbus disponibles para datos RMS.
|
|
|
HardwareSerial | ModbusSerial (1) |
| | Instancia del puerto serie para comunicación Modbus RS485.
|
|
ModbusServerRTU | MBserver (2000) |
| | Servidor Modbus RTU con timeout de 2000ms.
|
| void | dataUpdateTask (void *pvParameters) |
| | Tarea de actualización de registros Modbus con factores de conversión por canal.
|
| ModbusMessage | readHoldingRegistersWorker (ModbusMessage request) |
| | Worker para manejar peticiones Modbus de lectura de registros.
|
|
|
uint16_t | holdingRegisters [NUM_REGISTERS] |
| | Registros Modbus para datos RMS.
|
|
SemaphoreHandle_t | dataMutex |
| | Mutex para protección de registros Modbus.
|
|
TaskHandle_t | dataUpdateTaskHandle |
| | Handle de la tarea de actualización de datos Modbus.
|
|
SensorData | sensor = {1, 3, 10, NUM_REGISTERS, PROCESS_INTERVAL_MS, 1, 1, 0} |
| | Configuración del sensor para respuestas de descubrimiento.
|
|
const int | MODBUS_UPDATE_INTERVAL_MS = 300 |
| | Intervalo de actualización de registros Modbus en milisegundos.
|
Resumen
Este módulo implementa el servidor Modbus RTU (ESP32) y el flujo completo de:
- Respuesta a peticiones de descubrimiento de sensores por parte de maestros RS485.
- Gestión de registros holding para datos RMS y parámetros de configuración.
- Actualización periódica de datos desde el subsistema de procesamiento RMS.
- Manejo de errores y validación de direcciones en el protocolo Modbus.
Estructura y componentes
- Datos y configuración
- SensorData: definición de parámetros del sensor para descubrimiento.
- holdingRegisters[]: array de registros Modbus con datos RMS.
- sensor: instancia global con configuración del dispositivo.
- Comunicación y protocolo
- ModbusServerRTU: servidor RTU con timeout configurable.
- HardwareSerial: puerto serie RS485 para comunicación física.
- readHoldingRegistersWorker(): worker principal para función 03.
- Tareas principales
- dataUpdateTask: actualización periódica de registros desde historial RMS.
- Callbacks: worker registrado para READ_HOLD_REGISTER.
API Principal
Uso
Resumen del flujo:
1) Inicialización Modbus
- Configuración UART RS485 (19200 bps, 8N1) en pines RX=20, TX=21.
- Inicialización ModbusServerRTU con SLAVE_ID=1 y timeout=2000ms.
- Registro de worker para función 03 (lectura de holding registers).
- Creación de mutex dataMutex para protección de registros.
2) Descubrimiento de sensores
- readHoldingRegistersWorker() responde a peticiones de direcciones 0-7.
- Devuelve estructura SensorData con: sensorID=1, numberOfChannels=3, startAddress=10.
- Incluye parámetros: maxRegisters=18, samplingInterval=1000ms, dataType=1, scale=1.
- Permite identificación automática por maestros Modbus.
3) Actualización de datos
- dataUpdateTask se ejecuta cada 300ms en núcleo 0 con prioridad 1.
- Extrae historial RMS usando get_rms_history() para cada canal.
- Aplica CONVERSION_FACTOR=0.618 para convertir a unidades físicas.
- Actualiza holdingRegisters[] de forma thread-safe con dataMutex.
4) Respuesta a lecturas de datos
- readHoldingRegistersWorker() maneja peticiones de direcciones 10+.
- Valida rango de direcciones y número de registros solicitados.
- Protege acceso a holdingRegisters[] con dataMutex (timeout 100ms).
- Devuelve datos RMS organizados por canal o error ILLEGAL_DATA_ADDRESS.
5) Manejo de errores Modbus
- Validación de direcciones fuera de rango (>= NUM_REGISTERS).
- Respuesta SERVER_DEVICE_BUSY si no se puede obtener dataMutex.
- Logs de depuración para ServerID y FunctionCode recibidos.
Advertencias y mejores prácticas:
- Asegurar layout consistente de 8 registros de parámetros para descubrimiento.
- Respetar offset de datos en registros Modbus RTU según especificación.
- Proteger acceso a holdingRegisters[] con dataMutex en todas las operaciones.
- Verificar límites de NUM_REGISTERS para evitar desbordamiento de buffer.
- Mantener coherencia entre numberOfChannels y organización de datos en registros.
- Configurar timeout apropiado del servidor según latencia esperada del bus RS485.
◆ dataUpdateTask()
| void dataUpdateTask |
( |
void * | pvParameters | ) |
|
Tarea de actualización de registros Modbus con factores de conversión por canal.
Actualiza periódicamente los registros Modbus con los últimos valores RMS de todos los canales. Organiza los datos dinámicamente según el número de canales configurado. Aplica factores de conversión específicos para cada canal desde CONVERSION_FACTORS array.
- Parameters
-
| pvParameters | Parámetros de la tarea (no utilizados). |
Aplicación de factor de conversión específico por canal.
Usa CONVERSION_FACTORS[ch] en lugar del factor global para permitir calibración individual por canal.
◆ readHoldingRegistersWorker()
| ModbusMessage readHoldingRegistersWorker |
( |
ModbusMessage | request | ) |
|
Worker para manejar peticiones Modbus de lectura de registros.
Responde a dos tipos de consultas:
- Registros 0-7: Parámetros de configuración del sensor
- Registros 10+: Datos RMS históricos Implementa validación de límites de direcciones para prevenir accesos inválidos.
- Parameters
-
| request | Mensaje de petición Modbus recibido. |
- Returns
- ModbusMessage Respuesta Modbus formateada.