AirVOC_1000.lua 5.8 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207
  1. --[[
  2. @module AirVOC_1000
  3. @summary AirVOC_1000应用功能模块
  4. @version 1.0
  5. @date 2025.10.21
  6. @author 沈园园
  7. @usage
  8. 本文件为AirVOC_1000驱动配置文件,核心业务逻辑为:
  9. 1、打开AirVOC_1000;
  10. 2、读取TVOC的空气质量等级;
  11. 本文件没有对外接口,直接require "AirVOC_1000"就可以加载运行;
  12. ]]
  13. --本文件中的主机是指I2C主机,具体指Air780EPM
  14. --本文件中的从机是指I2C从机,具体指AirVOC_1000配件板上的ags02ma VOC(挥发性有机化合物)气体传感器芯片
  15. local AirVOC_1000 =
  16. {
  17. -- i2c_id:主机的i2c id;
  18. }
  19. -- 从机地址为0x1A
  20. local slave_address = 0x1A
  21. -- TVOC数据的寄存器地址
  22. local DATA_REG_ADDR = 0x00
  23. -- TVOC数据的长度
  24. local DATA_REG_LEN = 0x05
  25. --电平设为3.3v
  26. pm.ioVol(pm.IOVOL_ALL_GPIO, 3300)
  27. --设置gpio2输出,给camera_sda、camera_scl引脚提供上拉
  28. gpio.setup(2, 1)
  29. -- 计算数据表data中所有数据元素的crc8校验值
  30. local function crc8(data)
  31. local crc = 0xFF
  32. for i = 1, #data do
  33. crc = bit.bxor(crc, data[i])
  34. for j = 1, 8 do
  35. crc = crc * 2
  36. if crc >= 0x100 then
  37. crc = bit.band(bit.bxor(crc, 0x31), 0xff)
  38. end
  39. end
  40. end
  41. return crc
  42. end
  43. -- 读取AirVOC_1000的寄存器中指定长度的数据
  44. --reg:number类型;
  45. -- 表示AirVOC_1000上的寄存器地址;
  46. -- 必须传入,不允许为空;
  47. --返回值:失败返回false;成功返回读取到的指定长度的数据(string类型)
  48. local function read_register(reg, len)
  49. -- 发送寄存器地址
  50. i2c.send(AirVOC_1000.i2c_id, slave_address, reg)
  51. -- sys.wait(20)
  52. -- 读取应答的数据
  53. local data = i2c.recv(AirVOC_1000.i2c_id, slave_address, len)
  54. -- log.info("read_register", data:toHex())
  55. -- 读取到的数据为指定的长度,则表示读取成功
  56. -- 否则读取失败
  57. if type(data)=="string" and data:len()==len then
  58. return data
  59. else
  60. log.error("AirVOC_1000 read_register error", type(data), type(data)=="string" and data:len() or "invalid type", len)
  61. return false
  62. end
  63. end
  64. --打开AirVOC_1000;
  65. --i2c_id:number类型;
  66. -- 主机使用的I2C ID,用来控制AirVOC_1000;
  67. -- 取值范围:仅支持0和1;
  68. -- 如果没有传入此参数,则默认为0;
  69. --返回值:成功返回true,失败返回false
  70. function AirVOC_1000.open(i2c_id)
  71. --如果i2c_id为nil,则赋值为默认值0
  72. if i2c_id==nil then i2c_id=0 end
  73. --检查参数的合法性
  74. if not (i2c_id == 0 or i2c_id == 1) then
  75. log.error("AirVOC_1000.open", "invalid i2c_id", i2c_id)
  76. return false
  77. end
  78. AirVOC_1000.i2c_id = i2c_id
  79. --初始化I2C
  80. if i2c.setup(i2c_id, i2c.FAST) ~= 1 then
  81. log.error("AirVOC_1000.open", "i2c.setup error", i2c_id)
  82. return false
  83. end
  84. return true
  85. end
  86. --读取TVOC的ppb值;
  87. --ppb: 代表 parts per billion,即 十亿分之一。 1 ppb TVOC 表示在每 10 亿个体积单位的空气中,含有 1 个体积单位的 TVOC
  88. --返回值:失败返回false;
  89. -- 成功返回ppb值(number类型)
  90. function AirVOC_1000.get_ppb()
  91. --从寄存器DATA_REG_ADDR中读取DATA_REG_LEN长度的数据
  92. local raw = read_register(DATA_REG_ADDR, DATA_REG_LEN)
  93. --读取数据出错
  94. if not raw then
  95. log.error("AirVOC_1000.get_ppb", "read_register error")
  96. return false
  97. end
  98. --检查校验值
  99. if crc8({raw:byte(1), raw:byte(2), raw:byte(3), raw:byte(4)}) ~= raw:byte(5) then
  100. log.error("AirVOC_1000.get_ppb", "crc error")
  101. return false
  102. end
  103. --解析数据: 大端格式
  104. local tvoc = (raw:byte(2) << 16) |
  105. (raw:byte(3) << 8) |
  106. raw:byte(4)
  107. return tvoc
  108. end
  109. --读取TVOC的ppm值;
  110. --ppm: 代表 parts per million,即 百万分之一。 1 ppm TVOC 表示在每 100 万个体积单位的空气中,含有 1 个体积单位的 TVOC
  111. --返回值:失败返回false;
  112. -- 成功返回ppb值(number类型)
  113. function AirVOC_1000.get_ppm()
  114. --读取ppb值
  115. local ppb = AirVOC_1000.get_ppb()
  116. --如果ppb读取失败
  117. if not ppb then
  118. log.error("AirVOC_1000.get_ppm", "get_ppb error")
  119. return false
  120. end
  121. --ppb = ppm*1000
  122. return ppb/1000
  123. end
  124. --读取TVOC的空气质量等级;
  125. -- 根据 TVOC 浓度(通常以 ppb 或 ppm 表示)划分的等级,用于评估室内空气质量的优劣和对人体健康的潜在风险;
  126. -- 不同国家、地区或机构的标准可能略有差异,但核心划分逻辑相似:浓度越低,等级越好,风险越低。
  127. --返回值:失败返回false;
  128. -- 成功返回空气质量等级值(number类型,数值越小,表示空气质量越好)和空气质量描述(string类型,例如优、良好、轻度污染、中度污染、重度污染)
  129. -- 1:表示优
  130. -- 2:表示良好
  131. -- 3:表示轻度污染
  132. -- 4:表示中度污染
  133. -- 5:表示重度污染
  134. function AirVOC_1000.get_quality_level()
  135. --读取ppb值
  136. local ppb = AirVOC_1000.get_ppb()
  137. --如果ppb读取失败
  138. if not ppb then
  139. log.error("AirVOC_1000.get_qulity_level", "get_ppb error")
  140. return false
  141. end
  142. --根据ppb值计算空气质量等级
  143. if ppb < 200 then
  144. return 1,"优"
  145. elseif ppb < 1000 then
  146. return 2,"良好"
  147. elseif ppb < 3000 then
  148. return 3,"轻度污染"
  149. elseif ppb < 5000 then
  150. return 4,"中度污染"
  151. else
  152. return 5,"重度污染"
  153. end
  154. end
  155. --关闭AirVOC_1000
  156. --返回值:成功返回true,失败返回false
  157. function AirVOC_1000.close()
  158. --close接口没有返回值,理论上不会关闭失败
  159. i2c.close(AirVOC_1000.i2c_id)
  160. return true
  161. end
  162. return AirVOC_1000