modbus780epm.lua 3.3 KB

12345678910111213141516171819202122232425262728293031323334353637383940414243444546474849505152535455565758596061626364656667686970717273747576777879808182838485
  1. -- 如果你用的是合宙DTU整机系列,才需要打开,否则按自己设计的PCB来
  2. gpio.setup(1, 1) -- 485转TTL芯片供电打开
  3. -- gpio.setup(24, 1) -- 外置供电电源打开
  4. modbus_rtu = require("modbus_rtu")
  5. local uartid = 1
  6. -- 初始化modbus_rtu
  7. modbus_rtu.init({
  8. uartid = uartid, -- 接收/发送数据的串口id
  9. baudrate = 4800, -- 波特率
  10. gpio_485 = 25, -- 转向GPIO编号(1.2版本开发板是GPIO25)
  11. tx_delay = 50000 -- 转向延迟时间,单位us(4800的最佳转向时间为50000,9600为20000,可以咨询下位机厂家推荐的转向延迟时间)
  12. -- 下面这些数据不填也行,不填底层默认为如下参数
  13. -- databits = 8,--数据位
  14. -- stopbits = 1,--停止位
  15. -- parity = uart.None,--校验位
  16. -- endianness = uart.LSB,--大小端
  17. -- buffer_size = 1024,--缓冲区大小
  18. -- rx_level = 0,--rx初始电平
  19. })
  20. -- 定义modbus_rtu数据接收回调
  21. local function on_modbus_rtu_receive(frame)
  22. log.info("modbus_rtu frame received:", json.encode(frame))
  23. if frame.fun == 0x03 then -- 功能码0x03表示读取保持寄存器
  24. local byte = frame.byte
  25. local payload = frame.payload
  26. -- log.info("modbus_rtu payload (hex):", payload:toHex())
  27. -- 解析数据(假设数据为16位寄存器值)
  28. local values_big = {} -- 大端序解析结果
  29. for i = 1, #payload, 2 do
  30. local msb = payload:byte(i)
  31. local lsb = payload:byte(i + 1)
  32. -- 大端序解析
  33. local result_big = (msb * 256) + lsb
  34. table.insert(values_big, result_big)
  35. end
  36. -- 输出大端序的解析结果
  37. log.info("输出大端序的解析结果:", table.concat(values_big, ", "))
  38. -- 第一个寄存器是湿度,第二个是温度,除以10以获取实际值
  39. if #values_big == 2 then
  40. log.info("测试同款485温湿度计")
  41. local humidity = values_big[1] / 10
  42. local temperature = values_big[2] / 10
  43. -- 打印湿度和温度
  44. log.info(string.format("湿度: %.1f%%", humidity))
  45. log.info(string.format("温度: %.1f°C", temperature))
  46. -- 发布湿度和温度
  47. sys.publish("modbus_rtu_data", {humidity, temperature})
  48. else
  49. log.info("用户自己的485下位机,共有" .. #values_big .. "组数据")
  50. for index, value in ipairs(values_big) do
  51. log.info(string.format("寄存器 %d: %d (大端序)", index, value))
  52. end
  53. end
  54. else
  55. log.info("功能码不是03")
  56. end
  57. end
  58. -- 设置modbus_rtu数据接收回调
  59. modbus_rtu.set_receive_callback(uartid, on_modbus_rtu_receive)
  60. local function send_modbus_rtu_command()
  61. local addr = 0x01 -- 设备地址,此处填客户自己的
  62. local fun = 0x03 -- 功能码(03为读取保持寄存器),此处填客户自己的
  63. local data = string.char(0x00, 0x00, 0x00, 0x02) -- 起始地址和寄存器数量(此处填客户自己的起始地址进而寄存器数量)
  64. -- modbus_rtu.send_command(1, addr, fun, data) -- 只发送一次命令并等待响应处理
  65. modbus_rtu.send_command(uartid, addr, fun, data, 5000) -- 循环5S发送一次
  66. end
  67. sys.taskInit(function()
  68. sys.wait(5000)
  69. send_modbus_rtu_command()
  70. end)