added support for ads1015 (#2231)
* ads1015 is supported, up to 4 devices can be connected at the same time * removed debug, updated documentation * changed to oop API * added __gc to handle active timer cleanup * reworked argument validation and error reporting * stack is no longer messed up after __del
This commit is contained in:
parent
ed56d949ee
commit
f87d68ff8f
|
@ -8,6 +8,14 @@
|
|||
#include "lauxlib.h"
|
||||
#include "platform.h"
|
||||
#include "osapi.h"
|
||||
#include "c_stdlib.h"
|
||||
|
||||
|
||||
//***************************************************************************
|
||||
// CHIP
|
||||
//***************************************************************************
|
||||
#define ADS1115_ADS1015 ( 15)
|
||||
#define ADS1115_ADS1115 (115)
|
||||
|
||||
//***************************************************************************
|
||||
// I2C ADDRESS DEFINITON
|
||||
|
@ -17,6 +25,7 @@
|
|||
#define ADS1115_I2C_ADDR_VDD (0x49)
|
||||
#define ADS1115_I2C_ADDR_SDA (0x4A)
|
||||
#define ADS1115_I2C_ADDR_SCL (0x4B)
|
||||
#define IS_I2C_ADDR_VALID(addr) (((addr) & 0xFC) == 0x48)
|
||||
|
||||
//***************************************************************************
|
||||
// POINTER REGISTER
|
||||
|
@ -47,6 +56,7 @@
|
|||
#define ADS1115_MUX_SINGLE_1 (0x5000) // Single-ended AIN1
|
||||
#define ADS1115_MUX_SINGLE_2 (0x6000) // Single-ended AIN2
|
||||
#define ADS1115_MUX_SINGLE_3 (0x7000) // Single-ended AIN3
|
||||
#define IS_CHANNEL_VALID(channel) (((channel) & 0x8FFF) == 0)
|
||||
|
||||
#define ADS1115_PGA_MASK (0x0E00)
|
||||
#define ADS1115_PGA_6_144V (0x0000) // +/-6.144V range = Gain 2/3
|
||||
|
@ -61,14 +71,19 @@
|
|||
#define ADS1115_MODE_SINGLE (0x0100) // Power-down single-shot mode (default)
|
||||
|
||||
#define ADS1115_DR_MASK (0x00E0)
|
||||
#define ADS1115_DR_8SPS (0x0000) // 8 samples per second
|
||||
#define ADS1115_DR_16SPS (0x0020) // 16 samples per second
|
||||
#define ADS1115_DR_32SPS (0x0040) // 32 samples per second
|
||||
#define ADS1115_DR_64SPS (0x0060) // 64 samples per second
|
||||
#define ADS1115_DR_128SPS (0x0080) // 128 samples per second (default)
|
||||
#define ADS1115_DR_250SPS (0x00A0) // 250 samples per second
|
||||
#define ADS1115_DR_475SPS (0x00C0) // 475 samples per second
|
||||
#define ADS1115_DR_860SPS (0x00E0) // 860 samples per second
|
||||
#define ADS1115_DR_8SPS ( 8)
|
||||
#define ADS1115_DR_16SPS ( 16)
|
||||
#define ADS1115_DR_32SPS ( 32)
|
||||
#define ADS1115_DR_64SPS ( 64)
|
||||
#define ADS1115_DR_128SPS ( 128)
|
||||
#define ADS1115_DR_250SPS ( 250)
|
||||
#define ADS1115_DR_475SPS ( 475)
|
||||
#define ADS1115_DR_490SPS ( 490)
|
||||
#define ADS1115_DR_860SPS ( 860)
|
||||
#define ADS1115_DR_920SPS ( 920)
|
||||
#define ADS1115_DR_1600SPS (1600)
|
||||
#define ADS1115_DR_2400SPS (2400)
|
||||
#define ADS1115_DR_3300SPS (3300)
|
||||
|
||||
#define ADS1115_CMODE_MASK (0x0010)
|
||||
#define ADS1115_CMODE_TRAD (0x0000) // Traditional comparator with hysteresis (default)
|
||||
|
@ -88,44 +103,51 @@
|
|||
#define ADS1115_CQUE_4CONV (0x0002) // Assert ALERT/RDY after four conversions
|
||||
#define ADS1115_CQUE_NONE (0x0003) // Disable the comparator and put ALERT/RDY in high state (default)
|
||||
|
||||
#define ADS1115_DEFAULT_CONFIG_REG (0x8583) // Config register value after reset
|
||||
|
||||
//***************************************************************************
|
||||
|
||||
static const uint8_t ads1115_i2c_id = 0;
|
||||
static const uint8_t general_i2c_addr = 0x00;
|
||||
static const uint8_t ads1115_i2c_reset = 0x06;
|
||||
static uint8_t ads1115_i2c_addr = ADS1115_I2C_ADDR_GND;
|
||||
static uint16_t ads1115_os = ADS1115_OS_SINGLE;
|
||||
static uint16_t ads1115_gain = ADS1115_PGA_6_144V;
|
||||
static uint16_t ads1115_samples = ADS1115_DR_128SPS;
|
||||
static uint16_t ads1115_channel = ADS1115_MUX_SINGLE_0;
|
||||
static uint16_t ads1115_comp = ADS1115_CQUE_NONE;
|
||||
static uint16_t ads1115_mode = ADS1115_MODE_SINGLE;
|
||||
static uint16_t ads1115_threshold_low = 0x8000;
|
||||
static uint16_t ads1115_threshold_hi = 0x7FFF;
|
||||
static uint16_t ads1115_config = 0x8583;
|
||||
static uint16_t ads1115_conversion = 0;
|
||||
static double ads1115_volt = 0;
|
||||
os_timer_t ads1115_timer; // timer for conversion delay
|
||||
int ads1115_timer_ref; // callback when readout is ready
|
||||
static const char metatable_name[] = "ads1115.device";
|
||||
static const char unexpected_value[] = "unexpected value";
|
||||
|
||||
static int ads1115_lua_readoutdone(void);
|
||||
typedef struct {
|
||||
uint8_t i2c_addr;
|
||||
uint8_t chip_id;
|
||||
uint16_t gain;
|
||||
uint16_t samples_value; // sample per second
|
||||
uint16_t samples; // register value
|
||||
uint16_t comp;
|
||||
uint16_t mode;
|
||||
uint16_t threshold_low;
|
||||
uint16_t threshold_hi;
|
||||
uint16_t config;
|
||||
int timer_ref;
|
||||
os_timer_t timer;
|
||||
} ads_ctrl_ud_t;
|
||||
|
||||
static uint8_t write_reg(uint8_t reg, uint16_t config) {
|
||||
|
||||
static int ads1115_lua_readoutdone(void * param);
|
||||
static int ads1115_lua_register(lua_State *L, uint8_t chip_id);
|
||||
|
||||
static uint8_t write_reg(uint8_t ads_addr, uint8_t reg, uint16_t config) {
|
||||
platform_i2c_send_start(ads1115_i2c_id);
|
||||
platform_i2c_send_address(ads1115_i2c_id, ads1115_i2c_addr, PLATFORM_I2C_DIRECTION_TRANSMITTER);
|
||||
platform_i2c_send_address(ads1115_i2c_id, ads_addr, PLATFORM_I2C_DIRECTION_TRANSMITTER);
|
||||
platform_i2c_send_byte(ads1115_i2c_id, reg);
|
||||
platform_i2c_send_byte(ads1115_i2c_id, (uint8_t)(config >> 8));
|
||||
platform_i2c_send_byte(ads1115_i2c_id, (uint8_t)(config & 0xFF));
|
||||
platform_i2c_send_stop(ads1115_i2c_id);
|
||||
}
|
||||
|
||||
static uint16_t read_reg(uint8_t reg) {
|
||||
static uint16_t read_reg(uint8_t ads_addr, uint8_t reg) {
|
||||
platform_i2c_send_start(ads1115_i2c_id);
|
||||
platform_i2c_send_address(ads1115_i2c_id, ads1115_i2c_addr, PLATFORM_I2C_DIRECTION_TRANSMITTER);
|
||||
platform_i2c_send_address(ads1115_i2c_id, ads_addr, PLATFORM_I2C_DIRECTION_TRANSMITTER);
|
||||
platform_i2c_send_byte(ads1115_i2c_id, reg);
|
||||
platform_i2c_send_stop(ads1115_i2c_id);
|
||||
platform_i2c_send_start(ads1115_i2c_id);
|
||||
platform_i2c_send_address(ads1115_i2c_id, ads1115_i2c_addr, PLATFORM_I2C_DIRECTION_RECEIVER);
|
||||
platform_i2c_send_address(ads1115_i2c_id, ads_addr, PLATFORM_I2C_DIRECTION_RECEIVER);
|
||||
uint16_t buf = (platform_i2c_recv_byte(ads1115_i2c_id, 1) << 8);
|
||||
buf += platform_i2c_recv_byte(ads1115_i2c_id, 0);
|
||||
platform_i2c_send_stop(ads1115_i2c_id);
|
||||
|
@ -133,11 +155,11 @@ static uint16_t read_reg(uint8_t reg) {
|
|||
}
|
||||
|
||||
// convert ADC value to voltage corresponding to PGA settings
|
||||
static double get_volt(uint16_t value) {
|
||||
static double get_volt(uint16_t gain, uint16_t value) {
|
||||
|
||||
double volt = 0;
|
||||
|
||||
switch (ads1115_gain) {
|
||||
switch (gain) {
|
||||
case (ADS1115_PGA_6_144V):
|
||||
volt = (int16_t)value * 0.1875;
|
||||
break;
|
||||
|
@ -161,224 +183,293 @@ static double get_volt(uint16_t value) {
|
|||
return volt;
|
||||
}
|
||||
|
||||
// convert threshold in volt to ADC value corresponding to PGA settings
|
||||
static uint8_t get_value(int16_t *volt) {
|
||||
|
||||
switch (ads1115_gain) {
|
||||
// validates and convert threshold in volt to ADC value corresponding to PGA settings
|
||||
// returns true if valid
|
||||
static uint8_t get_value(uint16_t gain, uint16_t channel, int16_t *volt) {
|
||||
switch (gain) {
|
||||
case (ADS1115_PGA_6_144V):
|
||||
if ((*volt >= 6144) || (*volt < -6144) || ((*volt < 0) && (ads1115_channel >> 14))) return 1;
|
||||
if ((*volt >= 6144) || (*volt < -6144) || ((*volt < 0) && (channel >> 14))) return 0;
|
||||
*volt = *volt / 0.1875;
|
||||
break;
|
||||
case (ADS1115_PGA_4_096V):
|
||||
if ((*volt >= 4096) || (*volt < -4096) || ((*volt < 0) && (ads1115_channel >> 14))) return 1;
|
||||
if ((*volt >= 4096) || (*volt < -4096) || ((*volt < 0) && (channel >> 14))) return 0;
|
||||
*volt = *volt / 0.125;
|
||||
break;
|
||||
case (ADS1115_PGA_2_048V):
|
||||
if ((*volt >= 2048) || (*volt < -2048) || ((*volt < 0) && (ads1115_channel >> 14))) return 1;
|
||||
if ((*volt >= 2048) || (*volt < -2048) || ((*volt < 0) && (channel >> 14))) return 0;
|
||||
*volt = *volt / 0.0625;
|
||||
break;
|
||||
case (ADS1115_PGA_1_024V):
|
||||
if ((*volt >= 1024) || (*volt < -1024) || ((*volt < 0) && (ads1115_channel >> 14))) return 1;
|
||||
if ((*volt >= 1024) || (*volt < -1024) || ((*volt < 0) && (channel >> 14))) return 0;
|
||||
*volt = *volt / 0.03125;
|
||||
break;
|
||||
case (ADS1115_PGA_0_512V):
|
||||
if ((*volt >= 512) || (*volt < -512) || ((*volt < 0) && (ads1115_channel >> 14))) return 1;
|
||||
if ((*volt >= 512) || (*volt < -512) || ((*volt < 0) && (channel >> 14))) return 0;
|
||||
*volt = *volt / 0.015625;
|
||||
break;
|
||||
case (ADS1115_PGA_0_256V):
|
||||
if ((*volt >= 256) || (*volt < -256) || ((*volt < 0) && (ads1115_channel >> 14))) return 1;
|
||||
if ((*volt >= 256) || (*volt < -256) || ((*volt < 0) && (channel >> 14))) return 0;
|
||||
*volt = *volt / 0.0078125;
|
||||
break;
|
||||
}
|
||||
|
||||
return 0;
|
||||
return 1;
|
||||
}
|
||||
|
||||
// Initializes ADC
|
||||
// Lua: ads11115.setup(ADDRESS)
|
||||
static int ads1115_lua_setup(lua_State *L) {
|
||||
|
||||
// check variables
|
||||
if (!lua_isnumber(L, 1)) {
|
||||
return luaL_error(L, "wrong arg range");
|
||||
}
|
||||
|
||||
ads1115_i2c_addr = luaL_checkinteger(L, 1);
|
||||
if (!((ads1115_i2c_addr == ADS1115_I2C_ADDR_GND) || (ads1115_i2c_addr == ADS1115_I2C_ADDR_VDD) || (ads1115_i2c_addr == ADS1115_I2C_ADDR_SDA) || (ads1115_i2c_addr == ADS1115_I2C_ADDR_SCL))) {
|
||||
return luaL_error(L, "Invalid argument: adddress");
|
||||
}
|
||||
|
||||
// Reset of all devices
|
||||
// Lua: ads1115.reset()
|
||||
static int ads1115_lua_reset(lua_State *L) {
|
||||
platform_i2c_send_start(ads1115_i2c_id);
|
||||
platform_i2c_send_address(ads1115_i2c_id, general_i2c_addr, PLATFORM_I2C_DIRECTION_TRANSMITTER);
|
||||
platform_i2c_send_byte(ads1115_i2c_id, ads1115_i2c_reset);
|
||||
platform_i2c_send_stop(ads1115_i2c_id);
|
||||
return 0;
|
||||
}
|
||||
|
||||
// check for device on i2c bus
|
||||
if (read_reg(ADS1115_POINTER_CONFIG) != 0x8583) {
|
||||
// Register an ADS device
|
||||
// Lua: ads1115.ADS1115(I2C_ID, ADDRESS)
|
||||
static int ads1115_lua_register_1115(lua_State *L) {
|
||||
return ads1115_lua_register(L, ADS1115_ADS1115);
|
||||
}
|
||||
|
||||
static int ads1115_lua_register_1015(lua_State *L) {
|
||||
return ads1115_lua_register(L, ADS1115_ADS1015);
|
||||
}
|
||||
|
||||
static int ads1115_lua_register(lua_State *L, uint8_t chip_id) {
|
||||
uint8_t i2c_id = luaL_checkinteger(L, 1);
|
||||
luaL_argcheck(L, 0 == i2c_id, 1, "i2c_id must be 0");
|
||||
uint8_t i2c_addr = luaL_checkinteger(L, 2);
|
||||
luaL_argcheck(L, IS_I2C_ADDR_VALID(i2c_addr), 2, unexpected_value);
|
||||
uint16_t config_read = read_reg(i2c_addr, ADS1115_POINTER_CONFIG);
|
||||
if (config_read == 0xFFFF) {
|
||||
return luaL_error(L, "found no device");
|
||||
}
|
||||
|
||||
return 0;
|
||||
if (config_read != ADS1115_DEFAULT_CONFIG_REG) {
|
||||
return luaL_error(L, "unexpected config value (%p) please reset device before calling this function", config_read);
|
||||
}
|
||||
ads_ctrl_ud_t *ads_ctrl = (ads_ctrl_ud_t *)lua_newuserdata(L, sizeof(ads_ctrl_ud_t));
|
||||
if (NULL == ads_ctrl) {
|
||||
return luaL_error(L, "ads1115 malloc: out of memory");
|
||||
}
|
||||
luaL_getmetatable(L, metatable_name);
|
||||
lua_setmetatable(L, -2);
|
||||
ads_ctrl->chip_id = chip_id;
|
||||
ads_ctrl->i2c_addr = i2c_addr;
|
||||
ads_ctrl->gain = ADS1115_PGA_6_144V;
|
||||
ads_ctrl->samples = ADS1115_DR_128SPS;
|
||||
ads_ctrl->samples_value = chip_id == ADS1115_ADS1115 ? 128 : 1600;
|
||||
ads_ctrl->comp = ADS1115_CQUE_NONE;
|
||||
ads_ctrl->mode = ADS1115_MODE_SINGLE;
|
||||
ads_ctrl->threshold_low = 0x8000;
|
||||
ads_ctrl->threshold_hi = 0x7FFF;
|
||||
ads_ctrl->config = ADS1115_DEFAULT_CONFIG_REG;
|
||||
ads_ctrl->timer_ref = LUA_NOREF;
|
||||
return 1;
|
||||
}
|
||||
|
||||
// Change ADC settings
|
||||
// Lua: ads1115.setting(GAIN,SAMPLES,CHANNEL,MODE[,CONVERSION_RDY][,COMPARATOR,THRESHOLD_LOW,THRESHOLD_HI])
|
||||
// Change the ADC device settings
|
||||
// Lua: ads1115.device:settings(GAIN,SAMPLES,CHANNEL,MODE[,CONVERSION_RDY][,COMPARATOR,THRESHOLD_LOW,THRESHOLD_HI[,COMP_MODE])
|
||||
static int ads1115_lua_setting(lua_State *L) {
|
||||
|
||||
// check variables
|
||||
if (!lua_isnumber(L, 1) || !lua_isnumber(L, 2) || !lua_isnumber(L, 3) || !lua_isnumber(L, 4)) {
|
||||
return luaL_error(L, "wrong arg range");
|
||||
int argc = lua_gettop(L);
|
||||
if (argc != 5 && argc != 6 && argc != 8 && argc != 9) { // user data counts
|
||||
luaL_error(L, "invalid number of arguments to 'setting'");
|
||||
}
|
||||
|
||||
ads1115_gain = luaL_checkinteger(L, 1);
|
||||
if (!((ads1115_gain == ADS1115_PGA_6_144V) || (ads1115_gain == ADS1115_PGA_4_096V) || (ads1115_gain == ADS1115_PGA_2_048V) || (ads1115_gain == ADS1115_PGA_1_024V) || (ads1115_gain == ADS1115_PGA_0_512V) || (ads1115_gain == ADS1115_PGA_0_256V))) {
|
||||
return luaL_error(L, "Invalid argument: gain");
|
||||
ads_ctrl_ud_t *ads_ctrl = luaL_checkudata(L, 1, metatable_name);
|
||||
// gain
|
||||
uint16_t gain = luaL_checkinteger(L, 2);
|
||||
luaL_argcheck(L, (gain == ADS1115_PGA_6_144V) || (gain == ADS1115_PGA_4_096V) || (gain == ADS1115_PGA_2_048V) ||
|
||||
(gain == ADS1115_PGA_1_024V) || (gain == ADS1115_PGA_0_512V) || (gain == ADS1115_PGA_0_256V),
|
||||
2, unexpected_value);
|
||||
ads_ctrl->gain = gain;
|
||||
// samples
|
||||
uint16_t samples_value = luaL_checkinteger(L, 3);
|
||||
uint16_t samples = 0;
|
||||
if (ads_ctrl->chip_id == ADS1115_ADS1115) {
|
||||
switch(samples_value) {
|
||||
case ADS1115_DR_8SPS:
|
||||
samples = 0;
|
||||
break;
|
||||
case ADS1115_DR_16SPS:
|
||||
samples = 0x20;
|
||||
break;
|
||||
case ADS1115_DR_32SPS:
|
||||
samples = 0x40;
|
||||
break;
|
||||
case ADS1115_DR_64SPS:
|
||||
samples = 0x60;
|
||||
break;
|
||||
case ADS1115_DR_128SPS: // default
|
||||
samples = 0x80;
|
||||
break;
|
||||
case ADS1115_DR_250SPS:
|
||||
samples = 0xA0;
|
||||
break;
|
||||
case ADS1115_DR_475SPS:
|
||||
samples = 0xC0;
|
||||
break;
|
||||
case ADS1115_DR_860SPS:
|
||||
samples = 0xE0;
|
||||
break;
|
||||
default:
|
||||
luaL_argerror(L, 3, unexpected_value);
|
||||
}
|
||||
|
||||
ads1115_samples = luaL_checkinteger(L, 2);
|
||||
if (!((ads1115_samples == ADS1115_DR_8SPS) || (ads1115_samples == ADS1115_DR_16SPS) || (ads1115_samples == ADS1115_DR_32SPS) || (ads1115_samples == ADS1115_DR_64SPS) || (ads1115_samples == ADS1115_DR_128SPS) || (ads1115_samples == ADS1115_DR_250SPS) || (ads1115_samples == ADS1115_DR_475SPS) || (ads1115_samples == ADS1115_DR_860SPS))) {
|
||||
return luaL_error(L, "Invalid argument: samples");
|
||||
} else { // ADS1115_ADS1015
|
||||
switch(samples_value) {
|
||||
case ADS1115_DR_128SPS:
|
||||
samples = 0;
|
||||
break;
|
||||
case ADS1115_DR_250SPS:
|
||||
samples = 0x20;
|
||||
break;
|
||||
case ADS1115_DR_490SPS:
|
||||
samples = 0x40;
|
||||
break;
|
||||
case ADS1115_DR_920SPS:
|
||||
samples = 0x60;
|
||||
break;
|
||||
case ADS1115_DR_1600SPS: // default
|
||||
samples = 0x80;
|
||||
break;
|
||||
case ADS1115_DR_2400SPS:
|
||||
samples = 0xA0;
|
||||
break;
|
||||
case ADS1115_DR_3300SPS:
|
||||
samples = 0xC0;
|
||||
break;
|
||||
default:
|
||||
luaL_argerror(L, 3, unexpected_value);
|
||||
}
|
||||
|
||||
ads1115_channel = luaL_checkinteger(L, 3);
|
||||
if (!((ads1115_channel == ADS1115_MUX_SINGLE_0) || (ads1115_channel == ADS1115_MUX_SINGLE_1) || (ads1115_channel == ADS1115_MUX_SINGLE_2) || (ads1115_channel == ADS1115_MUX_SINGLE_3) || (ads1115_channel == ADS1115_MUX_DIFF_0_1) || (ads1115_channel == ADS1115_MUX_DIFF_0_3) || (ads1115_channel == ADS1115_MUX_DIFF_1_3) || (ads1115_channel == ADS1115_MUX_DIFF_2_3))) {
|
||||
return luaL_error(L, "Invalid argument: channel");
|
||||
}
|
||||
ads_ctrl->samples = samples;
|
||||
ads_ctrl->samples_value = samples_value;
|
||||
// channel
|
||||
uint16_t channel = luaL_checkinteger(L, 4);
|
||||
luaL_argcheck(L, IS_CHANNEL_VALID(channel), 4, unexpected_value);
|
||||
// mode
|
||||
uint16_t mode = luaL_checkinteger(L, 5);
|
||||
luaL_argcheck(L, (mode == ADS1115_MODE_SINGLE) || (mode == ADS1115_MODE_CONTIN), 5, unexpected_value);
|
||||
ads_ctrl->mode = mode;
|
||||
uint16_t os = mode == ADS1115_MODE_SINGLE ? ADS1115_OS_SINGLE : ADS1115_OS_NON;
|
||||
|
||||
ads1115_mode = luaL_checkinteger(L, 4);
|
||||
if (!((ads1115_mode == ADS1115_MODE_SINGLE) || (ads1115_mode == ADS1115_MODE_CONTIN))) {
|
||||
return luaL_error(L, "Invalid argument: mode");
|
||||
}
|
||||
|
||||
if (ads1115_mode == ADS1115_MODE_SINGLE) {
|
||||
ads1115_os = ADS1115_OS_SINGLE;
|
||||
} else {
|
||||
ads1115_os = ADS1115_OS_NON;
|
||||
}
|
||||
|
||||
ads1115_comp = ADS1115_CQUE_NONE;
|
||||
|
||||
uint16_t comp = ADS1115_CQUE_NONE;
|
||||
// Parse optional parameters
|
||||
if (lua_isnumber(L, 5) && !(lua_isnumber(L, 6) || lua_isnumber(L, 7))) {
|
||||
if (argc > 5) {
|
||||
// comparator or conversion count
|
||||
comp = luaL_checkinteger(L, 6);
|
||||
luaL_argcheck(L, (comp == ADS1115_CQUE_1CONV) || (comp == ADS1115_CQUE_2CONV) || (comp == ADS1115_CQUE_4CONV),
|
||||
6, unexpected_value);
|
||||
uint16_t threshold_low = 0x7FFF;
|
||||
uint16_t threshold_hi = 0x8000;
|
||||
if (argc > 6) {
|
||||
// comparator thresholds
|
||||
threshold_low = luaL_checkinteger(L, 7);
|
||||
threshold_hi = luaL_checkinteger(L, 8);
|
||||
luaL_argcheck(L, (int16_t)threshold_low <= (int16_t)threshold_hi, 7, "threshold_low > threshold_hi");
|
||||
luaL_argcheck(L, get_value(gain, channel, &threshold_low), 7, unexpected_value);
|
||||
luaL_argcheck(L, get_value(gain, channel, &threshold_hi), 8, unexpected_value);
|
||||
}
|
||||
ads_ctrl->threshold_low = threshold_low;
|
||||
ads_ctrl->threshold_hi = threshold_hi;
|
||||
NODE_DBG("ads1115 low: %04x\n", threshold_low);
|
||||
NODE_DBG("ads1115 hi : %04x\n", threshold_hi);
|
||||
write_reg(ads_ctrl->i2c_addr, ADS1115_POINTER_THRESH_LOW, threshold_low);
|
||||
write_reg(ads_ctrl->i2c_addr, ADS1115_POINTER_THRESH_HI, threshold_hi);
|
||||
}
|
||||
ads_ctrl->comp = comp;
|
||||
|
||||
// conversion ready mode
|
||||
ads1115_comp = luaL_checkinteger(L, 5);
|
||||
if (!((ads1115_comp == ADS1115_CQUE_1CONV) || (ads1115_comp == ADS1115_CQUE_2CONV) || (ads1115_comp == ADS1115_CQUE_4CONV))) {
|
||||
return luaL_error(L, "Invalid argument: conversion ready mode");
|
||||
uint16_t comparator_mode = ADS1115_CMODE_TRAD;
|
||||
if (argc == 9) {
|
||||
comparator_mode = luaL_checkinteger(L, 9);
|
||||
luaL_argcheck(L, (comparator_mode == ADS1115_CMODE_WINDOW) || (comparator_mode == ADS1115_CMODE_TRAD),
|
||||
9, unexpected_value);
|
||||
}
|
||||
|
||||
ads1115_threshold_low = 0x7FFF;
|
||||
ads1115_threshold_hi = 0x8000;
|
||||
|
||||
write_reg(ADS1115_POINTER_THRESH_LOW, ads1115_threshold_low);
|
||||
write_reg(ADS1115_POINTER_THRESH_HI, ads1115_threshold_hi);
|
||||
|
||||
} else if (lua_isnumber(L, 5) && lua_isnumber(L, 6) && lua_isnumber(L, 7)) {
|
||||
|
||||
// comparator mode
|
||||
ads1115_comp = luaL_checkinteger(L, 5);
|
||||
if (!((ads1115_comp == ADS1115_CQUE_1CONV) || (ads1115_comp == ADS1115_CQUE_2CONV) || (ads1115_comp == ADS1115_CQUE_4CONV))) {
|
||||
return luaL_error(L, "Invalid argument: comparator mode");
|
||||
}
|
||||
|
||||
ads1115_threshold_low = luaL_checkinteger(L, 5);
|
||||
ads1115_threshold_hi = luaL_checkinteger(L, 6);
|
||||
|
||||
if ((int16_t)ads1115_threshold_low > (int16_t)ads1115_threshold_hi) {
|
||||
return luaL_error(L, "Invalid argument: threshold_low > threshold_hi");
|
||||
}
|
||||
|
||||
if (get_value(&ads1115_threshold_low)) {
|
||||
return luaL_error(L, "Invalid argument: threshold_low");
|
||||
}
|
||||
|
||||
if (get_value(&ads1115_threshold_hi)) {
|
||||
return luaL_error(L, "Invalid argument: threshold_hi");
|
||||
}
|
||||
|
||||
write_reg(ADS1115_POINTER_THRESH_LOW, ads1115_threshold_low);
|
||||
write_reg(ADS1115_POINTER_THRESH_HI, ads1115_threshold_hi);
|
||||
|
||||
}
|
||||
|
||||
ads1115_config = (ads1115_os | ads1115_channel | ads1115_gain | ads1115_mode | ads1115_samples | ADS1115_CMODE_TRAD | ADS1115_CPOL_ACTVLOW | ADS1115_CLAT_NONLAT | ads1115_comp);
|
||||
|
||||
write_reg(ADS1115_POINTER_CONFIG, ads1115_config);
|
||||
uint16_t config = (os | channel | gain | mode | samples | comparator_mode | ADS1115_CPOL_ACTVLOW | ADS1115_CLAT_NONLAT | comp);
|
||||
ads_ctrl->config = config;
|
||||
|
||||
NODE_DBG("ads1115 config: %04x\n", ads_ctrl->config);
|
||||
write_reg(ads_ctrl->i2c_addr, ADS1115_POINTER_CONFIG, config);
|
||||
return 0;
|
||||
}
|
||||
|
||||
// Read the conversion register from the ADC
|
||||
// Lua: ads1115.startread(function(volt, voltdec, adc) print(volt,voltdec,adc) end)
|
||||
// Read the conversion register from the ADC device
|
||||
// Lua: ads1115.device:startread(function(volt, voltdec, adc) print(volt,voltdec,adc) end)
|
||||
static int ads1115_lua_startread(lua_State *L) {
|
||||
ads_ctrl_ud_t *ads_ctrl = luaL_checkudata(L, 1, metatable_name);
|
||||
|
||||
if (((ads1115_comp == ADS1115_CQUE_1CONV) || (ads1115_comp == ADS1115_CQUE_2CONV) || (ads1115_comp == ADS1115_CQUE_4CONV)) && (ads1115_threshold_low == 0x7FFF) && (ads1115_threshold_hi == 0x8000)) {
|
||||
|
||||
if (ads1115_mode == ADS1115_MODE_SINGLE) {
|
||||
write_reg(ADS1115_POINTER_CONFIG, ads1115_config);
|
||||
if (((ads_ctrl->comp == ADS1115_CQUE_1CONV) ||
|
||||
(ads_ctrl->comp == ADS1115_CQUE_2CONV) ||
|
||||
(ads_ctrl->comp == ADS1115_CQUE_4CONV)) &&
|
||||
(ads_ctrl->threshold_low == 0x7FFF) &&
|
||||
(ads_ctrl->threshold_hi == 0x8000)) {
|
||||
// conversion ready mode
|
||||
if (ads_ctrl->mode == ADS1115_MODE_SINGLE) {
|
||||
NODE_DBG("ads1115 trigger config: %04x", ads_ctrl->config);
|
||||
write_reg(ads_ctrl->i2c_addr, ADS1115_POINTER_CONFIG, ads_ctrl->config);
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
|
||||
return 0;
|
||||
luaL_argcheck(L, (lua_type(L, 2) == LUA_TFUNCTION || lua_type(L, 2) == LUA_TLIGHTFUNCTION), 2, "Must be function");
|
||||
lua_pushvalue(L, 2);
|
||||
ads_ctrl->timer_ref = luaL_ref(L, LUA_REGISTRYINDEX);
|
||||
|
||||
} else {
|
||||
|
||||
luaL_argcheck(L, (lua_type(L, 1) == LUA_TFUNCTION || lua_type(L, 1) == LUA_TLIGHTFUNCTION), 1, "Must be function");
|
||||
lua_pushvalue(L, 1);
|
||||
ads1115_timer_ref = luaL_ref(L, LUA_REGISTRYINDEX);
|
||||
|
||||
if (ads1115_mode == ADS1115_MODE_SINGLE) {
|
||||
write_reg(ADS1115_POINTER_CONFIG, ads1115_config);
|
||||
if (ads_ctrl->mode == ADS1115_MODE_SINGLE) {
|
||||
write_reg(ads_ctrl->i2c_addr, ADS1115_POINTER_CONFIG, ads_ctrl->config);
|
||||
}
|
||||
|
||||
// Start a timer to wait until ADC conversion is done
|
||||
os_timer_disarm (&ads1115_timer);
|
||||
os_timer_setfn (&ads1115_timer, (os_timer_func_t *)ads1115_lua_readoutdone, NULL);
|
||||
os_timer_disarm(&ads_ctrl->timer);
|
||||
os_timer_setfn(&ads_ctrl->timer, (os_timer_func_t *)ads1115_lua_readoutdone, (void *)ads_ctrl);
|
||||
|
||||
switch (ads1115_samples) {
|
||||
case (ADS1115_DR_8SPS):
|
||||
os_timer_arm (&ads1115_timer, 150, 0);
|
||||
int msec = 1; // ADS1115_DR_1600SPS, ADS1115_DR_2400SPS, ADS1115_DR_3300SPS
|
||||
switch (ads_ctrl->samples_value) {
|
||||
case ADS1115_DR_8SPS:
|
||||
msec = 150;
|
||||
break;
|
||||
case (ADS1115_DR_16SPS):
|
||||
os_timer_arm (&ads1115_timer, 75, 0);
|
||||
case ADS1115_DR_16SPS:
|
||||
msec = 75;
|
||||
break;
|
||||
case (ADS1115_DR_32SPS):
|
||||
os_timer_arm (&ads1115_timer, 35, 0);
|
||||
case ADS1115_DR_32SPS:
|
||||
msec = 35;
|
||||
break;
|
||||
case (ADS1115_DR_64SPS):
|
||||
os_timer_arm (&ads1115_timer, 20, 0);
|
||||
case ADS1115_DR_64SPS:
|
||||
msec = 20;
|
||||
break;
|
||||
case (ADS1115_DR_128SPS):
|
||||
os_timer_arm (&ads1115_timer, 10, 0);
|
||||
case ADS1115_DR_128SPS:
|
||||
msec = 10;
|
||||
break;
|
||||
case (ADS1115_DR_250SPS):
|
||||
os_timer_arm (&ads1115_timer, 5, 0);
|
||||
case ADS1115_DR_250SPS:
|
||||
msec = 5;
|
||||
break;
|
||||
case (ADS1115_DR_475SPS):
|
||||
os_timer_arm (&ads1115_timer, 3, 0);
|
||||
break;
|
||||
case (ADS1115_DR_860SPS):
|
||||
os_timer_arm (&ads1115_timer, 2, 0);
|
||||
case ADS1115_DR_475SPS:
|
||||
case ADS1115_DR_490SPS:
|
||||
msec = 3;
|
||||
break;
|
||||
case ADS1115_DR_860SPS:
|
||||
case ADS1115_DR_920SPS:
|
||||
msec = 2;
|
||||
}
|
||||
|
||||
os_timer_arm(&ads_ctrl->timer, msec, 0);
|
||||
return 0;
|
||||
}
|
||||
}
|
||||
|
||||
// adc conversion timer callback
|
||||
static int ads1115_lua_readoutdone(void) {
|
||||
static int ads1115_lua_readoutdone(void * param) {
|
||||
ads_ctrl_ud_t * ads_ctrl = (ads_ctrl_ud_t *)param;
|
||||
|
||||
ads1115_conversion = read_reg(ADS1115_POINTER_CONVERSION);
|
||||
ads1115_volt = get_volt(ads1115_conversion);
|
||||
uint16_t ads1115_conversion = read_reg(ads_ctrl->i2c_addr, ADS1115_POINTER_CONVERSION);
|
||||
double ads1115_volt = get_volt(ads_ctrl->gain, ads1115_conversion);
|
||||
int ads1115_voltdec = (int)((ads1115_volt - (int)ads1115_volt) * 1000);
|
||||
ads1115_voltdec = ads1115_voltdec > 0 ? ads1115_voltdec : 0 - ads1115_voltdec;
|
||||
|
||||
lua_State *L = lua_getstate();
|
||||
os_timer_disarm (&ads1115_timer);
|
||||
os_timer_disarm(&ads_ctrl->timer);
|
||||
|
||||
lua_rawgeti (L, LUA_REGISTRYINDEX, ads1115_timer_ref);
|
||||
luaL_unref (L, LUA_REGISTRYINDEX, ads1115_timer_ref);
|
||||
ads1115_timer_ref = LUA_NOREF;
|
||||
lua_rawgeti(L, LUA_REGISTRYINDEX, ads_ctrl->timer_ref);
|
||||
luaL_unref(L, LUA_REGISTRYINDEX, ads_ctrl->timer_ref);
|
||||
ads_ctrl->timer_ref = LUA_NOREF;
|
||||
|
||||
lua_pushnumber(L, ads1115_volt);
|
||||
lua_pushinteger(L, ads1115_voltdec);
|
||||
|
@ -387,12 +478,13 @@ static int ads1115_lua_readoutdone(void) {
|
|||
lua_call(L, 3, 0);
|
||||
}
|
||||
|
||||
// Read the conversion register from the ADC
|
||||
// Lua: volt,voltdec,adc = ads1115.read()
|
||||
// Read the conversion register from the ADC device
|
||||
// Lua: volt,voltdec,adc = ads1115.device:read()
|
||||
static int ads1115_lua_read(lua_State *L) {
|
||||
ads_ctrl_ud_t *ads_ctrl = luaL_checkudata(L, 1, metatable_name);
|
||||
|
||||
ads1115_conversion = read_reg(ADS1115_POINTER_CONVERSION);
|
||||
ads1115_volt = get_volt(ads1115_conversion);
|
||||
uint16_t ads1115_conversion = read_reg(ads_ctrl->i2c_addr, ADS1115_POINTER_CONVERSION);
|
||||
double ads1115_volt = get_volt(ads_ctrl->gain, ads1115_conversion);
|
||||
int ads1115_voltdec = (int)((ads1115_volt - (int)ads1115_volt) * 1000);
|
||||
ads1115_voltdec = ads1115_voltdec > 0 ? ads1115_voltdec : 0 - ads1115_voltdec;
|
||||
|
||||
|
@ -403,11 +495,20 @@ static int ads1115_lua_read(lua_State *L) {
|
|||
return 3;
|
||||
}
|
||||
|
||||
static int ads1115_lua_delete(lua_State *L) {
|
||||
ads_ctrl_ud_t *ads_ctrl = luaL_checkudata(L, 1, metatable_name);
|
||||
if (ads_ctrl->timer_ref != LUA_NOREF) {
|
||||
os_timer_disarm(&ads_ctrl->timer);
|
||||
luaL_unref(L, LUA_REGISTRYINDEX, ads_ctrl->timer_ref);
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
|
||||
static const LUA_REG_TYPE ads1115_map[] = {
|
||||
{ LSTRKEY( "setup" ), LFUNCVAL(ads1115_lua_setup) },
|
||||
{ LSTRKEY( "setting" ), LFUNCVAL(ads1115_lua_setting) },
|
||||
{ LSTRKEY( "startread" ), LFUNCVAL(ads1115_lua_startread) },
|
||||
{ LSTRKEY( "read" ), LFUNCVAL(ads1115_lua_read) },
|
||||
|
||||
{ LSTRKEY( "ads1115" ), LFUNCVAL(ads1115_lua_register_1115) },
|
||||
{ LSTRKEY( "ads1015" ), LFUNCVAL(ads1115_lua_register_1015) },
|
||||
{ LSTRKEY( "reset" ), LFUNCVAL(ads1115_lua_reset) },
|
||||
{ LSTRKEY( "ADDR_GND" ), LNUMVAL(ADS1115_I2C_ADDR_GND) },
|
||||
{ LSTRKEY( "ADDR_VDD" ), LNUMVAL(ADS1115_I2C_ADDR_VDD) },
|
||||
{ LSTRKEY( "ADDR_SDA" ), LNUMVAL(ADS1115_I2C_ADDR_SDA) },
|
||||
|
@ -435,14 +536,36 @@ static const LUA_REG_TYPE ads1115_map[] = {
|
|||
{ LSTRKEY( "DR_128SPS" ), LNUMVAL(ADS1115_DR_128SPS) },
|
||||
{ LSTRKEY( "DR_250SPS" ), LNUMVAL(ADS1115_DR_250SPS) },
|
||||
{ LSTRKEY( "DR_475SPS" ), LNUMVAL(ADS1115_DR_475SPS) },
|
||||
{ LSTRKEY( "DR_490SPS" ), LNUMVAL(ADS1115_DR_490SPS) },
|
||||
{ LSTRKEY( "DR_860SPS" ), LNUMVAL(ADS1115_DR_860SPS) },
|
||||
{ LSTRKEY( "DR_920SPS" ), LNUMVAL(ADS1115_DR_920SPS) },
|
||||
{ LSTRKEY( "DR_1600SPS" ), LNUMVAL(ADS1115_DR_1600SPS) },
|
||||
{ LSTRKEY( "DR_2400SPS" ), LNUMVAL(ADS1115_DR_2400SPS) },
|
||||
{ LSTRKEY( "DR_3300SPS" ), LNUMVAL(ADS1115_DR_3300SPS) },
|
||||
{ LSTRKEY( "CONV_RDY_1" ), LNUMVAL(ADS1115_CQUE_1CONV) },
|
||||
{ LSTRKEY( "CONV_RDY_2" ), LNUMVAL(ADS1115_CQUE_2CONV) },
|
||||
{ LSTRKEY( "CONV_RDY_4" ), LNUMVAL(ADS1115_CQUE_4CONV) },
|
||||
{ LSTRKEY( "COMP_1CONV" ), LNUMVAL(ADS1115_CQUE_1CONV) },
|
||||
{ LSTRKEY( "COMP_2CONV" ), LNUMVAL(ADS1115_CQUE_2CONV) },
|
||||
{ LSTRKEY( "COMP_4CONV" ), LNUMVAL(ADS1115_CQUE_4CONV) },
|
||||
{ LSTRKEY( "CMODE_TRAD"), LNUMVAL(ADS1115_CMODE_TRAD) },
|
||||
{ LSTRKEY( "CMODE_WINDOW"), LNUMVAL(ADS1115_CMODE_WINDOW) },
|
||||
{ LNILKEY, LNILVAL }
|
||||
};
|
||||
|
||||
NODEMCU_MODULE(ADS1115, "ads1115", ads1115_map, NULL);
|
||||
static const LUA_REG_TYPE ads1115_instance_map[] = {
|
||||
{ LSTRKEY( "setting" ), LFUNCVAL(ads1115_lua_setting) },
|
||||
{ LSTRKEY( "startread" ), LFUNCVAL(ads1115_lua_startread) },
|
||||
{ LSTRKEY( "read" ), LFUNCVAL(ads1115_lua_read) },
|
||||
{ LSTRKEY( "__index" ), LROVAL(ads1115_instance_map) },
|
||||
{ LSTRKEY( "__gc" ), LFUNCVAL(ads1115_lua_delete) },
|
||||
{ LNILKEY, LNILVAL }
|
||||
};
|
||||
|
||||
|
||||
int luaopen_ads1115(lua_State *L) {
|
||||
luaL_rometatable(L, metatable_name, (void *)ads1115_instance_map);
|
||||
return 0;
|
||||
}
|
||||
|
||||
NODEMCU_MODULE(ADS1115, "ads1115", ads1115_map, luaopen_ads1115);
|
||||
|
|
|
@ -3,17 +3,96 @@
|
|||
| :----- | :-------------------- | :---------- | :------ |
|
||||
| 2017-04-24 | [fetchbot](https://github.com/fetchbot) | [fetchbot](https://github.com/fetchbot) | [ads1115.c](../../../app/modules/ads1115.c)|
|
||||
|
||||
This module provides access to the ADS1115 16-Bit analog-to-digital converter.
|
||||
This module provides access to the ADS1115 (16-Bit) and ADS1015 (12-Bit) analog-to-digital converters.
|
||||
Other chips from the same family (ADS1113, ADS1114, ADS1013 and ADS1014) are likely to work. Missing hardware features will be silently ignored.
|
||||
|
||||
This module supports multiple devices connected to I²C bus. The devices of different types can be mixed.
|
||||
The addressing of ADS family allows for maximum of 4 devices connected to the same I²C bus.
|
||||
|
||||
!!! caution
|
||||
|
||||
The **ABSOLUTE MAXIMUM RATINGS** for all analog inputs are `–0.3V to VDD+0.3V` referred to GND.
|
||||
|
||||
## ads1115.read()
|
||||
|
||||
|
||||
## ads1115.ads1115()
|
||||
Registers ADS1115 (ADS1113, ADS1114) device.
|
||||
|
||||
#### Syntax
|
||||
`ads1115.ADS1115(I2C_ID, I2C_ADDR)`
|
||||
|
||||
#### Parameters
|
||||
- `I2C_ID` - always 0
|
||||
- `ADDRESS` - I²C address of a device
|
||||
* `ads1115.ADDR_GND`
|
||||
* `ads1115.ADDR_VDD`
|
||||
* `ads1115.ADDR_SDA`
|
||||
* `ads1115.ADDR_SCL`
|
||||
|
||||
#### Returns
|
||||
Registered `device` object
|
||||
|
||||
#### Example
|
||||
```lua
|
||||
local id, sda, scl = 0, 6, 5
|
||||
i2c.setup(id, sda, scl, i2c.SLOW)
|
||||
ads1115.reset()
|
||||
adc1 = ads1115.ads1115(id, ads1115.ADDR_GND)
|
||||
```
|
||||
|
||||
|
||||
## ads1115.ads1015()
|
||||
Registers ADS1015 (ADS1013, ADS1014) device.
|
||||
|
||||
#### Syntax
|
||||
`ads1115.ads1015(I2C_ID, I2C_ADDR)`
|
||||
|
||||
#### Parameters
|
||||
- `I2C_ID` - always 0
|
||||
- `ADDRESS` - I²C address of a device
|
||||
* `ads1115.ADDR_GND`
|
||||
* `ads1115.ADDR_VDD`
|
||||
* `ads1115.ADDR_SDA`
|
||||
* `ads1115.ADDR_SCL`
|
||||
|
||||
#### Returns
|
||||
Registered `device` object
|
||||
|
||||
#### Example
|
||||
```lua
|
||||
local id, sda, scl = 0, 6, 5
|
||||
i2c.setup(id, sda, scl, i2c.SLOW)
|
||||
ads1115.reset()
|
||||
adc1 = ads1115.ads1015(id, ads1115.ADDR_VDD)
|
||||
adc2 = ads1115.ads1115(id, ads1115.ADDR_SDA)
|
||||
```
|
||||
## ads1115.reset()
|
||||
Reset all devices connected to I²C interface.
|
||||
|
||||
### Syntax
|
||||
ads1115.reset()
|
||||
|
||||
#### Parameters
|
||||
none
|
||||
|
||||
#### Returns
|
||||
`nil`
|
||||
|
||||
#### Example
|
||||
```lua
|
||||
local id, alert_pin, sda, scl = 0, 7, 6, 5
|
||||
i2c.setup(id, sda, scl, i2c.SLOW)
|
||||
ads1115.reset()
|
||||
```
|
||||
|
||||
|
||||
# ADS Device
|
||||
|
||||
## ads1115.device:read()
|
||||
Gets the result stored in the register of a previously issued conversion, e.g. in continuous mode or with a conversion ready interrupt.
|
||||
|
||||
#### Syntax
|
||||
`volt, volt_dec, adc = ads1115.read()`
|
||||
`volt, volt_dec, adc = device:read()`
|
||||
|
||||
#### Parameters
|
||||
none
|
||||
|
@ -25,39 +104,43 @@ none
|
|||
|
||||
!!! note
|
||||
|
||||
If using float firmware then `volt` is a floating point number. On an integer firmware, the final value has to be concatenated from `volt` and `volt_dec`.
|
||||
If using float firmware then `volt` is a floating point number. On an integer firmware, the final value has to be concatenated from `volt` and `volt_dec`. Both values `volt` and `volt_dec` contains sign.
|
||||
|
||||
#### Example
|
||||
```lua
|
||||
local id, alert_pin, sda, scl = 0, 7, 6, 5
|
||||
i2c.setup(id, sda, scl, i2c.SLOW)
|
||||
ads1115.setup(ads1115.ADDR_GND)
|
||||
ads1115.reset()
|
||||
adc1 = ads1115.ads1115(id, ads1115.ADDR_GND)
|
||||
|
||||
-- continuous mode
|
||||
ads1115.setting(ads1115.GAIN_6_144V, ads1115.DR_128SPS, ads1115.SINGLE_0, ads1115.CONTINUOUS)
|
||||
adc1:setting(ads1115.GAIN_6_144V, ads1115.DR_128SPS, ads1115.SINGLE_0, ads1115.CONTINUOUS)
|
||||
-- read adc result with read()
|
||||
volt, volt_dec, adc = ads1115.read()
|
||||
volt, volt_dec, adc = ads1:read()
|
||||
print(volt, volt_dec, adc)
|
||||
|
||||
-- comparator
|
||||
ads1115.setting(ads1115.GAIN_6_144V, ads1115.DR_128SPS, ads1115.SINGLE_0, ads1115.CONTINUOUS, ads1115.COMP_1CONV, 1000, 2000)
|
||||
adc1:setting(ads1115.GAIN_6_144V, ads1115.DR_128SPS, ads1115.SINGLE_0, ads1115.CONTINUOUS, ads1115.COMP_1CONV, 1000, 2000)
|
||||
local function comparator(level, when)
|
||||
-- read adc result with read() when threshold reached
|
||||
volt, volt_dec, adc = ads1115.read()
|
||||
gpio.trig(alert_pin)
|
||||
volt, volt_dec, adc = ads1:read()
|
||||
print(volt, volt_dec, adc)
|
||||
end
|
||||
gpio.mode(alert_pin, gpio.INT)
|
||||
gpio.trig(alert_pin, "both", comparator)
|
||||
|
||||
-- read adc result with read()
|
||||
volt, volt_dec, adc = ads1115.read()
|
||||
volt, volt_dec, adc = ads1115:read()
|
||||
print(volt, volt_dec, adc)
|
||||
```
|
||||
|
||||
## ads1115.setting()
|
||||
|
||||
## ads1115.device:setting()
|
||||
Configuration settings for the ADC.
|
||||
|
||||
#### Syntax
|
||||
`ads1115.setting(GAIN, SAMPLES, CHANNEL, MODE[, CONVERSION_RDY][, COMPARATOR, THRESHOLD_LOW, THRESHOLD_HI])`
|
||||
`device:setting(GAIN, SAMPLES, CHANNEL, MODE[, CONVERSION_RDY][, COMPARATOR, THRESHOLD_LOW, THRESHOLD_HI[,COMP_MODE]])`
|
||||
|
||||
#### Parameters
|
||||
- `GAIN` Programmable gain amplifier
|
||||
|
@ -68,14 +151,19 @@ Configuration settings for the ADC.
|
|||
* `ads1115.GAIN_0_512V` 8x Gain
|
||||
* `ads1115.GAIN_0_256V` 16x Gain
|
||||
- `SAMPLES` Data rate in samples per second
|
||||
* `ads1115.DR_8SPS`
|
||||
* `ads1115.DR_16SPS`
|
||||
* `ads1115.DR_32SPS`
|
||||
* `ads1115.DR_64SPS`
|
||||
* `ads1115.DR_8SPS` ADS1115 only
|
||||
* `ads1115.DR_16SPS` ADS1115 only
|
||||
* `ads1115.DR_32SPS` ADS1115 only
|
||||
* `ads1115.DR_64SPS` ADS1115 only
|
||||
* `ads1115.DR_128SPS`
|
||||
* `ads1115.DR_250SPS`
|
||||
* `ads1115.DR_475SPS`
|
||||
* `ads1115.DR_860SPS`
|
||||
* `ads1115.DR_475SPS` ADS1115 only
|
||||
* `ads1115.DR_490SPS` ADS1015 only
|
||||
* `ads1115.DR_860SPS` ADS1115 only
|
||||
* `ads1115.DR_920SPS` ADS1015 only
|
||||
* `ads1115.DR_1600SPS` ADS1015 only
|
||||
* `ads1115.DR_2400SPS` ADS1015 only
|
||||
* `ads1115.DR_3300SPS` ADS1015 only
|
||||
- `CHANNEL` Input multiplexer for single-ended or differential measurement
|
||||
* `ads1115.SINGLE_0` channel 0 to GND
|
||||
* `ads1115.SINGLE_1` channel 1 to GND
|
||||
|
@ -102,6 +190,11 @@ Configuration settings for the ADC.
|
|||
- `THRESHOLD_HI`
|
||||
* `0` - `+ GAIN_MAX` in mV for single-ended inputs
|
||||
* `- GAIN_MAX` - `+ GAIN_MAX` in mV for differential inputs
|
||||
- `COMP_MODE` Comparator mode
|
||||
* `ads1115.CMODE_TRAD` traditional comparator mode (with hysteresis)
|
||||
* `ads1115.CMODE_WINDOW` window comparator mode
|
||||
|
||||
note: Comparator and conversion ready are always configured to non-latching, active low.
|
||||
|
||||
#### Returns
|
||||
`nil`
|
||||
|
@ -110,40 +203,18 @@ Configuration settings for the ADC.
|
|||
```lua
|
||||
local id, sda, scl = 0, 6, 5
|
||||
i2c.setup(id, sda, scl, i2c.SLOW)
|
||||
ads1115.setup(ads1115.ADDR_GND)
|
||||
ads1115.reset()
|
||||
adc1 = ads1115.ads1015(id, ads1115.ADDR_GND)
|
||||
|
||||
ads1115.setting(ads1115.GAIN_6_144V, ads1115.DR_128SPS, ads1115.SINGLE_0, ads1115.SINGLE_SHOT)
|
||||
adc1:setting(ads1115.GAIN_6_144V, ads1115.DR_3300SPS, ads1115.SINGLE_0, ads1115.SINGLE_SHOT)
|
||||
```
|
||||
|
||||
## ads1115.setup()
|
||||
Initializes the device on the defined I²C device address.
|
||||
|
||||
#### Syntax
|
||||
`ads1115.setup(ADDRESS)`
|
||||
|
||||
#### Parameters
|
||||
- `ADDRESS`
|
||||
* `ads1115.ADDR_GND`
|
||||
* `ads1115.ADDR_VDD`
|
||||
* `ads1115.ADDR_SDA`
|
||||
* `ads1115.ADDR_SCL`
|
||||
|
||||
#### Returns
|
||||
`nil`
|
||||
|
||||
#### Example
|
||||
```lua
|
||||
local id, sda, scl = 0, 6, 5
|
||||
i2c.setup(id, sda, scl, i2c.SLOW)
|
||||
|
||||
ads1115.setup(ads1115.ADDR_GND)
|
||||
```
|
||||
|
||||
## ads1115.startread()
|
||||
## ads1115.device:startread()
|
||||
Starts the ADC reading for single-shot mode and after the conversion is done it will invoke an optional callback function in which the ADC conversion result can be obtained.
|
||||
|
||||
#### Syntax
|
||||
`ads1115.startread([CALLBACK])`
|
||||
`device:startread([CALLBACK])`
|
||||
|
||||
#### Parameters
|
||||
- `CALLBACK` callback function which will be invoked after the adc conversion is done
|
||||
|
@ -156,21 +227,23 @@ Starts the ADC reading for single-shot mode and after the conversion is done it
|
|||
```lua
|
||||
local id, alert_pin, sda, scl = 0, 7, 6, 5
|
||||
i2c.setup(id, sda, scl, i2c.SLOW)
|
||||
ads1115.setup(ads1115.ADDR_GND)
|
||||
ads1115.reset()
|
||||
adc1 = ads1115.ads1115(id, ads1115.ADDR_VDD)
|
||||
|
||||
-- single shot
|
||||
ads1115.setting(ads1115.GAIN_6_144V, ads1115.DR_128SPS, ads1115.SINGLE_0, ads1115.SINGLE_SHOT)
|
||||
adc1:setting(ads1115.GAIN_6_144V, ads1115.DR_128SPS, ads1115.SINGLE_0, ads1115.SINGLE_SHOT)
|
||||
-- start adc conversion and get result in callback after conversion is ready
|
||||
ads1115.startread(function(volt, volt_dec, adc) print(volt, volt_dec, adc) end)
|
||||
adc1:startread(function(volt, volt_dec, adc) print(volt, volt_dec, adc) end)
|
||||
|
||||
-- conversion ready
|
||||
ads1115.setting(ads1115.GAIN_6_144V, ads1115.DR_128SPS, ads1115.SINGLE_0, ads1115.SINGLE_SHOT, ads1115.CONV_RDY_1)
|
||||
adc1:setting(ads1115.GAIN_6_144V, ads1115.DR_128SPS, ads1115.SINGLE_0, ads1115.SINGLE_SHOT, ads1115.CONV_RDY_1)
|
||||
local function conversion_ready(level, when)
|
||||
volt, volt_dec, adc = ads1115.read()
|
||||
gpio.trig(alert_pin)
|
||||
volt, volt_dec, adc = adc1:read()
|
||||
print(volt, volt_dec, adc)
|
||||
end
|
||||
gpio.mode(alert_pin, gpio.INT)
|
||||
gpio.trig(alert_pin, "down", conversion_ready)
|
||||
-- start conversion and get result with read() after conversion ready pin asserts
|
||||
ads1115.startread()
|
||||
adc1:startread()
|
||||
```
|
||||
|
|
Loading…
Reference in New Issue