项目概述本项目以ESP32为主控通过I2C 接口扩展芯片 PCF8575将有限的主控引脚扩展为 16 路数字 I/O并在其上挂载模块作用4×4 矩阵键盘人机输入控制灯效与工作模式2 路高电平 LED状态指示 / 感应联动照明RGB 三色灯模块多色彩显示与颜色轮播SR505 人体感应有人自动开灯、无人自动灭灯ST7789 1.3 寸屏240×240实时显示模式、灯态、感应状态系统上电后默认进入AUTO人体感应模式有人靠近时两路 LED 点亮人离开后熄灭。同时可通过矩阵键盘切换到MANUAL手动模式独立控制 LED、RGB 颜色与轮播。核心目标在一块扩展芯片上同时演示I2C 通信、数字输出驱动、数字输入采集、矩阵键盘扫描、传感器联动与图形界面刷新。项目亮点一芯多用键盘扫描输入、LED/RGB 驱动输出、人体感应采集输入全部走 PCF8575充分展示 I/O 扩展器的双向能力。AUTO / MANUAL 双模式感应自动控灯与按键手动控灯可一键切换互不抢占 RGB。矩阵键盘完整消抖 边沿触发按一下只触发一次不会连发。RGB 独立轮播按键C控制颜色循环与感应模式解耦避免彩灯干扰 PIR。ST7789 卡片式 UI240×240 方形屏上分区显示 MODE / LED / RGB / PIR状态变化即时刷新、不整屏闪烁。接线容错键盘排线反向P17→P10时仅改掩码数组即可适配无需重插线。项目难点及解决方案难点现象解决方案PCF8575 高电平驱动能力弱LED 极暗甚至几乎不亮输出引脚与 VCC 之间加330Ω~1kΩ 上拉电阻写 1 时由电阻供电流写 0 时芯片灌电流关灯矩阵键盘与 LED 同芯片扫描键盘时误把 LED 熄灭所有写端口统一走writePort()始终保留当前ledState/rgbIndexRGB 点亮干扰 SR505开 RGB 后 PIR 一直判“有人”感应模式只控制两路 LED不驱动 RGBRGB 由按键C/0~7独立控制按键连发 / 抖动一次按下触发多次20ms 软件消抖 仅在“按下边沿”调用onKeyPressed()键盘排线方向反了按键识别错位用ROW_MASKS/COL_MASKS映射实际引脚代码适配硬件屏幕频繁全刷闪烁UI 闪、观感差静态背景只画一次drawStaticUI状态区脏标记刷新displayDirtySR505 供电不稳亮灯后 OUT 粘高、关不掉保证模块VCC 接牢 5VGND 共地必要时电源脚加滤波电容一、硬件系统部分1.1 硬件清单名称规格 / 说明数量零知ESP32 开发板带 USB 下载I2C 默认 GPIO21/221零知ESP32 扩展板带屏幕接口方便接线1PCF8575 模块I2C 16 位 I/O 扩展默认地址 0x2014×4 薄膜矩阵键盘8 线排针无源1高电平触发 LED 模块单路信号 VCC/GND2RGB LED 模块R/G/B 三路独立共阴或模块 GND1SR505 人体感应模块工作电压约 4.5~20VOUT 数字输出1ST7789 彩屏240×240SPITFT_eSPI 驱动1杜邦线、面包板—若干1.2 接线方案1ESP32 ↔ PCF8575I2CESP32PCF8575GPIO21SDASDAGPIO22SCLSCL5VVCCGNDGND2PCF8575 外设分配PCF8575 引脚外设方向P00LED1 信号输出P01LED2 信号输出P02RGB-R输出P03RGB-G输出P04RGB-B输出P05SR505 OUT输入P06、P07未用—P17~P14键盘行 R1~R4输出扫描P13~P10键盘列 C1~C4输入读取34×4 键盘排线对应关系本工程实际接法键盘正面朝上、排线朝下从左到右 8 根线排线左 → 右R1 R2 R3 R4 C1 C2 C3 C4 接 PCF8575 P17 P16 P15 P14 P13 P12 P11 P101.3 硬件连接图┌─────────────┐ │ ESP32 │ │ SDAGPIO21 ├──┐ │ SCLGPIO22 ├──┼── I2C 总线 │ SPI → TFT │ │ └──────┬──────┘ │ │ │ ┌────────────┴───┐ │ │ ST7789 240² │ │ │ (TFT_eSPI) │ │ └────────────────┘ │ │ ┌────────────────┴──────┐ │ PCF8575 0x20 │ │ │ P00 ──[上拉]── LED1 │ P01 ──[上拉]── LED2 │ P02 ──[上拉]── RGB R │ P03 ──[上拉]── RGB G │ P04 ──[上拉]── RGB B │ P05 ────────── SR505 OUT (→5V) │ P17..P14 ───── 键盘行 R1..R4 │ P13..P10 ───── 键盘列 C1..C4 │ └───────────────────────┘系统数据流示意1.4 实物连接图二、软件架构设计2.1 系统初始化setup初始化顺序与代码一致打开串口115200tft.init()setRotation()调用drawStaticUI()画静态背景Wire.begin(21, 22)I2C 时钟 100kHz探测 PCF8575 地址0x20是否应答writePort(0xFF00)LED/RGB 灭行列写 1P05~P07 保持输入读取一次 PIR 电平置displayDirty等待主循环刷新动态区2.2 主循环逻辑loop每个循环周期约 5ms 间隔依次执行A[scanMatrix 扫描键盘] -- B[消抖 边沿检测]B --|确认按下| C[onKeyPressed]B -- D{autoMode?}D --|是| E[handleMotion 有人开灯/无人灭灯]D --|否| F[跳过感应]E -- G[handleRgbCycle]F -- GG -- H[每 200ms 采样 PIR 电平]H -- I{displayDirty?}I --|是| J[updateDisplay]I --|否| K[delay 5ms]J -- K设计要点键盘优先先扫键再处理感应保证按键响应及时脏标记刷新只有状态变化才重画动态卡片降低 SPI 负担感应与 RGB 解耦handleMotion只改ledState不改rgbIndex三、代码拆分讲解3.1 底层读写 PCF8575void writePCF8575(uint16_t value); // 先低字节 P00-P07再高字节 P10-P17 uint16_t readPCF8575(); // requestFrom 2 字节拼成 16 位writePort(rowColBits)是关键写出口高字节负责行列扫描低字节始终合并ledBits()LED1/2 RGB 三通道UNUSED_LOWP05~P07 写 1保证 PIR 可被外部驱动3.2 矩阵键盘扫描scanMatrix逐行将对应行掩码拉低其余行/列写 1延时约 500µs 等待稳定读端口列位为 0 表示该键按下扫完后恢复行列全 1并保持 LED/RGB 状态不变消抖在loop中完成电平变化后稳定 ≥20ms且仅在按下瞬间触发事件。3.3 按键事件onKeyPressed按键行为0~7直接设 RGB 颜色关闭轮播A/B切换 LED1 / LED2并退出 AUTOC开关 RGB 轮播开从红色起每秒换色关RGB 熄灭D切换 AUTO / MANUAL#LED 全亮 RGB 白退出 AUTO停轮播*全灭退出 AUTO停轮播3.4 人体感应handleMotion读 P05 → 50ms 消抖得到motionStabletrueledState 0x03两灯亮falseledState 0x00两灯灭不修改 RGB进入 AUTO 时setAutoMode(true)会故意翻转一次稳定态强制按当前传感器电平立刻同步灯态。3.5 RGB 轮播handleRgbCyclergbCycle true时每 1000msrgbIndex在 1~7 循环红→绿→黄→蓝→紫→青→白。3.6 屏幕显示drawStaticUI()背景、顶栏、分区标签只跑一次updateDisplay()刷新 MODE / LED 圆点 / RGB 色点与名称 / PIR 状态与OUT:H/L四、操作过程及数据展示4.1 操作步骤接线检查I2CSDA/SCL、共地LED/RGBIN→P00/P01/P02/P03/P04SR505→5VOUT→P05-→GND键盘左→右接 P17→P10编译烧录开发板选 零知ESP32波特率 115200打开串口监视器应看到PCF8575 OK.与Ready.功能验证步骤操作预期现象①上电默认 AUTO屏显 MODEAUTO挥手 LED 亮离开后灭PIR 显示 MOTION/IDLE②按A/B进入 MANUAL对应 LED 翻转③按1~7RGB 变为对应颜色屏上颜色名同步④按CRGB 开始轮播屏显 CYCLE再按C停止并熄灭⑤按D在 AUTO / MANUAL 间切换⑥按#/*全开白/ 全关屏幕与串口对照屏右上角显示最近按键字符串口打印Key: x LED1:.. LED2:.. RGB:.. Auto:ON/OFF感应动作打印[Auto] Motion - LEDs ON/Idle - LEDs OFF按键速查表[1] [2] [3] [A] 0~7 : RGB 定色停轮播 [4] [5] [6] [B] A/B : LED1 / LED2 切换进 MANUAL [7] [8] [9] [C] C : RGB 轮播开关 [*] [0] [#] [D] D : AUTO / MANUAL #/* : 全开 / 全关4.2 演示视频零知派ESP32--通过PCF8575使用矩阵键盘控制LED五、技术原理5.1 工作原理1PCF8575 准双向口写1引脚为弱上拉/高阻输入态可被外部拉低也可外加上拉电阻对外供电写0强下拉灌电流能力强适合关断高电平 LED因此“高电平点亮 LED”必须外加电阻不能指望芯片内部弱上拉直接点灯2矩阵键盘扫描行列交叉处按下时被拉低的行会把对应列线拉低。MCU 逐行输出低电平并读列即可定位键位再经KEYMAP映射为0‘9’、‘A’D、*、#。3SR505 人体感应热释电传感器检测人体红外变化。检测到运动时 OUT 输出高电平并保持约数秒硬件固定SR505 一般不可调电位器。本工程以该数字电平作为“有人/无人”依据。4I2C 多设备与 SPI 屏PCF8575 独占 I2C本工程地址 0x20ST7789 走 SPI与 I2C 总线分离互不抢总线5.2 工作模式配置模式进入方式LEDRGB说明AUTO上电默认 / 按D切入由 SR505 自动控制不联动仍可用C/0~7手动控屏显绿色 AUTOMANUAL按A/B/#/*或D切出按键手动按键手动屏显橙色 MANUAL相关宏配置可按硬件微调#define PCF8575_ADDR 0x20 // I2C 地址A0/A1/A2 接地时通常为 0x20 #define LED_ACTIVE_LOW 0 // 0高电平亮上拉接法1低电平亮灌电流接法 #define MOTION_ACTIVE_HIGH 1 // 1OUT 高表示有人模块相反则改 0 const uint32_t MOTION_DEBOUNCE_MS 50; const uint32_t DEBOUNCE_MS 20;键盘引脚映射本工程反向排线ROW_MASKS {P17, P16, P15, P14}; COL_MASKS {P13, P12, P11, P10};六、常见问题指引Q1串口提示PCF8575 not found at 0x20检查 SDA/SCL 是否接 GPIO21/22、模块供电与共地用 I2C 扫描确认实际地址若跳线改地址同步改PCF8575_ADDR。Q2按键识别错位按 1 变成别的键排线方向或行列对调。对照本文 1.2 节改线或只改ROW_MASKS/COL_MASKS/KEYMAP。Q3按一下键触发很多次确认使用的是边沿触发消抖逻辑机械抖动过大时可把DEBOUNCE_MS提到 30~50。