中国移动 ML302 4G cat.1 模组移植 Modbus Master 实现简单边缘计算
此次移植工作以中国移动 ML302 模组为基础,亿琪软件 YiDTU 设备为原型,开发基于 Modbus Master 应用;
传统模式下,DTU 都是以透传为主要工作,所有的业务需求都是从服务器端发出,而 YiDTU 是作为边缘计算的角色,在工业现场就已经把数据处理做完;
![yigate-yidtu.png][1]
准备工作
硬件设备
-
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][2]
[1]: https://yiqisoft.cn/blogs/usr/uploads/2021/01/1616746346.png
[2]: https://yiqisoft.cn/blogs/usr/uploads/2021/01/2439453110.jpg