ads1115.c 23 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598
  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 = (ads_ctrl_ud_t *)lua_newuserdata(L, sizeof(ads_ctrl_ud_t));
  219. if (NULL == ads_ctrl) {
  220. return luaL_error(L, "ads1115 malloc: out of memory");
  221. }
  222. luaL_getmetatable(L, metatable_name);
  223. lua_setmetatable(L, -2);
  224. ads_ctrl->chip_id = chip_id;
  225. ads_ctrl->i2c_addr = i2c_addr;
  226. ads_ctrl->gain = ADS1115_PGA_6_144V;
  227. ads_ctrl->samples = ADS1115_DR_128SPS;
  228. ads_ctrl->samples_value = chip_id == ADS1115_ADS1115 ? 128 : 1600;
  229. ads_ctrl->comp = ADS1115_CQUE_NONE;
  230. ads_ctrl->mode = ADS1115_MODE_SINGLE;
  231. ads_ctrl->threshold_low = 0x8000;
  232. ads_ctrl->threshold_hi = 0x7FFF;
  233. ads_ctrl->config = ADS1115_DEFAULT_CONFIG_REG;
  234. ads_ctrl->timer_ref = LUA_NOREF;
  235. return 1;
  236. }
  237. // Change the ADC device settings
  238. // Lua: ads1115.device:settings(GAIN,SAMPLES,CHANNEL,MODE[,CONVERSION_RDY][,COMPARATOR,THRESHOLD_LOW,THRESHOLD_HI[,COMP_MODE])
  239. static int ads1115_lua_setting(lua_State *L) {
  240. int argc = lua_gettop(L);
  241. if (argc != 5 && argc != 6 && argc != 8 && argc != 9) { // user data counts
  242. luaL_error(L, "invalid number of arguments to 'setting'");
  243. }
  244. ads_ctrl_ud_t *ads_ctrl = luaL_checkudata(L, 1, metatable_name);
  245. // gain
  246. uint16_t gain = luaL_checkinteger(L, 2);
  247. luaL_argcheck(L, (gain == ADS1115_PGA_6_144V) || (gain == ADS1115_PGA_4_096V) || (gain == ADS1115_PGA_2_048V) ||
  248. (gain == ADS1115_PGA_1_024V) || (gain == ADS1115_PGA_0_512V) || (gain == ADS1115_PGA_0_256V),
  249. 2, unexpected_value);
  250. ads_ctrl->gain = gain;
  251. // samples
  252. uint16_t samples_value = luaL_checkinteger(L, 3);
  253. uint16_t samples = 0;
  254. if (ads_ctrl->chip_id == ADS1115_ADS1115) {
  255. switch(samples_value) {
  256. case ADS1115_DR_8SPS:
  257. samples = 0;
  258. break;
  259. case ADS1115_DR_16SPS:
  260. samples = 0x20;
  261. break;
  262. case ADS1115_DR_32SPS:
  263. samples = 0x40;
  264. break;
  265. case ADS1115_DR_64SPS:
  266. samples = 0x60;
  267. break;
  268. case ADS1115_DR_128SPS: // default
  269. samples = 0x80;
  270. break;
  271. case ADS1115_DR_250SPS:
  272. samples = 0xA0;
  273. break;
  274. case ADS1115_DR_475SPS:
  275. samples = 0xC0;
  276. break;
  277. case ADS1115_DR_860SPS:
  278. samples = 0xE0;
  279. break;
  280. default:
  281. luaL_argerror(L, 3, unexpected_value);
  282. }
  283. } else { // ADS1115_ADS1015
  284. switch(samples_value) {
  285. case ADS1115_DR_128SPS:
  286. samples = 0;
  287. break;
  288. case ADS1115_DR_250SPS:
  289. samples = 0x20;
  290. break;
  291. case ADS1115_DR_490SPS:
  292. samples = 0x40;
  293. break;
  294. case ADS1115_DR_920SPS:
  295. samples = 0x60;
  296. break;
  297. case ADS1115_DR_1600SPS: // default
  298. samples = 0x80;
  299. break;
  300. case ADS1115_DR_2400SPS:
  301. samples = 0xA0;
  302. break;
  303. case ADS1115_DR_3300SPS:
  304. samples = 0xC0;
  305. break;
  306. default:
  307. luaL_argerror(L, 3, unexpected_value);
  308. }
  309. }
  310. ads_ctrl->samples = samples;
  311. ads_ctrl->samples_value = samples_value;
  312. // channel
  313. uint16_t channel = luaL_checkinteger(L, 4);
  314. luaL_argcheck(L, IS_CHANNEL_VALID(channel), 4, unexpected_value);
  315. // mode
  316. uint16_t mode = luaL_checkinteger(L, 5);
  317. luaL_argcheck(L, (mode == ADS1115_MODE_SINGLE) || (mode == ADS1115_MODE_CONTIN), 5, unexpected_value);
  318. ads_ctrl->mode = mode;
  319. uint16_t os = mode == ADS1115_MODE_SINGLE ? ADS1115_OS_SINGLE : ADS1115_OS_NON;
  320. uint16_t comp = ADS1115_CQUE_NONE;
  321. // Parse optional parameters
  322. if (argc > 5) {
  323. // comparator or conversion count
  324. comp = luaL_checkinteger(L, 6);
  325. luaL_argcheck(L, (comp == ADS1115_CQUE_1CONV) || (comp == ADS1115_CQUE_2CONV) || (comp == ADS1115_CQUE_4CONV),
  326. 6, unexpected_value);
  327. uint16_t threshold_low = 0x7FFF;
  328. uint16_t threshold_hi = 0x8000;
  329. if (argc > 6) {
  330. // comparator thresholds
  331. threshold_low = luaL_checkinteger(L, 7);
  332. threshold_hi = luaL_checkinteger(L, 8);
  333. luaL_argcheck(L, (int16_t)threshold_low <= (int16_t)threshold_hi, 7, "threshold_low > threshold_hi");
  334. luaL_argcheck(L, get_value(gain, channel, &threshold_low), 7, unexpected_value);
  335. luaL_argcheck(L, get_value(gain, channel, &threshold_hi), 8, unexpected_value);
  336. }
  337. ads_ctrl->threshold_low = threshold_low;
  338. ads_ctrl->threshold_hi = threshold_hi;
  339. NODE_DBG("ads1115 low: %04x\n", threshold_low);
  340. NODE_DBG("ads1115 hi : %04x\n", threshold_hi);
  341. write_reg(ads_ctrl->i2c_addr, ADS1115_POINTER_THRESH_LOW, threshold_low);
  342. write_reg(ads_ctrl->i2c_addr, ADS1115_POINTER_THRESH_HI, threshold_hi);
  343. }
  344. ads_ctrl->comp = comp;
  345. uint16_t comparator_mode = ADS1115_CMODE_TRAD;
  346. if (argc == 9) {
  347. comparator_mode = luaL_checkinteger(L, 9);
  348. luaL_argcheck(L, (comparator_mode == ADS1115_CMODE_WINDOW) || (comparator_mode == ADS1115_CMODE_TRAD),
  349. 9, unexpected_value);
  350. }
  351. uint16_t config = (os | channel | gain | mode | samples | comparator_mode | ADS1115_CPOL_ACTVLOW | ADS1115_CLAT_NONLAT | comp);
  352. ads_ctrl->config = config;
  353. NODE_DBG("ads1115 config: %04x\n", ads_ctrl->config);
  354. write_reg(ads_ctrl->i2c_addr, ADS1115_POINTER_CONFIG, config);
  355. return 0;
  356. }
  357. // Read the conversion register from the ADC device
  358. // Lua: ads1115.device:startread(function(volt, voltdec, adc, sign) print(volt,voltdec,adc,sign) end)
  359. static int ads1115_lua_startread(lua_State *L) {
  360. ads_ctrl_ud_t *ads_ctrl = luaL_checkudata(L, 1, metatable_name);
  361. if (((ads_ctrl->comp == ADS1115_CQUE_1CONV) ||
  362. (ads_ctrl->comp == ADS1115_CQUE_2CONV) ||
  363. (ads_ctrl->comp == ADS1115_CQUE_4CONV)) &&
  364. (ads_ctrl->threshold_low == 0x7FFF) &&
  365. (ads_ctrl->threshold_hi == 0x8000)) {
  366. // conversion ready mode
  367. if (ads_ctrl->mode == ADS1115_MODE_SINGLE) {
  368. NODE_DBG("ads1115 trigger config: %04x", ads_ctrl->config);
  369. write_reg(ads_ctrl->i2c_addr, ADS1115_POINTER_CONFIG, ads_ctrl->config);
  370. }
  371. return 0;
  372. }
  373. luaL_argcheck(L, lua_isfunction(L, 2), 2, "Must be function");
  374. lua_pushvalue(L, 2);
  375. ads_ctrl->timer_ref = luaL_ref(L, LUA_REGISTRYINDEX);
  376. if (ads_ctrl->mode == ADS1115_MODE_SINGLE) {
  377. write_reg(ads_ctrl->i2c_addr, ADS1115_POINTER_CONFIG, ads_ctrl->config);
  378. }
  379. // Start a timer to wait until ADC conversion is done
  380. os_timer_disarm(&ads_ctrl->timer);
  381. os_timer_setfn(&ads_ctrl->timer, (os_timer_func_t *)ads1115_lua_readoutdone, (void *)ads_ctrl);
  382. int msec = 1; // ADS1115_DR_1600SPS, ADS1115_DR_2400SPS, ADS1115_DR_3300SPS
  383. switch (ads_ctrl->samples_value) {
  384. case ADS1115_DR_8SPS:
  385. msec = 150;
  386. break;
  387. case ADS1115_DR_16SPS:
  388. msec = 75;
  389. break;
  390. case ADS1115_DR_32SPS:
  391. msec = 35;
  392. break;
  393. case ADS1115_DR_64SPS:
  394. msec = 20;
  395. break;
  396. case ADS1115_DR_128SPS:
  397. msec = 10;
  398. break;
  399. case ADS1115_DR_250SPS:
  400. msec = 5;
  401. break;
  402. case ADS1115_DR_475SPS:
  403. case ADS1115_DR_490SPS:
  404. msec = 3;
  405. break;
  406. case ADS1115_DR_860SPS:
  407. case ADS1115_DR_920SPS:
  408. msec = 2;
  409. }
  410. os_timer_arm(&ads_ctrl->timer, msec, 0);
  411. return 0;
  412. }
  413. static void read_common(ads_ctrl_ud_t * ads_ctrl, uint16_t raw, lua_State *L) {
  414. double mvolt = get_mvolt(ads_ctrl->gain, raw);
  415. #ifdef LUA_NUMBER_INTEGRAL
  416. int sign;
  417. if (mvolt == 0) {
  418. sign = 0;
  419. } else if (mvolt > 0) {
  420. sign = 1;
  421. } else {
  422. sign = -1;
  423. }
  424. int uvolt;
  425. if (sign >= 0) {
  426. uvolt = (int)((mvolt - (int)mvolt) * 1000 + 0.5);
  427. } else {
  428. uvolt = -(int)((mvolt - (int)mvolt) * 1000 - 0.5);
  429. mvolt = -mvolt;
  430. }
  431. lua_pushnumber(L, mvolt);
  432. lua_pushinteger(L, uvolt);
  433. lua_pushinteger(L, raw);
  434. lua_pushinteger(L, sign);
  435. #else
  436. lua_pushnumber(L, mvolt);
  437. lua_pushnil(L);
  438. lua_pushinteger(L, raw);
  439. lua_pushnil(L);
  440. #endif
  441. }
  442. // adc conversion timer callback
  443. static int ads1115_lua_readoutdone(void * param) {
  444. ads_ctrl_ud_t * ads_ctrl = (ads_ctrl_ud_t *)param;
  445. uint16_t raw = read_reg(ads_ctrl->i2c_addr, ADS1115_POINTER_CONVERSION);
  446. lua_State *L = lua_getstate();
  447. os_timer_disarm(&ads_ctrl->timer);
  448. lua_rawgeti(L, LUA_REGISTRYINDEX, ads_ctrl->timer_ref);
  449. luaL_unref(L, LUA_REGISTRYINDEX, ads_ctrl->timer_ref);
  450. ads_ctrl->timer_ref = LUA_NOREF;
  451. read_common(ads_ctrl, raw, L);
  452. luaL_pcallx(L, 4, 0);
  453. }
  454. // Read the conversion register from the ADC device
  455. // Lua: volt,voltdec,adc,sign = ads1115.device:read()
  456. static int ads1115_lua_read(lua_State *L) {
  457. ads_ctrl_ud_t *ads_ctrl = luaL_checkudata(L, 1, metatable_name);
  458. uint16_t raw = read_reg(ads_ctrl->i2c_addr, ADS1115_POINTER_CONVERSION);
  459. read_common(ads_ctrl, raw, L);
  460. return 4;
  461. }
  462. #ifdef ADS1115_INCLUDE_TEST_FUNCTION
  463. // this function simulates conversion using raw value provided as argument
  464. // Lua: volt,volt_dec,adc,sign = ads1115.test_volt_conversion(-1)
  465. static int test_volt_conversion(lua_State *L) {
  466. ads_ctrl_ud_t *ads_ctrl = luaL_checkudata(L, 1, metatable_name);
  467. uint16_t raw = luaL_checkinteger(L, 2);
  468. read_common(ads_ctrl, raw, L);
  469. return 4;
  470. }
  471. #endif
  472. static int ads1115_lua_delete(lua_State *L) {
  473. ads_ctrl_ud_t *ads_ctrl = luaL_checkudata(L, 1, metatable_name);
  474. if (ads_ctrl->timer_ref != LUA_NOREF) {
  475. os_timer_disarm(&ads_ctrl->timer);
  476. luaL_unref(L, LUA_REGISTRYINDEX, ads_ctrl->timer_ref);
  477. }
  478. return 0;
  479. }
  480. LROT_BEGIN(ads1115, NULL, 0)
  481. LROT_FUNCENTRY( ads1115, ads1115_lua_register_1115 )
  482. LROT_FUNCENTRY( ads1015, ads1115_lua_register_1015 )
  483. LROT_FUNCENTRY( reset, ads1115_lua_reset )
  484. LROT_NUMENTRY( ADDR_GND, ADS1115_I2C_ADDR_GND )
  485. LROT_NUMENTRY( ADDR_VDD, ADS1115_I2C_ADDR_VDD )
  486. LROT_NUMENTRY( ADDR_SDA, ADS1115_I2C_ADDR_SDA )
  487. LROT_NUMENTRY( ADDR_SCL, ADS1115_I2C_ADDR_SCL )
  488. LROT_NUMENTRY( SINGLE_SHOT, ADS1115_MODE_SINGLE )
  489. LROT_NUMENTRY( CONTINUOUS, ADS1115_MODE_CONTIN )
  490. LROT_NUMENTRY( DIFF_0_1, ADS1115_MUX_DIFF_0_1 )
  491. LROT_NUMENTRY( DIFF_0_3, ADS1115_MUX_DIFF_0_3 )
  492. LROT_NUMENTRY( DIFF_1_3, ADS1115_MUX_DIFF_1_3 )
  493. LROT_NUMENTRY( DIFF_2_3, ADS1115_MUX_DIFF_2_3 )
  494. LROT_NUMENTRY( SINGLE_0, ADS1115_MUX_SINGLE_0 )
  495. LROT_NUMENTRY( SINGLE_1, ADS1115_MUX_SINGLE_1 )
  496. LROT_NUMENTRY( SINGLE_2, ADS1115_MUX_SINGLE_2 )
  497. LROT_NUMENTRY( SINGLE_3, ADS1115_MUX_SINGLE_3 )
  498. LROT_NUMENTRY( GAIN_6_144V, ADS1115_PGA_6_144V )
  499. LROT_NUMENTRY( GAIN_4_096V, ADS1115_PGA_4_096V )
  500. LROT_NUMENTRY( GAIN_2_048V, ADS1115_PGA_2_048V )
  501. LROT_NUMENTRY( GAIN_1_024V, ADS1115_PGA_1_024V )
  502. LROT_NUMENTRY( GAIN_0_512V, ADS1115_PGA_0_512V )
  503. LROT_NUMENTRY( GAIN_0_256V, ADS1115_PGA_0_256V )
  504. LROT_NUMENTRY( DR_8SPS, ADS1115_DR_8SPS )
  505. LROT_NUMENTRY( DR_16SPS, ADS1115_DR_16SPS )
  506. LROT_NUMENTRY( DR_32SPS, ADS1115_DR_32SPS )
  507. LROT_NUMENTRY( DR_64SPS, ADS1115_DR_64SPS )
  508. LROT_NUMENTRY( DR_128SPS, ADS1115_DR_128SPS )
  509. LROT_NUMENTRY( DR_250SPS, ADS1115_DR_250SPS )
  510. LROT_NUMENTRY( DR_475SPS, ADS1115_DR_475SPS )
  511. LROT_NUMENTRY( DR_490SPS, ADS1115_DR_490SPS )
  512. LROT_NUMENTRY( DR_860SPS, ADS1115_DR_860SPS )
  513. LROT_NUMENTRY( DR_920SPS, ADS1115_DR_920SPS )
  514. LROT_NUMENTRY( DR_1600SPS, ADS1115_DR_1600SPS )
  515. LROT_NUMENTRY( DR_2400SPS, ADS1115_DR_2400SPS )
  516. LROT_NUMENTRY( DR_3300SPS, ADS1115_DR_3300SPS )
  517. LROT_NUMENTRY( CONV_RDY_1, ADS1115_CQUE_1CONV )
  518. LROT_NUMENTRY( CONV_RDY_2, ADS1115_CQUE_2CONV )
  519. LROT_NUMENTRY( CONV_RDY_4, ADS1115_CQUE_4CONV )
  520. LROT_NUMENTRY( COMP_1CONV, ADS1115_CQUE_1CONV )
  521. LROT_NUMENTRY( COMP_2CONV, ADS1115_CQUE_2CONV )
  522. LROT_NUMENTRY( COMP_4CONV, ADS1115_CQUE_4CONV )
  523. LROT_NUMENTRY( CMODE_TRAD, ADS1115_CMODE_TRAD )
  524. LROT_NUMENTRY( CMODE_WINDOW, ADS1115_CMODE_WINDOW )
  525. LROT_END(ads1115, NULL, 0)
  526. LROT_BEGIN(ads1115_instance, NULL, LROT_MASK_GC_INDEX)
  527. LROT_TABENTRY( __index , ads1115_instance )
  528. LROT_FUNCENTRY( __gc, ads1115_lua_delete )
  529. LROT_FUNCENTRY( setting, ads1115_lua_setting )
  530. LROT_FUNCENTRY( startread, ads1115_lua_startread )
  531. LROT_FUNCENTRY( read, ads1115_lua_read )
  532. #ifdef ADS1115_INCLUDE_TEST_FUNCTION
  533. LROT_FUNCENTRY( test_volt_conversion, test_volt_conversion )
  534. #endif
  535. LROT_END(ads1115_instance, NULL, LROT_MASK_GC_INDEX)
  536. int luaopen_ads1115(lua_State *L) {
  537. luaL_rometatable(L, metatable_name, LROT_TABLEREF(ads1115_instance));
  538. return 0;
  539. }
  540. NODEMCU_MODULE(ADS1115, "ads1115", ads1115, luaopen_ads1115);