手把手教你做一个非常酷的PoV显示器(附源码) àì夳堔傛蜴生んèń 2022-09-01 15:50 171阅读 0赞 **关注+****星标公众****号**,不错过精彩内容 ![ab25b34674b554eb8d95aa87febec801.gif][] 来源 | DF创客社区 作者 | Amal Shajan 今天为大家分享一个DIY产品,如下: ![edfc246e4b93d0f5a8cbf0b46f9d515b.png][] 前两天天我在浏览购物网站的时候,被一个购物清单吸引住了, 5个ATtiny13单片机售价1.5美元。 你敢相信,一个可编程的微控制器,只要0.3美元!于是我打算捡个便宜,买几个回来玩玩。 为了让买回来的ATtiny13不落在角落里吃灰,我上网搜索了 "ATtiny13 Arduino"的关键词,发现Arduino支持ATtiny13,所以我准备拿他搞些事情。 ATtiny13对库的支持有限,所以除了让它点亮几个LED之外,我暂时没有想到其他玩法。 正当我苦苦思索还能做什么时,突然想到了一个很久以前的项目。 那是一个使用ATtiny85的PoV显示器。 ![254cfbfd47fc84e943152e01554e19a2.gif][] (拍出来的效果会闪烁,眼睛看就不会) PoV显示器基本上是一堆闪烁的LED,并有一些精心安排的延迟。而我发现ATtiny13和ATtiny85都有相同的引脚布局。 那么…… 嘿嘿,我也来做一个! ### 材料准备 ### * 1 x ATtiny13 * 5个3毫米的LED(也可以用5毫米的LED,3毫米的看起来更好,因为可以更靠近PCB) * 1个CR2032电池 * 1个CR2032电池座 * 1个滑动开关 * 原型PCB或定制PCB * 电烙铁 > 什么是PoV显示器,它们是如何工作的? 人眼在观察景物时,光信号传入大脑神经,需经过一段短暂的时间(1/16秒),光的作用结束后,视觉形象并不立即消失,这种残留的视觉称“后像”,视觉的这一现象则被称为“视觉暂留”。 比如你看一个正常的显示器,像素是以矩阵方式排列的,但在PoV显示器中,像素或者LED则是排列成一个阵列的。就像是你快速翻动小人书那边,由于视觉暂留效应,小人书的人会动起来,这边我们看到的,也不会是一排LED,而是一串字母或者是一幅图像。 ![d696a88141299aed23c8a9b52df59684.gif][] ### Arduino IDE相关设置 ### 你可能正盯着ATtiny13,想知道 "我到底该怎样为这个东西编程,它又没有像Arduino那样的USB接口"。 好吧,要为这个微控制器编程,你需要另一个Arduino,Arduino Nano或Arduino Uno都可以。 下载并安装Arduino IDE。 用USB线将你的Arduino Nano / Uno连接到电脑上。 打开 `工具`\->`开发板`,选择你的主控板(注意选Uno/Nano而不是ATtiny13)。 现在我们需要将我们的Arduino转换成一个编程器。 在Arduino IDE中,打开`文件` \-> `示例` \-> `11.ArduinoISP` \-> `ArduinoISP` ![5073b62590acf7857c62a761cc36d929.png][] 并点击`上传`按钮。 如果上传成功,就可以用我们的Arduino为其他微控制器编程了。 现在我们还需要在Arduino IDE上安装ATtiny13的硬件包,因为IDE默认不支持ATtiny13。 打开`文件` \-> `首选项` \-> `附加开发版管理器网址` ![1218e7bad210c33e71ae17211e465638.png][] 然后粘贴上下面的链接: `https://mcudude.github.io/MicroCore/package_MCUdude_MicroCore_index.json` ![0e602beea347d5a7c8b00586762cc19b.png][] 然后打开`工具` \-> `开发板` \-> `开发板管理器`。 从列表中找到`MicroCore`并点击安装。 ![60bb1da5c9da3921ff14eb4064cf2f1e.png][] ok,现在你就可以从Arduino IDE中选择到ATtiny13了。 选择`工具` \-> `开发板` \-> `MicroCore` \-> `ATtiny13` 我们需要在Arduino IDE中再改变一些选项, 打开`工具`,并设置以下值: <table> <thead> <tr> <th>Option</th> <th>Value</th> </tr> </thead> <tbody> <tr> <td>Board</td> <td>ATtiny13</td> </tr> <tr> <td>BOD</td> <td>2.7v</td> </tr> <tr> <td>Clock</td> <td>9.6Mhz internal Osc.</td> </tr> <tr> <td>Timing</td> <td>"Micors Disabled"</td> </tr> <tr> <td>Port</td> <td>Select Serial Port in which your Arduino is connected</td> </tr> <tr> <td>Programmer</td> <td>Arduino as ISP (MicroCore)</td> </tr> </tbody> </table> ![b922693a5de59faa0621902a5e9da1ac.png][] ### 对ATtiny13进行编程 ### 现在可以把ATtiny连接到我们的Arduino了。 把ATtiny连接到Arduino,如下所示(在ATtiny中,针脚1将用一个点`.` 标记。) ![0a57842c113cd6da39097bd5129c0b00.png][] <table> <thead> <tr> <th>ATtiny13 Pin</th> <th>Arduino Pin</th> </tr> </thead> <tbody> <tr> <td>1</td> <td>10</td> </tr> <tr> <td>5</td> <td>11</td> </tr> <tr> <td>6</td> <td>12</td> </tr> <tr> <td>7</td> <td>13</td> </tr> <tr> <td>8</td> <td>5v</td> </tr> <tr> <td>4</td> <td>Ground (GND)</td> </tr> </tbody> </table> ![031f381df0cf67f0cca7cec0a70c847f.png][] ### 烧录引导程序到ATtiny13 ### 这是一个一次性的设置,不用在每次上传代码到ATtiny时都重复这个设置。 点击 `工具`\->`烧录引导程序`。 ![7b79373995919cee9901af133daf3d88.png][] 这将把引导程序烧到ATtiny上,现在我们就可以用Arduino IDE把程序上传到ATtiny了。 ### 上传PoV程序到ATtiny ### 在Arduino中新建一个程序。 复制代码并将其粘贴到新创建的程序中。 // https://github.com/B45i/Tiny-PoV // App to calculate array values: https://pov-display-calc.vercel.app/ // Preact app source: https://github.com/B45i/pov-display-calc #include <avr/pgmspace.h> #define DELAY_TIME 1 #define CHAR_BREAK 2 uint8_t leds[] = { 0, 1, 2, 3, 4 }; uint8_t keys[] = { 1, 2, 4, 8, 16 }; void setup() { for (uint8_t i = 0; i < 5; i++) { pinMode(leds[i], OUTPUT); } } const PROGMEM uint8_t alphabets[][5] = { { 0, 0, 0, 0, 0 }, // Space { 30, 5, 5, 30, 0 }, // A { 31, 21, 21, 10, 0 }, // B { 14, 17, 17, 10, 0 }, // C { 31, 17, 17, 14, 0 }, // D { 31, 21, 21, 17, 0 }, // E { 31, 20, 20, 16, 0 }, // F { 14, 17, 19, 10, 0 }, // G { 31, 4, 4, 4, 31 }, // H { 0, 17, 31, 17, 0 }, // I { 0, 17, 30, 16, 0 }, // J { 31, 4, 10, 17, 0 }, // K { 31, 1, 1, 1, 0 }, // L { 31, 12, 3, 12, 31 }, // M { 31, 12, 3, 31, 0 }, // N { 14, 17, 17, 14, 0 }, // O { 31, 20, 20, 8, 0 }, // P { 14, 17, 19, 14, 2 }, // Q { 31, 20, 22, 9, 0 }, // R { 8, 21, 21, 2, 0 }, // S { 16, 16, 31, 16, 16 }, // T { 30, 1, 1, 30, 0 }, // U { 24, 6, 1, 6, 24 }, // V { 28, 3, 12, 3, 28 }, // W { 17, 10, 4, 10, 17 }, // X { 17, 10, 4, 8, 16 }, // Y { 19, 21, 21, 25, 0 }, // Z { 31, 17, 31, 0, 0 }, // 0 { 18, 31, 16, 0, 0 }, // 1 { 29, 21, 23, 0, 0 }, // 2 { 21, 21, 31, 0, 0 }, // 3 { 7, 4, 31, 4, 0 }, // 4 { 23, 21, 29, 0, 0 }, // 5 { 31, 21, 29, 0, 0 }, // 6 { 1, 1, 31, 0, 0 }, // 7 { 31, 21, 31, 0, 0 }, // 8 { 23, 21, 31, 0, 0 }, // 9 }; void displayLine(uint8_t line) { for (uint8_t i = 0; i < 5; i++) { digitalWrite(leds[i], (line & keys[i]) == keys[i]); } } void displayLetter(uint8_t n) { for (uint8_t i = 0; i < 5; i++) { displayLine(pgm_read_word_near(alphabets[n] + i)); delay(DELAY_TIME); } displayLine(0); } void displayString(char *s) { for (uint8_t i = 0; i < strlen(s); i++) { uint8_t index; if (s[i] == ' ') { index = 0; } else if (isalpha(s[i])) { index = (uint8_t)toupper(s[i]) - 64; } else if (isdigit(s[i])) { index = (uint8_t)(s[i]) - 21; } displayLetter(index); delay(CHAR_BREAK); } } void loop() { displayString("HELLO 123 "); } 如果你想改变显示的文本,可以修改最后一行。 `displayString("HELLO 123 "); // 替换成你想要显示的文本` 根据你要使用的电机的速度,你可能还需要调整代码,更新变量`DELAY_TIME`和`CHAR_BREAK`。 #### 代码解释 #### 你可能会盯着这段代码思考,一些随机数怎么样能代表一个字符,我们如何用它们来正确地闪烁LED? 我们可能对使用数组来表示字符和图像比较熟悉,像类似这样: int a[][5] = { {0, 1, 1, 0, 0}, {1, 0, 0, 1, 0}, {1, 1, 1, 1, 0}, {1, 0, 0, 1, 0}, {1, 0, 0, 1, 0}, }; for (int i = 0; i < 5; i++) { for (int j = 0; j < 5; j++) { digitalWrite(LEDs[j], a[j][i]); } } 但是,这种方法会占用大量的内存,而且我们还必须使用多个循环来迭代它们。 现在,对于没有多少处理能力的ATtiny13来说,这并不是一个好方法。 ### 标记的枚举法 ### 我们不使用矩阵来表示一个字符,而是使用一个数组来表示它。 PoV显示器有5行和5列,所以我们可以使用一个长度为5的数组。 该数组中的每个元素将告诉我们是否需要打开某个特定的LED。 我们给每个LED分配一个数字(枚举),这些数字都是2的幂级数。 <table> <thead> <tr> <th>LED</th> <th>Enum</th> </tr> </thead> <tbody> <tr> <td>LED 1</td> <td>2^0= 1</td> </tr> <tr> <td>LED 2</td> <td>2^1= 2</td> </tr> <tr> <td>LED 3</td> <td>2^2= 4</td> </tr> <tr> <td>LED 4</td> <td>2^3= 8</td> </tr> <tr> <td>LED 5</td> <td>2^4= 16</td> </tr> </tbody> </table> ![b4be9fa711a34601cf6dc8b739811e4d.png][] 这些数字有一个特点,用他们组合,所产生的每一个数字的方式是唯一的。 比如:如果我们把2、4和8相加,就会得到14,而这些数字的其他组合不会产生14。 如果一个LED是关闭的,我们用0来表示它。 让我们来看看我们如何表示字母 "A"。 ![ac5699c24aa513f0d592e1d6a7884381.png][] 在第一列中,我们必须关闭LED1并打开所有其他的LED。因此,我们可以用`0(LED1关闭)+2+4+8+16=30`表示。 数组中的其他元素将是: <table> <thead> <tr> <th>列</th> <th>值</th> </tr> </thead> <tbody> <tr> <td>第1列</td> <td>0 + 2 + 4 + 8 + 16 = 30</td> </tr> <tr> <td>第2列</td> <td>1 + 0 + 4 + 0 + 0 = 5</td> </tr> <tr> <td>第3列</td> <td>1 + 0 + 4 + 0 + 0 = 5</td> </tr> <tr> <td>第4列</td> <td>0 + 2 + 4 + 8 + 16 = 30</td> </tr> <tr> <td>第5列</td> <td>0 + 0 + 0 + 0 + 0 = 0 (所有LED全不亮)</td> </tr> </tbody> </table> ![0987279306a07def2febc2c3bc3bff06.png][] 我们如何根据这些数字来开启和关闭LED? 很简单,你对数字和LED的枚举进行按位与运算(只有对应的两个二进位都为1时,结果位才为1),如果结果是枚举,我们就需要打开相应的LED。 拿数字30来举个例子: <table> <thead> <tr> <th>运算</th> <th>结果</th> <th>LED状态</th> </tr> </thead> <tbody> <tr> <td><code>30 & 1 == 1</code></td> <td>false</td> <td>关闭LED1</td> </tr> <tr> <td><code>30 & 2 == 2</code></td> <td>true</td> <td>点亮LED2</td> </tr> <tr> <td><code>30 & 4 == 4</code></td> <td>true</td> <td>点亮LED3</td> </tr> <tr> <td><code>30 & 4 == 8</code></td> <td>true</td> <td>点亮LED4</td> </tr> <tr> <td><code>30 & 16 == 16</code></td> <td>true</td> <td>点亮LED5</td> </tr> </tbody> </table> ![c819edf4a6cfe090bb5e3ec5f3027079.png][] > 30二进制是`11110` 这个概念通常被称为标记的枚举。 你可以添加更多的字母和数字。 手动生成这些数组是很难的,所以我做了两个应用程序方便大家更好更快地生成数组。 第一个是用Preact编写的,它是专门为这个项目制作的,最多支持5个LED。 ![dd21ee6dd192b5e9d8dbf0ea9d152e21.png][] 地址:`https://pov-display-calc.vercel.app/` 第二个是用Angular编写的,它可以支持n个LED。 ![1efcf25040292f93b8678b83846603d5.png][] 地址:`https://po-v-display-calculator.vercel.app/` 你也可以用这俩个网页来为其他PoV项目生成代码。 只要使用这些应用程序生成数组,并将代码添加到程序中的数组即可。 ### 建立PoV显示电路 ### PoV显示电路是相当简单的,可以用下面的电路图来连接电路。 ![f54a2a122eda55ca32d6f19143e8c559.png][] ![69e5e1e1e0a04aa3dbc69aaaadc132f5.png][] 你可以使用原型电路板来焊接电路。 我已经为这个电路设计了一块PCB。如果你使用的是PCB,那么你就不用做任何布线,只需焊接元件就好了。 **PCB文件可以在文末下载。** 焊接好所有部件,加入电池,打开开关,把它连接到可以旋转的东西上,比如一个微型电机甚至风扇(别忘了根据角速度调整代码中的延迟,这一块儿可能需要一些试验)。 好了,现在你就有一个元件总成本不到1美元的PoV显示器了,试试效果怎么样吧! 祝你玩得开心! 原文链接: https://www.hackster.io/B45i/make-a-pov-display-with-attiny13-for-1-e94b25 **免责声明:**本文素材来源网络,版权归原作者所有。如涉及作品版权问题,请与我联系删除。 \------------ **END** ------------ 后台回复『**硬件DIY**』阅读更多相关文章。 **欢迎关注我的公众号,**回复“**加群**”按规则加入技术交流群,回复“**1024**”查看更多内容。 **欢迎关注我的视频号:** ![27584b47b309861b9789ac120909d351.png][] 点击“**阅读原文**”查看更多分享,欢迎**点分享、收藏、点赞、在看。** [ab25b34674b554eb8d95aa87febec801.gif]: /images/20220829/f36aa08c1c854b7cbc61705032797d79.png [edfc246e4b93d0f5a8cbf0b46f9d515b.png]: /images/20220829/9727a0224d1e4fecbab2106dfa5aad66.png [254cfbfd47fc84e943152e01554e19a2.gif]: /images/20220829/86526d528c4b4cfa934feee8a2d87709.png [d696a88141299aed23c8a9b52df59684.gif]: /images/20220829/566f77cac069469099b703ab85d39500.png [5073b62590acf7857c62a761cc36d929.png]: /images/20220829/57d0eaeebf4a4bbbb92253fa343dcef2.png [1218e7bad210c33e71ae17211e465638.png]: /images/20220829/a415b51f56a24dcfad6ea32b032442e0.png [0e602beea347d5a7c8b00586762cc19b.png]: /images/20220829/12546ccd1a494b258a234b36ccee58cb.png [60bb1da5c9da3921ff14eb4064cf2f1e.png]: /images/20220829/cd96e610083e40a4b341c860eca3f1f5.png [b922693a5de59faa0621902a5e9da1ac.png]: /images/20220829/3573e585e6284fa3b09332d34d991ff6.png [0a57842c113cd6da39097bd5129c0b00.png]: /images/20220829/d3c41acaa7d84c7f92bb93e4b68b0174.png [031f381df0cf67f0cca7cec0a70c847f.png]: /images/20220829/b2952e7d13214c47bb96b2dc89566636.png [7b79373995919cee9901af133daf3d88.png]: /images/20220829/fa9b4f0d807f4bc6bbaafac056986253.png [b4be9fa711a34601cf6dc8b739811e4d.png]: /images/20220829/7a6f609ef63944caba0e7b87d5591838.png [ac5699c24aa513f0d592e1d6a7884381.png]: /images/20220829/ac153e1a7b1f40f294246fe3e4df6d52.png [0987279306a07def2febc2c3bc3bff06.png]: /images/20220829/8e96e499d6d544a6ac4f8c848d5c907f.png [c819edf4a6cfe090bb5e3ec5f3027079.png]: /images/20220829/2e38cd32f5454912a8e4ff4f2a3d7102.png [dd21ee6dd192b5e9d8dbf0ea9d152e21.png]: /images/20220829/2a2a3e602c534b0697091e6003e249c4.png [1efcf25040292f93b8678b83846603d5.png]: /images/20220829/815f45958c7b4c4a8641577749daa781.png [f54a2a122eda55ca32d6f19143e8c559.png]: https://img-blog.csdnimg.cn/img_convert/f54a2a122eda55ca32d6f19143e8c559.png [69e5e1e1e0a04aa3dbc69aaaadc132f5.png]: /images/20220829/0d16460329c042e7affb6d56f398142f.png [27584b47b309861b9789ac120909d351.png]: /images/20220829/2819433f086e41b2957f5210955a154b.png
还没有评论,来说两句吧...