am2320.lua 2.0 KB

12345678910111213141516171819202122232425262728293031323334353637383940414243444546474849505152535455565758596061626364656667686970717273
  1. --[[
  2. @module am2320
  3. @summary am2320 温湿度传感器
  4. @version 1.0
  5. @date 2023.07.31
  6. @author wendal
  7. @demo am2320
  8. @usage
  9. -- 用法实例
  10. local am2320 = require "am2320"
  11. sys.taskInit(function()
  12. local i2c_id = 0
  13. i2c.setup(i2c_id, i2c.FAST)
  14. while 1 do
  15. local t, h = am2320.read(i2c_id)
  16. log.info("am2320", "温度", t, "湿度", h)
  17. sys.wait(1000)
  18. end
  19. end)
  20. ]]
  21. local am2320 = {}
  22. --[[
  23. 读取温湿度数据
  24. @api am2320.read(i2c_id)
  25. @int i2c总线的id, 默认是0, 需要按实际接线来填, 例如0/1/2/3
  26. @return number 温度,单位摄氏度,若读取失败会返回nil
  27. @return number 相对湿度,单位1%,若读取失败会返回nil
  28. ]]
  29. function am2320.read(i2c_id)
  30. if not i2c_id then
  31. i2c_id = 0
  32. end
  33. local i2cslaveaddr = 0x5C -- 8bit地址为0xb8 7bit 为0x5C
  34. i2c.send(i2c_id, i2cslaveaddr, 0x03)
  35. -- 查询功能码:0x03 查询的寄存器首地址:0 长度:4
  36. i2c.send(i2c_id, i2cslaveaddr, {0x03, 0x00, 0x04})
  37. local _, ismain = coroutine.running()
  38. if ismain then
  39. timer.mdelay(2)
  40. else
  41. sys.wait(2)
  42. end
  43. local data = i2c.recv(i2c_id, i2cslaveaddr, 8)
  44. -- 传感器返回的8位数据格式:
  45. -- 1 2 3 4 5 6 7 8
  46. -- 0x03 0x04 0x03 0x39 0x01 0x15 0xE1 0XFE
  47. -- 功能码 数据长度 湿度高位 湿度数据 温度高位 温度低位 CRC低 CRC高
  48. if data == nil or #data ~= 8 then
  49. return
  50. end
  51. -- log.info("AM2320", "buf data:", buf)
  52. -- log.info("AM2320", "HEX data:", data:toHex())
  53. local _, crc = pack.unpack(data, '<H', 7)
  54. data = data:sub(1, 6)
  55. if crc == crypto.crc16_modbus(data, 6) then
  56. local _, hum, tmp = pack.unpack(string.sub(data, 3, -1), '>H2')
  57. -- 正负温度处理
  58. if tmp >= 0x8000 then
  59. tmp = 0x8000 - tmp
  60. end
  61. tmp, hum = tmp / 10, hum / 10
  62. -- log.info("AM2320", "data(tmp hum):", tmp, hum)
  63. return tmp, hum
  64. end
  65. end
  66. return am2320