
esp32s3三模小键盘
简介
esp32s3作为主控的小键盘,支持有线、蓝牙、espnow连接(需另一个esp设备)。可选的屏幕、旋转编码器、usb hub和ina226电流检测功能。可以使用网页或msc配置键盘和更新固件。
简介:esp32s3作为主控的小键盘,支持有线、蓝牙、espnow连接(需另一个esp设备)。可选的屏幕、旋转编码器、usb hub和ina226电流检测功能。可以使用网页或msc配置键盘和更新固件。开源协议
:GPL 3.0
描述
之前做过一版用arduino实现的键盘,但后来对外形不太满意,有些功能也不知道怎么实现,干脆改用esp-idf重新做了一遍,修改了硬件,增加(也减少)了部分功能。
因为功能比较杂,我也没优化内存使用,所以至少需要2MB psram版本的esp32s3,没有psram的esp32s3同时开启部分功能时会爆内存。
视频介绍:点我跳转到b站

这款键盘设计初衷是功能足够的前提下尽可能有性价比,但如果啥元件都没有从头开始做,还只做一个,价格也没法压很低,大致统计如下,没有计算使用优惠券的情况,详细信息放在附件的bom表里了。

更新日志
最新键盘固件以github中的文件为准,附件中固件不一定会及时更新。
- 2025.9.28
- 对rgb灯部分进行验证,修复固件中的bug,当前该功能硬件存在问题,详见rgb灯部分。github上最新固件默认设置的rgb灯数量由1改为24。
功能介绍
有线、蓝牙、espnow三模
- espnow模式
- 类似接收器模式,需要另一个设备有线连接电脑并接收本键盘发送的数据,我使用的是另一个esp32s3,但像esp32s2这种支持usb和wifi的应该都可以,如果esp设备本身不支持usb,就需要额外的usb芯片了。
- 睡眠唤醒时不吞键:
- espnow模式下,可以做到睡眠模式唤醒时不吞键。
- 蓝牙模式下无法做到睡眠唤醒时不吞键,必须等设备唤醒后连接上蓝牙,才能向主机(电脑)输入按键。
- 按键本身状态可以被记录,只是要等待蓝牙连接,我体感短时间内断连后重连需要1s以上,如果这种延迟后再输入按键,感觉会很奇怪。
- 有线模式下理论上不需要睡眠。
- 蓝牙功能没有做多设备切换支持。
- 整活功能:三种模式可以同时开启,连接相同或不同的设备,但不保证这种情况下不吞键。
全键无冲,媒体按键,2层fn层,原始层和fn层切换
- 键盘外形:
- 类似108键键盘的小键盘区,共6行4列,enter等大键都拆成了两个小键,想要大键的大概需要自行修改pcb,或将按键设置相同功能,然后自行设计和3d打印大键键帽。
- 因为有额外引脚,所以还可以增加一列,但我目前只在这列放了一个按键,见封面图键盘第五列的右侧面位置,需要更多的可自行设计扩展或修改pcb。
。
- 原始层和fn层切换功能:
- 切换后,直接按就是fn层按键,按住fn后为原始层按键,睡眠或重启后不保留切换状态,会恢复默认。
- 和之前使用arduino的实现相比,没有做组合键功能,如果需要,本键盘支持部分在普通108键键盘上并不存在的按键,可以考虑结合powertoys等电脑上的软件来实现组合键。
- 如果刚需组合键,可以给我反馈,描述具体需求,我要根据具体需求来考虑实现。
- arduino版本说明和源码放在附件了,感兴趣可以看看,支持配置组合键,但不支持网页功能。
可以和按键互相替换的功能
-
屏幕
- 第一行的第1、2或2、3列可以替换为屏幕:
- 屏幕支持显示当前键盘上每个键对应的功能,显示按键被按下的状态。
- 被按下的按键覆盖阴影:
- 部分按键必须手动在固件中设置要显示在屏幕上的字符串,比如所有不可直接显示的字符。
- 如果关闭屏幕后再打开,控制屏幕亮灭的按键可能会显示为错误状态,需要按一下刷新状态或慢点松开按键。
- 被按下的按键覆盖阴影:
- 屏幕支持显示部分键盘信息:
- 显示usb、蓝牙、espnow、wifi功能的开关和连接状态。
- 我把espnow设计为完全不做额外通信,所以设备断连或可以连接时不一定能及时检测到并改变显示。
- 显示usb的vbus引脚电压、电池电压、ina226采集到的电压、电流、功率信息。
- 显示numlock和capslock的锁定状态,但可能不稳定。
- 如果同时使用多个模式连接了多个不同设备,显示优先级为有线>蓝牙>espnow,如果高优先级设备断开,指示灯不会自动切换为其它设备的状态。
- 显示usb、蓝牙、espnow、wifi功能的开关和连接状态。
- 屏幕可以显示自定义的png图片,和上述屏幕信息显示二选一(可在运行时切换)。

- 在信息显示界面其实也可以显示图片,但会因为信息刷新导致很卡,可能可以优化,但代价是内存需求进一步增加,不想搞。
-
旋转编码器(旋钮)
- 第一行的第4列可以替换为旋转编码器。
- 如果使用我当前的方案,做完后不支持在编码器位置安装按键,因为2.54mm的排母太高了,会挡住键帽,不过我脑测换成带爪簧的套筒可解决问题。
- 套筒图,有不封底和封底两种:

usb2.0 hub和ina226扩展

- 当前版本的数据口是直连的sl2.1a这个hub芯片,esp32s3的usb引脚连接到sl2.1a,再引出两个typeA和一个typeC引脚,还有一个typeC引脚专门用于供电。
- hub的供电口只给hub2、3、4连接的设备供电,不给esp32s3供电,但主数据口会给所有设备供电。
- sl2.1a部分情况下兼容性不好,如果不需要,可以直接飞线将esp32s3的usb引脚连接到数据口。
- ina226用于检测hub上的电压、电流和功率(不包括esp32s3)。
RGB灯(未完全验证)
- 每个按键下方预留了rgb灯的位置,兼容侧刻键帽。

- 目前灯配置了如上模式,都是官方例程中的预设模式,支持调节单色模式时的亮度和的颜色。
- 调节灯光亮度时,因为电压与亮度关系不线性,颜色会有变化。
- 在当前电路下,如果要使用电阻限流,根据灯珠数量不同可能需要调整阻值,我验证了在24个灯珠时,使用20Ω电阻可能存在的问题。
- 存在的问题:
- rgb供电电路的开关无法完全控制电源的开启和关闭,因为控制开关的mos管连接5v供电,但控制端使用的3.3v,如果需要能切断供电,需要做好保护措施后,将控制端连接5v供电,或选择要更大压差才开启的mos管。
- 当前电路将rgb亮度设置为低于一定值时,灯光会出现肉眼可见的闪烁,不确定是软件还是硬件问题,但供电问题嫌疑较大,待验证加大rgb供电端电容的作用。
- 建议考虑抛弃当前供电电路,添加一个led恒流驱动供电。
通过网页或者msc功能修改配置和更新固件
-
网页功能:
- 事先声明:网页是使用ai构建的框架,部分不人性化或者有bug的地方大概率是我不会或懒得改,别人/机写的代码我是改不了一点 。
- 本键盘有http服务器功能,可以通过键盘的ap(wifi热点)让键盘作为sta(连路由器)访问键盘服务器。
- 注意,espnow模式和ap、sta模式不能同时开启,因为espnow也是利用了wifi协议,sta模式可能导致信道改变,睡眠不通信时,无法保证键盘和接收器间信道一致,影响唤醒时的初次数据传输,而我不建议初次配置以外再使用ap模式,所以简单粗暴地禁止它们同时开启了其实就是懒。
- 连接键盘的ap:

- 默认设置下开启键盘的ap功能后,应该可以搜索到一个名为ESP32AP_xxxx的wifi,连接密码为esp32passwd;
- 连接上ap后,如果设备有mdns功能,可以使用esp32.local访问网页,如果没有,就需要找到键盘的ip,通过ip访问,ap模式的默认ip为192.168.4.1
- 对于windows设备,要装bonjour服务才会有mdns功能,是个苹果家的打印机服务,去苹果官网下。
- 键盘作为sta连路由器:
- esp32s3只支持2.4g的wifi,配置wifi名和密码后,打开sta功能就会自动连接路由器,可以在固件中、通过网页或msc进行配置,具体步骤见后面的网页和msc配置功能介绍。
- 访问网页:
- 可以通过esp32.local(可在固件中修改)或ip访问键盘的网页并进行一些控制,服务器会自动重定向到最高优先级的网页,默认是一个导航网页:


- 因为ap和sta模式的mdns都使用esp32.local作为键盘的域名,如果一个有线电脑和键盘连接到同一个路由器,电脑的无线网卡又连接了键盘的ap,用esp32.local访问可能变慢,这种情况下建议用ip访问,更建议不要同时开启sta和ap功能。
- 设备配置页面:

- 这里可以查看和修改设备的当前配置,如果要让键盘连接路由器,可以在网络设置里输入wifi名称和密码,然后点击应用配置,我还在部分选项右侧放了注释。
- 注意:应用配置后,设备会重启来应用配置,建议应用后手动刷新一次页面来获取最新配置,部分配置重启后可能会自动恢复初始,比如睡眠模式开关,重启后默认打开。
- 按键设置页面:

- 这里可以修改键盘按键的配置,点击对应按键后,可以选择按键类型,并选择可能需要的按键值,可以输入关键词来筛选我预先配置了的选项,如果你知道自己在做什么,也可以输入具体的值来将按键配置为我没有预设的选项,当然也得看键盘是否支持。
- 设置完后,同样需要点击应用配置按钮,键盘会自动重启来应用配置。
- 文件服务器页面:

- 文件服务器可以访问和管理flash中fat分区的数据,也可以上传文件和删除文件,键盘配置的修改也是基于这些数据,关于部分数据的具体作用,见后续网页相关数据和通过msc配置部分。
- 注意:不要随便点击较大文件的链接,可能会触发下载而硬控键盘几十秒。
- 网页相关数据:
- 网页相关数据都放在/web/这个文件夹下,所有类似/any/dir/filename.ext的访问,如果没有匹配到其它有效路径,都会被重定向到/web/路径下,即会访问/web/any/dir/filename.ext。
- 直接访问esp32.local或ip时,会自动重定向,优先级为:/web/index.html > /web/control/index.html > /web/fileserver/index.html ,其中第二个是上述导航页面,第三个是上述文件服务器页面,第一个页面默认不存在,如果你想用自己的页面,可以将它放到
/web/index.html下。
- 自定义网页和网页控制键盘的api:
- 如果对默认的网页不满意,可以修改对应的网页文件,默认情况下/web/文件夹里的文件都是写入固件里的,如果已存在,键盘不会修改它,如果不存在,会在重启时自动创建,可以上传新的文件覆盖,也可以根据重定向优先级,添加高优先级的index.html文件,下面列出可能需要的uri。
-
api/fileget?path=/file/to/get.ext 获取路径参数对应的文件 api/filelist?path=/dir 获取文件夹下的文件列表 api/fileupload?path=/path/to/upload.ext 上传文件到对应路径下,仅支持post api/filedelete?path=/file/to/delete.ext 删除对应文件 api/rename?old_path=xxx&new_path=xxx 重命名文件或文件夹,路径需要为绝对路径,也可以用于实现剪切操作 api/dev 可用于检查设备是否在线 api/dev/curconfig 返回当前的设备设置和按键设置 api/dev/defconfig 返回固件中默认的设备设置和按键设置,设置会在开机时自动获取并保存,所以如果开机后手动删了,就得重启后才能尝试获取 api/dev/nvsconfig 返回当前的设备设置 api/dev/kbdconfig 返回当前的按键设置 api/dev/getinfo 获取一些设备采集到的信息 api/dev/restart 重启设备 api/dev/update 尝试触发设备固件更新,需要满足一定条件,见下文 api/dev/setconfig?path=/config/file&restart=n 加载配置,后面的两个参数为可选项,当存在restart=n时,设备在应用配置后不会自动重启,其它情况都会自动重启,当为GET请求时,必须存在path参数,参数对应键盘fat分区中实际存在的配置文件,会应用那个配置文件,当为POST请求时,需要发送要应用的配置,如果存在path参数,会在应用配置后将配置文件保存在path所在路径 api/dir?type=xx&path=/dir/path 文件夹操作,path为要操作的文件夹路径,type参数有两个可选值,mk和rm,分别为新建和删除文件夹,文件夹为空才能删除
- 可以通过esp32.local(可在固件中修改)或ip访问键盘的网页并进行一些控制,服务器会自动重定向到最高优先级的网页,默认是一个导航网页:
-
msc功能
- msc即大容量存储设备,将键盘模拟成一个u盘,可以通过电脑的文件资源管理器管理键盘fat分区中的文件。
- 可以通过网页或按键盘上的对应按键开启msc功能,开启后重启进入msc模式,在msc模式重启后会自动恢复默认的键盘模式。
- msc模式和键盘模式不兼容,另外,进入msc模式后,需要通过电源开关来重启。
- 在msc模式中配置键盘(键盘配置数据指南)
- 键盘的配置数据主要是json格式,数据默认放在
/.configs/文件夹中,其中/.configs/.data/文件夹中存放了部分键盘生成的文件。 - 让键盘应用配置需要修改
/.configs/configIndex.json文件,将其中的configChange值改为true,并将configPath的值改为配置文件的路径,路径如果以"/"开头则为绝对路径,不以"/"开头,则被认为是/.configs/文件夹下的相对路径。 /.configs/.data/下的文件/.configs/.data/defCfgs.json为在读取用户配置前生成的固件默认配置,json配置的格式可以参考该文件,修改不会影响键盘运行,但通过网页api获取默认配置时是获取的该文件内容。- 更推荐通过网页修改配置,直接编辑json格式不够直观。
/.configs/.data/keys.bin是键盘每次启动时实际读取的按键配置,会在每次应用新的按键配置时生成,如果手动删除,且没有应用按键配置,则会使用默认的按键配置。- 如果有其它文件,则是某一时刻应用了用户配置后生成的当前配置,也可以作为配置的模板。
- 键盘的配置数据主要是json格式,数据默认放在
-
更新固件
- 可以通过msc复制文件或网页上传文件来更新固件。
- 固件更新的条件,通过msc模式更新
- 首先要确定这个固件兼容你的esp32s3模块,且固件大小不能大于fat分区的大小,固件应该使用相同大小的分区表文件,我没有测试过使用不同分区表固件的情况。
- 固件需要放在
/__bin_/update.bin路径,且要保证不存在/__bin_/OK.README.txt文件,尝试更新后,键盘会自动生成/__bin_/OK.README.txt文件用来指示已经尝试过更新,防止多次尝试更新,所以需要手动删除。 - 最后需要修改配置文件,将设备配置的
checkUpdate值改为1,这个值会在每次启动后或尝试更新后被重置为0。
- 通过网页更新,推荐
- 首先查看上述固件更新条件,确定固件可用,然后通过文件服务器将固件上传到
/__bin_/update.bin路径,删除/__bin_/OK.README.txt文件。- 如果不存在
/__bin_/文件夹,需要先使用新建文件夹的请求esp32.local/api/dir?type=mk&path=/__bin_/新建文件夹。
- 如果不存在
- 最后使用
esp32.local/api/dev/update请求更新固件即可,固件大小为1-2MB时,通过网页上传到键盘的flash至少需要约30s,请耐心等待。
- 首先查看上述固件更新条件,确定固件可用,然后通过文件服务器将固件上传到
控制键盘配置的功能按键在屏幕上的缩写
- 因为屏幕显示范围有限,部分屏幕上显示的功能按键缩写比较抽象,在此列出并解释。
-
按键的枚举值 在屏幕上显示的缩写 功能描述 0 RST 重启设备 1 DS 手动让设备进入深睡,可能会延迟几秒 2 MSC 设置下次启动时进入msc模式,需要手动重启 3 USB 切换usb键盘功能开关 4 BLE 切换蓝牙键盘功能开关 5 STA 切换sta模式开关,不能和espnow同时开启,espnow模式开启时无法开启 6 AP 切换ap模式开关,不能和espnow同时开启,espnow模式开启时无法开启 7 NOW 切换espnow模式开关,不能和ap以及sta模式同时开启,并且开启时会自动关闭ap或sta模式 8 SCR 切换屏幕的开关 9 BRI 切换屏幕的亮度,在10%-100%间循环,每次按下增加10% 10 SEN 切换自动进入深睡模式开关,默认开启,关闭后长时间无操作不会自动进入深睡,重启强制恢复默认 11 PAI espnow模式下配对接收器,按下后会马上清除原配对信息 12 LOG 调试用,输出log等级,平时使用时建议调至error或none 13 ERA 清除nvs配置,即清除设备配置,不包括按键配置 14 LVS 切换屏幕的界面,在信息显示界面和自定义图片界面切换 15 LED 切换led灯光模式 16 LBR 当led为单色模式时,调节灯光亮度,不会为0,要关灯请通过灯光模式调节
接收器按键功能
- 接收器默认用boot按键作为功能键,因此应该任意开发板都可用。
- 双击boot键切换usb键盘的开关,开机恢复默认。
- 三击boot键设置下次启动模式为msc模式,重启后进入msc模式。
- 注意,没做超时判定,三击之前一定会触发双击。
- 长按boot键删除原配对信息,进入配对模式。
焊接和安装
焊接
我大致整理了一下bom放在附件,但其中的具体型号仅供参考,建议根据封装、值和备注自行选型,部分焊盘为预留位可以不焊,请结合下面的实物图食用。
做的时候满脑子都是模块化,功能可选,所以分的板子比较多orz,需要3个月(算上定位板4个月)才能白嫖打完所有板子,原理图和板子布局也很乱,需要优化的地方很多,但因为能跑起来,所以我懒得动了。
- 键盘控制板
- 本板子为工程中的“键盘控制板”,我放了4层和2层两个版本,已验证版本为4层板。
- 板子厚度为1mm,如果要阻抗,选择JLC04101H-3313。(不过板子没有高速线路,阻抗应该影响不大)
- 别问我为啥天线放内侧,电源放在可能被手干扰的外侧,整体布局瞎改导致的orz。
- 键盘上板和下板
- 本板子为工程中的“键盘上板”和“键盘下板”,已验证版本为带“已验证”前缀的,但建议使用带“优化”前缀的,因为已验证版本漏加了一个二极管。
- 板子厚度为1.6mm,板子厚度需要根据轴座的突起部分选择
。 - bom是从“02-键盘矩阵板”导出的,其中的位号可能和键盘上/下板文件不同。

- 上板注意事项:
- 图中左上旋转编码器位置不需要电容,加了电容会导致睡眠中启动时,没法正确检测到编码器旋转方向。
- 如果要rgb灯,请结合原理图确认引脚定义,我买的灯珠标识的方向和封装上标识的方向就不一样。
- 上下板中中间行的rgb灯焊盘方向和另外两行不一样,务必注意。
- 图中下方的col4焊盘对应额外的第5列,这列我只在下板设计了1个按键,因为fpc连接器引脚数不够,只能额外接线。
- 如果不需要上下板分离,可以直接将下方这排焊盘和下板上方的这排焊盘焊到一起,就不需要通过fpc排线连接。

- 下板注意事项:
- 同上板,col4的焊盘要额外接线。
- 图中侧面的额外按钮少了一个二极管,在“已优化”版本中添加上了。
- 屏幕转接板
- 本板子为工程中的“插接屏幕”。
- 推荐板子厚度为1.6mm。

- 注意事项:
- 最上面那排焊盘和右下方的fpc焊盘是方便测试用,没实际作用。
- 图中的fpc连接器选得太宽了,插不进定位板的键盘按键开孔,建议选型时考虑更短的。
- 旋转编码器模块
- 本板子为工程中的“旋转编码器模块”。
- 推荐板子厚度为1.6mm。

- 注意事项:
- 如果不在意晃动,这个转接板其实可以不打,ec11直接插到排母里也能被识别。
- 先把编码器引脚焊接到孔位内侧,再根据键盘上板插编码器的孔位在孔外侧焊接排针,最后可以把排针胶壳弄下来降低高度。
- 如果参考我的方案,建议编码器尽可能矮。
- hub转接板和电流传感器
- 本板子为工程中的“usb_hub转接板”,如果不需要该板来连接键盘上下板,建议使用“usb_hub转接板_小”。
- 如果要通过该板连接键盘上下板,建议1.6mm厚度,如果不需要则厚度随意。

- 注意事项:
- 红圈内为电流传感器相关元件。
- 定位板
- 建议使用工程中的“贰-上/下板定位板”。
- 厚度选择1.6mm,如果不用pcb定位板,能控制厚度则要1.5mm。
安装
我的安装方案如下图,在垂直方向上使用螺柱来连接各个板,放到外壳中时,主要靠定位板来支撑,下图是不使用外壳的版本参考,在四角使用螺柱将键盘架起一定高度和角度。
定位板和矩阵板之间的螺柱高度不建议更改,矩阵板、控制板、hub转接板之间的高度可以加高,但不建议更低,当前使用的高度下,hub转接板的typea接口可能碰到控制板上的元件,建议控制板上贴层胶。

- 连接定位板和按键矩阵板

- 红框螺丝位置先接上3.5mm高的双通螺柱,螺丝选用3mm高,也可一侧3mm另一侧4mm;
- 在旋转编码器位置,如果觉得旋转编码器容易晃动,可以预先插上向上的螺丝来固定,该处孔位小于m2,可以用m1.4或m1.2;
- 注:侧面的按钮如果卡不进定位板,可能需要剪钳修剪下金属支架;
- 背面示意图如下,黄圈处安装4mm单通螺柱,红圈处安装10mm单通螺柱,紫圈处安装螺丝,如果要用hub转接板连接上下板,蓝圈处安装10mm单通螺柱,否则也可换成螺丝。

- 连接键盘矩阵板和控制板
- 接螺丝前,需要先在键盘矩阵板上插上fpc排线,矩阵板上40pin底座旁的底座用于连接ina226电流传感器,如果不需要可不接;

- 接上排线后,按上图红圈位置连接矩阵板和控制板,螺柱为5mm高单通。
- 连接hub转接板
- 连接hub板之前,要接好所有排线,如下图,不要忘了电池和连接侧面按钮的焊盘。

- 所有连接处都用螺丝即可,电池可以用蓝丁胶等固定到板子上。

- 装上屏幕、编码器、按键测试并安装外壳
- 建议先装上屏幕测试后再放入外壳,如果直接使用我画的3d打印外壳,壳盖和底建议用4mm长的m2自攻螺丝连接。
固件烧录
源码已上传至github,点我跳转,建议自行搭建环境构建,下面介绍如果不想搭建环境,如何使用现成的固件完成初次烧录。
无esp-idf环境初次烧录
- 先自行安装python,然后运行如下命令安装工具:
pip Install esptool
- 下载并解压附件中的“键盘固件”压缩包,如果是接收器,则下载“接收器固件”。
- 压缩包中的“my_esp32s3_keyboard.bin”文件是应用程序的固件,通过msc或网页升级时,只需要这个文件。
- 通过usb将控制板连到电脑。
- 在固件文件夹运行如下命令即可:
esptool write-flash @flash_project_args
设计图
未生成预览图,请在编辑器重新保存一次BOM
暂无BOM
克隆工程
。











。










评论