123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175 |
- /**
- * @Author: 李建
- * @Date: 2025/4/27 15:35
- * Description: 实现485主站
- * Copyright: Copyright (©) 2025 永续绿建. All rights reserved.
- */
- #include <esp_err.h>
- #include "modbus_master.h"
- #include "mbcontroller.h"
- #define OPTS(min_val, max_val, step_val) { .opt1 = min_val, .opt2 = max_val, .opt3 = step_val }
- static const char *TAG = "MODBUS_MASTER";
- enum {
- // 热泵主机从站号
- MB_DEVICE_HP_ADDR = 1,
- // 分集水器集控盒站
- MB_DEVICE_FJSQ_ADDR = 5,
- };
- static void *master_handle = NULL;
- #define STR(fieldname) ((const char *)( fieldname ))
- const mb_parameter_descriptor_t device_parameters[] = {
- // { CID, Param Name, Units, Modbus Slave Addr, Modbus Reg Type, Reg Start, Reg Size, Instance Offset, Data Type, Data Size, Parameter Options, Access Mode}
- {CID_HP_SET_MODE, STR("mode"), STR(""), MB_DEVICE_HP_ADDR, MB_PARAM_HOLDING,
- HP_SET_MODE_REG_ADDRESS, 1, 0, PARAM_TYPE_U16, 2, OPTS(0, 0, 0), PAR_PERMS_READ_WRITE},
- {CID_HP_COOL_SET_TEMP, STR("c_temp"), STR(""), MB_DEVICE_HP_ADDR, MB_PARAM_HOLDING,
- HP_COOL_SET_TEMP_REG_ADDRESS, 1, 0, PARAM_TYPE_U16, 2, OPTS(0, 0, 0), PAR_PERMS_READ_WRITE},
- {CID_HP_HEAT_SET_TEMP, STR("h_temp"), STR(""), MB_DEVICE_HP_ADDR, MB_PARAM_HOLDING,
- HP_HEAT_SET_TEMP_REG_ADDRESS, 1, 0, PARAM_TYPE_U16, 2, OPTS(0, 0, 0), PAR_PERMS_READ_WRITE},
- {CID_HP_OUTDOOR_TEMP, STR("o_temp"), STR(""), MB_DEVICE_HP_ADDR, MB_PARAM_HOLDING,
- HP_OUTDOOR_TEMP_REG_ADDRESS, 1, 0, PARAM_TYPE_U16, 2, OPTS(0, 0, 0), PAR_PERMS_READ},
- {CID_HP_OUT_WATER_TEMP, STR("out"), STR(""), MB_DEVICE_HP_ADDR, MB_PARAM_HOLDING,
- HP_OUT_WATER_TEMP_REG_ADDRESS, 1, 0, PARAM_TYPE_U16, 2, OPTS(0, 0, 0), PAR_PERMS_READ},
- {CID_HP_IN_WATER_TEMP, STR("in"), STR(""), MB_DEVICE_HP_ADDR, MB_PARAM_HOLDING,
- HP_IN_WATER_TEMP_REG_ADDRESS, 1, 0, PARAM_TYPE_U16, 2, OPTS(0, 0, 0), PAR_PERMS_READ},
- {CID_HP_POWER, STR("power"), STR(""), MB_DEVICE_HP_ADDR, MB_PARAM_COIL, 0, 1,0, PARAM_TYPE_U8, 1, OPTS(0, 0, 0), PAR_PERMS_READ_WRITE},
- {CID_HP_ERROR, STR("error"), STR(""), MB_DEVICE_HP_ADDR, MB_PARAM_COIL, 40, 1,0, PARAM_TYPE_U8, 1, OPTS(0, 0, 0), PAR_PERMS_WRITE},
- {CID_RELAY_1_STATUS, STR("r1"), STR(""), MB_DEVICE_FJSQ_ADDR, MB_PARAM_HOLDING, RELAY_1_STATUS_REG_ADDRESS, 1,0, PARAM_TYPE_U16, 2, OPTS(0, 0, 0), PAR_PERMS_READ_WRITE},
- {CID_RELAY_2_STATUS, STR("r2"), STR(""), MB_DEVICE_FJSQ_ADDR, MB_PARAM_HOLDING, RELAY_2_STATUS_REG_ADDRESS, 1,0, PARAM_TYPE_U16, 2, OPTS(0, 0, 0), PAR_PERMS_READ_WRITE},
- {CID_RELAY_3_STATUS, STR("r3"), STR(""), MB_DEVICE_FJSQ_ADDR, MB_PARAM_HOLDING, RELAY_3_STATUS_REG_ADDRESS, 1,0, PARAM_TYPE_U16, 2, OPTS(0, 0, 0), PAR_PERMS_READ_WRITE},
- {CID_RELAY_4_STATUS, STR("r4"), STR(""), MB_DEVICE_FJSQ_ADDR, MB_PARAM_HOLDING, RELAY_4_STATUS_REG_ADDRESS, 1,0, PARAM_TYPE_U16, 2, OPTS(0, 0, 0), PAR_PERMS_READ_WRITE},
- {CID_RELAY_5_STATUS, STR("r5"), STR(""), MB_DEVICE_FJSQ_ADDR, MB_PARAM_HOLDING, RELAY_5_STATUS_REG_ADDRESS, 1,0, PARAM_TYPE_U16, 2, OPTS(0, 0, 0), PAR_PERMS_READ_WRITE},
- {CID_RELAY_6_STATUS, STR("r6"), STR(""), MB_DEVICE_FJSQ_ADDR, MB_PARAM_HOLDING, RELAY_6_STATUS_REG_ADDRESS, 1,0, PARAM_TYPE_U16, 2, OPTS(0, 0, 0), PAR_PERMS_READ_WRITE},
- {CID_RELAY_7_STATUS, STR("r7"), STR(""), MB_DEVICE_FJSQ_ADDR, MB_PARAM_HOLDING, RELAY_7_STATUS_REG_ADDRESS, 1,0, PARAM_TYPE_U16, 2, OPTS(0, 0, 0), PAR_PERMS_READ_WRITE},
- {CID_RELAY_8_STATUS, STR("r8"), STR(""), MB_DEVICE_FJSQ_ADDR, MB_PARAM_HOLDING, RELAY_8_STATUS_REG_ADDRESS, 1,0, PARAM_TYPE_U16, 2, OPTS(0, 0, 0), PAR_PERMS_READ_WRITE},
- {CID_MODIFY_COMMUNICATION_ADDRESS, STR("md"), STR(""), MB_DEVICE_FJSQ_ADDR, MB_PARAM_HOLDING, MODIFY_COMMUNICATION_ADDRESS_REGISTER, 1,0, PARAM_TYPE_U16, 2, OPTS(0, 0, 0), PAR_PERMS_READ_WRITE},
- };
- // Calculate number of parameters in the table
- const uint16_t num_device_parameters = (sizeof(device_parameters) / sizeof(device_parameters[0]));
- IRAM_ATTR static esp_err_t master_init() {
- // Initialize Modbus controller
- mb_communication_info_t comm = {
- .ser_opts.port = MB_PORT_NUM,
- .ser_opts.mode = MB_RTU,
- .ser_opts.baudrate = MB_DEV_SPEED,
- .ser_opts.parity = MB_PARITY_NONE,
- .ser_opts.response_tout_ms = 1000,
- .ser_opts.data_bits = UART_DATA_8_BITS,
- .ser_opts.stop_bits = UART_STOP_BITS_1
- };
- ESP_LOGI(TAG, "Modbus controller initialized...");
- esp_err_t err = mbc_master_create_serial(&comm, &master_handle);
- MB_RETURN_ON_FALSE((master_handle != 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);
- // Set UART pin numbers
- err = uart_set_pin(MB_PORT_NUM, MB_GPIO_TX, MB_GPIO_RX,
- 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(master_handle);
- 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_UART);
- 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(master_handle, &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...");
- return err;
- }
- //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;
- // 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;
- //}
- void modbus_master_task(void *arg) {
- vTaskDelay(5000 / portTICK_PERIOD_MS);
- ESP_LOGI(TAG, "Modbus master task started...");
- esp_err_t err = ESP_OK;
- uint8_t temp_data[2] = {0}; // temporary buffer to hold maximum CID size
- uint8_t type = 0;
- const mb_parameter_descriptor_t *param_descriptor = NULL;
- for (;;) {
- for (uint16_t cid = 0; (err != ESP_ERR_NOT_FOUND) && cid < 16; cid++) {
- err = mbc_master_get_cid_info(master_handle, cid, ¶m_descriptor);
- if ((err != ESP_ERR_NOT_FOUND) && (param_descriptor != NULL)) {
- err = mbc_master_get_parameter(master_handle, param_descriptor->cid, (uint8_t *) temp_data, &type);
- if (err == ESP_OK) {
- ESP_LOGI(TAG, "Characteristic #%d %s (%s) value = %d read successful.",
- param_descriptor->cid,
- (char *) param_descriptor->param_key,
- (char *) param_descriptor->param_units,
- *(uint16_t *) temp_data);
- } else {
- ESP_LOGE(TAG, "Characteristic #%d (%s) read fail, err = 0x%x (%s).",
- param_descriptor->cid,
- (char *) param_descriptor->param_key,
- (int) err,
- (char *) esp_err_to_name(err));
- }
- }
- vTaskDelay(1000 / portTICK_PERIOD_MS);
- }
- vTaskDelay(5000 / portTICK_PERIOD_MS);
- }
- }
- void modbus_master_init() {
- ESP_LOGI(TAG, "Modbus master init...");
- ESP_ERROR_CHECK(master_init());
- //vTaskDelay(10);
- //xTaskCreatePinnedToCore(modbus_master_task, "modbus_master_task", 4 * 1024, NULL, 5, NULL, 1);
- }
- esp_err_t mm_set_param(uint16_t cid, uint8_t *value) {
- uint8_t type = PARAM_TYPE_U16;
- return mbc_master_set_parameter(master_handle, cid, value, &type);
- }
- esp_err_t mm_get_param(uint16_t cid, uint8_t *value) {
- uint8_t type = PARAM_TYPE_U16;
- return mbc_master_get_parameter(master_handle, cid, value, &type);
- }
- esp_err_t send_request(mb_param_request_t *request, void *data_prt) {
- return mbc_master_send_request(master_handle, request, data_prt);
- }
- void modbus_master_destroy() {
- mbc_master_delete(master_handle);
- }
|