ads1115.c 23 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595
  1. //***************************************************************************
  2. // Si7021 module for ESP8266 with nodeMCU
  3. // fetchbot @github
  4. // MIT license, http://opensource.org/licenses/MIT
  5. //***************************************************************************
  6. #include "module.h"
  7. #include "lauxlib.h"
  8. #include "platform.h"
  9. #include "osapi.h"
  10. #include <stdlib.h>
  11. //***************************************************************************
  12. // CHIP
  13. //***************************************************************************
  14. #define ADS1115_ADS1015 ( 15)
  15. #define ADS1115_ADS1115 (115)
  16. //***************************************************************************
  17. // I2C ADDRESS DEFINITON
  18. //***************************************************************************
  19. #define ADS1115_I2C_ADDR_GND (0x48)
  20. #define ADS1115_I2C_ADDR_VDD (0x49)
  21. #define ADS1115_I2C_ADDR_SDA (0x4A)
  22. #define ADS1115_I2C_ADDR_SCL (0x4B)
  23. #define IS_I2C_ADDR_VALID(addr) (((addr) & 0xFC) == 0x48)
  24. //***************************************************************************
  25. // POINTER REGISTER
  26. //***************************************************************************
  27. #define ADS1115_POINTER_MASK (0x03)
  28. #define ADS1115_POINTER_CONVERSION (0x00)
  29. #define ADS1115_POINTER_CONFIG (0x01)
  30. #define ADS1115_POINTER_THRESH_LOW (0x02)
  31. #define ADS1115_POINTER_THRESH_HI (0x03)
  32. //***************************************************************************
  33. // CONFIG REGISTER
  34. //***************************************************************************
  35. #define ADS1115_OS_MASK (0x8000)
  36. #define ADS1115_OS_NON (0x0000)
  37. #define ADS1115_OS_SINGLE (0x8000) // Write: Set to start a single-conversion
  38. #define ADS1115_OS_BUSY (0x0000) // Read: Bit = 0 when conversion is in progress
  39. #define ADS1115_OS_NOTBUSY (0x8000) // Read: Bit = 1 when device is not performing a conversion
  40. #define ADS1115_MUX_MASK (0x7000)
  41. #define ADS1115_MUX_DIFF_0_1 (0x0000) // Differential P = AIN0, N = AIN1 (default)
  42. #define ADS1115_MUX_DIFF_0_3 (0x1000) // Differential P = AIN0, N = AIN3
  43. #define ADS1115_MUX_DIFF_1_3 (0x2000) // Differential P = AIN1, N = AIN3
  44. #define ADS1115_MUX_DIFF_2_3 (0x3000) // Differential P = AIN2, N = AIN3
  45. #define ADS1115_MUX_SINGLE_0 (0x4000) // Single-ended AIN0
  46. #define ADS1115_MUX_SINGLE_1 (0x5000) // Single-ended AIN1
  47. #define ADS1115_MUX_SINGLE_2 (0x6000) // Single-ended AIN2
  48. #define ADS1115_MUX_SINGLE_3 (0x7000) // Single-ended AIN3
  49. #define IS_CHANNEL_VALID(channel) (((channel) & 0x8FFF) == 0)
  50. #define ADS1115_PGA_MASK (0x0E00)
  51. #define ADS1115_PGA_6_144V (0x0000) // +/-6.144V range = Gain 2/3
  52. #define ADS1115_PGA_4_096V (0x0200) // +/-4.096V range = Gain 1
  53. #define ADS1115_PGA_2_048V (0x0400) // +/-2.048V range = Gain 2 (default)
  54. #define ADS1115_PGA_1_024V (0x0600) // +/-1.024V range = Gain 4
  55. #define ADS1115_PGA_0_512V (0x0800) // +/-0.512V range = Gain 8
  56. #define ADS1115_PGA_0_256V (0x0A00) // +/-0.256V range = Gain 16
  57. #define ADS1115_MODE_MASK (0x0100)
  58. #define ADS1115_MODE_CONTIN (0x0000) // Continuous conversion mode
  59. #define ADS1115_MODE_SINGLE (0x0100) // Power-down single-shot mode (default)
  60. #define ADS1115_DR_MASK (0x00E0)
  61. #define ADS1115_DR_8SPS ( 8)
  62. #define ADS1115_DR_16SPS ( 16)
  63. #define ADS1115_DR_32SPS ( 32)
  64. #define ADS1115_DR_64SPS ( 64)
  65. #define ADS1115_DR_128SPS ( 128)
  66. #define ADS1115_DR_250SPS ( 250)
  67. #define ADS1115_DR_475SPS ( 475)
  68. #define ADS1115_DR_490SPS ( 490)
  69. #define ADS1115_DR_860SPS ( 860)
  70. #define ADS1115_DR_920SPS ( 920)
  71. #define ADS1115_DR_1600SPS (1600)
  72. #define ADS1115_DR_2400SPS (2400)
  73. #define ADS1115_DR_3300SPS (3300)
  74. #define ADS1115_CMODE_MASK (0x0010)
  75. #define ADS1115_CMODE_TRAD (0x0000) // Traditional comparator with hysteresis (default)
  76. #define ADS1115_CMODE_WINDOW (0x0010) // Window comparator
  77. #define ADS1115_CPOL_MASK (0x0008)
  78. #define ADS1115_CPOL_ACTVLOW (0x0000) // ALERT/RDY pin is low when active (default)
  79. #define ADS1115_CPOL_ACTVHI (0x0008) // ALERT/RDY pin is high when active
  80. #define ADS1115_CLAT_MASK (0x0004) // Determines if ALERT/RDY pin latches once asserted
  81. #define ADS1115_CLAT_NONLAT (0x0000) // Non-latching comparator (default)
  82. #define ADS1115_CLAT_LATCH (0x0004) // Latching comparator
  83. #define ADS1115_CQUE_MASK (0x0003)
  84. #define ADS1115_CQUE_1CONV (0x0000) // Assert ALERT/RDY after one conversions
  85. #define ADS1115_CQUE_2CONV (0x0001) // Assert ALERT/RDY after two conversions
  86. #define ADS1115_CQUE_4CONV (0x0002) // Assert ALERT/RDY after four conversions
  87. #define ADS1115_CQUE_NONE (0x0003) // Disable the comparator and put ALERT/RDY in high state (default)
  88. #define ADS1115_DEFAULT_CONFIG_REG (0x8583) // Config register value after reset
  89. // #define ADS1115_INCLUDE_TEST_FUNCTION
  90. //***************************************************************************
  91. static const uint8_t ads1115_i2c_id = 0;
  92. static const uint8_t general_i2c_addr = 0x00;
  93. static const uint8_t ads1115_i2c_reset = 0x06;
  94. static const char metatable_name[] = "ads1115.device";
  95. static const char unexpected_value[] = "unexpected value";
  96. typedef struct {
  97. uint8_t i2c_addr;
  98. uint8_t chip_id;
  99. uint16_t gain;
  100. uint16_t samples_value; // sample per second
  101. uint16_t samples; // register value
  102. uint16_t comp;
  103. uint16_t mode;
  104. uint16_t threshold_low;
  105. uint16_t threshold_hi;
  106. uint16_t config;
  107. int timer_ref;
  108. os_timer_t timer;
  109. } ads_ctrl_ud_t;
  110. static int ads1115_lua_readoutdone(void * param);
  111. static int ads1115_lua_register(lua_State *L, uint8_t chip_id);
  112. static uint8_t write_reg(uint8_t ads_addr, uint8_t reg, uint16_t config) {
  113. platform_i2c_send_start(ads1115_i2c_id);
  114. platform_i2c_send_address(ads1115_i2c_id, ads_addr, PLATFORM_I2C_DIRECTION_TRANSMITTER);
  115. platform_i2c_send_byte(ads1115_i2c_id, reg);
  116. platform_i2c_send_byte(ads1115_i2c_id, (uint8_t)(config >> 8));
  117. platform_i2c_send_byte(ads1115_i2c_id, (uint8_t)(config & 0xFF));
  118. platform_i2c_send_stop(ads1115_i2c_id);
  119. }
  120. static uint16_t read_reg(uint8_t ads_addr, uint8_t reg) {
  121. platform_i2c_send_start(ads1115_i2c_id);
  122. platform_i2c_send_address(ads1115_i2c_id, ads_addr, PLATFORM_I2C_DIRECTION_TRANSMITTER);
  123. platform_i2c_send_byte(ads1115_i2c_id, reg);
  124. platform_i2c_send_stop(ads1115_i2c_id);
  125. platform_i2c_send_start(ads1115_i2c_id);
  126. platform_i2c_send_address(ads1115_i2c_id, ads_addr, PLATFORM_I2C_DIRECTION_RECEIVER);
  127. uint16_t buf = (platform_i2c_recv_byte(ads1115_i2c_id, 1) << 8);
  128. buf += platform_i2c_recv_byte(ads1115_i2c_id, 0);
  129. platform_i2c_send_stop(ads1115_i2c_id);
  130. return buf;
  131. }
  132. // convert ADC value to voltage corresponding to PGA settings
  133. // returned voltage is in milivolts
  134. static double get_mvolt(uint16_t gain, uint16_t value) {
  135. double volt = 0;
  136. switch (gain) {
  137. case (ADS1115_PGA_6_144V):
  138. volt = (int16_t)value * 0.1875;
  139. break;
  140. case (ADS1115_PGA_4_096V):
  141. volt = (int16_t)value * 0.125;
  142. break;
  143. case (ADS1115_PGA_2_048V):
  144. volt = (int16_t)value * 0.0625;
  145. break;
  146. case (ADS1115_PGA_1_024V):
  147. volt = (int16_t)value * 0.03125;
  148. break;
  149. case (ADS1115_PGA_0_512V):
  150. volt = (int16_t)value * 0.015625;
  151. break;
  152. case (ADS1115_PGA_0_256V):
  153. volt = (int16_t)value * 0.0078125;
  154. break;
  155. }
  156. return volt;
  157. }
  158. // validates and convert threshold in volt to ADC value corresponding to PGA settings
  159. // returns true if valid
  160. static uint8_t get_value(uint16_t gain, uint16_t channel, int16_t *volt) {
  161. switch (gain) {
  162. case (ADS1115_PGA_6_144V):
  163. if ((*volt >= 6144) || (*volt < -6144) || ((*volt < 0) && (channel >> 14))) return 0;
  164. *volt = *volt / 0.1875;
  165. break;
  166. case (ADS1115_PGA_4_096V):
  167. if ((*volt >= 4096) || (*volt < -4096) || ((*volt < 0) && (channel >> 14))) return 0;
  168. *volt = *volt / 0.125;
  169. break;
  170. case (ADS1115_PGA_2_048V):
  171. if ((*volt >= 2048) || (*volt < -2048) || ((*volt < 0) && (channel >> 14))) return 0;
  172. *volt = *volt / 0.0625;
  173. break;
  174. case (ADS1115_PGA_1_024V):
  175. if ((*volt >= 1024) || (*volt < -1024) || ((*volt < 0) && (channel >> 14))) return 0;
  176. *volt = *volt / 0.03125;
  177. break;
  178. case (ADS1115_PGA_0_512V):
  179. if ((*volt >= 512) || (*volt < -512) || ((*volt < 0) && (channel >> 14))) return 0;
  180. *volt = *volt / 0.015625;
  181. break;
  182. case (ADS1115_PGA_0_256V):
  183. if ((*volt >= 256) || (*volt < -256) || ((*volt < 0) && (channel >> 14))) return 0;
  184. *volt = *volt / 0.0078125;
  185. break;
  186. }
  187. return 1;
  188. }
  189. // Reset of all devices
  190. // Lua: ads1115.reset()
  191. static int ads1115_lua_reset(lua_State *L) {
  192. platform_i2c_send_start(ads1115_i2c_id);
  193. platform_i2c_send_address(ads1115_i2c_id, general_i2c_addr, PLATFORM_I2C_DIRECTION_TRANSMITTER);
  194. platform_i2c_send_byte(ads1115_i2c_id, ads1115_i2c_reset);
  195. platform_i2c_send_stop(ads1115_i2c_id);
  196. return 0;
  197. }
  198. // Register an ADS device
  199. // Lua: ads1115.ADS1115(I2C_ID, ADDRESS)
  200. static int ads1115_lua_register_1115(lua_State *L) {
  201. return ads1115_lua_register(L, ADS1115_ADS1115);
  202. }
  203. static int ads1115_lua_register_1015(lua_State *L) {
  204. return ads1115_lua_register(L, ADS1115_ADS1015);
  205. }
  206. static int ads1115_lua_register(lua_State *L, uint8_t chip_id) {
  207. uint8_t i2c_id = luaL_checkinteger(L, 1);
  208. luaL_argcheck(L, 0 == i2c_id, 1, "i2c_id must be 0");
  209. uint8_t i2c_addr = luaL_checkinteger(L, 2);
  210. luaL_argcheck(L, IS_I2C_ADDR_VALID(i2c_addr), 2, unexpected_value);
  211. uint16_t config_read = read_reg(i2c_addr, ADS1115_POINTER_CONFIG);
  212. if (config_read == 0xFFFF) {
  213. return luaL_error(L, "found no device");
  214. }
  215. if (config_read != ADS1115_DEFAULT_CONFIG_REG) {
  216. return luaL_error(L, "unexpected config value (%p) please reset device before calling this function", config_read);
  217. }
  218. ads_ctrl_ud_t *ads_ctrl = lua_newuserdata(L, sizeof(ads_ctrl_ud_t));
  219. luaL_getmetatable(L, metatable_name);
  220. lua_setmetatable(L, -2);
  221. ads_ctrl->chip_id = chip_id;
  222. ads_ctrl->i2c_addr = i2c_addr;
  223. ads_ctrl->gain = ADS1115_PGA_6_144V;
  224. ads_ctrl->samples = ADS1115_DR_128SPS;
  225. ads_ctrl->samples_value = chip_id == ADS1115_ADS1115 ? 128 : 1600;
  226. ads_ctrl->comp = ADS1115_CQUE_NONE;
  227. ads_ctrl->mode = ADS1115_MODE_SINGLE;
  228. ads_ctrl->threshold_low = 0x8000;
  229. ads_ctrl->threshold_hi = 0x7FFF;
  230. ads_ctrl->config = ADS1115_DEFAULT_CONFIG_REG;
  231. ads_ctrl->timer_ref = LUA_NOREF;
  232. return 1;
  233. }
  234. // Change the ADC device settings
  235. // Lua: ads1115.device:settings(GAIN,SAMPLES,CHANNEL,MODE[,CONVERSION_RDY][,COMPARATOR,THRESHOLD_LOW,THRESHOLD_HI[,COMP_MODE])
  236. static int ads1115_lua_setting(lua_State *L) {
  237. int argc = lua_gettop(L);
  238. if (argc != 5 && argc != 6 && argc != 8 && argc != 9) { // user data counts
  239. luaL_error(L, "invalid number of arguments to 'setting'");
  240. }
  241. ads_ctrl_ud_t *ads_ctrl = luaL_checkudata(L, 1, metatable_name);
  242. // gain
  243. uint16_t gain = luaL_checkinteger(L, 2);
  244. luaL_argcheck(L, (gain == ADS1115_PGA_6_144V) || (gain == ADS1115_PGA_4_096V) || (gain == ADS1115_PGA_2_048V) ||
  245. (gain == ADS1115_PGA_1_024V) || (gain == ADS1115_PGA_0_512V) || (gain == ADS1115_PGA_0_256V),
  246. 2, unexpected_value);
  247. ads_ctrl->gain = gain;
  248. // samples
  249. uint16_t samples_value = luaL_checkinteger(L, 3);
  250. uint16_t samples = 0;
  251. if (ads_ctrl->chip_id == ADS1115_ADS1115) {
  252. switch(samples_value) {
  253. case ADS1115_DR_8SPS:
  254. samples = 0;
  255. break;
  256. case ADS1115_DR_16SPS:
  257. samples = 0x20;
  258. break;
  259. case ADS1115_DR_32SPS:
  260. samples = 0x40;
  261. break;
  262. case ADS1115_DR_64SPS:
  263. samples = 0x60;
  264. break;
  265. case ADS1115_DR_128SPS: // default
  266. samples = 0x80;
  267. break;
  268. case ADS1115_DR_250SPS:
  269. samples = 0xA0;
  270. break;
  271. case ADS1115_DR_475SPS:
  272. samples = 0xC0;
  273. break;
  274. case ADS1115_DR_860SPS:
  275. samples = 0xE0;
  276. break;
  277. default:
  278. luaL_argerror(L, 3, unexpected_value);
  279. }
  280. } else { // ADS1115_ADS1015
  281. switch(samples_value) {
  282. case ADS1115_DR_128SPS:
  283. samples = 0;
  284. break;
  285. case ADS1115_DR_250SPS:
  286. samples = 0x20;
  287. break;
  288. case ADS1115_DR_490SPS:
  289. samples = 0x40;
  290. break;
  291. case ADS1115_DR_920SPS:
  292. samples = 0x60;
  293. break;
  294. case ADS1115_DR_1600SPS: // default
  295. samples = 0x80;
  296. break;
  297. case ADS1115_DR_2400SPS:
  298. samples = 0xA0;
  299. break;
  300. case ADS1115_DR_3300SPS:
  301. samples = 0xC0;
  302. break;
  303. default:
  304. luaL_argerror(L, 3, unexpected_value);
  305. }
  306. }
  307. ads_ctrl->samples = samples;
  308. ads_ctrl->samples_value = samples_value;
  309. // channel
  310. uint16_t channel = luaL_checkinteger(L, 4);
  311. luaL_argcheck(L, IS_CHANNEL_VALID(channel), 4, unexpected_value);
  312. // mode
  313. uint16_t mode = luaL_checkinteger(L, 5);
  314. luaL_argcheck(L, (mode == ADS1115_MODE_SINGLE) || (mode == ADS1115_MODE_CONTIN), 5, unexpected_value);
  315. ads_ctrl->mode = mode;
  316. uint16_t os = mode == ADS1115_MODE_SINGLE ? ADS1115_OS_SINGLE : ADS1115_OS_NON;
  317. uint16_t comp = ADS1115_CQUE_NONE;
  318. // Parse optional parameters
  319. if (argc > 5) {
  320. // comparator or conversion count
  321. comp = luaL_checkinteger(L, 6);
  322. luaL_argcheck(L, (comp == ADS1115_CQUE_1CONV) || (comp == ADS1115_CQUE_2CONV) || (comp == ADS1115_CQUE_4CONV),
  323. 6, unexpected_value);
  324. uint16_t threshold_low = 0x7FFF;
  325. uint16_t threshold_hi = 0x8000;
  326. if (argc > 6) {
  327. // comparator thresholds
  328. threshold_low = luaL_checkinteger(L, 7);
  329. threshold_hi = luaL_checkinteger(L, 8);
  330. luaL_argcheck(L, (int16_t)threshold_low <= (int16_t)threshold_hi, 7, "threshold_low > threshold_hi");
  331. luaL_argcheck(L, get_value(gain, channel, &threshold_low), 7, unexpected_value);
  332. luaL_argcheck(L, get_value(gain, channel, &threshold_hi), 8, unexpected_value);
  333. }
  334. ads_ctrl->threshold_low = threshold_low;
  335. ads_ctrl->threshold_hi = threshold_hi;
  336. NODE_DBG("ads1115 low: %04x\n", threshold_low);
  337. NODE_DBG("ads1115 hi : %04x\n", threshold_hi);
  338. write_reg(ads_ctrl->i2c_addr, ADS1115_POINTER_THRESH_LOW, threshold_low);
  339. write_reg(ads_ctrl->i2c_addr, ADS1115_POINTER_THRESH_HI, threshold_hi);
  340. }
  341. ads_ctrl->comp = comp;
  342. uint16_t comparator_mode = ADS1115_CMODE_TRAD;
  343. if (argc == 9) {
  344. comparator_mode = luaL_checkinteger(L, 9);
  345. luaL_argcheck(L, (comparator_mode == ADS1115_CMODE_WINDOW) || (comparator_mode == ADS1115_CMODE_TRAD),
  346. 9, unexpected_value);
  347. }
  348. uint16_t config = (os | channel | gain | mode | samples | comparator_mode | ADS1115_CPOL_ACTVLOW | ADS1115_CLAT_NONLAT | comp);
  349. ads_ctrl->config = config;
  350. NODE_DBG("ads1115 config: %04x\n", ads_ctrl->config);
  351. write_reg(ads_ctrl->i2c_addr, ADS1115_POINTER_CONFIG, config);
  352. return 0;
  353. }
  354. // Read the conversion register from the ADC device
  355. // Lua: ads1115.device:startread(function(volt, voltdec, adc, sign) print(volt,voltdec,adc,sign) end)
  356. static int ads1115_lua_startread(lua_State *L) {
  357. ads_ctrl_ud_t *ads_ctrl = luaL_checkudata(L, 1, metatable_name);
  358. if (((ads_ctrl->comp == ADS1115_CQUE_1CONV) ||
  359. (ads_ctrl->comp == ADS1115_CQUE_2CONV) ||
  360. (ads_ctrl->comp == ADS1115_CQUE_4CONV)) &&
  361. (ads_ctrl->threshold_low == 0x7FFF) &&
  362. (ads_ctrl->threshold_hi == 0x8000)) {
  363. // conversion ready mode
  364. if (ads_ctrl->mode == ADS1115_MODE_SINGLE) {
  365. NODE_DBG("ads1115 trigger config: %04x", ads_ctrl->config);
  366. write_reg(ads_ctrl->i2c_addr, ADS1115_POINTER_CONFIG, ads_ctrl->config);
  367. }
  368. return 0;
  369. }
  370. luaL_argcheck(L, lua_isfunction(L, 2), 2, "Must be function");
  371. lua_pushvalue(L, 2);
  372. ads_ctrl->timer_ref = luaL_ref(L, LUA_REGISTRYINDEX);
  373. if (ads_ctrl->mode == ADS1115_MODE_SINGLE) {
  374. write_reg(ads_ctrl->i2c_addr, ADS1115_POINTER_CONFIG, ads_ctrl->config);
  375. }
  376. // Start a timer to wait until ADC conversion is done
  377. os_timer_disarm(&ads_ctrl->timer);
  378. os_timer_setfn(&ads_ctrl->timer, (os_timer_func_t *)ads1115_lua_readoutdone, (void *)ads_ctrl);
  379. int msec = 1; // ADS1115_DR_1600SPS, ADS1115_DR_2400SPS, ADS1115_DR_3300SPS
  380. switch (ads_ctrl->samples_value) {
  381. case ADS1115_DR_8SPS:
  382. msec = 150;
  383. break;
  384. case ADS1115_DR_16SPS:
  385. msec = 75;
  386. break;
  387. case ADS1115_DR_32SPS:
  388. msec = 35;
  389. break;
  390. case ADS1115_DR_64SPS:
  391. msec = 20;
  392. break;
  393. case ADS1115_DR_128SPS:
  394. msec = 10;
  395. break;
  396. case ADS1115_DR_250SPS:
  397. msec = 5;
  398. break;
  399. case ADS1115_DR_475SPS:
  400. case ADS1115_DR_490SPS:
  401. msec = 3;
  402. break;
  403. case ADS1115_DR_860SPS:
  404. case ADS1115_DR_920SPS:
  405. msec = 2;
  406. }
  407. os_timer_arm(&ads_ctrl->timer, msec, 0);
  408. return 0;
  409. }
  410. static void read_common(ads_ctrl_ud_t * ads_ctrl, uint16_t raw, lua_State *L) {
  411. double mvolt = get_mvolt(ads_ctrl->gain, raw);
  412. #ifdef LUA_NUMBER_INTEGRAL
  413. int sign;
  414. if (mvolt == 0) {
  415. sign = 0;
  416. } else if (mvolt > 0) {
  417. sign = 1;
  418. } else {
  419. sign = -1;
  420. }
  421. int uvolt;
  422. if (sign >= 0) {
  423. uvolt = (int)((mvolt - (int)mvolt) * 1000 + 0.5);
  424. } else {
  425. uvolt = -(int)((mvolt - (int)mvolt) * 1000 - 0.5);
  426. mvolt = -mvolt;
  427. }
  428. lua_pushnumber(L, mvolt);
  429. lua_pushinteger(L, uvolt);
  430. lua_pushinteger(L, raw);
  431. lua_pushinteger(L, sign);
  432. #else
  433. lua_pushnumber(L, mvolt);
  434. lua_pushnil(L);
  435. lua_pushinteger(L, raw);
  436. lua_pushnil(L);
  437. #endif
  438. }
  439. // adc conversion timer callback
  440. static int ads1115_lua_readoutdone(void * param) {
  441. ads_ctrl_ud_t * ads_ctrl = (ads_ctrl_ud_t *)param;
  442. uint16_t raw = read_reg(ads_ctrl->i2c_addr, ADS1115_POINTER_CONVERSION);
  443. lua_State *L = lua_getstate();
  444. os_timer_disarm(&ads_ctrl->timer);
  445. lua_rawgeti(L, LUA_REGISTRYINDEX, ads_ctrl->timer_ref);
  446. luaL_unref(L, LUA_REGISTRYINDEX, ads_ctrl->timer_ref);
  447. ads_ctrl->timer_ref = LUA_NOREF;
  448. read_common(ads_ctrl, raw, L);
  449. luaL_pcallx(L, 4, 0);
  450. }
  451. // Read the conversion register from the ADC device
  452. // Lua: volt,voltdec,adc,sign = ads1115.device:read()
  453. static int ads1115_lua_read(lua_State *L) {
  454. ads_ctrl_ud_t *ads_ctrl = luaL_checkudata(L, 1, metatable_name);
  455. uint16_t raw = read_reg(ads_ctrl->i2c_addr, ADS1115_POINTER_CONVERSION);
  456. read_common(ads_ctrl, raw, L);
  457. return 4;
  458. }
  459. #ifdef ADS1115_INCLUDE_TEST_FUNCTION
  460. // this function simulates conversion using raw value provided as argument
  461. // Lua: volt,volt_dec,adc,sign = ads1115.test_volt_conversion(-1)
  462. static int test_volt_conversion(lua_State *L) {
  463. ads_ctrl_ud_t *ads_ctrl = luaL_checkudata(L, 1, metatable_name);
  464. uint16_t raw = luaL_checkinteger(L, 2);
  465. read_common(ads_ctrl, raw, L);
  466. return 4;
  467. }
  468. #endif
  469. static int ads1115_lua_delete(lua_State *L) {
  470. ads_ctrl_ud_t *ads_ctrl = luaL_checkudata(L, 1, metatable_name);
  471. if (ads_ctrl->timer_ref != LUA_NOREF) {
  472. os_timer_disarm(&ads_ctrl->timer);
  473. luaL_unref(L, LUA_REGISTRYINDEX, ads_ctrl->timer_ref);
  474. }
  475. return 0;
  476. }
  477. LROT_BEGIN(ads1115, NULL, 0)
  478. LROT_FUNCENTRY( ads1115, ads1115_lua_register_1115 )
  479. LROT_FUNCENTRY( ads1015, ads1115_lua_register_1015 )
  480. LROT_FUNCENTRY( reset, ads1115_lua_reset )
  481. LROT_NUMENTRY( ADDR_GND, ADS1115_I2C_ADDR_GND )
  482. LROT_NUMENTRY( ADDR_VDD, ADS1115_I2C_ADDR_VDD )
  483. LROT_NUMENTRY( ADDR_SDA, ADS1115_I2C_ADDR_SDA )
  484. LROT_NUMENTRY( ADDR_SCL, ADS1115_I2C_ADDR_SCL )
  485. LROT_NUMENTRY( SINGLE_SHOT, ADS1115_MODE_SINGLE )
  486. LROT_NUMENTRY( CONTINUOUS, ADS1115_MODE_CONTIN )
  487. LROT_NUMENTRY( DIFF_0_1, ADS1115_MUX_DIFF_0_1 )
  488. LROT_NUMENTRY( DIFF_0_3, ADS1115_MUX_DIFF_0_3 )
  489. LROT_NUMENTRY( DIFF_1_3, ADS1115_MUX_DIFF_1_3 )
  490. LROT_NUMENTRY( DIFF_2_3, ADS1115_MUX_DIFF_2_3 )
  491. LROT_NUMENTRY( SINGLE_0, ADS1115_MUX_SINGLE_0 )
  492. LROT_NUMENTRY( SINGLE_1, ADS1115_MUX_SINGLE_1 )
  493. LROT_NUMENTRY( SINGLE_2, ADS1115_MUX_SINGLE_2 )
  494. LROT_NUMENTRY( SINGLE_3, ADS1115_MUX_SINGLE_3 )
  495. LROT_NUMENTRY( GAIN_6_144V, ADS1115_PGA_6_144V )
  496. LROT_NUMENTRY( GAIN_4_096V, ADS1115_PGA_4_096V )
  497. LROT_NUMENTRY( GAIN_2_048V, ADS1115_PGA_2_048V )
  498. LROT_NUMENTRY( GAIN_1_024V, ADS1115_PGA_1_024V )
  499. LROT_NUMENTRY( GAIN_0_512V, ADS1115_PGA_0_512V )
  500. LROT_NUMENTRY( GAIN_0_256V, ADS1115_PGA_0_256V )
  501. LROT_NUMENTRY( DR_8SPS, ADS1115_DR_8SPS )
  502. LROT_NUMENTRY( DR_16SPS, ADS1115_DR_16SPS )
  503. LROT_NUMENTRY( DR_32SPS, ADS1115_DR_32SPS )
  504. LROT_NUMENTRY( DR_64SPS, ADS1115_DR_64SPS )
  505. LROT_NUMENTRY( DR_128SPS, ADS1115_DR_128SPS )
  506. LROT_NUMENTRY( DR_250SPS, ADS1115_DR_250SPS )
  507. LROT_NUMENTRY( DR_475SPS, ADS1115_DR_475SPS )
  508. LROT_NUMENTRY( DR_490SPS, ADS1115_DR_490SPS )
  509. LROT_NUMENTRY( DR_860SPS, ADS1115_DR_860SPS )
  510. LROT_NUMENTRY( DR_920SPS, ADS1115_DR_920SPS )
  511. LROT_NUMENTRY( DR_1600SPS, ADS1115_DR_1600SPS )
  512. LROT_NUMENTRY( DR_2400SPS, ADS1115_DR_2400SPS )
  513. LROT_NUMENTRY( DR_3300SPS, ADS1115_DR_3300SPS )
  514. LROT_NUMENTRY( CONV_RDY_1, ADS1115_CQUE_1CONV )
  515. LROT_NUMENTRY( CONV_RDY_2, ADS1115_CQUE_2CONV )
  516. LROT_NUMENTRY( CONV_RDY_4, ADS1115_CQUE_4CONV )
  517. LROT_NUMENTRY( COMP_1CONV, ADS1115_CQUE_1CONV )
  518. LROT_NUMENTRY( COMP_2CONV, ADS1115_CQUE_2CONV )
  519. LROT_NUMENTRY( COMP_4CONV, ADS1115_CQUE_4CONV )
  520. LROT_NUMENTRY( CMODE_TRAD, ADS1115_CMODE_TRAD )
  521. LROT_NUMENTRY( CMODE_WINDOW, ADS1115_CMODE_WINDOW )
  522. LROT_END(ads1115, NULL, 0)
  523. LROT_BEGIN(ads1115_instance, NULL, LROT_MASK_GC_INDEX)
  524. LROT_TABENTRY( __index , ads1115_instance )
  525. LROT_FUNCENTRY( __gc, ads1115_lua_delete )
  526. LROT_FUNCENTRY( setting, ads1115_lua_setting )
  527. LROT_FUNCENTRY( startread, ads1115_lua_startread )
  528. LROT_FUNCENTRY( read, ads1115_lua_read )
  529. #ifdef ADS1115_INCLUDE_TEST_FUNCTION
  530. LROT_FUNCENTRY( test_volt_conversion, test_volt_conversion )
  531. #endif
  532. LROT_END(ads1115_instance, NULL, LROT_MASK_GC_INDEX)
  533. int luaopen_ads1115(lua_State *L) {
  534. luaL_rometatable(L, metatable_name, LROT_TABLEREF(ads1115_instance));
  535. return 0;
  536. }
  537. NODEMCU_MODULE(ADS1115, "ads1115", ads1115, luaopen_ads1115);