Page 1 of 1

Not able to read Input registers via Modbus

Posted: Wed Sep 04, 2024 12:09 pm
by rdkulkarni
I have written a modbus code which has separate functions to read and write holding registers, read and write coils and read input registers. The rest of the functions work properly except read input registers. The error says that the CID declaration is wrong but I am not able to find what is wrong with it.

I am getting this error when I read Input register:
E (480) MB_CONTROLLER_MASTER: mbc_serial_master_get_parameter: The requested cid(2) is not configured correctly. Check data dictionary for correctness.
E (500) MB_CONTROLLER_MASTER: mbc_master_get_parameter(74): Master get parameter failure, error=(0x102) (ESP_ERR_INVALID_ARG).
E (510) MASTER_TEST: Characteristic #2 (Length) read failed, err = 0x102 (ESP_ERR_INVALID_ARG).

My function call is this:
float test1 = master_read_input_register(2);

Read input register function:
float master_read_input_register(uint16_t cid) {
esp_err_t err = ESP_OK;
float value = NAN; // Default to NAN to indicate an error if read fails
const mb_parameter_descriptor_t* param_descriptor = NULL;
bool alarm_state = false;

ESP_LOGI(TAG, "Start reading input register for CID: %u...", cid);

// Get parameter descriptor for the provided CID
err = mbc_master_get_cid_info(cid, &param_descriptor);

if ((err != ESP_ERR_NOT_FOUND) && (param_descriptor != NULL) && param_descriptor->mb_param_type == MB_PARAM_INPUT) {
void* temp_data_ptr = master_get_param_data(param_descriptor);
assert(temp_data_ptr);

uint8_t type = 0;
err = mbc_master_get_parameter(cid, (char*)param_descriptor->param_key,
(uint8_t*)temp_data_ptr, &type);

if (err == ESP_OK) {
uint16_t raw_value = *(uint16_t*)temp_data_ptr;
ESP_LOGI(TAG, "Raw value = %u", raw_value);
value = (float)raw_value; // Convert raw value to float
ESP_LOGI(TAG, "Characteristic #%u %s (%s) value = %f read successfully.",
param_descriptor->cid,
param_descriptor->param_key,
param_descriptor->param_units,
value);

// Check if value is within the expected range
if ((value > param_descriptor->param_opts.max) || (value < param_descriptor->param_opts.min)) {
ESP_LOGW(TAG, "Value is out of range: %f", value);
alarm_state = true; // Set alarm if value is out of range
return NAN; // Return NAN if the value is out of range
}
} else {
ESP_LOGE(TAG, "Characteristic #%u (%s) read failed, err = 0x%x (%s).",
param_descriptor->cid,
param_descriptor->param_key,
(int)err,
(char*)esp_err_to_name(err));
}
} else {
ESP_LOGE(TAG, "Parameter descriptor not found or invalid type for CID: %u", cid);
}

if (alarm_state) {
ESP_LOGI(TAG, "Alarm triggered by CID #%u.", param_descriptor->cid);
}

return value;
}

CID declaration:
enum {
CID_HOLD_DATA_0 = 0, // Unique identifier for the 'Length' parameter (for reading)
CID_HOLD_DATA_1, // Unique identifier for the 'sending data' parameter (for writing)
CID_INPUT_DATA_0, // Unique identifier for the 'Length' parameter in input registers
CID_COIL_0, // Unique identifier for the coil
CID_COUNT
};

const mb_parameter_descriptor_t device_parameters[] = {
{ CID_HOLD_DATA_0, STR("Length"), STR("cm"), 1, MB_PARAM_HOLDING, 775, 2,
HOLD_OFFSET(holding_data0), PARAM_TYPE_FLOAT, 4, OPTS_NO_LIMIT, PAR_PERMS_READ_WRITE_TRIGGER },
{ CID_HOLD_DATA_1, STR("sending data"), STR("words.."), 1, MB_PARAM_HOLDING, 775, 2, // Same address
HOLD_OFFSET(holding_data1), PARAM_TYPE_FLOAT, 4, OPTS_NO_LIMIT, PAR_PERMS_READ_WRITE_TRIGGER },
{ CID_INPUT_DATA_0, STR("Length"), STR("cm"), 1, MB_PARAM_INPUT, 770, 2,
INPUT_OFFSET(input_data0), PARAM_TYPE_FLOAT, 4, OPTS_NO_LIMIT, PAR_PERMS_READ },
{ CID_COIL_0, STR("Coil_0"), STR("state"), 1, MB_PARAM_COIL, 522, 1, // Address 522, 1-bit size
0, PARAM_TYPE_U8, 1, OPTS_NO_LIMIT, PAR_PERMS_READ_WRITE_TRIGGER }
};