零知IDE——基于ESP32的ADS1115 多通道数据采集系统:从差分测量到Web实时监控

零知IDE——基于ESP32的ADS1115 多通道数据采集系统:从差分测量到Web实时监控

  ✔零知开源(零知IDE)是一个专为电子初学者/电子兴趣爱好者设计的开源软硬件平台,在硬件上提供超高性价比STM32系列开发板、物联网控制板。取消了Bootloader程序烧录,让开发重心从 “配置环境” 转移到 “创意实现”,极大降低了技术门槛。零知IDE编程软件,内置上千个覆盖多场景的示例代码,支持项目源码一键下载,项目文章在线浏览。零知开源(零知IDE)平台通过软硬件协同创新,让你的创意快速转化为实物,来动手试试吧!

✔访问零知实验室,获取更多实战项目和教程资源吧!

www.lingzhilab.com

目录

一、系统接线部分

1.1 硬件清单

1.2 接线方案表

1.3 接线示意图

1.4 实物连接图

二、安装与使用部分

三、代码讲解部分

3.1 初始化配置

3.2 多模式数据采集

3.3 Web数据接口

3.4 前端数据可视化

四、项目结果演示

4.1 操作流程

4.2 视频演示

五、ADS1115技术讲解

5.1 寄存器配置

5.2 I2C 通信协议

六、常见问题解答(FAQ)

Q1:测量负电压的原理?

Q2:Web 页面能打开,但数值不更新 / 波形无变化?

Q3: I2C地址冲突怎么办?


项目概述

       本项目基于零知ESP32-WROOM-32主控板,结合TI ADS1115 16位高精度ADC模数转换器,实现了一个功能完整的多通道数据采集与Web监控系统。系统不仅支持传统的4通道单端电压测量,更实现了A0-A1差分电压测量功能,并通过现代化的Web界面实时展示数据变化趋势

项目难点及解决方案

        问题描述:在单次转换模式下,每次测量都需要重新配置MUX通道选择寄存器。频繁切换差分和单端模式可能导致数据读取错误

解决方案:采集流程中先读取差分数据、再读取单端数据,每次读取前库自动完成寄存器重新配置,避免手动操作寄存器的出错

一、系统接线部分

1.1 硬件清单

组件型号/规格数量备注
主控板零知ESP32-WROOM-321核心控制器
ADC模块ADS1115 16位1高精度模数转换
杜邦线公对公若干连接线
电位器10kΩ2模拟信号源
电源5V/2A1供电

1.2 接线方案表

        根据代码设计,接线配置如下:
ESP32引脚ADS1115引脚连接说明备注
GPIO21SDAI2C数据线模块内置上拉电阻
GPIO22SCLI2C时钟线模块内置上拉电阻
3.3VVDD电源正极电源5V供电,避免模块损坏
GNDGND电源地共地很重要
电位器1AIN0通道0输入差分正输入端
电位器2AIN1通道1输入差分负输入端
GNDAIN2通道2输入单端测量
-AIN3通道3输入单端测量

注意:GAIN_ONE模式输入电压必须在±4.096V范围内

1.3 接线示意图

        PS:旋转电位器和ADS1115 ADC模块都采用系统3.3V供电

1.4 实物连接图

二、安装与使用部分

2.1 开源平台-输入"ADS1115 多通道数据采集"并搜索-代码下载自动打开

2.2 连接-验证-上传

2.3 调试-串口监视器

三、代码讲解部分

代码文件结构

        主程序文件,实现 WiFi 连接、ADS1115 数据采集、WebServer 搭建;头文件,存储 Web 页面的 HTML/CSS/JavaScript 代码

3.1 初始化配置

// 增益设置: GAIN_ONE (+/- 4.096V) // 1 bit = 0.125mV const float multiplier = 0.000125; void setup() { Serial.begin(115200); // 1. 初始化 ADS1115 if (!ads.begin()) { Serial.println("无法初始化 ADS1115,请检查连线!"); while (1); } // 设置增益以匹配 3.3V 系统,同时保留一定的余量 ads.setGain(GAIN_ONE); // 2. 连接 WiFi WiFi.begin(ssid, password); Serial.print("正在连接 WiFi"); while (WiFi.status() != WL_CONNECTED) { delay(500); Serial.print("."); } Serial.println("\nWiFi 已连接"); Serial.print("访问地址: http://"); Serial.println(WiFi.localIP()); // 3. 配置 Web 服务器路由 // 首页 server.on("/", HTTP_GET, []() { server.send_P(200, "text/html", index_html); }); // API 接口:返回 JSON 数据 server.on("/data", HTTP_GET, []() { String json = "{"; json += "\"diff_raw\":" + String(raw_diff) + ","; json += "\"diff_v\":" + String(volt_diff, 4) + ","; json += "\"v0\":" + String(volt_a0, 4) + ","; json += "\"v1\":" + String(volt_a1, 4) + ","; json += "\"v2\":" + String(volt_a2, 4); json += "}"; server.send(200, "application/json", json); }); server.begin(); Serial.println("HTTP 服务器已启动"); }
        GAIN_ONE增益倍数1,满量程±4.096V;multiplier每个LSB对应的电压值(0.125mV)

3.2 多模式数据采集

// --- 变量存储 --- int16_t raw_diff; // 差分原始值 int16_t raw_a0, raw_a1, raw_a2; // 单端原始值 float volt_diff, volt_a0, volt_a1, volt_a2; // 转换后的电压值 void loop() { server.handleClient(); // --- 关键步骤:切换模式读取数据 --- // 注意:频繁切换配置寄存器会消耗一点时间,但为了同时显示单端和差分是必须的。 // 1. 读取 A0-A1 差分值 (Differential) // 如果 A0 > A1,值为正;如果 A1 > A0,值为负 raw_diff = ads.readADC_Differential_0_1(); volt_diff = raw_diff * multiplier; // 2. 读取单端值 (Single Ended) 用于参考 raw_a0 = ads.readADC_SingleEnded(0); volt_a0 = raw_a0 * multiplier; raw_a1 = ads.readADC_SingleEnded(1); volt_a1 = raw_a1 * multiplier; raw_a2 = ads.readADC_SingleEnded(2); // 备用通道 volt_a2 = raw_a2 * multiplier; // 简单的串口调试 (可选) // Serial.printf("Diff: %.4f V, A0: %.4f V, A1: %.4f V\n", volt_diff, volt_a0, volt_a1); delay(5); // 短暂延时,避免 CPU 过载 }
        测量AIN0和AIN1之间的电压差、结果可正可负,代表相对极性、差分模式能抑制共模噪声,提高测量精度

3.3 Web数据接口

// --- 全局对象 --- WebServer server(80); // 3. 配置 Web 服务器路由 // 首页 server.on("/", HTTP_GET, []() { server.send_P(200, "text/html", index_html); }); // API 接口:返回 JSON 数据 server.on("/data", HTTP_GET, []() { String json = "{"; json += "\"diff_raw\":" + String(raw_diff) + ","; json += "\"diff_v\":" + String(volt_diff, 4) + ","; json += "\"v0\":" + String(volt_a0, 4) + ","; json += "\"v1\":" + String(volt_a1, 4) + ","; json += "\"v2\":" + String(volt_a2, 4); json += "}"; server.send(200, "application/json", json); }); server.begin();
        使用JSON格式便于前端解析、保留4位小数确保精度同时提供原始值和计算值

3.4 前端数据可视化

<script> // --- Chart.js 初始化配置 --- const ctx = document.getElementById('voltageChart').getContext('2d'); // 创建渐变填充 let gradient = ctx.createLinearGradient(0, 0, 0, 400); gradient.addColorStop(0, 'rgba(102, 252, 241, 0.4)'); // 顶部颜色 gradient.addColorStop(1, 'rgba(102, 252, 241, 0)'); // 底部透明 const voltageChart = new Chart(ctx, { type: 'line', data: { labels: [], // 时间轴标签 datasets: [{ label: 'Differential Voltage (A0 - A1)', data: [], borderColor: '#66fcf1', backgroundColor: gradient, borderWidth: 2, pointRadius: 0, // 隐藏数据点,使线条更平滑 fill: true, tension: 0.4 // 曲线平滑度 }] }, options: { responsive: true, maintainAspectRatio: false, scales: { x: { display: false }, // 隐藏X轴标签保持简洁 y: { grid: { color: '#333' }, ticks: { color: '#888' }, suggestedMin: -4.0, suggestedMax: 4.0 } }, plugins: { legend: { labels: { color: '#c5c6c7' } } }, animation: false // 禁用动画以提高实时性能 } }); // --- 数据获取与更新逻辑 --- const maxDataPoints = 100; // 图表保留的数据点数量 function updateDashboard() { fetch('/data') .then(response => response.json()) .then(data => { // 1. 更新卡片数值 document.getElementById('valDiff').innerText = data.diff_v.toFixed(4); document.getElementById('val0').innerText = data.v0.toFixed(4); document.getElementById('val1').innerText = data.v1.toFixed(4); document.getElementById('val2').innerText = data.v2.toFixed(4); // 2. 更新图表 // 获取当前时间戳作为简单的标签 const now = new Date().toLocaleTimeString(); // 添加新数据 voltageChart.data.labels.push(now); voltageChart.data.datasets[0].data.push(data.diff_v); // 如果数据点过多,移除最早的数据 if (voltageChart.data.labels.length > maxDataPoints) { voltageChart.data.labels.shift(); voltageChart.data.datasets[0].data.shift(); } voltageChart.update(); }) .catch(error => console.error('Error:', error)); } // 设置刷新频率 (100ms = 10Hz刷新率) setInterval(updateDashboard, 100); </script>

系统流程图

差分测量模式深度解析

// 读取A0-A1差分原始值,底层自动配置寄存器 raw_diff = ads.readADC_Differential_0_1(); // 转换为实际电压(有符号,支持正负电位差) volt_diff = raw_diff * multiplier;

ADS1115 的差分测量是将两个输入引脚(A0/A1)的电位差作为输入信号,而非相对于 GND 的单端信号,核心优势是抑制共模干扰

差分测量原理图

         当 A0 电压 > A1 电压时,raw_diff为正,volt_diff为正;当 A0 电压 < A1 电压时,raw_diff为负,volt_diff

 

 

差分量程与增益配置一致(GAIN_ONE 对应 ±4.096V),即 A0-A1 的电位差范围为 - 4.096V~+4.096V

四、项目结果演示

4.1 操作流程

        按照接线方案表完成 ESP32 与 ADS1115 的连接,A0/A1 接电位器(模拟差分信号),A2 接备用传感器,修改主程序SSID和PASSWORD为实际 WiFi 路由信息

上电运行

给 ESP32 上电,打开串口监视器,设置波特率为 115200,等待 WiFi 连接成功,记录打印的 “访问地址,如http://192.168.x.x

 

 

数据查看

打开电脑 / 手机浏览器,输入上述访问地址,即可看到实时电压数值和差分电压波形

信号调试 

调节电位器,观察 A0/A1 电压变化,以及差分电压的实时波形变化

4.2 视频演示

ESP32+ADS1115多通道采集:差分电压实时波形可视化

完整演示 ESP32 驱动 ADS1115 的多通道单端 / 差分采集流程,包含代码烧录、代码修改、WiFi 连接、Web 可视化全流程,直观展示差分电压随输入信号变化的实时波形,以及各通道电压的高精度显示效果

五、ADS1115技术讲解

 ADS1115 具有 一个输入多路复用器 (MUX),可实现双路差分输入或 四路单端输入测量。兼容 I 2C 的 16 位低功耗精密模数转换器 (ADC)

Multiplexer 复用器

ADS1115包含两个差分输入,AIN0和AIN1可以与AIN3进行差分测量,多路复用器由配置寄存器中的位MUX [2:0]配置

5.1 寄存器配置

        ADS1115 有 4 个寄存器,本项目核心用到配置寄存器(0x01) 和转换寄存器(0x00)

 转换寄存器(0x00)

        存储 ADC 转换后有符号的原始值,ESP32 读取该寄存器值后,乘以转换系数即可得到实际电压

配置寄存器(0x01)[15:0]

         16位配置寄存器用于控制工作模式、输入选择、数据速率、满量程范围和比较器模式

①MUX位详解(输入选择):

 

 

本项目设置MUX[2:0]位为000,使用差分通道AIN0和AIN1

②PGA位详解(增益设置):

 

 

本项目设置PGA[2:0]位为001,采用GAIN_ONE增益

5.2 I2C 通信协议

 ① I2C地址选择

        ADS1115有一个地址引脚 ADDR,用于配置器件的 I2C 地址。该引脚可连接至 GND、VDD、SDA 或 SCL,通过一个引脚即可选择四种不同的地址

  ② 向寄存器写入数据

        要访问 ADS111x 中的特定寄存器,主机必须首先向地址指针寄存器中的寄存器地址指针位 P [1:0] 写入适当的值。

 地址指针寄存器是在从机地址字节、低电平的读 / 写位以及从机成功应答之后直接写入,从机进行应答,主机发出停止条件或重复起始条件

 ③ 从寄存器读取数据

        从 ADS111x 读取数据时,先前写入位 P [1:0] 的值决定了要读取的寄存器。要更改读取的寄存器,必须向 P [1:0] 写入新值

 ④ 数据格式

        以二进制补码格式提供 16 位数据。正满量程(+FS)输入产生的输出代码为 7FFFh,负满量程(–FS)输入产生的输出代码为 8000h

对于超过满量程的信号,输出会钳位在这些代码上

电压计算原理

        ADS1115的输出代码与输入电压的关系为:电压 = (ADC读数 × 满量程电压) / (2¹⁵ - 1)

在GAIN_ONE模式下:满量程电压 = 4.096V、分辨率 = 4.096V / 32767 ≈ 0.125mV

六、常见问题解答(FAQ)

Q1:测量负电压的原理?

        A: ADS1115本身不能直接测量负电压(相对GND)。但通过以下方法间接测量:使用差分模式时V-接负电压,V+接GND、使用电平移位电路将负电压抬升到0-3.3V范围、使用双电源供电给ADS1115提供±2.5V电源

Q2:Web 页面能打开,但数值不更新 / 波形无变化?

        A:排查步骤:检查 ESP32 是否仍连接 WiFi、检查浏览器控制台(F12)是否有报错、确认代码中setInterval(updateDashboard, 100)未被注释,刷新频率正常

Q3: I2C地址冲突怎么办?

        A:ADS1115的I2C地址由ADDR引脚决定:默认ADDR接地0x48、ADDR接VDD地址为0x49、ADDR接SDA地址为0x4A、ADDR接SCL地址为0x4B。在代码Adafruit_ADS1115 ads(0x49); 中修改地址为0x49

 项目资源整合:

        ADS1115库文件:Adafruit_ADS1X15

        ADS1115数据手册:ADS111x datasheet

Read more

AI绘画提示词工程:从基础原理到高效实践

快速体验 在开始今天关于 AI绘画提示词工程:从基础原理到高效实践 的探讨之前,我想先分享一个最近让我觉得很有意思的全栈技术挑战。 我们常说 AI 是未来,但作为开发者,如何将大模型(LLM)真正落地为一个低延迟、可交互的实时系统,而不仅仅是调个 API? 这里有一个非常硬核的动手实验:基于火山引擎豆包大模型,从零搭建一个实时语音通话应用。它不是简单的问答,而是需要你亲手打通 ASR(语音识别)→ LLM(大脑思考)→ TTS(语音合成)的完整 WebSocket 链路。对于想要掌握 AI 原生应用架构的同学来说,这是个绝佳的练手项目。 从0到1构建生产级别应用,脱离Demo,点击打开 从0打造个人豆包实时通话AI动手实验 AI绘画提示词工程:从基础原理到高效实践 背景:提示词的重要性与当前痛点 AI绘画模型如Stable Diffusion已经让图像生成变得触手可及,但很多开发者发现,同样的模型在不同提示词下表现差异巨大。常见问题包括: * 语义歧义:模型对抽象词汇理解不一致,比如&

面向电力线场景下无人机返航任务的尺度不变逼近检测器

点击蓝字 关注我们 关注并星标 从此不迷路 计算机视觉研究院 公众号ID|计算机视觉研究院 学习群|扫码在主页获取加入方式 https://pmc.ncbi.nlm.nih.gov/articles/PMC11852856/pdf/biomimetics-10-00099.pdf 计算机视觉研究院专栏 Column of Computer Vision Institute 无人机为电网维护提供了高效解决方案,但返航过程中的避障问题面临跨越电力线的挑战,尤其对于计算资源有限的小型无人机而言更为突出。传统视觉系统难以检测纤细、复杂的电力线,常出现漏检或误判。尽管深度学习方法提升了图像中静态电力线的检测效果,但在动态场景下仍难以实时识别碰撞风险。 PART/1      概述    受视叶巨运动检测器(LGMD)通过检测逼近目标的连续、聚集运动轮廓,从而区分背景中稀疏、非相干运动的机制启发,本文提出一种尺度不变逼近检测器(SILD)。SILD通过视频帧预处理实现运动检测,利用注意力掩码增强运动区域,并模拟生物唤醒机制识别逼近威胁、抑制噪声;同时可预测高速飞行中

【征文计划】AR健身教练:形随心动 - 基于Rokid CXR-M SDK的实践落地

【征文计划】AR健身教练:形随心动 - 基于Rokid CXR-M SDK的实践落地

一、项目背景与创意起源 在当今快节奏的都市生活中,健身已成为许多人保持健康的重要方式。然而,居家健身面临一个普遍痛点:缺乏专业指导,容易因动作不规范导致运动损伤,同时低头看手机或平板的体验也大大降低了健身的沉浸感和效率。 根据《2024年中国健身行业白皮书》显示,超过65%的居家健身用户表示"缺乏专业指导"是他们放弃健身的主要原因。而Rokid Glasses作为一款轻量级AR眼镜,其独特的"抬头即见"交互方式,为解决这一问题提供了绝佳的硬件基础。 "形随心动"创意的诞生源于一个简单但关键的观察:如果能将专业教练"投射"到用户视野中,实时指导动作,同时提供直观的数据反馈,那么居家健身体验将发生质的飞跃。通过Rokid CXR-M SDK的AI场景、自定义页面和提词器功能,我们能够实现这一愿景。 二、Rokid CXR-M SDK 相关 1. Rokid

米家API完全指南:轻松掌控智能家居生态系统

米家API完全指南:轻松掌控智能家居生态系统 【免费下载链接】mijia-api米家API 项目地址: https://gitcode.com/gh_mirrors/mi/mijia-api 米家API是一个功能强大的Python工具库,让开发者和普通用户都能轻松控制小米智能设备。通过封装复杂的网络通信协议,您只需几行代码即可实现设备远程操控、状态监测和场景自动化,打造专属的智能家居体验。 🌟 米家API的核心优势 简单易用:无需深入了解底层技术细节,初学者也能快速上手 功能全面:支持设备发现、属性设置、动作执行等核心操作 兼容性强:适配米家生态链中的各类智能设备 扩展灵活:提供丰富的API接口,满足个性化开发需求 🚀 三分钟快速上手 第一步:安装米家API 推荐方式:通过PyPI安装 pip install mijiaAPI 备选方案:从源码构建 git clone https://gitcode.com/gh_mirrors/mi/mijia-api