Hola, estoy teniendo algunos problemas con un pequeño proyecto en el que estoy trabajando actualmente. Mi objetivo es el siguiente:
Tengo dos dispositivos:
- Un dispositivo de transferencia de datos que utiliza el protocolo de coma flotante de 32 bits IEEE 754.
- Un dispositivo receptor que solo puede aceptar datos de 16 bits.
Planeo usar un microcontrolador ESP32 y dos transceptores MAX485 para que actúen como una pasarela (gateway).
El objetivo es:
- Recibir los datos del primer dispositivo (que están divididos porque cada valor de 32 bits llega a través de dos direcciones).
- Concatenar las dos partes de 16 bits recibidas de nuevo en el valor original de coma flotante de 32 bits.
- Convertir/reducir el valor de coma flotante de 32 bits a un formato de 16 bits (ya que el dispositivo receptor solo lo soporta).
- Enviar los datos de 16 bits resultantes a través de una única dirección al dispositivo receptor.
Los datos del primer dispositivo siguen esta tabla:
Necesito recibir los datos de las direcciones 1 y 2, y 7 y 8. Quiero concatenar los datos de cada par (1 y 2, 7 y 8) y que los resultados (después de la conversión) se envíen a los Registros de Retención (Holding Registers) Modbus 40001 y 40002, respectivamente.
Algunos detalles importantes son:
Dispositivo 1 (Fuente):
- ID Esclavo (Slave ID): 3
- Velocidad (Baud Rate): 9600
- Bits de Datos (Data Bits): 8
- Bits de Parada (Stop Bits): 1
- Paridad (Parity): Ninguna
Dispositivo Receptor (Destino):
- ID Maestro (Master ID): 1
- Velocidad (Baud Rate): 9600
- Bits de Datos (Data Bits): 8
- Bits de Parada (Stop Bits): 1
- Paridad (Parity): Ninguna
He estado utilizando una IA para que me ayude, pero sigo topándome con un muro porque tengo problemas con las librerías ModbusRTUSlave.
Actualmente, este es mi progreso:
#include <ModbusIP_ESP.h>
#include <ModbusRTU.h>
#include <ModbusMaster.h>
// ¡ÚLTIMA CORRECCIÓN DE INCLUSIÓN! Forzando la ruta dentro del nombre de la librería:
#include <modbus-esp/Modbus.h>
// ******************************************************
// --- DEFINICIONES DE HARDWARE Y PINES ---
// ******************************************************
#define SERIAL_MAESTRO Serial2
#define RX2_PIN 16
#define TX2_PIN 17
#define CTRL_BUS1_MAESTRO 4
#define BAUD_RATE_485_IN 9600
#define SERIAL_ESCLAVO Serial1
#define RX1_PIN 9
#define TX1_PIN 10
#define CTRL_BUS2_ESCLAVO 5
#define BAUD_RATE_485_OUT 9600
// ******************************************************
// --- OBJETOS MODBUS ---
// ******************************************************
ModbusMaster bus_maestro;
Modbus modbus_slave(SERIAL_ESCLAVO, CTRL_BUS2_ESCLAVO, CTRL_BUS2_ESCLAVO);
// ******************************************************
// --- REGISTROS Y CONVERSIÓN ---
// ******************************************************
#define SLAVE_ID_ENTRADA 1
#define REG_COUNT_FLOAT 2
#define START_REG_FLOAT_P 1
#define START_REG_FLOAT_T 7
#define SLAVE_ID_SALIDA 1
#define REG_SALIDA_P 0 // Mapeada a 40001
#define REG_SALIDA_T 1 // Mapeada a 40002
#define TOTAL_REGISTERS_SALIDA 2
const float FACTOR_ESCALA = 100.0;
typedef union {
float f;
uint16_t w[2];
} ModbusFloat;
uint16_t holding_registers[TOTAL_REGISTERS_SALIDA] = {0, 0};
// ******************************************************
// --- FUNCIONES DE CONTROL DE DIRECCIÓN RS-485 ---
// ******************************************************
void preTransmissionBus1() { digitalWrite(CTRL_BUS1_MAESTRO, HIGH); }
void postTransmissionBus1() { digitalWrite(CTRL_BUS1_MAESTRO, LOW); }
// ******************************************************
// --- Función de Transferencia ---
// ******************************************************
void transferAndScale(uint16_t startRegIn, uint16_t regOut) {
uint8_t result;
ModbusFloat data_in;
int16_t valor_final_16bit;
result = bus_maestro.readHoldingRegisters(SLAVE_ID_ENTRADA, startRegIn, REG_COUNT_FLOAT);
if (result == bus_maestro.ku8MBSuccess) {
data_in.w[0] = bus_maestro.getResponseBuffer(0);
data_in.w[1] = bus_maestro.getResponseBuffer(1);
float valor_escalado = data_in.f * FACTOR_ESCALA;
valor_final_16bit = (int16_t)valor_escalado;
if (abs(valor_escalado) > 32767) {
valor_final_16bit = (valor_escalado > 0) ? 32767 : -32768;
}
holding_registers[regOut] = (uint16_t)valor_final_16bit;
Serial.printf("Reg %d (Float: %.2f) -> Reg 4000%d (Int: %d)\n",
startRegIn, data_in.f, regOut + 1, valor_final_16bit);
} else {
Serial.printf("Error de lectura en Reg %d: %d\n", startRegIn, result);
}
}
// ******************************************************
// --- SETUP: Inicialización de la Pasarela ---
// ******************************************************
void setup() {
Serial.begin(115200);
Serial.println("Iniciando Pasarela Modbus...");
// Inicialización de Pines
pinMode(CTRL_BUS1_MAESTRO, OUTPUT);
digitalWrite(CTRL_BUS1_MAESTRO, LOW);
pinMode(CTRL_BUS2_ESCLAVO, OUTPUT);
digitalWrite(CTRL_BUS2_ESCLAVO, LOW);
// --- CONFIGURACIÓN MAESTRO (BUS DE ENTRADA) ---
SERIAL_MAESTRO.begin(BAUD_RATE_485_IN, SERIAL_8N1, RX2_PIN, TX2_PIN);
bus_maestro.begin(SLAVE_ID_ENTRADA, SERIAL_MAESTRO);
bus_maestro.preTransmission(preTransmissionBus1);
bus_maestro.postTransmission(postTransmissionBus1);
// --- CONFIGURACIÓN ESCLAVO (BUS DE SALIDA) ---
SERIAL_ESCLAVO.begin(BAUD_RATE_485_OUT, SERIAL_8N1, RX1_PIN, TX1_PIN);
modbus_slave.begin(SLAVE_ID_SALIDA, BAUD_RATE_485_OUT, SERIAL_8N1);
// ASIGNACIÓN CRÍTICA DE MEMORIA:
modbus_slave.setupHoldingRegisters(holding_registers, TOTAL_REGISTERS_SALIDA);
Serial.println("Configuración completa. Ejecutando LOOP.");
}
// ******************************************************
// --- LOOP: Lógica de Transferencia Continua ---
// ******************************************************
void loop() {
transferAndScale(START_REG_FLOAT_P, REG_SALIDA_P);
transferAndScale(START_REG_FLOAT_T, REG_SALIDA_T);
modbus_slave.poll();
delay(100);
}
Agradezco cualquier apoyo y consejo que puedan darme
