main.lua 4.8 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138
  1. PROJECT = "modbus_rtu"
  2. VERSION = "001.000.000"
  3. sys = require("sys")
  4. -- mobile.simid(2)
  5. -- Air780E的AT固件默认会为开机键防抖, 导致部分用户刷机很麻烦
  6. if rtos.bsp() == "EC618" and pm and pm.PWK_MODE then
  7. pm.power(pm.PWK_MODE, false)
  8. end
  9. -- 如果你用的是合宙DTU整机系列,才需要打开,否则按自己设计的PCB来
  10. -- gpio.setup(1, 1) -- 485转TTL芯片供电打开
  11. -- gpio.setup(24, 1) -- 外置供电电源打开
  12. modbus_rtu = require("modbus_rtu")
  13. -- 初始化modbus_rtu
  14. modbus_rtu.init({
  15. uartid = 1, -- 接收/发送数据的串口id
  16. baudrate = 4800, -- 波特率
  17. gpio_485 = 25, -- 转向GPIO编号
  18. tx_delay = 50000 -- 转向延迟时间,单位us
  19. -- 下面这些数据不填也行,不填底层默认为如下参数
  20. -- databits = 8,--数据位
  21. -- stopbits = 1,--停止位
  22. -- parity = uart.None,--校验位
  23. -- endianness = uart.LSB,--大小端
  24. -- buffer_size = 1024,--缓冲区大小
  25. -- rx_level = 0,--rx初始电平
  26. })
  27. -- 定义modbus_rtu数据接收回调
  28. local function on_modbus_rtu_receive(frame)
  29. log.info("modbus_rtu frame received:", json.encode(frame))
  30. if frame.fun == 0x03 then -- 功能码0x03表示读取保持寄存器
  31. local byte = frame.byte
  32. local payload = frame.payload
  33. -- log.info("modbus_rtu payload (hex):", payload:toHex())
  34. -- 解析数据(假设数据为16位寄存器值)
  35. local values_big = {} -- 大端序解析结果
  36. for i = 1, #payload, 2 do
  37. local msb = payload:byte(i)
  38. local lsb = payload:byte(i + 1)
  39. -- 大端序解析
  40. local result_big = (msb * 256) + lsb
  41. table.insert(values_big, result_big)
  42. end
  43. -- 输出大端序的解析结果
  44. log.info("输出大端序的解析结果:", table.concat(values_big, ", "))
  45. -- 第一个寄存器是湿度,第二个是温度,除以10以获取实际值
  46. if #values_big == 2 then
  47. log.info("测试同款485温湿度计")
  48. local humidity = values_big[1] / 10
  49. local temperature = values_big[2] / 10
  50. -- 打印湿度和温度
  51. log.info(string.format("湿度: %.1f%%", humidity))
  52. log.info(string.format("温度: %.1f°C", temperature))
  53. -- 发布湿度和温度
  54. sys.publish("modbus_rtu_data", {humidity, temperature})
  55. else
  56. log.info("用户自己的485下位机,共有" .. #values_big .. "组数据")
  57. for index, value in ipairs(values_big) do
  58. log.info(string.format("寄存器 %d: %d (大端序)", index, value))
  59. end
  60. end
  61. else
  62. log.info("功能码不是03")
  63. end
  64. end
  65. -- 设置modbus_rtu数据接收回调
  66. modbus_rtu.set_receive_callback(1, on_modbus_rtu_receive)
  67. local function send_modbus_rtu_command()
  68. local addr = 0x01 -- 设备地址,此处填客户自己的
  69. local fun = 0x03 -- 功能码(03为读取保持寄存器),此处填客户自己的
  70. local data = string.char(0x00, 0x00, 0x00, 0x02) -- 起始地址和寄存器数量(此处填客户自己的起始地址进而寄存器数量)
  71. -- modbus_rtu.send_command(1, addr, fun, data) -- 只发送一次命令并等待响应处理
  72. modbus_rtu.send_command(1, addr, fun, data, 5000) -- 循环5S发送一次
  73. end
  74. sys.taskInit(function()
  75. sys.wait(5000)
  76. send_modbus_rtu_command()
  77. end)
  78. -- local modbus_tcp = require("modbus_tcp")
  79. -- function modbus_tcp_test()
  80. -- sys.waitUntil("IP_READY")
  81. -- -- 连接到 Modbus TCP 服务器
  82. -- local netc, err = modbus_tcp.connect("112.125.89.8", 42514)
  83. -- if not netc then
  84. -- log.error("Modbus TCP", "连接失败:", err)
  85. -- return
  86. -- end
  87. -- -- 示例 1: 读取保持寄存器
  88. -- local response, err = modbus_tcp.send_request(netc, 1, 0x03, 0, 10) -- 读取从站地址为 1 的保持寄存器,起始地址为 0,数量为 10
  89. -- if not response then
  90. -- log.error("Modbus TCP", "读取保持寄存器失败:", err)
  91. -- else
  92. -- log.info("Modbus TCP", "读取保持寄存器响应数据:", response.data)
  93. -- end
  94. -- -- 示例 2: 写入单个寄存器
  95. -- local write_response, err = modbus_tcp.send_request(netc, 1, 0x06, 5, 1234) -- 向从站地址为 1 的寄存器地址 5 写入值 1234
  96. -- if not write_response then
  97. -- log.error("Modbus TCP", "写入单个寄存器失败:", err)
  98. -- else
  99. -- log.info("Modbus TCP", "写入单个寄存器响应数据:", write_response.data)
  100. -- end
  101. -- -- 关闭连接
  102. -- -- modbus_tcp.close(netc)
  103. -- end
  104. -- sys.taskInit()
  105. -- log.info("mem.lua", rtos.meminfo())
  106. -- log.info("mem.sys", rtos.meminfo("sys"))
  107. -- 用户代码已结束---------------------------------------------
  108. -- 结尾总是这一句
  109. sys.run()
  110. -- sys.run()之后后面不要加任何语句!!!!!