近期同事给我看了一下网上各路大神展示的用Arduino制作的8x8x8光立方,效果可谓酷炫夺目,自己也想动手制作一个,但无奈时间有限,无法动手焊接这么多的LED灯(8x8x8=512),于是花了两个晚上做了个缩水版本的4x4x4光立方,具体过程在此记录一下,以便给各位看官一点参考。
一、材料准备
(1)首先要准备的东西毫无疑问的就是LED小灯了,这东西老便宜了,几块钱一大堆,理论上只需444=64个就可以了,但为了防止制作过程中的损坏,还是买了100个。

(2)其次要准备的当然是Arduino主板,我用的是国产的UNO,也是便宜货。通过其I/O接口输出电信号来控制LED的明暗。

(3)由于Arduino上的接口不多,以一个接口控制一个LED的方式来控制光立方64个LED灯是不可能的。因此,还必须要使用锁存器,把串行的信号转化为并行,才能对正个光立方进行控制。我这里使用的是74HC595N电位信号锁存器(也是几毛钱一个),这里理论上只需要2颗就足够了。(如果是8阶光立方需要用10个)

(4)面包板和导线若干,这个就没什么好说的了,验证阶段,先把线路接好和调试程序,试验成功后条件成熟了再制作PCB板。
二、工作原理和焊接步骤
由于4x4x4的光立方也有64盏灯,因此要用64个I/O口控制64盏灯也是不可能的,因此,制作光立方采用了取巧的办法,就是快速地切换立方中的每一行的显示内容,利用人的肉眼的视觉残留,错觉光立方的四行是在同时被控制。例如下图,用极快的速度播放图1-4,人的肉眼就会看成是5的样子(我在程序中设定的是15毫秒切换)。

焊接阶段,把LED正极掰弯,然后如法炮制4个作为一列,把一列的LED灯的正极焊接在一起,保证每一列的LED共阳。(注意千万别离LED负极太近,以免短接)。本人在实物中焊接得实在够差的,因此画了一些示意图来表示:

如法炮制4个一模一样的。

适当地把阴极截短,然后把每一行的阴极焊接在一起。

说白了就是在一个立面上,列方向共阳极,横方向共阴极。然后再如法炮制上图结构4个,再把每个横面的16盏灯的阴极再连接在一起。如下图所示:

刚好形成了4层共阴极的结构(如下图),为了方便观看,已经标注不同颜色,蓝红绿黄分别对应连接了每一层的LED的阴极,这四层可以分别引线接到Arduino的4个I/O接口:

此时,一共产生了16个LED的共阳极接口,和4个共阴极的接口,为了方便观看,我标注了一些编号:

这其中的逻辑关系很明显了,当D1-D16中,任意一个接口为高电平的时候,该接口所在的列只要有某一层的阴极为F1-F4为低电平时候,他们相交的点上的LED灯就会发亮。例如,D1为高电平,F3为低电平,F1、F2、F4为高电平的时候,D1所在的列从上至下的第二盏LED就会亮起来。

这样,我们的立方结构就准备完毕了!!!以下是本人做的,因为经历了一些意外和材料不足,十分丑陋。

三、74HC595N锁存器的使用
74HC595N锁存器经过查阅了一些文档之后,发现很适合结合Arduino来进行电位的输出。以下是74HC595的示意图:
VCC和GND没什么好说的,电源的输入端和接地;MR端用于重置锁存器电位(低电位时候重置,因此一直保持为1就可以了);OE是使能端,没必要用,一直保持为0;Q7‘用于串接,不必理会。Q0、Q1、Q2、Q3、Q4、Q5、Q6、Q7分别是锁存器的8个输出接口。本实例关键用到的输入控制端口为DS、ST_CP和SH_CP。

当ST_CP为低电位时,整个锁存器处于电位推入状态,此时,Q0-Q7还未能输出任何想要的电位。当SH_CP从低电位转变成高电位的时候,DS所在的电位会按照Q7、Q6、Q5、Q4、Q3、Q2、Q1、Q0的顺序推入。当Q0-Q7这8个电位已经被推入了目标电位之后,把ST_CP置为高电位即可把目标电位进行输出。

假设我们要让Q0-Q7输出10011100的话,整个工作的流程是:
(1)把ST_CP置为0。
(2)把SH_CP置为0,把DS置为0,把SH_CP置为1。
(3)把SH_CP置为0,把DS置为0,把SH_CP置为1。
(4)把SH_CP置为0,把DS置为1,把SH_CP置为1。
(5)把SH_CP置为0,把DS置为1,把SH_CP置为1。
(6)把SH_CP置为0,把DS置为1,把SH_CP置为1。
(7)把SH_CP置为0,把DS置为0,把SH_CP置为1。
(8)把SH_CP置为0,把DS置为0,把SH_CP置为1。
(9)把SH_CP置为0,把DS置为1,把SH_CP置为1。
(10)把ST_CP置为1。(把10011100倒过来)

由于两个74HC595N的ST_CP和SH_CP的步调其实是一致的,因此可以只用一个Arduino的I/O来控制两个74HC595N的ST_CP,只用一个Arduino的I/O来控制两个74HC595N的SH_CP。(其他接口不是接VCC就是GND,不再画了)

通过Arduino的2号I/O接口来控制两个74HC595N的ST_CP,通过Arduino的3号I/O接口来控制两个74HC595N的SH_CP,通过Arduino的4号I/O接口对第一块74HC595N的电位进行输入,通过Arduino的5号I/O接口对第二块74HC595N的电位进行输入。

因此,通过在Arduino IDE中使用以下程序,可以对两个锁存器进行数据输入,由于两个锁存器都可以保存8位(一个字节的数据)因此可以通过两个十进制数字的方式来为两个锁存器录入数据:

int ST_CP = 2;    //设置两块锁存器用同一个ST_CP位
int SH_CP = 3;    //设置两块锁存器用同一个SH_CP位
int DATA1 = 4;    //设置第一块锁存器的DS位
int DATA2 = 5;    //设置第二块锁存器的DS位
void setup(){Serial.begin(9600);//设置串口输出波特率pinMode(ST_CP, OUTPUT);pinMode(SH_CP, OUTPUT);pinMode(DATA1, OUTPUT);pinMode(DATA2, OUTPUT);//对以上定义的io口设置为输出状态
}void loop(){put_byte(240,211);//第一个锁存器输入11110000,第二个锁存器输入11010011
}void put_one(int num1, int num2) {digitalWrite(SH_CP, LOW);digitalWrite(DATA1, num1);digitalWrite(DATA2, num2);digitalWrite(SH_CP, HIGH);
}//设定往两个锁存器分别输入一个数位的函数,先将SH_CP设定低位,传入数据后再将SH_CP设定低位。void put_byte(int d1, int d2)
{digitalWrite(ST_CP, LOW);//把ST_CP置为低位put_one(d1 & 1, b & 1);//通过位移运算获得两个数字的第一位put_one(d1 >> 1 & 1, d2 >> 1 & 1);//通过位移运算获得两个数字的第二位put_one(d1 >> 2 & 1, d2 >> 2 & 1);//通过位移运算获得两个数字的第三位put_one(d1 >> 3 & 1, d2 >> 3 & 1);//通过位移运算获得两个数字的第四位put_one(d1 >> 4 & 1, d2 >> 4 & 1);//通过位移运算获得两个数字的第五位put_one(d1 >> 5 & 1, d2 >> 5 & 1);//通过位移运算获得两个数字的第六位put_one(d1 >> 6 & 1, d2 >> 6 & 1);//通过位移运算获得两个数字的第七位put_one(d1 >> 7 & 1, d2 >> 7 & 1);//通过位移运算获得两个数字的第八位digitalWrite(ST_CP, HIGH);//把ST_CP置为高位,把8个数位推出到Q0-Q7
}

四、电位输出

把电位锁存器1号Q0-Q7连接已经焊接好的光立方的D1-D8位置,把电位锁存器2号Q0-Q7连接光立方的D9-D16位置。

把Arduino中的7,8,9,10号引脚分别接入光立方的共阴层F1,F2,F3,F4。添加以下代码进行控制:

int lv4 = 10; //定义第四层引脚
int lv3 = 9; //定义第三层引脚
int lv2 = 8; //定义第二层引脚
int lv1 = 7; //定义第一层引脚
void setup() {pinMode(lv4, OUTPUT);pinMode(lv3, OUTPUT);pinMode(lv2, OUTPUT);pinMode(lv1, OUTPUT);//把上述四层的引脚进行初始化输出
}
void golv(int n)//定义设置某一个共阴层为低电位的函数
{if (n == 1) {digitalWrite(lv1, 0);digitalWrite(lv2, 1);digitalWrite(lv3, 1);digitalWrite(lv4, 1);}//当设置第一层为低电位时候,把二、三、四层设置为高电位。if (n == 2) {digitalWrite(lv1, 1);digitalWrite(lv2, 0);digitalWrite(lv3, 1);digitalWrite(lv4, 1);}//当设置第一层为低电位时候,把二、三、四层设置为高电位。if (n == 3) {digitalWrite(lv1, 1);digitalWrite(lv2, 1);digitalWrite(lv3, 0);digitalWrite(lv4, 1);}//当设置第一层为低电位时候,把二、三、四层设置为高电位。if (n == 4) {digitalWrite(lv1, 1);digitalWrite(lv2, 1);digitalWrite(lv3, 1);digitalWrite(lv4, 0);}//当设置第一层为低电位时候,把二、三、四层设置为高电位。
}

此时,所有初始化工作已经完成,可以在Arduino的loop函数中设定动画播放内容。
五、输出动画
下面就以“口”字型动画为例,分析一下这个动画的程序应该怎么编写。

我们可以看到,动画一共分为四帧,每一帧又分为四层,每一层又分为两个锁存器所对应的八位,因此,第一帧的第一层的第一个锁存器的内容是1111 0000,第二帧为0000 0000。

由此可以得到,第一帧第一层的数字为1111 0000 0000 0000,第一帧第二层的数字为1001 0000 0000 0000,第一帧第三层的数字为1001 0000 0000 0000,第一帧第四层的数字为1111 0000 0000 0000。
第二帧第一层的数字为0000 1111 0000 0000,第二帧第二层的数字为0000 1001 0000 0000,第二帧第三层的数字为0000 1001 0000 0000,第二帧第四层的数字为0000 1111 0000 0000。
第三帧第一层的数字为0000 0000 1111 0000,第二帧第二层的数字为0000 0000 1001 0000,第二帧第三层的数字为0000 0000 1001 0000,第二帧第四层的数字为0000 0000 1111 0000。
第四帧第一层的数字为0000 0000 0000 1111,第二帧第二层的数字为0000 0000 0000 1001,第二帧第三层的数字为0000 0000 0000 1001,第二帧第四层的数字为0000 0000 0000 1111。
因此,第一帧锁存器中的数字分别是第一层(240,0),第二层(144,0),第三层(144,0),第四层(240,0)。
第二帧锁存器中的数字分别是第一层(15,0),第二层(9,0),第三层(9,0),第四层(15,0)
第三帧锁存器中的数字分别是第一层(0,240),第二层(0,144),第三层(0,144),第四层(0,240)。
第四帧锁存器中的数字分别是第一层(0,15),第二层(0,9),第三层(0,9),第四层(0,15)。
因此,在loop函数中应该这样书写动画效果:

void loop()
{for(int i=0;i<600;i++)  //把第一帧的闪烁播放次数设置为600次,由于时间间隔太短,造成下面四个层的切换变成了常亮的感觉{put_byte(240, 0);//把两个数字推入两个锁存器golv(1);//把第一层设置为低电位delayMicroseconds(15);//上述效果只持续15微秒put_byte(144, 0);//把两个数字推入两个锁存器golv(2);//把第二层设置为低电位delayMicroseconds(15);//上述效果只持续15微秒put_byte(144, 0);//把两个数字推入两个锁存器golv(3);//把第三层设置为低电位delayMicroseconds(15);//上述效果只持续15微秒put_byte(240, 0);//把两个数字推入两个锁存器golv(4);//把第三层设置为低电位}//第一帧完结for(int i=0;i<600;i++)  //把第二帧的闪烁播放次数设置为600次{put_byte(15, 0);//把两个数字推入两个锁存器golv(1);//把第一层设置为低电位delayMicroseconds(15);//上述效果只持续15微秒put_byte(9, 0);//把两个数字推入两个锁存器golv(2);//把第二层设置为低电位delayMicroseconds(15);//上述效果只持续15微秒put_byte(9, 0);//把两个数字推入两个锁存器golv(3);//把第三层设置为低电位delayMicroseconds(15);//上述效果只持续15微秒put_byte(15, 0);//把两个数字推入两个锁存器golv(4);//把第三层设置为低电位}//第二帧完结for(int i=0;i<600;i++)  //把第三帧的闪烁播放次数设置为600次{put_byte(0, 240);//把两个数字推入两个锁存器golv(1);//把第一层设置为低电位delayMicroseconds(15);//上述效果只持续15微秒put_byte(0, 144);//把两个数字推入两个锁存器golv(2);//把第二层设置为低电位delayMicroseconds(15);//上述效果只持续15微秒put_byte(0, 144);//把两个数字推入两个锁存器golv(3);//把第三层设置为低电位delayMicroseconds(15);//上述效果只持续15微秒put_byte(0, 240);//把两个数字推入两个锁存器golv(4);//把第三层设置为低电位}//第三帧完结for(int i=0;i<600;i++)  //把第四帧的闪烁播放次数设置为600次{put_byte(0, 15);//把两个数字推入两个锁存器golv(1);//把第一层设置为低电位delayMicroseconds(15);//上述效果只持续15微秒put_byte(0, 9);//把两个数字推入两个锁存器golv(2);//把第二层设置为低电位delayMicroseconds(15);//上述效果只持续15微秒put_byte(0, 8);//把两个数字推入两个锁存器golv(3);//把第三层设置为低电位delayMicroseconds(15);//上述效果只持续15微秒put_byte(0, 15);//把两个数字推入两个锁存器golv(4);//把第三层设置为低电位}//第二帧完结
}

通过上述代码,可以实现一个口字型的点阵从前排一直播放到后排的效果,其实从理论上来说,只要仔细分析出动画效果中的每一帧,就都可以用这种方法,来一帧帧地输出动画。

虽然被重物压得东倒西歪,但最后效果还是实现了。

这可能是最详细的Arduino制作4*4光立方教程(原创)相关推荐

  1. arduino点阵声音频谱_参赛-使用Arduino制作32频段音频(音乐)频谱分析仪

    该项目用于使用Arduino制作32频段音频(音乐)频谱分析仪/可视化器. 硬件组件: Arduino Nano R3× 1 电阻10k欧姆× 1 电阻4.75k欧姆× 3 电容器100 nF× 2 ...

  2. 用米思齐(mixly)或者Arduino制作红外线遥控灯

    ----用米思齐(mixly)或者Arduino制作红外线遥控灯 一.先设置红外线遥控和LED灯的端口 二.在面包板上把LED灯的电路接好,注意要接电阻! 三.Arduino代码 #include & ...

  3. 网站建设教程(详细企业网站制作的步骤)

    网站建设教程(详细企业网站制作的步骤)今天珍奶bb给大家简单唠唠网站建设教程(企业制作网站的步骤)?企业建网站早已不是一件很难的事情,虽然建设网站涉及到代码.服务器.域名申请等等,但是这么专业的事情早 ...

  4. arduino 控制无刷电机_单片机控制无刷电机(详细程序)——arduino源代码.doc

    单片机控制无刷电机(详细程序)--arduino源代码 最近对arduino很感兴趣,因为它的开源,编写简单,用它来控制.通过调节电位器来控制无刷电机的转速.程序是根据arduino中自带的Servo ...

  5. arduino 电压表_如何使用Arduino制作数字电压表

    arduino 电压表 by Harshita Arora 通过Harshita Arora 如何使用Arduino制作数字电压表 (How to make a digital voltmeter u ...

  6. 工业设计课程作业——基于Arduino制作的宋代点茶文化小夜灯

    文章目录 前言 一.产品介绍 二.代码分享 总结 前言 工业设计--电子信息课程作业,我们第一次使用Arduino制作了一个以宋代点茶文化为背景的带有交互体验的小夜灯. 一.产品介绍 简单介绍一下宋代 ...

  7. Arduino制作天猫精灵朋友天狗精灵-LD3320语音模块

    设计者:STCode (公众号同名) Arduino制作天猫精灵好朋友"天狗精灵"语音识别和语音控制外接设备 LD3320语音识别模块使用 1)功能描述 这个设计应用LD3320语 ...

  8. arduinosw_用arduino制作具有无线数据传输功能的气象站

    原标题:用arduino制作具有无线数据传输功能的气象站 本项目是用arduino开源硬件,来快速制作具有无限数据传输功能的气象站,我之前做过一个带数据记录功能的气象站项目,这次算是升级和改进的版本. ...

  9. Arduino Mixly入门到精通教程

    目录 1.介绍 2.实验器材和相关资料下载链接 3. Uno Plus 开发板和米思齐软件 第1小节  简单介绍 Uno Plus 开发板 第2小节 Uno Plus 开发板的驱动安装方法 第3小节 ...

  10. Arduino可穿戴开发入门教程Windows平台下安装Arduino IDE

    Arduino可穿戴开发入门教程Windows平台下安装Arduino IDE Windows平台下安装Arduino IDE Windows操作系统下可以使用安装向导和压缩包形式安装.下面详细讲解这 ...

最新文章

  1. linux ssh 脚本 密码,ssh自动登录的4种实现方法
  2. sklearn之pipeline:sklearn.pipeline函数使用及其参数解释之详细攻略
  3. android学习笔记46——File存储
  4. python编写安全工具_Python3学习系列(四):编写属于自己的邮件伪造工具
  5. CF444C-DZY Loves Colors【线段树,set】
  6. 使用JUnit规则进行干净的集成测试
  7. android sdcard 压缩图片,android如何往SDCard中存取图片
  8. c语言中休眠的作用,使用C语言让Windows睡眠/休眠
  9. 我的oh my zsh主题
  10. java之pdf打印
  11. 电容式触摸按键原理调研总结
  12. SAP-FI-财务报表版本设定
  13. linux下载工具,2019年最受欢迎的5款Linux下载管理器
  14. Windows 11 v22000.318 11月更新版
  15. 个人开发者应用如何接入主流微信和支付宝支付
  16. c语言(http://c.biancheng.net/view/1714.html)
  17. 高性能RPC框架gRPC竟恐怖如斯~
  18. 2021年中国DR设备市场竞争格局分析,未来DR市场将进入发展平台期「图」
  19. 《杀出个黎明》(From Dusk Till Dawn)--This is the fucking movie
  20. 从单机架构------》到现在复杂的微服务,分布式,集群,云平台途中是遇到了什么问题,又如何解决的?

热门文章

  1. python win32api sendmessage_Python win32api.SendMessage方法代码示例
  2. Unity,Socket发送消息字符串问题
  3. Python实现人脸识别
  4. python生成手写汉字字体_「zi2zi」:用AI生成自己的手写字体
  5. maven下手动导入ojdbc6.jar
  6. 《用户故事与敏捷方法》读书笔记 04 客户团队
  7. 计算机Excel运行环境,Excel Server Tutorial
  8. Spring定时器cron表达式
  9. eclipse配置java环境变量_eclipse配置环境变量
  10. wincc版本升级_【西门子】WinCC V7.4 SP1:常规信息和安装 (较新).pdf