[ESP32]:基于esp-modbus实现serial从机

本文详细介绍了如何在ESP32平台上利用esp-modbus库实现串行从机功能,包括定义离散输入、线圈和保持寄存器,以及根据主机事件处理读写操作。作者还分享了一个实验示例,设置保持寄存器的值并处理各种事件。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

[ESP32]:基于esp-modbus实现serial从机

开发环境:

  • esp idf 5.1
  • esp-modbus 1.0.13

使用如下指令添加组件,或者访问esp-modbus

idf.py add-dependency "espressif/esp-modbus^1.0.13"

1.mb_register_area_descriptor_t

对于slave而言,最重要的定义你的reg area

// 离散输入寄存器
mb_register_area_descriptor_t descrete_reg_area = {
    .type = MB_PARAM_DISCRETE,
    .start_offset = 0x0000,
    .address = (void *)&discrete_reg_params,
    .size = sizeof(discrete_reg_params_t),
};
ESP_ERROR_CHECK(mbc_slave_set_descriptor(descrete_reg_area));

// 线圈
mb_register_area_descriptor_t coil_reg_area = {
    .type = MB_PARAM_COIL,
    .start_offset = 0x0000,
    .address = (void *)&coil_reg_params,
    .size = sizeof(coil_reg_params_t),
};
ESP_ERROR_CHECK(mbc_slave_set_descriptor(coil_reg_area));

// 保持寄存器
mb_register_area_descriptor_t holding_reg_area = {
    .type = MB_PARAM_HOLDING,
    .start_offset = 0x0000,
    .address = (void *)&holding_reg_params,
    .size = sizeof(holding_reg_params_t),
};
ESP_ERROR_CHECK(mbc_slave_set_descriptor(holding_reg_area));

可以看到我们这里定义了输入寄存器,保持寄存器、线圈

其中,偏移默认为0x0000,如果要修改的话,记得同步改上位机的偏移地址

2.等待主机读取

这个比较简单,主要根据event做对应的动作就行

while (1)
{
    mb_event_group_t event = mbc_slave_check_event(MB_READ_WRITE_MASK);

    if (event & MB_EVENT_DISCRETE_RD)
    {
        // 主机读取离散输入寄存器
        ESP_ERROR_CHECK(mbc_slave_get_param_info(&reg_info, 10));
        ESP_LOGI(TAG, "DISCRETE READ");
    }
    else if (event & MB_EVENT_COILS_RD)
    {
        // 主机读取线圈
        ESP_LOGI(TAG, "COIL READ");
    }
    else if (event & MB_EVENT_COILS_WR)
    {
        // 主机写线圈
        ESP_LOGI(TAG, "COIL WRITE");
        ESP_LOGI(TAG, "Coil: %d %d", coil_reg_params.coils_port_0, coil_reg_params.coils_port_1);
    }
    else if (event & MB_EVENT_HOLDING_REG_RD)
    {
        // 主机读取保持寄存器
        ESP_LOGI(TAG, "HOLDING READ");
    }
    else if (event & MB_EVENT_HOLDING_REG_WR)
    {
        // 主机写保持寄存器
        ESP_LOGI(TAG, "HOLDING WRITE");
        ESP_LOGI(TAG, "Holding: %d %d", holding_reg_params.holding_0, holding_reg_params.holding_1);
    }
}

感觉做从机比主机简单一点。

简单跑一个实验:
我们设置保持寄存器的两个值为1234和7788

holding_reg_params_t holding_reg_params = {1234, 7788};

在这里插入图片描述

### ESP32 实现 Modbus RTU 从站配置教程 #### 使用 `esp32ModbusRTU` 库创建 Modbus RTU 从站实例 为了使ESP32作为Modbus RTU从站运行,可以利用专门为此目的开发的库——`esp32ModbusRTU`[^1]。该库不仅简化了与其它支持相同协议标准的装置间的交互过程,还提供了必要的API来处理请求和服务响应。 ```cpp #include "modbus.h" // 创建一个Modbus对象并初始化为从模式 Modbus slave(MODBUS_RTU, SERIAL_8N1); void setup() { Serial.begin(9600); // 配置串口参数 (波特率, 数据位, 奇偶校验, 停止位) slave.configSerial(115200, MODBUS_PARITY_NONE); // 设置本地址(即从站ID) slave.setAddress(1); // 初始化Modbus接口 if (!slave.begin()) { while(true){ delay(1000); Serial.println("Failed to initialize Modbus"); } } // 注册保持寄存器区域 uint16_t holdingRegisters[] = {0}; slave.registerHoldingRegister(holdingRegisters, sizeof(holdingRegisters)/sizeof(uint16_t)); } void loop(){ // 处理来自主站的消息循环 slave.task(); } ``` 这段代码展示了如何设置ESP32作为一个简单的Modbus RTU从站,它会监听特定端口上的命令,并根据接收到的数据更新内部状态或返回查询结果给主站设备。 对于更复杂的场景,则可能需要进一步定义输入寄存器、线圈以及离散输入等功能区,并通过相应的函数注册这些资源到Modbus栈中以便于访问和管理。 此外,在实际应用过程中还需要考虑错误检测制、超时重传策略等因素以提高系统的稳定性和可靠性。
评论 8
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值