Files
matrix-screen-controller/硬件相关资料和硬件的连接/M5Stack Unit ADC v1.1相关内容/02_ADS1110使用与开发约定_给Codex.md
T

177 lines
9.1 KiB
Markdown
Raw Blame History

This file contains ambiguous Unicode characters
This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.
# M5Stack Unit ADC v1.1 / ADS1110 开发约定
本文供后续 Codex 或维护者读取。动手写驱动前,先确认实物是 `M5Stack Unit ADC v1.1`、SKU `U013-V11`、ADC 芯片 `ADS1110`。不要把旧版 Unit ADC、ADS1100 库或其他 ADS111x 芯片的寄存器接口混进来。
## 1. 当前项目边界
- 主控:`WalnutPi ZeroW`(H618)
- 目的:测量点阵屏输入端 5V 电压,作为供电压降的数字观测值
- I²C 总线:`/dev/i2c-1`
- 7 位地址:`0x48`
- GPIO:物理脚 3 / `PI8/SDA1`,物理脚 5 / `PI7/SCL1`
- 供电假设:系统已经提供可靠、共地的 `5V/GND`
- 当前交付:本地资料、独立脚本,以及主服务中的电压状态、校准和可选低电压亮度保护
- 明确不做:电流、功率、实际发光亮度识别、BMS、物理断电、充电管理或核桃派关机
测量端是并联采样。屏幕负载电流不得经过模块。v1.1 原理图中 P1 测量负端经 `0Ω` 电阻接模块 GND,因此不能把它当成与核桃派隔离的差分表使用。
## 2. 资料优先级和已知冲突
遇到资料冲突时采用以下优先级:
1. 实物型号、v1.1 原理图和 TI ADS1110 数据手册
2. M5Stack Unit ADC v1.1 产品描述及管脚表
3. M5Stack 产品页中的规格汇总表
4. M5Stack 旧 Arduino 示例和 `M5-ADS1100` 仓库
当前 M5Stack 产品页存在混杂信息:正文把 v1.1 描述为 ADS1110,并给出 `15/30/60/240 SPS`;但部分规格/比较表仍显示 ADS1100 或 `8/16/32/128 SPS`,链接的旧 Arduino 例程也使用 `M5_ADS1100.h`。对 `U013-V11` 必须使用 ADS1110 的 `15/30/60/240 SPS` 位定义,不得照抄旧库常量。
本地官方文件、原始 URL、下载日期和 SHA-256 见 `官方资料/来源索引.md`。
## 3. 板级模拟换算
v1.1 原理图在测量输入端使用 `510kΩ` 与 `100kΩ` 分压,并由 LM358 缓冲后送入 ADS1110。标称分压倍率为:
```text
(510k + 100k) / 100k = 6.1
```
ADS1110 在 PGA=1 时的差分满量程为 `±2.048V`。选择 15 SPS 时输出为 16 位二进制补码,因此:
```text
ADC差分电压 = signed_raw × 2.048 / 32768
屏幕输入电压 = ADC差分电压 × 6.1 × calibration_factor
```
默认 `calibration_factor = 1.0`。屏幕端每 LSB 的标称分辨率为:
```text
2.048 / 32768 × 6.1 = 0.00038125V
```
快速合理性检查:
| 屏幕输入端标称电压 | 预期 raw(约) |
|---:|---:|
| `0V` | `0` |
| `4.5V` | `11803` |
| `5.0V` | `13115` |
| `5.3V` | `13902` |
| `12.0V` | `31475` |
`raw=32767` 对应标称约 `12.4924V`,但这只是数学满量程;模块官方输入范围仍按 `0V ~ 12V`,不能把多出的计算余量当成允许输入范围。
## 4. ADS1110 配置字节
ADS1110 配置寄存器只有 1 字节:
| 位 | 名称 | 本项目值 | 含义 |
|---:|---|---:|---|
| 7 | `ST/DRDY` | 写入时 `0` | 连续模式下写入值被忽略;读取时 `0` 表示本次结果是新数据 |
| 6:5 | 保留 | `00` | 必须为 0 |
| 4 | `SC` | `0` | 连续转换模式 |
| 3:2 | `DR1:DR0` | `11` | 15 SPS、16 位 |
| 1:0 | `PGA1:PGA0` | `00` | PGA=1 |
因此本项目写入:
```text
0b00001100 = 0x0C
```
ADS1110 上电默认配置读值通常为 `0x8C`;位 7 是读取状态,校验配置时只比较低 7 位是否等于 `0x0C`。不要把 ADS1100 的采样率名称套在相同位值上。
## 5. I²C 读写顺序
ADS1110 没有常见的“寄存器地址指针”步骤:
1. 以 7 位地址 `0x48` 打开 I²C 从设备。
2. 写入单个配置字节 `0x0C`。
3. 至少等待一个 15 SPS 转换周期,约 `66.7ms`;实现可留少量余量。
4. 一次读取 3 字节:
- 字节 0:输出寄存器高字节
- 字节 1:输出寄存器低字节
- 字节 2:配置/状态字节
5. 将前两个字节按大端、有符号 16 位二进制补码解析。
6. 检查配置低 7 位仍为 `0x0C`;位 7 为 `0` 时,本次结果为新数据。
不要使用会自动在事务前发送“寄存器编号”的 SMBus 便捷函数,除非确认它能发出 ADS1110 所需的原始事务。当前独立脚本直接操作 `/dev/i2c-1`,避免引入依赖或错误的寄存器前缀。
## 6. 独立脚本接口
文件:`示例程序/read_unit_adc_v1_1.py`
默认行为:
- 总线 `/dev/i2c-1`
- 地址 `0x48`
- 配置 `0x0C`
- 每次取 5 个新样本的中位数
- 输出屏幕输入端电压、raw 中位数和配置字节
常用命令:
```bash
# 本机纯计算/协议自测,不访问 I²C,Windows 也可以运行
python "硬件相关资料和硬件的连接/M5Stack Unit ADC v1.1相关内容/示例程序/read_unit_adc_v1_1.py" --self-test
# 核桃派单次读数
python3 "硬件相关资料和硬件的连接/M5Stack Unit ADC v1.1相关内容/示例程序/read_unit_adc_v1_1.py"
# 连续读数
python3 "硬件相关资料和硬件的连接/M5Stack Unit ADC v1.1相关内容/示例程序/read_unit_adc_v1_1.py" --watch
# 使用一次比例校正
python3 "硬件相关资料和硬件的连接/M5Stack Unit ADC v1.1相关内容/示例程序/read_unit_adc_v1_1.py" --calibration-factor 1.00604 --watch
```
额外参数通过 `--help` 查看。独立工具必须保持 Python 标准库实现并与主服务监测器分开;不能把独立无限循环直接放进 FastAPI 进程,也不能与主服务同时长期读取同一地址。
## 7. 错误与排障语义
后续修改脚本时必须保留可区分的错误:
- `/dev/i2c-1` 不存在:I²C 未启用或设备节点不同。
- 权限不足:用户没有访问 I²C 设备的权限。
- 地址无响应:`0x48` 没有 ACK,优先查接线、供电和型号。
- 地址被占用:内核驱动已经 claim 该地址。
- 短读取:没有取得完整 3 字节,结果不可用。
- 配置低 7 位不是 `0x0C`:设备/协议不符或配置被改变,不能继续按 15 SPS/PGA=1 换算。
- 负 raw:按二进制补码保留并报告,不要在协议层静默截成 0;对本项目的正电压输入,持续负值应视为接线或偏置异常。
- 读数超出 `0V ~ 12V`:报告异常并检查硬件,不能用软件裁剪后假装正常。
`i2cdetect` 只用于首次诊断,不要在长期读取过程中反复扫描总线。
## 8. 主服务集成约束
主服务已经按 `WEB-SCREEN-VOLTAGE` / `CONFIG-SCREEN-VOLTAGE` 接入网页电压显示和每台设备独立的软件校准,并按 `WEB-LOW-VOLTAGE-PROTECTION`、`CONFIG-LOW-VOLTAGE-PROTECTION`、`DISPLAY-LOW-VOLTAGE-PROTECTION` 接入可选保护。实现必须继续满足:
- ADC 缺失或读取失败不能拖垮显示服务。
- 只有一个组件负责持续读取设备,其他组件读取缓存值,避免并发争用 I²C。
- 原始电压、校正系数、采样时间和错误状态要可区分,不能把读取失败伪装成 `0V`。
- 低电压保护阈值来自本项目真实屏幕和供电试验:校准后、未舍入的组中位数严格大于 `4.8V` 不限制,`4.5..4.8V` 使用 `floor(50 + 50 × (V-4.5)/0.3)` 限制实际亮度,严格低于 `4.5V` 进入 35% 低电图标;不能从 ADC 量程另行推导或改写边界。35% 来自覆盖保护膜后的红色可视性复测。
- 电压正常不等于屏幕状态正常;界面文案必须称为“屏幕输入电压”,不能称为“屏幕亮度传感器”。
- 正常轮询与校准专用采样都必须经过同一个监测组件,不能让 API 请求和后台线程并发打开设备。
- 校准使用同一测量点的可靠万用表参考值,只做单点比例修正;更换 ADC、接线或测量点后恢复 `1.0` 并重新校准。
- 每组继续取 `5` 个 15 SPS 新样本中位数。保护关闭或稳定高于 `4.8V` 时组起始间隔为 `5s`;高于阈值但持续下降时按预计到达阈值缩短为 `1..5s`;限亮为 `1s`;首次临界为 `0.5s`,之后按 `clamp(0.5, 2.0, 0.02/max(|dV/dt|, 0.01))` 自适应,放慢每轮最多增加 `0.5s`、加速立即生效;错误按 `1/2/5s` 退避。
- 每次 I²C 尝试使用单调序号并拒绝晚到旧结果。更严格保护一组立即发布,任何放宽需连续两组成功样本;失败取消待放宽,首次尚无样本不锁屏,已有成功样本后保持最后保护并标记 stale。
- 保护回调必须在监测锁和 I²C 锁外执行;回调错误与 ADC 状态分开,不能污染样本或解除保护,并要在后续周期重试。完整网页、配置和显示契约以 `WEB-LOW-VOLTAGE-PROTECTION`、`CONFIG-LOW-VOLTAGE-PROTECTION`、`DISPLAY-LOW-VOLTAGE-PROTECTION` 为准。
## 9. 浏览器救援条件
以下情况才进入浏览器:
- 实物不是 `U013-V11` 或 PCB 修订发生变化。
- 地址不是 `0x48`。
- 本地 PDF 损坏或与实物丝印冲突。
- 需要确认 ADS1110 电气极限、时序或未在本文覆盖的模式。
优先访问官方来源:
- M5Stack:<https://docs.m5stack.com/zh_CN/unit/Unit-ADC_V1.1>
- v1.1 原理图:<https://m5stack-doc.oss-cn-shenzhen.aliyuncs.com/576/Sch_UNIT_ADC_v1.1.pdf>
- TI ADS1110:<https://www.ti.com/lit/ds/symlink/ads1110.pdf>
- 核桃派项目约定:使用系统已有的 `/dev/i2c-1`,不运行其他开发板专用配置工具
浏览时使用 `U013-V11 ADS1110` 作为组合关键词,并记录所用来源和日期。论坛、商家详情和旧 `M5-ADS1100` 代码只能作为线索,不能覆盖原理图与 TI 数据手册。