此次移植工作以中国移动 ML302 模组为基础,亿琪软件 YiDTU 设备为原型,开发基于 Modbus Master 应用;
传统模式下,DTU 都是以透传为主要工作,所有的业务需求都是从服务器端发出,而 YiDTU 是作为边缘计算的角色,在工业现场就已经把数据处理做完;

yigate-yidtu.png

准备工作

硬件设备

  • YiDTU 设备一台
    亿琪软件 YiDTU 设备内置 UART 转 RS485 模块,对外连接 RS485 双线设备,如:YiSensor 模拟量采集模块;对于开发而言,那就是主要针对 UART 串口操作;
  • Micro USB 线一根
    用于操作 YiDTU 设备:AT 串口操作,烧录操作;
  • RS485 设备若干
    可用 USB 转 RS485 转换器代替(需配合 modbus slave 软件使用);有支持 Modbus Slave 设备最好;准备了两个:模拟量 4-20mA 和 开关量各一个;
  • 9~30V 直流电源一个
    支持最大 2A 电流的直流电源一个,用于给 YiDTU 设备供电;
  • 将以上硬件设备连接好

软件 SDK

  • 从中国移动物联网公司获取 ML302 相关 SDK,;
  • 确保 SDK 编译正常;
  • 烧录基本应用成功;

移植过程

Modbus Master 库

  • https://github.com/jiekechoo/ModBus-Master.git 获取源代码,使用 STM32 环境编译成功,确保你的环境没问题;
  • 将 Modbus_Master 目录移植到 ML302 工程中 src/demo/modbus 下,根据需求删除不必要的组件功能;
  • ML302 环境下编译通过,确保没有错误出现;
  • Modbus 枚举值要重新定义
typedef enum
{
  // Modbus function codes for bit access
  ku8MBReadCoils = 0x01,          ///< Modbus function 0x01 Read Coils
  ku8MBReadDiscreteInputs = 0x02, ///< Modbus function 0x02 Read Discrete Inputs
  ku8MBWriteSingleCoil = 0x05,    ///< Modbus function 0x05 Write Single Coil
  ku8MBWriteMultipleCoils = 0x0F, ///< Modbus function 0x0F Write Multiple Coils

  // Modbus function codes for 16 bit access
  ku8MBReadHoldingRegisters = 0x03,      ///< Modbus function 0x03 Read Holding Registers
  ku8MBReadInputRegisters = 0x04,        ///< Modbus function 0x04 Read Input Registers
  ku8MBWriteSingleRegister = 0x06,       ///< Modbus function 0x06 Write Single Register
  ku8MBWriteMultipleRegisters = 0x10,    ///< Modbus function 0x10 Write Multiple Registers
  ku8MBMaskWriteRegister = 0x16,         ///< Modbus function 0x16 Mask Write Register
  ku8MBReadWriteMultipleRegisters = 0x17 ///< Modbus function 0x17 Read Write Multiple Registers
} modbusFunc;

串口接收支持

  • 串口接收任务中,将收到的内容复制到全局变量中,目的是把 Modbus Slave 回复的内容获取到,交给 Modbus 组件使用;
extern uint8_t u8ModbusADU[1024];
extern uint8_t u8ModbusADUSize;

// 接收处理函数中
{
            u8ModbusADUSize = uart_buf_len;
            memcpy(u8ModbusADU, uart_buf, u8ModbusADUSize);
}
  • 接收完成后,创建一个 信号量,通知 Modbus 组件来处理;
{
                uart_buf_len = 0;
                recv_count = 0;
                osSignalSet(OC_Main_TaskHandle, 0x0004);
}

Modbus 组件

  • 将 Modbus 组件中接收处理替换成信号量等待,超时重置接收缓冲区;
  // 串口收到数据信号量,2000ms 超时
  osEvent osevent = osSignalWait(0x0004, ku16MBResponseTimeout);
  if (osevent.status == osEventTimeout)
  {
    u8MBStatus = ku8MBResponseTimedOut;
    memset(u8ModbusADU, 0, sizeof(u8ModbusADU));
    u8ModbusADUSize = 0;
  }
  • Modbus 发送函数重写
uint8_t Modbus_Master_Write(uint8_t *buf, uint8_t length)
{
  //  if(HAL_UART_Transmit(&huart2 ,(uint8_t *)buf,length,0xff))
  if (cm_uart_send_no_cache(OPENCPU_MAIN_URAT, (uint8_t *)buf, length, 0xff) == 0)
  {
    return HAL_ERROR;
  }
  else
  {
    return HAL_OK;
  }
}
  • 如果有 CS 控制口 IO,需要自定义相关函数
#if 0
  // transmit request RS485接口是需要每次发送前改变接口的模式
  
  if (_preTransmission)
  {
    _preTransmission();
  }
#endif

  //串口发送数据
  Modbus_Master_Write(u8ModbusADU, u8ModbusADUSize);
  u8ModbusADUSize = 0;

#if 0
// transmit request RS485接口是需要每次发送后改变接口的模式
      if (_postTransmission)
  {
    _postTransmission();
  }
#endif

移植过程比较简单,细节需要一定的嵌入式和 C 语言基础。

效果展示

在 YiDTU 业务逻辑中增加相应的功能模块,把数据传输到云平台,这样,就可以及时获取现场的模拟量数据。
PSX_20210119_151717.jpg

标签: YiDTU, 边缘计算, Modbus Master, 移植

添加新评论