|
“ 读大学的时候就很喜欢这些开脑洞的小玩意儿。看到一个印度小哥用ESP32 做了个高分辨率的 POV,而且开源了全部的硬件和代码,忍不住想分享给大家。”
什么是 POV?POV(Persistence of Vision)中文翻译为“视觉暂留”,它的基本原理是使我们的眼睛能够从独立的图像中感知连续的运动,这也是电影中运动错觉的关键概念。实现原理其实也很简单,就是把一定数量的 LED 安装可以旋转或者摇晃的杆子上,通过 MCU 对 LED 编程,结合杆子摇晃和旋转的特定频率,就会在视觉上产生动态的效果。下面的视频可以直观地理解 POV 的实现和效果:
你肯定在网上看到过很多这样的项目,但它们大多分辨率很低,只能显示一些文字和几何图形。而这位印度小哥创建的 POV 显示屏不仅限于文本或简单的形状,他的 POV 显示器可以显示分辨率为 128 像素的图像和动画,而且很容易制作。
项目概览项目选择了 ESP32 模块作为显示器的大脑,因为它便宜、容易获得,而且功能强大。显示器将有两个旋转臂,每个旋转臂装有 64 个 LED,总分辨率为 128 像素。在 ESP32 的控制下,旋转臂将以恒定的速度旋转,LED 灯以精心安排的模式闪烁。通过这种同步方式,显示屏可以生成悬浮在半空中的图像或文字,带来流畅、连续的视觉体验。
POV 显示器项目特点:128 像素分辨率。帧频为 20 FPS。易于制造。易于控制。基于 ESP32。完全开源。配套网络应用程序,可轻松转换图像。
元器件 BOM
ESP32 WROOM 模块 - x174HC595D 移位寄存器 - x16CH340K USB - UART 控制器 - x1TP4056 锂离子充电器 IC - x1AMS1117 3.3v LDO - x1AO3401 P - MOSFET - x12N7002DW 双 N - MOSFET - x1霍尔效应传感器 - x2SS34 二极管 - x1Typc C USB 连接器 16 针 - x1SMD LED 蓝色 0603 - x128775 电机 - x1直流电机速度控制器 - x1SMD 电阻和电容SMD LEDSMD 轻触开关SDM 滑动开关连接器3D 打印部件和安装螺钉。其他工具和耗材。
原理图
完整的原理图如下所示:
fzs0ygwi3246402516.png
让我们看一下原理图的细节,以便更好地理解。USB Type C 端口用于充电和编程。USB 端口的电源连接到 P 沟道 MOSFET U7 和二极管 D67 构成的电源控制电路。连接器 J4 可用于提供外部 5V 电压。同一端口还可用于连接无线充电器模块,以备在不充电的情况下连续运行。在电压调节方面,使用了常用的 AMS1117 3.3V LDO,它能够提供高达 1A 的电流,满载时的压降约为 1.1V。连接器 J3 用于连接外部开关,以打开和关闭整个电路。为了给内部电池充电,我们使用了 TP4056 充电控制器,其最大充电电流为 1A。现在我们来看看编程电路,它是围绕 WCH 的 CH340K 芯片构建的。为了实现自动复位,我们使用了双 MOSFET 2N7002DW。现在,整个电路的大脑是一个 ESP32-WROOM 模块。我们之所以选择这个 SoC,是因为它价格便宜、易于获得,而且功能强大,能够以足够的帧速率驱动显示屏。LED(像素点)分别位于两个旋转臂,每个旋转臂有 64 个 LED(像素)。因此,我们总共有 128 个像素的分辨率。我们还使用了两个霍尔效应传感器进行转速测量和位置感应。在PCB中,我们原本设计了 SMD 封装,但后来决定使用 TO-92 封装的普通 A3144 传感器,因为它们更容易采购,而且易于安装到当前的支架设计中。
0alhgetbv2v6402616.png
tl2tpfvmowb6402717.png
下一部分是 LED 及其驱动。我们使用 74HC595D 移位寄存器来驱动 LED。由于单个 s74HC595 最多可以驱动 8 个 LED,因此总共使用了 16 个这样的芯片来驱动全部 128 个 LED。我们使用了一个 1KOhms 电阻器来限制电流,但您可以根据自己需要的亮度来改变电阻值。由于有两只旋转臂,因此只需要转半圈就能绘制整个画面或图像。一只旋转臂绘制图像的一半,另一只旋转臂绘制图像的另一半。通过这种方法,我们可以将帧频提高一倍。显示屏可以提供大约 20FPS 的帧频。
3rykqivnbsh6402817.png
g5fjohb04bx6402917.png
PCB
PCB 的尺寸约为 210 毫米 x 60 毫米。下面是 PCB 的顶层和底层。
preo1ldmtu06403017.png
jev0sgfy0bq6403117.png
qfzpmn3o2q46403217.png
crvuw43zsop6403318.png
装配完成后的样子:
mkzdz2p0c1f6403418.png
idk3xfxijsd6403518.png
oihix0muvx46403618.png
工作原理
现在让我们来看看 POV 显示屏是如何工作的。请看下图,我们将一个圆平均分成 32 块。如果用这样分割来的方式完成一幅图像,必须在每次旋转就绘制 32 行像素。在显示每一行像素时时,必须根据像素数据来决定每个LED(像素)是点亮还是熄灭。通过快速旋转和逐行点亮像素,就可以在观察者眼中形成一幅连续的图像。
2q3pv0wkio56403718.png
图像分割
在实际项目中,我们将每个图像径向分成 360 块。也就是说必须在每次旋转时画 360 条相距 1 度的线来绘制图像。
线条和像素
每条线上将有 64 个像素或 LED 灯(两条手臂上共有 128 个 LED 灯),这些像素或LED需要根据像素数据进行操作。坐标系统问题
一般图像使用的是笛卡尔坐标系。但为了在旋转 POV 显示器上显示图像,我们必须使用极坐标。在笛卡尔坐标系中,位置由水平距离(x)和垂直距离(y)指定。而极坐标则基于圆形网格,位置由半径(r)和水平角度(θ)指定。因此,像素并不均匀:随着与原点距离的增加,像素的面积也会增加,形状也会改变。
0r0c5je0hye6403818.png
要从图像中获取像素数据,我们必须使用一些三角函数计算和插值法。然而,对每幅图像的每个像素都进行这样的计算将耗费大量时间,并会减慢像素的响应时间。为了避免这种情况,并获得极短的像素响应时间和最高的刷新率,我们决定使用预计算值来处理图像,这将在编码部分进行说明。根据我们目前的设置,绘制一帧或一幅分辨率为 128 像素、360 段的图像大约需要 50 毫秒,因此有效帧频为 20fps。
下一个挑战是优化图像的存储方式。使用传统工具转换的普通图像阵列,每个像素也会占用 1 个字节的空间。也就是说,128x128 的图像需要 16384 字节的空间。但这样一来,我们在代码空间内存储的图像数量就会受到限制。为了克服这个问题,并获得更好的优化效果,我们采用了一种新方法。每行图像像素将存储在 16 个字节中。每个字节将包含 8 个像素的数据,即黑色或白色。然后使用一个简单的函数对这些数据进行解码,得到实际的像素数据。使用这种方法,一幅 128x128 像素的图像只需要 2048 (128x16) 个字节空间。使用这种方法,我们可以将图像的大小缩小 8 倍。
代码 & 仓库
所有的代码及 KiCad 设计文件都可以在以下仓库找到,这里就不再赘述:
https://github.com/Circuit-Digest/POV-Display
结束语
今天的分享就到这儿,感兴趣的小伙伴赶紧动手实践吧!
部分内容引用自:https://circuitdigest.com/microcontroller-projects/diy-pov-display-using-ESP32-Arduino
注意:如果想第一时间收到 KiCad 内容推送,请点击下方的名片,按关注,再设为星标。
常用合集汇总:
和 Dr Peter 一起学 KiCad
KiCad 8 探秘合集
KiCad 使用经验分享KiCad 设计项目(Made with KiCad)常见问题与解决方法KiCad 开发笔记插件应用
发布记录 |
|