标签存档: Arduino

ESP32-S3 JPEG 实测:从解码库对比到 DMA 优化,最终撞上 SPI 上限

前言

之前做了 ESP32-S3 上常见 JPEG 解码库(Tjpg_Decoder、JPEGDEC、ESP_NEW_JPEG)的性能测试,最终结论是 ESP_NEW_JPEG 在此前测试中表现最强(见 ESP32-S3 + Arduino 各种 JPEG 解码库速度对比,到底哪个才是最快的?勘误:ESP_NEW_JPEG 更新到最新版后,所有分辨率都是最快的)。

但是上次是用的静态图片,每次解码都是同样图片数据,与真实使用场景会有差异,毕竟如果是使用 ESP32-S3 播放视频,每一帧的内容都是不一样的,解码时间也会有波动。

这次直接从视频里抽帧,模拟一下真实视频播放场景,看看在这个条件下能把 FPS 推到多高。

另外上次测试时也没有优化解码与传输步骤,理论上可以使用 DMA 实现 CPU 时间更有效的利用,这次也优化一下代码,对比看看效果。

那么这次测试在以下两个条件下,最终结果会如何?

  1. 图片数据使用真实视频抽帧,每帧内容不同,更接近播放场景;
  2. 加入 DMA 和 Block 合并策略,测试“解码”和“上屏”能否真正并行。

先说结论:在 240×240 + RGB565 + SPI 40MHz 的配置下,最终逼近链路上限,实测约 40

阅读全文 »

勘误:ESP_NEW_JPEG 更新到最新版后,所有分辨率都是最快的

前言

上篇文章(见 ESP32-S3 + Arduino 各种 JPEG 解码库速度对比,到底哪个才是最快的?)测试了三个 JPEG 解码库的性能,最终结论是 ESP_NEW_JPEG 在低分辨率遥遥领先,但到了 240x240 和 320x240,被 JPEGDEC 追平。

结果最近想测试 ESP_NEW_JPEG 的 block 解码方式,发现怎么找都找不到对应的 API,这才意识到——我用的库版本根本不对 😅。

问题出在哪里

esp32-jpeg-decoder-errata-2

上篇文章用的是 Arduino 生态里的封装库 ESP32_JPEG,这个库最后一次更新是三年前,是对 ESP_JPEG 早期版本的封装,早就停止维护了。

乐鑫官方真正在维护的最新版本是另一个仓库:esp-adf-libs/esp_new_jpeg,五个月前还在更新,block 解码、最新的 SIMD 优化都在这里。

两个库同名,但版本差距已经是三年了,之前完全踩坑了 😂。

更新库,重新测试

换成最新版 ESP_NEW_JPEG,测试环境与上次完全一致:

  • ESP32-S3-Zero,240MHz 双核
  • 测试图片:Lenna,160x80


阅读全文 »

电磁铁驱动的段码时钟找到解法了,先来一位试试

电磁铁段码时钟这个项目还是年初的时候在 Instructables 看到的,中间尝试过复刻,但是有两点实在有点麻烦就一直没弄:

  1. 原作者是自己绕电磁线圈,太费事了
  2. 原作者用了我不懂的达林顿管啥的来驱动电磁铁,太麻烦了

然后最近逛淘宝发现了有现成的线圈卖,买了测试一下,还真可以推动 5x2mm 的圆形永磁铁了,这下可以开始搞一搞了。

单个数字演示效果

这里因为是放在桌子上拍的,段码翻转声音会比较大,实际竖着放的时候会好一些。

PS. 拍视频的时候左上角那个段有一个电磁铁坏了,所以最后可以看到它没有翻转成黑色 😃。

电磁铁选择

在找 DeepSeek 学习了一大圈之后,终于对电磁铁明白一点点,需要足够多的匝数,才能会有大一点的磁性。

然后就找到了这个商品,应该是顺着别人做磁悬浮的配件找到的。

买回来之后把铁芯敲掉就可以了。

magnet-clock-finished-one-digit-2

之前还买过下面这两种,测试的时候完全推不动 5x2mm 的圆形永磁铁,因此从年初到现在都没有折腾过。

magnet-clock-finished-one-digit-3

magnet-clock-finished-one-digit-4

驱动电路

原项目使用了达林顿管还有移位寄存器什么的组合起来控制,我觉得比较麻烦,板子也太多了。

在拿到电磁铁线圈之后,就想着既然是控制通断,是不是可以直接用 NMOS 就可以了。直接用零件搭了个测试电路,完全可以把圆形磁铁推开,那就开始画块板子吧。

直接最省事的做法了,MCU 的 GPIO 直接控制 NMOS Gate,电磁铁线圈接在 Drain 上,通过短暂开启 GPIO,就可以让电磁铁产生磁力推开特定的段码。

magnet-clock-finished-one-digit-5

这里使用 NMOS 而不是 PMOS 来控制电磁铁通断,是因为如果电磁铁需要更大推力,需要更高的电压,测试了在 10V 的时候效果比较好,因此如果需要 MCU 3.3V 的 GPIO …

阅读全文 »

让串流小电视更实用,通过抖动实现 4 阶灰度图像显示

前言、先看效果对比

二值化黑白图像展示

灰度抖动图像展示

一、黑白世界的色彩想象

之前使用 ESP32-S3 + 12864 OLED 做了个串流小电视(见 桌面小电视新思路,ESP32-S3 + 12864 OLED 串流视频),通过网络发送视频帧的方式来播放视频。

因为 12864 OLED 是一个单色显示屏,因此在播放视频时,整个画面的颜色通过“灰度化->二值化”的步骤来生成黑白纯色画面,在视频中可以看到画面没有层次和细节,不太容易看清画面内容是什么。

因此我们需要引入灰度来让整个画面更加丰富,但是在 12864 OLED 没有灰度的情况下如何显示灰度信息呢?

在这里我们就可以引入一种特别的显示技术——抖动 (Dithering),它能让单色屏幕拥有显示4阶灰度的能力。

二、什么是抖动 (Dithering)?

抖动,它的原理却非常直观,相当于通过大脑形成一种视觉错觉。

在单色屏幕上,只有纯黑和纯白的像素。抖动的核心思想就是:通过改变像素点的排布密度,来模拟出不同程度的灰度。

举个最简单的例子,如果你仔细观察报纸上的照片,你会发现那些“灰色”的部分,其实是由许多大小不一或疏密不同的黑色墨点组成的。在远处看,这些墨点混合在一起,就形成了我们看到的灰度。旧式的点阵打印机也是同样的原理,通过打印点的疏密来表现深浅。

抖动就是利用人眼的这种视觉混合效应。当我们观察一个由许多纯黑和纯白像素组成的区域时,如果这些像素非常小并且排列得足够紧密,我们的大脑就会将这些黑白像素的混合视为一个统一的灰色。像素点越密,看起来就越黑;像素点越稀疏,看起来就越白。

三、4 阶灰度:从纯黑到纯白

我们通常说的灰度,可以有 256 级,甚至更多。但是通过抖动模拟出的灰度,其实是牺牲了有效分辨率换来的。

对于 12864 OLED 来说,原生的黑白分辨率是 …

阅读全文 »

桌面小电视新思路,ESP32-S3 + 12864 OLED 串流视频

之前搞了个小电脑使用 ESP32-S3 + OLED 显示视频(见 3 步从 nana banana AI 生成的复古小电脑到真实桌面小玩具),但是受制于 Flash 空间有限,只放了 10 秒。

后来就想到是不是可以 ESP32-S3 只作为一个播放设备,视频数据从电脑上串流过去,而且在 ESP32-S3 支持这样串流的能力之后,理论上可以显示任意想要显示的信息,例如作为电脑的小副屏。

说干就干~

先看看效果

串流完整流程

因为屏幕使用的是 OLED,分辨率是 128x64,颜色是单色, 单帧数据只需要 128x64/8 =1,024 字节,即使串流 30 FPS 也只有 30 KB/s 的流量,因此在电脑端直接发送完整屏幕数据是完全可以接受的。

并且大部分图像处理工作都在电脑端处理完成了,ESP32-S3 的固件在实现渲染时压力就会小很多,只需要 接收数据->写入 OLED 显存 即可。

通信协议为了省事,直接使用 WebSocket 了,这样直接一个消息就是一帧数据

阅读全文 »

简单逆向某蓝牙血氧仪通信协议,配合 ESP32 实现全天血氧监控

之前买了个血氧仪,带蓝牙数据传输功能,想使用它监控一下整晚睡眠时的血氧。

lepu-oximeter-re-1

但是在使用时才发现,如果想要持续监控,配套的 App 需要一直在前台保持激活状态,就是手机不能息屏,浪费电不说,在后续查看数据时发现 App 中查看也不太好用。

这时想到它既然是使用蓝牙传输数据的,那大概率是直接用了 BLE,如果传输没有加密的话,那不是可以直接用 ESP32-S3 直接来读取一下,再转发到 MQTT 服务器,就可以实现全天的血氧监控了,而且可以有全部数据点的详细数据。

注:本文仅供学习研究与互操作性分析之用。请仅在对目标设备与数据拥有合法权利或已获明确授权的前提下使用。禁止用于未授权访问、数据窃取、绕过安全机制等违法用途;一切后果由使用者自行承担。

拿 Lightblue 测试一下

说干就干,先在电脑上用 BLE 测试软件看看能不能抓到一些数据。

将手指放进血氧仪,待数据稳定之后,打开 Lightblue 看看能不能找到设备~

很快就找到一个 PC-60F 打头的设备。

lepu-oximeter-re-2

可以看到这个设备,有一个 Notify 的 Character,看看这个是不是

lepu-oximeter-re-3

可以看到在订阅这个 Character 之后,血氧仪在一直发送数据,这时把这些数据日志保存下来,看看能不能找到血氧数值在哪条消息里。

怎么逆向?

好吧,其实我用了一个笨方法,通过观察血氧仪的读数,再在日志中查找对应的数字,一般来说,血氧最大值 100%,那么用一个字节就可以表示了,应该是可以直接搜索到的。

在观察过程中,血氧仪显示 97%,那么在日志中搜索对应的 16 进制数 0x61:

lepu-oximeter-re-4

截取这段中有 3 条数据出现了 0x61,但是前一个字节不太一样,分别是 0x01 和 0x02,这个时候可以选择再继续观察后续数据,来确认哪一个是上报的血氧数据。

但是我选择了对比一下心率,当时看到的心率是 81,对应 16 …

阅读全文 »

ESP32-S3 + Arduino 各种 JPEG 解码库速度对比,到底哪个才是最快的?

前段时间做了个 ESP32-S3 串流小电视(见 桌面小电视新思路,ESP32-S3 + 12864 OLED 串流视频)的项目,最近准备试试显示彩色图片,这就需要持续显示 JPEG 图片来模拟视频播放。

在 Arduino 生态中找到了好几个解码库,虽然也有一些对比测试,还是想自己实测一下,看看具体的效果怎么样 😃。

起因

在串流进行视频播放时,需要视频的每一帧解码、上屏,如果需要达到 30 FPS 的刷新率,那么解码 + 上屏的时间要在 1000 / 30 = 33.333 ms 以内。在这种情况下,图片解码性能直接影响用户体验。

另外,ESP32-S3 有双核 + 更高主频 + PSRAM + SIMD 指令支持,理论上应该可以跑得更快,但是具体能快多少,不同库之间差距多大,都需要实测数据。

测试环境

硬件平台

  • 开发板: ESP32-S3-Zero 开发板
  • PSRAM: 2MB


阅读全文 »

AI 误诊 macOS IOKIT Bug:ESP32-S3 USB HID 通信调试记录

前段时间想模仿 BLEUnlock 搞个使用指纹给 macOS 解锁的应用,让 AI Vibe Coding 了很多代码,特别是 USB HID 通信以及 CTAP 协议处理部分。

这中间在调试协议时,AI 花了相当多的时间来反复调整 USB HID 通信时的 Payload 大小,AI 最终的结论是:macOS IOKIT 在发送数据到 USB 设备时有 Bug,会缺少 1 个字节,所以通过宏定义的方式,将包大小减少 1 个字节来绕过这个 Bug 😂。

当然我是不相信这个结论的,毕竟 macOS 上通过 USB HID 通信的设备那么多,不可能有这么明显的 Bug,周末花了点时间来看看到底是咋回事。

问题表现

在整个通信协议相关代码写完,并且主机和设备通信测试成功之后,在设备端会提示 USB HID 在收到消息时,Payload 大小为

阅读全文 »

百元成本,DIY 一个 ESP32-S3 驱动的炫酷 IV-18 荧光管时钟

前段时间分享了 HV5812 驱动 IV-18 荧光管(见 使用 C 语言位运算和宏,编写一个可自由配置的 HV5812 + IV-18 荧光管驱动),这段时间把固件和外壳搞了搞,总算是差不多做完了,桌上又多了个吃灰的摆件 😃。

在这次开发过程中,固件也是继续尝试了使用 AI 编写,体验还不错,不再需要为配网 + Web 配置界面这些烦琐的事花太多时间了。

成品效果

 

元件选型

做这个 IV-18 桌面时钟,元件中主要的成本就是 IV-18 荧光管本身了,占了绝对的大头。

  • 荧光管:IV-18 真空荧光管透明基板版本,约 95 元
  • 主控:ESP32-S3 Zero 开发板,21 元
  • DCDC 升压芯片:XL6007,7 毛
  • LED 高压驱动:HV5812,6 元
  • 其他阻容:算 5 元吧

PCB 还是老样子,嘉立创每月两样免费打样,外壳 3D 打印也不算了,总成本大约在 130 …

阅读全文 »

Wokwi + VSCode 插件在线仿真 ESP32 更好用,值得一试

之前在《玩 ESP32 和 Arduino 的同学一定不能错过这个在线仿真网站》这篇文章中分享了 Wokwi 这个在线仿真平台,它支持 ESP32、STM32、树莓派等众多 MCU,还有相当丰富的外设库,在手边没有硬件设备时临时调试一下固件代码还是很方便的。

不过之前测试的是使用 Wokwi 的在线编译功能,作为免费用户,经常会碰到服务器编译超时错误,然后导致无法调试,又或者是固件项目依赖了太多的三方库,编辑项目相当麻烦。

这个时候想到了它还有一个 VSCode 插件,似乎可以在本地编译固件再进行仿真,尝试了一下发现还真挺好用,妈妈再也不用担心手边没硬件了。

操作演示

这里以我本地编译了一个 ArduinoBASIC 项目进行测试,可以看到整个使用过程还是相当流畅的,完全不用等待 Wokwi 的服务端编译时间了。

安装插件

要安装 Wokwi 的插件也很简单,直接在 VSCode 中的插件市场搜索 wokwi 或者通过以下链接安装即可:

https://marketplace.visualstudio.com/items?itemName=wokwi.wokwi-vscode

wokwi-vscode-simulator-1

在安装完成后,就可以通过 Command + Shift + P 呼出 VSCode 命令窗口,再搜索 wokwi 找到 Wokwi: Start Simulator 就可以开始使用了。

获取免费授权

在第一次使用 Wokwi …

阅读全文 »