luat_lib_adc.c 5.3 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178
  1. /*
  2. @module adc
  3. @summary 模数转换
  4. @version 1.0
  5. @date 2020.07.03
  6. @demo adc
  7. @tag LUAT_USE_ADC
  8. @usage
  9. -- 本库可读取硬件adc通道, 也支持读取CPU温度和VBAT供电电源(若模块支持的话)
  10. -- 读取CPU温度, 单位为0.001摄氏度, 是内部温度, 非环境温度
  11. adc.open(adc.CH_CPU)
  12. local temp = adc.get(adc.CH_CPU)
  13. adc.close(adc.CH_CPU)
  14. -- 读取VBAT供电电压, 单位为mV
  15. adc.open(adc.CH_VBAT)
  16. local vbat = adc.get(adc.CH_VBAT)
  17. adc.close(adc.CH_VBAT)
  18. -- 物理ADC通道请查阅adc.get或者adc.read的注释
  19. */
  20. #include "luat_base.h"
  21. #include "luat_adc.h"
  22. /**
  23. 打开adc通道
  24. @api adc.open(id)
  25. @int 通道id,与具体设备有关,通常从0开始
  26. @return boolean 打开结果
  27. @usage
  28. -- 打开adc通道4,并读取
  29. if adc.open(4) then
  30. log.info("adc", adc.read(4)) -- 返回值有2个, 原始值和计算值,通常只需要后者
  31. log.info("adc", adc.get(4)) -- 返回值有1个, 仅计算值
  32. end
  33. adc.close(4) -- 若需要持续读取, 则不需要close, 功耗会高一点.
  34. */
  35. static int l_adc_open(lua_State *L) {
  36. if (luat_adc_open(luaL_checkinteger(L, 1), NULL) == 0) {
  37. lua_pushboolean(L, 1);
  38. }
  39. else {
  40. lua_pushboolean(L, 0);
  41. }
  42. return 1;
  43. }
  44. /**
  45. 设置ADC的测量范围,注意这个和具体芯片有关,目前只支持air105/Air780EXXX系列
  46. @api adc.setRange(range)
  47. @int range参数,与具体设备有关,比如air105填adc.ADC_RANGE_1_8和adc.ADC_RANGE_3_6
  48. @return nil
  49. @usage
  50. -- 本函数要在调用adc.open之前就调用, 之后调用无效!!!
  51. -- 关闭air105内部分压
  52. adc.setRange(adc.ADC_RANGE_1_8)
  53. -- 打开air105内部分压
  54. adc.setRange(adc.ADC_RANGE_3_6)
  55. -- Air780EXXX支持多种,但是建议用以下2种
  56. adc.setRange(adc.ADC_RANGE_MIN) -- 关闭分压
  57. adc.setRange(adc.ADC_RANGE_MAX) -- 启用分压
  58. */
  59. static int l_adc_set_range(lua_State *L) {
  60. luat_adc_global_config(ADC_SET_GLOBAL_RANGE, luaL_checkinteger(L, 1));
  61. return 0;
  62. }
  63. /**
  64. 读取adc通道
  65. @api adc.read(id)
  66. @int 通道id,与具体设备有关,通常从0开始
  67. @return int 原始值,一般没用,可以直接抛弃
  68. @return int 从原始值换算得出的实际值,通常单位是mV
  69. @usage
  70. -- 打开adc通道2,并读取
  71. if adc.open(2) then
  72. -- 这里使用的是adc.read会返回2个值, 推荐走adc.get函数,直接取实际值
  73. log.info("adc", adc.read(2))
  74. end
  75. adc.close(2)
  76. */
  77. static int l_adc_read(lua_State *L) {
  78. int val = 0xFF;
  79. int val2 = 0xFF;
  80. if (luat_adc_read(luaL_checkinteger(L, 1), &val, &val2) == 0) {
  81. lua_pushinteger(L, val);
  82. lua_pushinteger(L, val2);
  83. return 2;
  84. }
  85. else {
  86. lua_pushinteger(L, 0xFF);
  87. return 1;
  88. }
  89. }
  90. /**
  91. 获取adc计算值
  92. @api adc.get(id)
  93. @int 通道id,与具体设备有关,通常从0开始
  94. @return int 单位通常是mV, 部分通道会返回温度值,单位千分之一摄氏度. 若读取失败,会返回-1
  95. @usage
  96. -- 本API 在 2022.10.01后编译的固件可用
  97. -- 打开adc通道2,并读取
  98. if adc.open(2) then
  99. log.info("adc", adc.get(2))
  100. end
  101. adc.close(2) -- 按需关闭
  102. */
  103. static int l_adc_get(lua_State *L) {
  104. int val = 0xFF;
  105. int val2 = 0xFF;
  106. if (luat_adc_read(luaL_checkinteger(L, 1), &val, &val2) == 0) {
  107. lua_pushinteger(L, val2);
  108. }
  109. else {
  110. lua_pushinteger(L, -1);
  111. }
  112. return 1;
  113. }
  114. /**
  115. 关闭adc通道
  116. @api adc.close(id)
  117. @int 通道id,与具体设备有关,通常从0开始
  118. @usage
  119. -- 打开adc通道2,并读取
  120. if adc.open(2) then
  121. log.info("adc", adc.read(2))
  122. end
  123. adc.close(2)
  124. */
  125. static int l_adc_close(lua_State *L) {
  126. luat_adc_close(luaL_checkinteger(L, 1));
  127. return 0;
  128. }
  129. #include "rotable2.h"
  130. static const rotable_Reg_t reg_adc[] =
  131. {
  132. { "open" , ROREG_FUNC(l_adc_open)},
  133. { "setRange" , ROREG_FUNC(l_adc_set_range)},
  134. { "read" , ROREG_FUNC(l_adc_read)},
  135. { "get" , ROREG_FUNC(l_adc_get)},
  136. { "close" , ROREG_FUNC(l_adc_close)},
  137. //@const ADC_RANGE_3_6 number air105的ADC分压电阻开启,范围0~3.76V
  138. { "ADC_RANGE_3_6", ROREG_INT(1)},
  139. //@const ADC_RANGE_1_8 number air105的ADC分压电阻关闭,范围0~1.88V
  140. { "ADC_RANGE_1_8", ROREG_INT(0)},
  141. //@const ADC_RANGE_3_8 number air780E开启ADC0,1分压电阻,范围0~3.8V,将要废弃,不建议使用
  142. { "ADC_RANGE_3_8", ROREG_INT(LUAT_ADC_AIO_RANGE_3_8)},
  143. //@const ADC_RANGE_1_2 number air780E关闭ADC0,1分压电阻,范围0~1.2V,将要废弃,不建议使用
  144. { "ADC_RANGE_1_2", ROREG_INT(0)},
  145. //@const ADC_RANGE_MAX number ADC开启内部分压后所能到达最大量程,由具体芯片决定
  146. { "ADC_RANGE_MAX", ROREG_INT(LUAT_ADC_AIO_RANGE_MAX)},
  147. //@const ADC_RANGE_MIN number ADC关闭内部分压后所能到达最大量程,由具体芯片决定
  148. { "ADC_RANGE_MIN", ROREG_INT(0)},
  149. //@const CH_CPU number CPU内部温度的通道id
  150. { "CH_CPU", ROREG_INT(LUAT_ADC_CH_CPU)},
  151. //@const CH_VBAT number VBAT供电电压的通道id
  152. { "CH_VBAT", ROREG_INT(LUAT_ADC_CH_VBAT)},
  153. //@const T1 number ADC1 (如存在多个adc可利用此常量使用多ADC 例如 adc.open(ADC1+2) 打开ADC1 channel 2)
  154. { "T1", ROREG_INT(16)},
  155. //@const T2 number ADC2 (如存在多个adc可利用此常量使用多ADC 例如 adc.open(ADC2+3) 打开ADC2 channel 3)
  156. { "T2", ROREG_INT(32)},
  157. { NULL, ROREG_INT(0) }
  158. };
  159. LUAMOD_API int luaopen_adc( lua_State *L ) {
  160. luat_newlib2(L, reg_adc);
  161. return 1;
  162. }