2025-03-04 15:21:41 +08:00
|
|
|
|
|
2025-03-08 10:17:00 +08:00
|
|
|
|
#include "FluxMod.h"
|
2025-03-04 15:21:41 +08:00
|
|
|
|
|
|
|
|
|
|
static const char *TAG = "MASTER_TEST";
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
/*<2A><><EFBFBD><EFBFBD><EFBFBD>豸<EFBFBD>Ĵ<EFBFBD><C4B4><EFBFBD><EFBFBD>洢<EFBFBD><E6B4A2>ַ*/
|
|
|
|
|
|
const mb_parameter_descriptor_t device_parameters[] = {
|
|
|
|
|
|
{ CID_INP_DATA_0, STR("Data_channel_0"), STR("Volts"), MB_DEVICE_ADDR1, MB_PARAM_INPUT, 0, 2,
|
|
|
|
|
|
INPUT_OFFSET(input_data0), PARAM_TYPE_FLOAT, 4, OPTS( -10, 10, 1 ), PAR_PERMS_READ_WRITE_TRIGGER },
|
|
|
|
|
|
{ CID_HOLD_DATA_0, STR("Humidity_1"), STR("%rH"), MB_DEVICE_ADDR1, MB_PARAM_HOLDING, 0, 2,
|
|
|
|
|
|
HOLD_OFFSET(holding_data0), PARAM_TYPE_FLOAT, 4, OPTS( 0, 100, 1 ), PAR_PERMS_READ_WRITE_TRIGGER },
|
|
|
|
|
|
};
|
|
|
|
|
|
// Calculate number of parameters in the table
|
|
|
|
|
|
const uint16_t num_device_parameters = (sizeof(device_parameters)/sizeof(device_parameters[0]));
|
|
|
|
|
|
|
2025-03-08 10:17:00 +08:00
|
|
|
|
esp_err_t modbus_master_init(void)
|
2025-03-04 15:21:41 +08:00
|
|
|
|
{
|
2025-03-08 16:49:26 +08:00
|
|
|
|
|
2025-03-04 15:21:41 +08:00
|
|
|
|
// Initialize and start Modbus controller
|
|
|
|
|
|
mb_communication_info_t comm = {
|
|
|
|
|
|
.port = MB_PORT_NUM,
|
|
|
|
|
|
.mode = MB_MODE_RTU,
|
|
|
|
|
|
.baudrate = MB_DEV_SPEED,
|
|
|
|
|
|
.parity = MB_PARITY_NONE
|
|
|
|
|
|
};
|
|
|
|
|
|
void* master_handler = NULL;
|
|
|
|
|
|
|
|
|
|
|
|
esp_err_t err = mbc_master_init(MB_PORT_SERIAL_MASTER, &master_handler);
|
2025-03-08 16:49:26 +08:00
|
|
|
|
/*<2A><><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>*/
|
2025-03-04 15:21:41 +08:00
|
|
|
|
MB_RETURN_ON_FALSE((master_handler != NULL), ESP_ERR_INVALID_STATE, TAG,
|
|
|
|
|
|
"mb controller initialization fail.");
|
|
|
|
|
|
MB_RETURN_ON_FALSE((err == ESP_OK), ESP_ERR_INVALID_STATE, TAG,
|
|
|
|
|
|
"mb controller initialization fail, returns(0x%x).", (int)err);
|
|
|
|
|
|
err = mbc_master_setup((void*)&comm);
|
|
|
|
|
|
MB_RETURN_ON_FALSE((err == ESP_OK), ESP_ERR_INVALID_STATE, TAG,
|
|
|
|
|
|
"mb controller setup fail, returns(0x%x).", (int)err);
|
|
|
|
|
|
|
|
|
|
|
|
// Set UART pin numbers
|
|
|
|
|
|
err = uart_set_pin(MB_PORT_NUM, CONFIG_MB_UART_TXD, CONFIG_MB_UART_RXD,
|
|
|
|
|
|
UART_PIN_NO_CHANGE, UART_PIN_NO_CHANGE);
|
|
|
|
|
|
MB_RETURN_ON_FALSE((err == ESP_OK), ESP_ERR_INVALID_STATE, TAG,
|
|
|
|
|
|
"mb serial set pin failure, uart_set_pin() returned (0x%x).", (int)err);
|
|
|
|
|
|
|
|
|
|
|
|
err = mbc_master_start();
|
|
|
|
|
|
MB_RETURN_ON_FALSE((err == ESP_OK), ESP_ERR_INVALID_STATE, TAG,
|
|
|
|
|
|
"mb controller start fail, returned (0x%x).", (int)err);
|
|
|
|
|
|
|
|
|
|
|
|
// Set driver mode to Half Duplex
|
|
|
|
|
|
err = uart_set_mode(MB_PORT_NUM, UART_MODE_RS485_HALF_DUPLEX);
|
|
|
|
|
|
MB_RETURN_ON_FALSE((err == ESP_OK), ESP_ERR_INVALID_STATE, TAG,
|
|
|
|
|
|
"mb serial set mode failure, uart_set_mode() returned (0x%x).", (int)err);
|
|
|
|
|
|
|
|
|
|
|
|
vTaskDelay(5);
|
|
|
|
|
|
err = mbc_master_set_descriptor(&device_parameters[0], num_device_parameters);
|
|
|
|
|
|
MB_RETURN_ON_FALSE((err == ESP_OK), ESP_ERR_INVALID_STATE, TAG,
|
|
|
|
|
|
"mb controller set descriptor fail, returns(0x%x).", (int)err);
|
|
|
|
|
|
ESP_LOGI(TAG, "Modbus master stack initialized...");
|
2025-03-08 16:49:26 +08:00
|
|
|
|
ESP_LOGI(TAG, "Modbus master initialized...");
|
2025-03-04 15:21:41 +08:00
|
|
|
|
return err;
|
2025-03-08 16:49:26 +08:00
|
|
|
|
|
|
|
|
|
|
uint8_t data=0;
|
|
|
|
|
|
mbc_master_get_parameter(device_parameters->cid,device_parameters->param_key,&data,0);
|
|
|
|
|
|
|
2025-03-04 15:21:41 +08:00
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
2025-03-11 15:15:37 +08:00
|
|
|
|
void master_operation_func(void *arg)
|
|
|
|
|
|
{
|
|
|
|
|
|
esp_err_t err = ESP_OK;
|
|
|
|
|
|
float value = 0;
|
|
|
|
|
|
bool alarm_state = false;
|
|
|
|
|
|
const mb_parameter_descriptor_t* param_descriptor = NULL;
|
|
|
|
|
|
|
|
|
|
|
|
ESP_LOGI(TAG, "Start modbus test...");
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
for(uint16_t retry = 0; retry <= MASTER_MAX_RETRY && (!alarm_state); retry++)
|
|
|
|
|
|
{
|
|
|
|
|
|
// Read all found characteristics from slave(s)
|
|
|
|
|
|
for (uint16_t cid = 0; (err != ESP_ERR_NOT_FOUND) && cid < MASTER_MAX_CIDS; cid++)
|
|
|
|
|
|
{
|
|
|
|
|
|
// Get data from parameters description table
|
|
|
|
|
|
// and use this information to fill the characteristics description table
|
|
|
|
|
|
// and having all required fields in just one table
|
|
|
|
|
|
err = mbc_master_get_cid_info(cid, ¶m_descriptor);
|
|
|
|
|
|
if ((err != ESP_ERR_NOT_FOUND) && (param_descriptor != NULL))
|
|
|
|
|
|
{
|
|
|
|
|
|
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)
|
|
|
|
|
|
{
|
|
|
|
|
|
if ((param_descriptor->mb_param_type == MB_PARAM_HOLDING) || (param_descriptor->mb_param_type == MB_PARAM_INPUT))
|
|
|
|
|
|
{
|
|
|
|
|
|
value = *(float*)temp_data_ptr;
|
|
|
|
|
|
ESP_LOGI(TAG, "Characteristic #%u %s (%s) value = %f (0x%" PRIx32 ") read successful.",
|
|
|
|
|
|
param_descriptor->cid,
|
|
|
|
|
|
param_descriptor->param_key,
|
|
|
|
|
|
param_descriptor->param_units,
|
|
|
|
|
|
value,
|
|
|
|
|
|
*(uint32_t*)temp_data_ptr);
|
|
|
|
|
|
if (((value > param_descriptor->param_opts.max) || (value < param_descriptor->param_opts.min)))
|
|
|
|
|
|
{
|
|
|
|
|
|
alarm_state = true;
|
|
|
|
|
|
break;
|
|
|
|
|
|
}
|
|
|
|
|
|
}else{
|
|
|
|
|
|
uint8_t state = *(uint8_t*)temp_data_ptr;
|
|
|
|
|
|
const char* rw_str = (state & param_descriptor->param_opts.opt1) ? "ON" : "OFF";
|
|
|
|
|
|
if ((state & param_descriptor->param_opts.opt2) == param_descriptor->param_opts.opt2)
|
|
|
|
|
|
{
|
|
|
|
|
|
ESP_LOGI(TAG, "Characteristic #%u %s (%s) value = %s (0x%" PRIx8 ") read successful.",
|
|
|
|
|
|
param_descriptor->cid,
|
|
|
|
|
|
param_descriptor->param_key,
|
|
|
|
|
|
param_descriptor->param_units,
|
|
|
|
|
|
(const char*)rw_str,
|
|
|
|
|
|
*(uint8_t*)temp_data_ptr);
|
|
|
|
|
|
} else {
|
|
|
|
|
|
ESP_LOGE(TAG, "Characteristic #%u %s (%s) value = %s (0x%" PRIx8 "), unexpected value.",
|
|
|
|
|
|
param_descriptor->cid,
|
|
|
|
|
|
param_descriptor->param_key,
|
|
|
|
|
|
param_descriptor->param_units,
|
|
|
|
|
|
(const char*)rw_str,
|
|
|
|
|
|
*(uint8_t*)temp_data_ptr);
|
|
|
|
|
|
alarm_state = true;
|
|
|
|
|
|
break;
|
|
|
|
|
|
}
|
|
|
|
|
|
}
|
|
|
|
|
|
}
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
ESP_LOGI(TAG, "Destroy master...");
|
|
|
|
|
|
ESP_ERROR_CHECK(mbc_master_destroy());
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
static void* master_get_param_data(const mb_parameter_descriptor_t* param_descriptor)
|
|
|
|
|
|
{
|
|
|
|
|
|
assert(param_descriptor != NULL);
|
|
|
|
|
|
void* instance_ptr = NULL;
|
|
|
|
|
|
if (param_descriptor->param_offset != 0) {
|
|
|
|
|
|
switch(param_descriptor->mb_param_type)
|
|
|
|
|
|
{
|
|
|
|
|
|
case MB_PARAM_HOLDING:
|
|
|
|
|
|
instance_ptr = ((void*)&holding_reg_params + param_descriptor->param_offset - 1);
|
|
|
|
|
|
break;
|
|
|
|
|
|
case MB_PARAM_INPUT:
|
|
|
|
|
|
instance_ptr = ((void*)&input_reg_params + param_descriptor->param_offset - 1);
|
|
|
|
|
|
break;
|
|
|
|
|
|
case MB_PARAM_COIL:
|
|
|
|
|
|
instance_ptr = ((void*)&coil_reg_params + param_descriptor->param_offset - 1);
|
|
|
|
|
|
break;
|
|
|
|
|
|
case MB_PARAM_DISCRETE:
|
|
|
|
|
|
instance_ptr = ((void*)&discrete_reg_params + param_descriptor->param_offset - 1);
|
|
|
|
|
|
break;
|
|
|
|
|
|
default:
|
|
|
|
|
|
instance_ptr = NULL;
|
|
|
|
|
|
break;
|
|
|
|
|
|
}
|
|
|
|
|
|
} else {
|
|
|
|
|
|
ESP_LOGE(TAG, "Wrong parameter offset for CID #%u", (unsigned)param_descriptor->cid);
|
|
|
|
|
|
assert(instance_ptr != NULL);
|
|
|
|
|
|
}
|
|
|
|
|
|
return instance_ptr;
|
|
|
|
|
|
}
|