Code: Select all
#include "modbus.h"
#include <mbcontroller.h>
#include "../resources/modbus_params.h"
#include "../utils/settings.h"
#include <esp_err.h>
#include <esp_log.h>
#include <esp_system.h>
#include <esp_wifi.h>
#include <esp_event.h>
#include <esp_log.h>
#include <nvs_flash.h>
#include <esp_netif.h>
#include <esp_mac.h>
#include <sys/time.h>
#include "../tasks/task_wifi.h"
#include "pump.h"
#include "valves.h"
#define HOLD_OFFSET(field) ((uint16_t)(offsetof(holding_reg_params_t, field) >> 1))
#define INPUT_OFFSET(field) ((uint16_t)(offsetof(input_reg_params_t, field) >> 1))
#define MB_REG_DISCRETE_INPUT_START (0x0000)
#define MB_REG_COILS_START (0x0000)
#define MB_REG_INPUT_START (INPUT_OFFSET(battery_voltage))
#define MB_REG_HOLDING_START (HOLD_OFFSET(w_datetime))
#define MB_READ_MASK (MB_EVENT_INPUT_REG_RD \
| MB_EVENT_HOLDING_REG_RD \
| MB_EVENT_DISCRETE_RD \
| MB_EVENT_COILS_RD)
#define MB_WRITE_MASK (MB_EVENT_HOLDING_REG_WR \
| MB_EVENT_COILS_WR)
#define MB_READ_WRITE_MASK (MB_READ_MASK | MB_WRITE_MASK)
static const char *TAG = "MODBUS";
extern Settings_t settings;
static portMUX_TYPE param_lock = portMUX_INITIALIZER_UNLOCKED;
static void init_reg_data(void)
{
discrete_reg_params.gasket_lock = 0;
holding_reg_params.w_datetime = 0;
strcpy(holding_reg_params.serial_number, "12345678");
strcpy(holding_reg_params.id_position, "abcdefgh");
// other initializations
}
static void slave_operation_func(void *arg)
{
esp_err_t err;
mb_param_info_t reg_info;
while (1)
{
mb_event_group_t event = mbc_slave_check_event(MB_WRITE_MASK);
if (event & MB_EVENT_HOLDING_REG_WR)
{
err = mbc_slave_get_param_info(®_info, MB_PAR_INFO_GET_TOUT);
ESP_LOGI(TAG, "%d\tHOLDING WRITE, ADDR:%u, TYPE:%u, INST_ADDR:0x%" PRIx32 ", SIZE:%u",
err,
(unsigned)reg_info.mb_offset,
(unsigned)reg_info.type,
(uint32_t)reg_info.address,
(unsigned)reg_info.size);
}
printf(".\n");
vTaskDelay(pdMS_TO_TICKS(100));
}
}
esp_err_t init_reg_area(mb_param_type_t type, uint16_t start_offset, void *address, size_t size)
{
mb_register_area_descriptor_t reg_area;
reg_area.type = type;
reg_area.start_offset = start_offset;
reg_area.address = address;
reg_area.size = size;
esp_err_t err = mbc_slave_set_descriptor(reg_area);
MB_RETURN_ON_FALSE(err == ESP_OK, ESP_ERR_INVALID_STATE, TAG, "mbc_slave_set_descriptor fail, returns(0x%x).", (int) err);
return err;
}
static esp_err_t slave_init(mb_communication_info_t *comm_info)
{
void *slave_handler = NULL;
esp_err_t err = mbc_slave_init_tcp(&slave_handler);
MB_RETURN_ON_FALSE((err == ESP_OK && slave_handler != NULL), ESP_ERR_INVALID_STATE, TAG, "mb controller initialization fail.");
comm_info->ip_addr = NULL;
comm_info->ip_netif_ptr = (void*) Wifi_GetNetif();
comm_info->slave_uid = MB_SLAVE_ADDR;
err = mbc_slave_setup((void*)comm_info);
MB_RETURN_ON_FALSE((err == ESP_OK), ESP_ERR_INVALID_STATE, TAG, "mbc_slave_setup fail, returns(0x%x).", (int)err);
init_reg_area(MB_PARAM_HOLDING, MB_REG_HOLDING_START, (void*)&holding_reg_params, sizeof(holding_reg_params));
init_reg_area(MB_PARAM_INPUT, MB_REG_INPUT_START, (void*)&input_reg_params, sizeof(input_reg_params));
init_reg_area(MB_PARAM_COIL, MB_REG_COILS_START, (void*)&coil_reg_params, sizeof(coil_reg_params));
init_reg_area(MB_PARAM_DISCRETE, MB_REG_DISCRETE_INPUT_START, (void*)&discrete_reg_params, sizeof(discrete_reg_params));
init_reg_data();
err = mbc_slave_start();
MB_RETURN_ON_FALSE((err == ESP_OK), ESP_ERR_INVALID_STATE, TAG, "mbc_slave_start fail, returns(0x%x).", (int)err);
vTaskDelay(5);
return err;
}
static esp_err_t slave_destroy(void)
{
esp_err_t err = mbc_slave_destroy();
MB_RETURN_ON_FALSE((err == ESP_OK), ESP_ERR_INVALID_STATE, TAG, "mbc_slave_destroy fail, returns(0x%x).", (int) err);
return err;
}
void Modbus_Init(void)
{
mb_communication_info_t comm_info = { 0 };
comm_info.ip_addr_type = MB_IPV4;
comm_info.ip_mode = MB_MODE_TCP;
comm_info.ip_port = MB_TCP_PORT_NUMBER;
ESP_ERROR_CHECK(slave_init(&comm_info));
slave_operation_func(NULL);
}
void Modbus_Deinit(void)
{
slave_destroy();
}
I don't understand why it does not catch the other addresses. Also the size is wron: it returns the whole size of the holding registers, not of the one being written.I (31790) MODBUS: 0 HOLDING WRITE, ADDR:0, TYPE:2, INST_ADDR:0x3fca1ff0, SIZE:40
Here my data definition:
Code: Select all
#pragma pack(push, 1)
typedef struct
{
uint64_t w_datetime; // 400001
char serial_number[10]; // 400005
char id_position[10]; // 400010
float target_pressure; // 400015
float critical_pressure; // 400017
float min_pressure; // 400019
int16_t timeout; // 40021
int16_t target_pressure_max; // 40022
int16_t target_pressure_min; // 40023
int16_t target_inflate_timeout; // 40024
int16_t target_hold_timeout; // 40025
int16_t target_hold_duration; // 40026
int16_t test_pressure_drop; // 40027
int16_t test_duration; // 40028
float t_offset; // 40029
float t_gain; // 40031
float e_offset; // 40033
float e_gain; // 40035
uint64_t calibration_datetime; // 400037
} holding_reg_params_t;
#pragma pack(pop)