跳转至

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

  1. 更新时间:2026 - 08 - 24
  2. 更新内容:
  3. 初版,实现 ads1115 驱动所有基础功能
  4. 支持 I2C 初始化与设备地址自动探测(0x48~0x4B)
  5. 支持 4 路单端 / 2 路差分通道配置与读取
  6. 支持 PGA 六档增益与数据速率八档配置
  7. 支持比较器阈值报警与 ALERT/RDY 中断
  8. 支持 offset / gain 校准

六、产品支持说明

  • 当前版本适配 Air780EPM 核心板,I2C1 引脚:PIN66=SDA、PIN67=SCL。

  • 适用固件:建议使用 Air780EPM 最新版本 LuatOS 固件(V1103 及以上版本)。

  • 其他支持 I2C 的合宙模组亦可使用,修改 config.i2c_id 与接线即可。

  • 使用中遇到问题可在合宙开发者社区(docs.openluat.com)搜索"ADS1115"或"exs_ads1115"。

搜索