exs_ads1115 扩展库
作者:王城钧 | 最后修改:2026-08-24
一、概述
1.1 主要特性
- exs_ads1115 是 TI 公司 16 位精密 ΔΣ 模数转换器(ADC)ADS1115 的 LuatOS 扩展库,
通过 I2C 接口读取电压数据。
-
支持 4 路单端或 2 路差分输入通道,通道通过 MUX 自动切换,一次 setup 即可轮询全部通道。
-
内置可编程增益放大器(PGA)六档:±6.144V / ±4.096V / ±2.048V / ±1.024V / ±0.512V / ±0.256V,适配 0~5V 电池/电源电压监测等场景。
-
数据速率八档可选:8 / 16 / 32 / 64 / 128 / 250 / 475 / 860 SPS,速率越低噪声越小。
-
支持单次模式(转换完成自动掉电,静态电流 0.5μA)与连续模式(工作电流 150μA), 适合低功耗物联网设备。
-
内置可编程比较器,ALERT/RDY 引脚支持阈值报警与转换就绪两种中断模式,无需轮询等待。
-
提供 offset / gain 校准接口,补偿芯片失调误差(±1~3 LSB)与增益误差(0.01%~0.15%)。
1.2 注意事项
-
模拟输入电压范围 GND ~ VDD,不能超过 VDD+0.3V;不能直接测量负电压, 负信号需差分接法或电平偏移。
-
单次模式读取时内部需要等待转换完成(含 sys.wait),get_data 必须在 sys.taskInit 创建的协程中调用。
-
高增益档(PGA=16)输入阻抗低至 710kΩ,高阻信号源会被分压导致读数偏小, 建议使用运放缓冲。
-
改变 PGA 增益后电压换算满量程自动跟随,但已设置的比较器阈值需重新调用 set_threshold() 设置。
-
I2C 的 SCL/SDA 必须接 4.7kΩ(1k~10kΩ 范围)上拉电阻到 VDD,成品模块通常已内置。
-
ADDR 引脚决定 I2C 地址(0x48~0x4B),不能悬空,悬空会导致地址不确定、设备无法探测。
1.3 功耗说明
-
单次模式:转换完成后芯片自动掉电,静态电流 0.5μA(25°C),适合周期性采集场景。
-
连续模式:芯片持续转换,工作电流 150μA(典型值),适合持续监测场景。
1.4 中断说明
-
ALERT/RDY 引脚默认低有效:比较器触发或转换就绪时输出低电平,需接模组 GPIO 并配置 下降沿中断。
-
锁存模式(set_comparator 的 latch 参数设为 true)下,报警保持到读取数据后清除。
-
转换就绪模式(RDY)下,每次转换完成输出低电平脉冲,可代替轮询等待转换完成。
1.5 硬件连接
ASCII 接线图:
Air780EPM 核心板 ADS1115 模块
────────────────── ───────────────
3.3V (VDD_EXT) ──────── VCC
GND ──────── GND
PIN66 (I2C1_SDA) ──────── SDA
PIN67 (I2C1_SCL) ──────── SCL
GND ──────── ADDR(地址 0x48)
GPIO22 ──────── ALERT/RDY(可选,比较器中断)
说明:
-
I2C 上拉:SCL/SDA 各接 4.7kΩ 到 3.3V(成品模块通常已内置上拉电阻)。
-
电源:模块 VCC 接 3.3V,与模组 IO 电平匹配;模拟输入电压不能超过 3.6V。
-
被测电压超过 3.3V 时必须电阻分压后接入 AIN 引脚。
接线实物图:

1.6 加载方式
-- 扩展库需要 require 加载后才能调用
local exs_ads1115 = require "exs_ads1115"
二、核心示例
2.1 场景一:电池/电源电压监测(轮询读取)
电池电压经 2:1 电阻分压后接入 AIN0,定时轮询读取并换算实际电池电压。
-- 电池电压监测示例:AIN0 单端,PGA=±4.096V,单次模式
local exs_ads1115 = require "exs_ads1115"
sys.taskInit(function()
-- 初始化:I2C1,地址自动探测,AIN0 通道,PGA=1(±4.096V),128SPS,单次模式
local ok = exs_ads1115.setup({
i2c_id = 1,
channel = 0,
pga = 1,
sps = 128,
mode = 1,
})
if not ok then
log.error("ads1115", "初始化失败,请检查接线")
return
end
-- 主循环:每 2 秒读取一次电压
while true do
local data = exs_ads1115.get_data()
if data then
-- 电池电压 = AIN0 测量电压 × 2(2:1 分压)
local battery_voltage = data.voltage * 2
log.info("ads1115", string.format("电池电压 = %.3f V (raw=%d)", battery_voltage, data.raw))
else
log.warn("ads1115", "读取失败")
end
sys.wait(2000) -- 每 2 秒采集一次,电池电压为缓变信号
end
end)
2.2 场景二:比较器中断报警(ALERT/RDY)
电压超过 3.0V 或低于 2.0V 时触发 ALERT 中断,锁存报警,读取数据后自动清除。
-- 比较器中断示例:AIN0 单端,超过 3.0V 或低于 2.0V 报警
local exs_ads1115 = require "exs_ads1115"
local ALERT_PIN = 22 -- ALERT/RDY 接模组 GPIO22,以实际接线为准
sys.taskInit(function()
-- 初始化:连续模式 + 比较器锁存报警
local ok = exs_ads1115.setup({
i2c_id = 1,
channel = 0,
pga = 1, -- ±4.096V
sps = 128,
mode = 0, -- 连续模式
})
if not ok then
log.error("ads1115", "初始化失败")
return
end
-- 设置比较器:窗口模式(高于 3.0V 或低于 2.0V 都报警),1 次越界报警,锁存
exs_ads1115.set_comparator(1, 0, true)
-- 设置阈值:低于 2.0V 或高于 3.0V 触发报警
exs_ads1115.set_threshold(2.0, 3.0)
-- ALERT 引脚下降沿中断回调
gpio.setup(ALERT_PIN, function()
log.warn("ads1115", "电压超过阈值 3.0V!")
-- 锁存模式下读取数据可清除报警
local data = exs_ads1115.get_data()
if data then
log.info("ads1115", string.format("当前电压 = %.3f V", data.voltage))
end
end, nil, gpio.FALLING)
-- 主循环持续运行,报警由中断处理
while true do
sys.wait(10000) -- 每 10 秒打印一次当前电压,报警由中断处理
local data = exs_ads1115.get_data()
if data then
log.info("ads1115", string.format("当前电压 = %.3f V", data.voltage))
end
end
end)
三、常量解释
扩展库常量,顾名思义是由 exs_ads1115 扩展库中定义的、不可重新赋值或修改的固定值, 在脚本代码中不需要声明,可直接调用,本扩展库没有常量。
四、函数详解
4.1 初始化
4.1.1 exs_ads1115.setup(config)
功能
初始化 ADS1115,完成 I2C 初始化、设备地址自动探测与默认配置加载,返回是否成功。
参数
config
参数含义:配置参数表
数据类型:table
取值范围:
{
参数含义:硬件 I2C 总线编号(与 scl/sda 二选一,同时传优先硬件 I2C)
数据类型:number
取值范围:0 / 1,具体取决于模组硬件支持
是否必选:否
注意事项:Air780EPM 核心板使用 I2C1,对应 PIN66=SDA、PIN67=SCL
参数示例:1
config.i2c_id ,
参数含义:软件 I2C SCL 引脚(与 i2c_id 二选一)
数据类型:number
取值范围:模组 GPIO 引脚编号
是否必选:否
注意事项:软件 I2C 速率约 100K,受网络业务影响,建议优先硬件 I2C
参数示例:31
config.scl ,
参数含义:软件 I2C SDA 引脚(与 i2c_id 二选一)
数据类型:number
取值范围:模组 GPIO 引脚编号
是否必选:否
注意事项:与 scl 需同时传入
参数示例:30
config.sda ,
参数含义:I2C 设备地址(芯片支持多个地址,可不传,自动探测)
数据类型:number
取值范围:0x48 / 0x49 / 0x4A / 0x4B
(由 ADDR 引脚决定:接 GND=0x48,接 VDD=0x49,接 SDA=0x4A,接 SCL=0x4B)
是否必选:否
注意事项:不传时扩展库自动探测并按寄存器校验锁定实际地址;接线改变后需重新上电
参数示例:0x48
config.addr ,
参数含义:默认读取通道
数据类型:number
取值范围:0 / 1 / 2 / 3(单端,对应 AIN0 / AIN1 / AIN2 / AIN3);差分模式 0 / 1
是否必选:否
注意事项:默认 0;差分测量时通道 0 对应 AIN0-AIN1,通道 1 对应 AIN2-AIN3,
需同时传 config.diff=true
参数示例:0
config.channel ,
参数含义:是否差分输入模式
数据类型:boolean
取值范围:false(单端,默认)/ true(差分)
是否必选:否
注意事项:差分时电压可为负值(范围 -FS ~ +FS)
参数示例:false
config.diff ,
参数含义:PGA 增益,决定满量程测量范围
数据类型:number
取值范围:0.667(满量程 ±6.144V,分辨率 187.5μV,适合 0~5V 电源监测)
/ 1(±4.096V,125μV,默认,适合 0~3.3V 信号)
/ 2(±2.048V,62.5μV)
/ 4(±1.024V,31.25μV)
/ 8(±0.512V,15.6μV)
/ 16(±0.256V,7.8μV,适合毫伏级小信号)
是否必选:否
注意事项:增益越高分辨率越高但满量程越小;信号幅度应尽量占满量程,默认 1
参数示例:1
config.pga ,
参数含义:数据速率
数据类型:number
取值范围:8 / 16 / 32 / 64 / 128(默认,适合大多数监测场景)/ 250 / 475 / 860
(单位 SPS)
是否必选:否
注意事项:速率越低噪声越小、转换等待时间越长;8SPS 时单次转换约 125ms
参数示例:128
config.sps ,
参数含义:工作模式
数据类型:number
取值范围:1(单次模式,转换完成自动掉电,静态电流 0.5μA,默认,
适合周期性采集)/ 0(连续模式,工作电流 150μA,适合持续监测)
是否必选:否
注意事项:单次模式读取时内部等待转换完成,必须在 sys.taskInit 协程中调用
参数示例:1
config.mode ,
参数含义:ALERT/RDY 中断引脚编号(模组 GPIO 编号)
数据类型:number
取值范围:根据模组 GPIO 引脚定义,如 22
是否必选:否
注意事项:传入后 get_alert() 可查询引脚电平;中断回调请自行 gpio.setup 配置
参数示例:22
config.alert_pin ,
}
是否必选:是
返回值
local result = exs_ads1115.setup(config)
result
含义说明:初始化是否成功
数据类型:boolean
取值范围:true(成功)/ false(失败,如 I2C 无应答、地址探测失败)
注意事项:失败时可通过日志查看原因,常见为接线错误、上拉电阻缺失、ADDR 悬空
返回示例:true
示例
-- 初始化:I2C1,地址自动探测,AIN0,PGA=±4.096V,128SPS,单次模式
local ok = exs_ads1115.setup({
i2c_id = 1,
channel = 0,
pga = 1,
sps = 128,
mode = 1,
})
log.info("ads1115", "初始化结果", ok)
4.1.2 exs_ads1115.close()
功能
关闭 ADS1115,释放 I2C 资源。设备进入掉电状态(静态电流 0.5μA)。
参数
无
返回值
local result = exs_ads1115.close()
result
含义说明:是否成功关闭
数据类型:boolean
取值范围:true(成功)/ false(失败)
返回示例:true
示例
-- 关闭 ADS1115 并释放 I2C 资源
exs_ads1115.close()
4.1.3 exs_ads1115.version()
功能
返回扩展库版本号,格式为 yyyymmddhhmm 时间戳。
参数
无
返回值
local ver = exs_ads1115.version()
ver
含义说明:扩展库版本号
数据类型:string
取值范围:时间戳格式,如 "202608211030"
返回示例:"202608211030"
示例
-- 打印扩展库版本号
log.info("ads1115", "版本号", exs_ads1115.version())
4.2 数据读取
4.2.1 exs_ads1115.get_data()
功能
读取当前通道的电压数据,返回电压值(V)、16 位原始码与当前通道号。
协程限制:必须在 sys.taskInit 创建的协程中调用。
原因:单次模式下内部需要等待转换完成(sys.wait),时长按数据速率计算, 128SPS 时约 8ms,8SPS 时最长约 125ms。
参数
无
返回值
local data = exs_ads1115.get_data()
data
含义说明:读取结果,读取失败返回 nil
数据类型:table 或 nil
取值范围:
data.voltage - 电压值,单位 V,单端输入范围 0 ~ 满量程 FS,
精度 1LSB 对应 FS/32768
data.raw - 16 位原始码,范围 -32768 ~ 32767
data.channel - 当前通道号(单端 0~3,差分 0/1)
注意事项:差分输入时 voltage 可为负值(范围 -FS ~ +FS)
返回示例:{ voltage = 1.2345, raw = 9876, channel = 0 }
示例
-- 读取当前通道电压
local data = exs_ads1115.get_data()
if data then
log.info("ads1115", string.format("电压 = %.4f V", data.voltage))
end
4.2.2 exs_ads1115.get_raw(channel)
功能
读取指定通道的 16 位原始码,不进行电压换算,用于校准与调试。
参数
channel
参数含义:要读取的通道号
数据类型:number
取值范围:0 / 1 / 2 / 3(单端);差分模式 0 / 1
是否必选:否
注意事项:不传时读取 setup 配置的默认通道
参数示例:0
返回值
local raw = exs_ads1115.get_raw(0)
raw
含义说明:16 位原始码,读取失败返回 nil
数据类型:number 或 nil
取值范围:-32768 ~ 32767(二进制补码)
返回示例:9876
示例
-- 读取 AIN0 原始码
local raw = exs_ads1115.get_raw(0)
log.info("ads1115", "AIN0 raw =", raw)
4.2.3 exs_ads1115.set_config(cfg)
功能
动态修改通道、PGA 增益、数据速率与工作模式,无需重新 setup。
参数
cfg
参数含义:新配置参数表,仅需传入要修改的字段
数据类型:table
取值范围:
{
参数含义:通道号
数据类型:number
取值范围:0 / 1 / 2 / 3(单端);差分模式 0 / 1
是否必选:否
注意事项:不传则保持原配置
cfg.channel ,
参数含义:是否差分输入模式
数据类型:boolean
取值范围:false(单端)/ true(差分)
是否必选:否
cfg.diff ,
参数含义:PGA 增益
数据类型:number
取值范围:0.667 / 1 / 2 / 4 / 8 / 16
是否必选:否
注意事项:修改后需重新调用 set_threshold() 设置比较器阈值
cfg.pga ,
参数含义:数据速率
数据类型:number
取值范围:8 / 16 / 32 / 64 / 128 / 250 / 475 / 860(单位 SPS)
是否必选:否
cfg.sps ,
参数含义:工作模式
数据类型:number
取值范围:1(单次)/ 0(连续)
是否必选:否
cfg.mode ,
}
是否必选:是
返回值
local result = exs_ads1115.set_config(cfg)
result
含义说明:配置是否成功
数据类型:boolean
取值范围:true(成功)/ false(失败)
返回示例:true
示例
-- 切换到 AIN2 通道,PGA 改为 ±2.048V,250SPS
local ok = exs_ads1115.set_config({ channel = 2, pga = 2, sps = 250 })
log.info("ads1115", "切换配置", ok)
4.3 比较器与中断
4.3.1 exs_ads1115.set_threshold(lo_v, hi_v)
功能
设置比较器低阈值与高阈值(输入电压值,单位 V),内部自动换算为 16 位补码写入芯片。 电压低于 lo_v 或高于 hi_v 时 ALERT/RDY 引脚触发报警。
参数
lo_v
参数含义:比较器低阈值
数据类型:number
取值范围:0 ~ 满量程 FS,单位 V,精度 1LSB 对应 FS/32768
是否必选:是
注意事项:需小于 hi_v;超过 FS 的值会被钳位到满量程
参数示例:2.0
hi_v
参数含义:比较器高阈值
数据类型:number
取值范围:0 ~ 满量程 FS,单位 V,精度 1LSB 对应 FS/32768
是否必选:是
注意事项:需大于 lo_v;超过 FS 的值会被钳位到满量程
参数示例:3.0
返回值
local result = exs_ads1115.set_threshold(2.0, 3.0)
result
含义说明:阈值设置是否成功
数据类型:boolean
取值范围:true(成功)/ false(失败)
返回示例:true
示例
-- 设置比较器:低于 2.0V 或高于 3.0V 触发报警
local ok = exs_ads1115.set_threshold(2.0, 3.0)
log.info("ads1115", "设置阈值", ok)
4.3.2 exs_ads1115.set_comparator(mode, queue, latch)
功能
配置比较器工作模式、触发次数与锁存行为,控制 ALERT/RDY 引脚输出方式。
参数
mode
参数含义:比较器工作模式
数据类型:number
取值范围:0(传统模式,超过高阈值报警,回落到低阈值以下恢复)
/ 1(窗口模式,超过高阈值或低于低阈值都报警)
是否必选:否
注意事项:默认 0(传统模式)
参数示例:0
queue
参数含义:连续触发次数
数据类型:number
取值范围:0(1 次超限即报警)/ 1(连续 2 次)/ 2(连续 4 次)
是否必选:否
注意事项:次数越多抗毛刺能力越强,默认 0
参数示例:0
latch
参数含义:是否锁存报警
数据类型:boolean
取值范围:false(不锁存,信号恢复后自动解除报警)
/ true(锁存,需读取数据后清除)
是否必选:否
注意事项:默认 false;使用锁存模式时,中断回调中调用 get_data() 即可清除报警
参数示例:true
返回值
local result = exs_ads1115.set_comparator(0, 0, true)
result
含义说明:比较器配置是否成功
数据类型:boolean
取值范围:true(成功)/ false(失败)
返回示例:true
示例
-- 传统模式,1 次超限报警,锁存
local ok = exs_ads1115.set_comparator(0, 0, true)
log.info("ads1115", "比较器配置", ok)
4.3.3 exs_ads1115.get_alert()
功能
读取 ALERT/RDY 引脚当前电平状态,判断比较器是否处于报警状态。 需要 setup 时传入 config.alert_pin 指定引脚编号。
参数
无
返回值
local alert = exs_ads1115.get_alert()
alert
含义说明:ALERT/RDY 引脚电平状态
数据类型:number 或 nil
取值范围:0(报警触发,引脚为低电平)/ 1(正常,引脚为高电平)
注意事项:未配置 alert_pin 时返回 nil
返回示例:0
示例
-- 轮询检查报警状态
if exs_ads1115.get_alert() == 0 then
log.warn("ads1115", "电压超阈值报警!")
end
4.4 校准
4.4.1 exs_ads1115.set_offset(value)
功能
设置零偏校准值(单位 V),补偿芯片失调误差。实际电压 = 测量电压 - offset。
参数
value
参数含义:零偏校准值
数据类型:number
取值范围:-FS/32768 ~ FS/32768,单位 V,精度 1LSB 对应 FS/32768
是否必选:是
注意事项:将输入端短接(电压为 0)后读取数据,取读数的相反数作为 offset
参数示例:0.001
返回值
local result = exs_ads1115.set_offset(0.001)
result
含义说明:校准值设置是否成功
数据类型:boolean
取值范围:true(成功)/ false(失败)
返回示例:true
示例
-- 输入端短接后读取原始码,计算零偏并设置
local raw = exs_ads1115.get_raw(0)
local fs = 4.096 -- 当前 PGA=1 的满量程
exs_ads1115.set_offset(-raw * fs / 32768)
4.4.2 exs_ads1115.set_gain(value)
功能
设置增益校准系数,补偿芯片增益误差(0.01%~0.15%)。 实际电压 = (测量电压 - offset) × gain。
参数
value
参数含义:增益校准系数
数据类型:number
取值范围:0.9 ~ 1.1,精度 0.0001
是否必选:是
注意事项:输入已知精密电压 Vref 后,gain = Vref / 测量电压;默认 1.0
参数示例:1.001
返回值
local result = exs_ads1115.set_gain(1.001)
result
含义说明:校准值设置是否成功
数据类型:boolean
取值范围:true(成功)/ false(失败)
返回示例:true
示例
-- 输入 2.500V 精密电压,读取测量值后计算增益系数
local data = exs_ads1115.get_data()
local gain = 2.500 / data.voltage
exs_ads1115.set_gain(gain)
五、版本更新说明
版本号:202608241540
- 更新时间:2026 - 08 - 24
- 更新内容:
- 初版,实现 ads1115 驱动所有基础功能
- 支持 I2C 初始化与设备地址自动探测(0x48~0x4B)
- 支持 4 路单端 / 2 路差分通道配置与读取
- 支持 PGA 六档增益与数据速率八档配置
- 支持比较器阈值报警与 ALERT/RDY 中断
- 支持 offset / gain 校准
六、产品支持说明
-
当前版本适配 Air780EPM 核心板,I2C1 引脚:PIN66=SDA、PIN67=SCL。
-
适用固件:建议使用 Air780EPM 最新版本 LuatOS 固件(V1103 及以上版本)。
-
其他支持 I2C 的合宙模组亦可使用,修改 config.i2c_id 与接线即可。
-
使用中遇到问题可在合宙开发者社区(docs.openluat.com)搜索"ADS1115"或"exs_ads1115"。