硬件接线与注意事项 - hongligongsi/Consumables-storage-temperature-and-humidity GitHub Wiki
硬件接线与注意事项
主控板 ESP32-S3-WROOM-1 N16R8(16 MB Flash + 8 MB PSRAM), SCH_1-P1 原理图(2026-01-30,嘉立创EDA V1.0)。引脚名全部集中在 include/pins.h, 修改硬件版本时只需改这一个文件。
- 原理图(2026-01-30 高清版):hardware/sch-p1-2026-01-30.png
- 整机接线:hardware/wiring-diagram.png
- 主界面 UI 功能标注:docs/images/ui-main-desc.png
2026-09-29 复核(重要):2026-09-22 那次「校正」把引脚改错了 —— 它是按 ESP32 classic 的脚位习惯改的(classic 上 GPIO39/40 是 ADC),但本板是 ESP32-S3:ADC 只有 GPIO1
10(ADC1)与 GPIO1120(ADC2,与 WiFi 冲突禁用), GPIO35~40 是纯数字 IO。实机日志每 500 ms 报[E][esp32-hal-adc.c:158] __analogReadRaw(): Pin 39 is not ADC pin!、温度显示 nan,实锤ADC_NTC = 39非法。本次对照 2026-01-30 原理图网络名逐一回滚, 下表为当前生效值(与原理图一致)。
引脚映射
显示(ST7796,SPI,480×320 横屏)
| 信号 | GPIO | 说明 |
|---|---|---|
TFT_RESET |
9 | 复位 |
TFT_SPI_MISO |
10 | 主入从出 |
TFT_SPI_MOSI |
11 | 主出从入 |
TFT_SPI_SCLK |
12 | 时钟 |
TFT_DATA_CMD |
13 | 数据/命令选择(A0) |
TFT_CHIP_SELECT |
14 | 片选 |
TFT_BACKLIGHT |
21 | 背光 + LED 使能 |
SPI 频率 27 MHz。驱动在 platformio.ini 的 build_flags 中以
-DST7796_DRIVER、-DTFT_WIDTH=320、-DTFT_HEIGHT=480 等宏配置。
TFT_eSPI 还必须带 -DUSE_FSPI_PORT,否则 SPI 寄存器基址算成 0,开机即
StoreProhibited 崩溃。
屏幕排线为 FPC-05FB-40PH20(40 针 0.5 mm),原理图标注「不带触摸 / 带触摸」两种版本。
本板 TFT 排针已引出 X+/X−/Y+/Y− 四线,故 Pin::HAS_TOUCH_PANEL = true(具备触摸能力)。
编码器与触摸
| 信号 | GPIO | 说明 |
|---|---|---|
ENCODER_KEY |
15 | EC11 中键(EC_D) |
ENCODER_B |
16 | EC11 B 相(EC_B) |
ENCODER_A |
17 | EC11 A 相(EC_A) |
TFT_YD |
4 | 电阻触摸 Y− |
TFT_XR |
5 | 电阻触摸 X+ |
TFT_YU |
6 | 电阻触摸 Y+ |
TFT_XL |
7 | 电阻触摸 X− |
触摸有两道闸。第一道是编译期的 Pin::HAS_TOUCH_PANEL —— 它是硬件能力开关,
只有当硬件根本没有触摸走线时才置 false(此时触摸采样完全不编译)。第二道是运行时
的系统设置「触摸模式」(第 27 项,touchMode 三态):
| 模式 | 行为 |
|---|---|
| 自动(出厂默认) | 开机做电阻膜在位探测,探到膜才启用轮询与校准 |
| 开 | 强制启用,用于探测不准或特殊排线(用户自负误触风险) |
| 关 | 强制关闭,只用编码器 |
判定合并在 main.cpp 的 touchEnabledNow()(编译期闸 × 模式 × 探测结果),触摸轮询与
校准入口都只问它;改完保存即时生效、无需重启。系统设置的「触摸屏校准」项据此显示
「已关闭 / 不支持 / 未校准 / 已校准」。
「自动」档的电阻膜在位探测(detectTouchPanel():把每层膜一端拉低、另一端弱上拉
读电平,膜在则读数脚被层电阻拉低)针对的是「固件开了触摸但实装非触摸屏、或排线未接」。
探测不到膜时触摸轮询与校准入口整路关闭,浮空触摸线上的随机 ADC 采样不会再被误判成
触点(幽灵触摸)。探测结果见开机串口日志 Touch panel: detected / NOT detected。
执行器
| 信号 | GPIO | 原理图网络名 | 说明 |
|---|---|---|---|
RGB |
18 | WS2812B DIN | LED 灯带数据线,单线串 4 颗 WS2812(四颗同显一色),板载 WS2811S MOS 驱动 |
BUZZER |
1 | BUZ | 蜂鸣器 TF0405-1-4P,2.7 kHz |
AIR_FAN_PWM |
39 | AIR_FAN_PWM | 排气风扇 4 线 PWM 调速(CN6) |
AIR_FAN_DC |
38 | AIR_FAN_DC | 排气风扇电源 MOS Q4 栅极 |
HOT_FAN |
36 | HOT_FAN | 加热风扇 MOS Q5 栅极 |
LED_ENABLE |
37 | LED | LED 灯带 MOS Q6 栅极 |
HOT_PWM |
40 | HOT_PWM | 发热板 MPT40N08S MOS 栅极 |
BOARD_FAN |
45 | BOARD_FAN | 主板散热风扇 MOS Q7 栅极(strapping,见下) |
传感器
| 信号 | GPIO | 原理图网络名 | 说明 |
|---|---|---|---|
PIR |
35 | PIR | 红外感应模块输出(CN3,HC-SR501) |
ADC_NTC |
3 | ADC_NTC | 发热板 NTC 热敏电阻(ZX-NTC1.25-P2ZZ)采样,ADC1_CH2 |
ADC_VCC |
2 | IO2 | 24 V 分压采样(R16 10 k + R18 1 k,量程 36.3 V),ADC1_CH1;固件暂未使用,电压走 INA226 |
I2C_SCL |
41 | SCL | I²C 总线(AHT20 + INA226) |
I2C_SDA |
42 | SDA | I²C 总线(AHT20 + INA226) |
状态输出
| 信号 | GPIO | 说明 |
|---|---|---|
PRINTING_STATUS |
8 | 打印中 3.3 V 状态输出 |
HEATING_STATUS |
47 | 加热中 3.3 V 状态输出 |
Gerber 飞针网表已确认这两路为独立 3.3 V 输出,故 HAS_STATUS_OUTPUTS = true。
外接负载必须经光耦或驱动器,不可由 GPIO 直接驱动。
USB 与 Strapping
| GPIO | 类型 | 默认 | 说明 |
|---|---|---|---|
| 0 | Strapping | 弱上拉 | BOOT 按钮,按低时进入下载模式 |
| 2 | Strapping | 需为高 | 接 ADC_VCC(24 V 分压网络静态 ≈2.2 V,恰为高电平,不影响启动) |
| 3 | Strapping | 浮空 | 默认不参与启动(需烧 STRAP_JTAG_SEL eFuse 才生效),现接 NTC 采样 |
| 19 | USB | — | USB D−,板载 USB-SERIAL-JTAG bridge 专用,别作 GPIO |
| 20 | USB | — | USB D+,同上 |
| 45 | Strapping | 弱下拉 | VDD_SPI 电压选择:低 = 3.3 V,高 = 1.8 V |
| 46 | Strapping | 弱下拉 | 启动模式(与 GPIO0 配合)+ ROM messages 打印控制 |
| 48 | 板载 | — | ESP32-S3 模组板载 WS2812 RGB LED,LGA-33 封装没对外引出 |
USB-UART 走内置 USB-SERIAL-JTAG bridge(UART0),无需占用 GPIO43/44。
封装限制(LGA-33 N16R8 未引出)
以下 GPIO 在 ESP32-S3 内核 die 上存在,但 LGA-33 封装没引出到 PCB:
- GPIO33 / GPIO34 — ROM / RTC 功能
- GPIO43 / GPIO44 — UART0 默认 RX / TX(已由 USB-SERIAL-JTAG 取代)
引脚校正史(2026-09-22 → 2026-09-29)
2026-09-22:一次误判(已回滚)
9-22 那次「校正」是按 ESP32 classic 的脚位习惯改的:classic 的 ADC1 确实挂在 GPIO36/37/38/39/40(GPIO39 = ADC1_CH3、GPIO40 = ADC1_CH0),所以那次改动看起来 「把 ADC 挪到 39/40 很合理」。
但本板是 ESP32-S3,ADC 分布完全不同:
| 芯片 | ADC1 | ADC2 | GPIO35~40 |
|---|---|---|---|
| ESP32 classic | GPIO32~39 | GPIO0/2/4/12 |
ADC / 输入专用 |
| ESP32-S3(本板) | GPIO1~10 | GPIO11~20(与 WiFi 冲突,禁用) | 纯数字 IO,无 ADC |
所以在 S3 上 ADC_NTC = 39 会让 analogRead() 直接报 Pin 39 is not ADC pin!,
温度恒为 nan —— 这就是 9-29 复查的触发点。
2026-09-29:对照 2026-01-30 原理图回滚
下表给出 9-22 误改后、9-29 回滚后的完整对照(网络名取自 2026-01-30 原理图):
| 常量 | 原始值 | 9-22 误改 | 9-29 生效值 | 原理图网络名 |
|---|---|---|---|---|
PIR |
3 | 35 | 35 | PIR |
AIR_FAN_PWM |
2 | 39 | 39 | AIR_FAN_PWM |
AIR_FAN_DC |
35 | 38 | 38 | AIR_FAN_DC |
HOT_PWM |
38 | 40 | 40 | HOT_PWM |
ADC_NTC |
39 | 3 | 3 | ADC_NTC |
ADC_VCC |
40 | 40 | 2 | IO2 |
BOARD_FAN |
45 | 45 | 45 | BOARD_FAN |
LED_ENABLE |
37 | 37 | 37 | LED |
HOT_FAN |
36 | 36 | 36 | HOT_FAN |
要点:9-22 的「新值」和 9-29 的「生效值」其实是同一批数字,只是方向不同。
原始值(PIR = 35、AIR_FAN_DC = 38、HOT_PWM = 40)本来就是对的,9-22 把它们
改到了 ADC 脚位上;9-29 又原样改回来。结论:以原理图网络名为准,不要按「哪个脚
是 ADC」去猜。
ADC_VCC 是 9-22 新增的常量,原始值写成 40,9-29 按原理图网络名 IO2 改为 2。
注意 IO35/36/37 在 OPI PSRAM 模组上被 PSRAM 占用;本板 PSRAM 已禁用 (
platformio.ini用qio_qspi变体),故这三脚可用。若日后恢复 PSRAM, 这三脚必须换。
上电前必须复核
以下各项在实物确认前不能启用加热。完整清单与仓库 README 的 「待验证项清单」同源(12 项),前 6 项在下方有详细说明。
怎么逐项闭环:工具、操作步骤、通过判据、"不通过改哪一行"见 硬件验收流程。
| # | 项目 | 固件当前设定 | 依据位置 | 需要确认的动作 |
|---|---|---|---|---|
| 1 | 加热总开关 | HEATER_ENABLED = false |
src/main.cpp |
复核 GPIO40 PWM、NTC 引脚与 MOSFET 有效电平后改为 true |
| 2 | 热板 NTC 型号/分压 | 10 kΩ / 10 kΩ / B3950(R14 = 10 kΩ) | src/main.cpp 的 readSensors()、readNtcCelsius() |
万用表测常温阻值,按实物参数改写 |
| 3 | 热板 NTC 引脚 | ADC_NTC = GPIO3 |
include/pins.h |
对照原理图网络名与 PCB 焊盘 |
| 4 | INA226 地址与分流 | 0x40、R15 = 5 mΩ(原理图值)、1 mA/LSB |
include/ina226_sensor.h 的 kShuntOhms / kCurrentLsbA |
量实物 R15(原理图为 5 mΩ,曾按 10 mΩ 写码 = 读数差一倍);按串口 d 自检的 cal 值核对 |
| 5 | 仓温传感器安装位 | AHT20(I²C) | src/main.cpp |
确认位于仓内且具代表性,避开热风直吹 |
| 6 | 电阻触摸 | HAS_TOUCH_PANEL = true(硬件具备) |
include/pins.h |
运行时启停改走设置页「触摸模式」(自动/开/关,出厂默认自动);「开」用于探测不准或特殊排线,之后用「触摸屏校准」做两点采点。仅当硬件根本没有触摸走线时才把此常量改为 false |
| 7 | 状态输出负载 | GPIO8 / GPIO47 独立 3.3 V | include/pins.h |
外接负载须经光耦或驱动器 |
| 8 | 排气风扇双路 | AIR_FAN_DC(38) + AIR_FAN_PWM(39) |
src/main.cpp |
确认两路接线与风扇调速方式 |
| 9 | 显示与背光 | ST7796 SPI,480×320,BL=GPIO21 | platformio.ini、include/pins.h |
花屏/白屏时核对 TFT_eSPI 配置与 setRotation(1) |
| 10 | 限流闭环 | 电压/电流采样接入但未标定 | src/controller.cpp |
用钳形表或分流比对读数后启用完整电流闭环 |
| 11 | 主板风扇条件 | MCU > 60 ℃ 或 电流 > 0.05 A 等 | src/controller.cpp |
确认 GPIO45 驱动方式与风道方向(GPIO45 为 strapping 脚,上电须为低) |
| 12 | 环境总电流 | 热板 + 风扇 + 灯带同开 | — | 核对电源额定功率与线径 |
1. HEATER_ENABLED 默认关闭
src/main.cpp
中 constexpr bool HEATER_ENABLED = false;。此状态下 PID 会算出占空比但
不输出 PWM,加热不会误启动。
确认 GPIO40 的 HOT_PWM、GPIO3 的 NTC 引脚与 MOSFET 有效电平均正确后,
才可改为 true。
2. 热板 NTC 参数
加热模块有独立两芯 NTC,接 ADC_NTC(GPIO3,ADC1_CH2)。NTC 型号为
ZX-NTC1.25-P2ZZ,原理图上分压上臂电阻 R14 = 10 kΩ,故 seriesOhm 应取
10 kΩ。当前预设换算(已按原理图校正):
heaterBoardTemp = readNtcCelsius(Pin::ADC_NTC, 10000.0f, 10000.0f, 3950.0f);
readNtcCelsius(pin, seriesOhm, nominalOhm, beta) 的公式为
R_ntc = seriesOhm × raw / (4095 − raw),其中 seriesOhm 是与 NTC 串联的那只
固定电阻(即 R14),nominalOhm 是 NTC 在 25 ℃ 的标称阻值。此前误按
100 kΩ / B3950 预设(seriesOhm = nominalOhm = 100000.0f),与 R14 = 10 kΩ
不符,会把温度算错。若实物 NTC 阻值/β 与预设不同,请以万用表实测 25 ℃ 阻值为准再改。
3. INA226 地址与分流电阻
主板按原理图 R15 = 5 mΩ、I²C 地址 0x40(图纸 A1/A0 均接 GND)接入,量程 1 mA/LSB(
include/ina226_sensor.h
中 kShuntOhms = 0.005f)。实物地址不同则改 ina226.begin(Wire)。
⚠️ 分流电阻不能写错:电流换算依赖 Rshunt,校准寄存器 = 0.00512 / (Current_LSB × Rshunt)。实物 5 mΩ 却按 10 mΩ 写码,写进芯片的校准值只有一半,电流读数就只有真实值的
一半——"限流 8 A"实际要 16 A 才动作,硬过流保护(1.5 倍)也整体延后一倍。量一次实物
R15 的阻值,与 kShuntOhms 对齐,再用串口 d 自检打印的 cal 值复核。
INA226 用于加热电流软降功率;读取失败会在加热状态下触发故障保护(F-06)。
4. 仓温传感器 AHT20
AHT20 位于仓内,作为自动仓温闭环的输入。上电串口会打印
AHT20: detected / not detected,未检测到时仓温项显示为无效;若在预热或打印中
连续 3 秒无效,会锁定 Fault 并在故障页显示 F-01(AhtLost)。
5. GPIO45(BOARD_FAN)上电风险
GPIO45 是 ESP32-S3 的 strapping 脚,上电时选择 VDD_SPI 电压:
| GPIO45 上电电平 | VDD_SPI |
|---|---|
| 低(默认,内部弱下拉) | 3.3 V |
| 高 | 1.8 V |
本板用模组内置 flash,走默认 3.3 V,因此 GPIO45 在上电瞬间必须为低。
它接 BOARD_FAN MOS Q7 栅极,栅极是高阻输入,正常不会影响电平。
风险在于 MOS 栅极电阻分压或栅源电容残留把 GPIO45 拉高:一旦上电被读成高, 芯片会按 1.8 V 配置 VDD_SPI,与 3.3 V 的 flash 不匹配,直接启动失败。
首次上板烧录前,建议确认 Q7 栅极在上电瞬间没有把 GPIO45 拉高(示波器看 GPIO45 上升沿,或临时断开 BOARD_FAN 那路)。确认能正常启动后再接回去。 注意不要为了「保险」给 GPIO45 加上拉 —— 那恰好会触发 1.8 V 配置。
6. Flash 分区表
board_build.partitions = default_16MB.csv,含 app0 / app1 双槽,这是
ArduinoOTA 能工作的前提。详见 编译烧录与预编译固件。
PSRAM 与显示降级
板载 8 MB OPI PSRAM 硬件不可用(大块分配会挂死总线),因此 platformio.ini
改用 qio_qspi 变体,PSRAM 不并入堆。渲染随之走
TFT: direct-render fallback, PSRAM free=0 bytes 的直绘路径 —— 这是预期行为,
不是故障。