news 2026/8/15 23:08:19

零知派ESP32--通过I2C 接口扩展芯片PCF8575使用矩阵键盘控制LED

作者头像

张小明

前端开发工程师

1.2k 24
文章封面图
零知派ESP32--通过I2C 接口扩展芯片PCF8575使用矩阵键盘控制LED

项目概述

本项目以ESP32为主控,通过I2C 接口扩展芯片 PCF8575,将有限的主控引脚扩展为 16 路数字 I/O,并在其上挂载:

模块作用
4×4 矩阵键盘人机输入,控制灯效与工作模式
2 路高电平 LED状态指示 / 感应联动照明
RGB 三色灯模块多色彩显示与颜色轮播
SR505 人体感应有人自动开灯、无人自动灭灯
ST7789 1.3 寸屏(240×240)实时显示模式、灯态、感应状态

系统上电后默认进入AUTO(人体感应)模式:有人靠近时两路 LED 点亮,人离开后熄灭。同时可通过矩阵键盘切换到MANUAL(手动)模式,独立控制 LED、RGB 颜色与轮播。

核心目标:在一块扩展芯片上同时演示I2C 通信、数字输出驱动、数字输入采集、矩阵键盘扫描、传感器联动与图形界面刷新


项目亮点

  1. 一芯多用:键盘扫描(输入)、LED/RGB 驱动(输出)、人体感应采集(输入)全部走 PCF8575,充分展示 I/O 扩展器的双向能力。
  2. AUTO / MANUAL 双模式:感应自动控灯与按键手动控灯可一键切换,互不抢占 RGB。
  3. 矩阵键盘完整消抖 + 边沿触发:按一下只触发一次,不会连发。
  4. RGB 独立轮播:按键C控制颜色循环,与感应模式解耦,避免彩灯干扰 PIR。
  5. ST7789 卡片式 UI:240×240 方形屏上分区显示 MODE / LED / RGB / PIR,状态变化即时刷新、不整屏闪烁。
  6. 接线容错:键盘排线反向(P17→P10)时,仅改掩码数组即可适配,无需重插线。

项目难点及解决方案

难点现象解决方案
PCF8575 高电平驱动能力弱LED 极暗甚至几乎不亮输出引脚与 VCC 之间加330Ω~1kΩ 上拉电阻,写 1 时由电阻供电流,写 0 时芯片灌电流关灯
矩阵键盘与 LED 同芯片扫描键盘时误把 LED 熄灭所有写端口统一走writePort(),始终保留当前ledState/rgbIndex
RGB 点亮干扰 SR505开 RGB 后 PIR 一直判“有人”感应模式只控制两路 LED,不驱动 RGB;RGB 由按键C/0~7独立控制
按键连发 / 抖动一次按下触发多次20ms 软件消抖 + 仅在“按下边沿”调用onKeyPressed()
键盘排线方向反了按键识别错位ROW_MASKS/COL_MASKS映射实际引脚,代码适配硬件
屏幕频繁全刷闪烁UI 闪、观感差静态背景只画一次(drawStaticUI),状态区脏标记刷新(displayDirty
SR505 供电不稳亮灯后 OUT 粘高、关不掉保证模块VCC 接牢 5V,GND 共地;必要时电源脚加滤波电容

一、硬件系统部分

1.1 硬件清单

名称规格 / 说明数量
零知ESP32 开发板带 USB 下载,I2C 默认 GPIO21/221
零知ESP32 扩展板带屏幕接口,方便接线1
PCF8575 模块I2C 16 位 I/O 扩展,默认地址 0x201
4×4 薄膜矩阵键盘8 线排针,无源1
高电平触发 LED 模块单路信号 + VCC/GND2
RGB LED 模块R/G/B 三路独立,共阴或模块 GND1
SR505 人体感应模块工作电压约 4.5~20V,OUT 数字输出1
ST7789 彩屏240×240,SPI,TFT_eSPI 驱动1
杜邦线、面包板若干

1.2 接线方案

(1)ESP32 ↔ PCF8575(I2C)

ESP32PCF8575
GPIO21(SDA)SDA
GPIO22(SCL)SCL
5VVCC
GNDGND

(2)PCF8575 外设分配

PCF8575 引脚外设方向
P00LED1 信号输出
P01LED2 信号输出
P02RGB-R输出
P03RGB-G输出
P04RGB-B输出
P05SR505 OUT输入
P06、P07未用
P17~P14键盘行 R1~R4输出扫描
P13~P10键盘列 C1~C4输入读取

(3)4×4 键盘排线对应关系(本工程实际接法)

键盘正面朝上、排线朝下,从左到右 8 根线:

排线左 → 右:R1 R2 R3 R4 C1 C2 C3 C4 接 PCF8575: P17 P16 P15 P14 P13 P12 P11 P10

1.3 硬件连接图

┌─────────────┐ │ ESP32 │ │ SDA=GPIO21 ├──┐ │ SCL=GPIO22 ├──┼── 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

初始化顺序与代码一致:

  1. 打开串口115200
  2. tft.init()+setRotation(),调用drawStaticUI()画静态背景
  3. Wire.begin(21, 22),I2C 时钟 100kHz
  4. 探测 PCF8575 地址0x20是否应答
  5. writePort(0xFF00):LED/RGB 灭,行列写 1,P05~P07 保持输入
  6. 读取一次 PIR 电平,置displayDirty,等待主循环刷新动态区

2.2 主循环逻辑(loop

每个循环周期(约 5ms 间隔)依次执行:


A[scanMatrix 扫描键盘] --> B[消抖 + 边沿检测]
B -->|确认按下| C[onKeyPressed]
B --> D{autoMode?}
D -->|是| E[handleMotion 有人开灯/无人灭灯]
D -->|否| F[跳过感应]
E --> G[handleRgbCycle]
F --> G
G --> H[每 200ms 采样 PIR 电平]
H --> I{displayDirty?}
I -->|是| J[updateDisplay]
I -->|否| K[delay 5ms]
J --> K

设计要点:

  • 键盘优先:先扫键再处理感应,保证按键响应及时
  • 脏标记刷新:只有状态变化才重画动态卡片,降低 SPI 负担
  • 感应与 RGB 解耦handleMotion只改ledState,不改rgbIndex

三、代码拆分讲解

3.1 底层读写 PCF8575

void writePCF8575(uint16_t value); // 先低字节 P00-P07,再高字节 P10-P17 uint16_t readPCF8575(); // requestFrom 2 字节拼成 16 位

writePort(rowColBits)是关键写出口:高字节负责行列扫描,低字节始终合并:

  • ledBits():LED1/2 + RGB 三通道
  • UNUSED_LOW:P05~P07 写 1,保证 PIR 可被外部驱动

3.2 矩阵键盘扫描scanMatrix

  1. 逐行将对应行掩码拉低,其余行/列写 1
  2. 延时约 500µs 等待稳定
  3. 读端口,列位为 0 表示该键按下
  4. 扫完后恢复行列全 1,并保持 LED/RGB 状态不变

消抖在loop中完成:电平变化后稳定 ≥20ms,且仅在按下瞬间触发事件。

3.3 按键事件onKeyPressed

按键行为
0~7直接设 RGB 颜色,关闭轮播
A/B切换 LED1 / LED2,并退出 AUTO
C开关 RGB 轮播(开:从红色起每秒换色;关:RGB 熄灭)
D切换 AUTO / MANUAL
#LED 全亮 + RGB 白,退出 AUTO,停轮播
*全灭,退出 AUTO,停轮播

3.4 人体感应handleMotion

  • 读 P05 → 50ms 消抖得到motionStable
  • trueledState = 0x03(两灯亮)
  • falseledState = 0x00(两灯灭)
  • 不修改 RGB

进入 AUTO 时,setAutoMode(true)会故意翻转一次稳定态,强制按当前传感器电平立刻同步灯态。

3.5 RGB 轮播handleRgbCycle

rgbCycle == true时,每 1000ms:rgbIndex在 1~7 循环(红→绿→黄→蓝→紫→青→白)。

3.6 屏幕显示

  • drawStaticUI():背景、顶栏、分区标签(只跑一次)
  • updateDisplay():刷新 MODE / LED 圆点 / RGB 色点与名称 / PIR 状态与OUT:H/L

四、操作过程及数据展示

4.1 操作步骤

  1. 接线检查

    • I2C:SDA/SCL、共地
    • LED/RGB:IN→P00/P01/P02/P03/P04
    • SR505:+→5V,OUT→P05,-→GND
    • 键盘:左→右接 P17→P10
  2. 编译烧录

    • 开发板选 零知ESP32,波特率 115200
    • 打开串口监视器,应看到PCF8575 OK.Ready.
  3. 功能验证

步骤操作预期现象
上电默认 AUTO屏显 MODE=AUTO;挥手 LED 亮,离开后灭;PIR 显示 MOTION/IDLE
A/B进入 MANUAL;对应 LED 翻转
1~7RGB 变为对应颜色;屏上颜色名同步
CRGB 开始轮播,屏显 CYCLE;再按C停止并熄灭
D在 AUTO / MANUAL 间切换
#/*全开(白)/ 全关
  1. 屏幕与串口对照
    • 屏右上角显示最近按键字符
    • 串口打印: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 工作原理

(1)PCF8575 准双向口

  • 1:引脚为弱上拉/高阻输入态,可被外部拉低,也可外加上拉电阻对外供电
  • 0:强下拉,灌电流能力强(适合关断高电平 LED)
  • 因此“高电平点亮 LED”必须外加电阻,不能指望芯片内部弱上拉直接点灯

(2)矩阵键盘扫描

行列交叉处按下时,被拉低的行会把对应列线拉低。MCU 逐行输出低电平并读列,即可定位键位,再经KEYMAP映射为'0'`‘9’`、`‘A’`'D''*''#'

(3)SR505 人体感应

热释电传感器检测人体红外变化。检测到运动时 OUT 输出高电平,并保持约数秒(硬件固定,SR505 一般不可调电位器)。本工程以该数字电平作为“有人/无人”依据。
(4)I2C 多设备与 SPI 屏

  • PCF8575 独占 I2C(本工程地址 0x20)
  • ST7789 走 SPI,与 I2C 总线分离,互不抢总线

5.2 工作模式配置

模式进入方式LEDRGB说明
AUTO上电默认 / 按D切入由 SR505 自动控制不联动;仍可用C/0~7手动控屏显绿色 AUTO
MANUALA/B/#/*D切出按键手动按键手动屏显橙色 MANUAL

相关宏配置(可按硬件微调):

#define PCF8575_ADDR 0x20 // I2C 地址,A0/A1/A2 接地时通常为 0x20 #define LED_ACTIVE_LOW 0 // 0=高电平亮(上拉接法);1=低电平亮(灌电流接法) #define MOTION_ACTIVE_HIGH 1 // 1=OUT 高表示有人;模块相反则改 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。

版权声明: 本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若内容造成侵权/违法违规/事实不符,请联系邮箱:809451989@qq.com进行投诉反馈,一经查实,立即删除!
网站建设 2026/8/15 23:07:54

2026年7月拉萨市二手房价格深度分析报告

一、报告背景与数据说明本报告基于2026年7月拉萨市二手房市场实际成交案例,结合成交价格、户型结构、区域分布、楼层朝向等多维度数据,对当前拉萨市二手房价格走势进行深度剖析。报告旨在为购房者、投资者及行业从业者提供客观、真实的市场参考。数据来源…

作者头像 李华
网站建设 2026/8/15 23:05:24

机器学习泛化理论:均匀稳定性与无对数矩界推导

在机器学习理论中,算法的泛化能力是衡量其从训练数据学习并推广到未见数据的关键指标。一个核心问题是:我们能否仅通过算法在训练集上的表现,来严格地界定其在未知数据上的预期风险?这催生了泛化误差界的研究。其中,均…

作者头像 李华
网站建设 2026/8/15 23:00:06

CTF竞赛:大学生网络安全实战技能提升与职业发展黄金路径

最近在后台收到不少计算机相关专业同学的私信,问得最多的就是:“学长,大学里要不要参加CTF比赛?感觉大家都在卷算法和项目,搞CTF是不是有点‘不务正业’?” 作为一个过来人,我想说,如…

作者头像 李华
网站建设 2026/8/15 22:52:20

Token钱包下载APP代码开发流程

随着Web3.0生态持续发展,各类链上资产、多链代币、去中心化应用(DApp)快速普及,Token钱包作为用户管理链上资产、私钥、助记词、参与链上交互的核心入口,是Web3生态中最重要的基础设施之一。为满足项目标准化展示、Token钱包下载APP导流入口地址【imTK.公司】、用户引导、版本统…

作者头像 李华
网站建设 2026/8/15 22:51:00

Oil Motion:让 AI 生成的动画“听从“你的滚动

用自然语言告诉 AI 你想要什么动画,然后让页面滚动、鼠标移动、触摸手势来控制它——Oil Motion 把 AI 视频生成和网页交互之间的那层墙拆掉了。 这个项目解决什么问题? 2026 年 8 月,GitHub 上出现了一个叫 Oil Motion 的项目,一…

作者头像 李华