ESP8266的的花样点灯
使用74H595制作4x4x4光立方
实物效果和程序运行效果如下
.
光立方实物制作
材料清单
名称 | 数量 |
---|---|
NodeMCU Lua | 1 |
74H595 | 2 |
led灯珠 | 64 |
(上一篇在文章的最后推荐了一个视频教程,里面有讲解关于74H595的使用方法,讲的很好)
光立方的大小是4x4x4,所以需要用到两块74H595控制64颗led灯。
此光立方制作需要参考该视频https://www.bilibili.com/video/BV18f4y1H7De/?spm_id_from=333.337.search-card.all.click
视频中的led灯是直接通过IO口供电,用四个100欧姆电阻限流。
为了对开发板的引脚起到保护作用,此次光立方的制作使用四个三极管控制对应层的电位高低,使用esp8266开发板的电源引脚供电,每个三极管使用200欧姆限流,电路图如图。
VCC连接开发板的电源5V引脚。
esp8266的D1,D2,D3,D8引脚分别控制1,2,3,4层的电位。
Layer 1, Layer 2, Layer 3, Layer 4分别连接对应的层。
每一层的LED灯电路图如图。
Layer #为对应的Layer 1,Layer 2,Layer 3,Layer 4。
Layer #为高电平,Q #为低电平则LED灯被点亮。
两块74HC595的电路连接如图。
两块74HC595的引脚分别按照图中方式连接,使用灌电流的方式点亮LED灯。
注意,第一块74HC595的Q7’连接第二块的DS引脚。第二块74HC595的Q7’引脚无需连接。
具体的工作方法会在程序中说明。
74HC595实际对应引脚如图。
.
光立方演示程序的编写
- 引脚初始化
#define DS_PIN D5
#define STC_PIN D6
#define SHC_PIN D7
//引脚初始化
void InitPin(){
pinMode(DS_PIN,OUTPUT);//数据
pinMode(STC_PIN,OUTPUT);//显示保持
pinMode(SHC_PIN,OUTPUT);//数据锁存
pinMode(5,OUTPUT);//GPIO5 D1控制第1层
pinMode(4,OUTPUT);//GPIO4 D2控制第2层
pinMode(0,OUTPUT);//GPIO0 D3控制第3层
pinMode(15,OUTPUT);//GPIO15 D8控制第4层
//将所有引脚拉低
digitalWrite(5,LOW);
digitalWrite(4,LOW);
digitalWrite(0,LOW);
digitalWrite(15,LOW);
digitalWrite(DS_PIN,LOW);
digitalWrite(STC_PIN,LOW);
digitalWrite(SHC_PIN,LOW);
}
- 数组的构建
int S0to1_Length = 0;
int S0to1_array[]={//0到1方向 S型路线
1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,0,
1,1,1,1,1,1,1,1,1,1,1,1,1,1,0,1,
1,1,1,1,1,1,1,1,1,1,1,1,1,0,1,1,
1,1,1,1,1,1,1,1,1,1,1,1,0,1,1,1,
1,1,1,1,1,1,1,1,1,1,1,0,1,1,1,1,
1,1,1,1,1,1,1,1,1,1,0,1,1,1,1,1,
1,1,1,1,1,1,1,1,1,0,1,1,1,1,1,1,
1,1,1,1,1,1,1,1,0,1,1,1,1,1,1,1,
1,1,1,1,1,1,1,0,1,1,1,1,1,1,1,1,
1,1,1,1,1,1,0,1,1,1,1,1,1,1,1,1,
1,1,1,1,1,0,1,1,1,1,1,1,1,1,1,1,
1,1,1,1,0,1,1,1,1,1,1,1,1,1,1,1,
1,1,1,0,1,1,1,1,1,1,1,1,1,1,1,1,
1,1,0,1,1,1,1,1,1,1,1,1,1,1,1,1,
1,0,1,1,1,1,1,1,1,1,1,1,1,1,1,1,
0,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1
};
因为有两个74HC595串联控制16个LED灯珠,所以一组有16位,在构建数组时,每16位数为一帧。
例如数组中第一行的
1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,0,
若当控制此层的引脚为高电平时,三极管导通,此层的LED灯阳极端为高电位。
其中为1时74HC595对应的输出引脚为高电位,所以LED灯不亮,0时74HC595对应的输出引脚为低电位,LED灯导通从而被点亮。
显示效果是D1~D15的LED灯不亮,D16被点亮。
数组类型也可以更改为其他类型数组以减小耗费的空间。
.
所以在数组中写入所有的帧并暂停相应的时间即可。
.
- 数组内容的显示
//array为构建的数组 ,len为数组长度 ,time_delay为延迟时间
void WriteArray(int *array,int len,int time_delay){
int Group_number = len/16;//计算数组里的帧数
for(int i=0;i<Group_number;i++){
digitalWrite(STC_PIN,LOW);//将STC_PIN引脚拉低
for(int j=0;j<16;j++){
digitalWrite(SHC_PIN,LOW);//将SHC_PIN拉低
digitalWrite(DS_PIN,array[i*16+j]);//写入74HC595第i帧第j位的状态
digitalWrite(SHC_PIN,HIGH);///将SHC_PIN拉高 产生一个上升沿 将DS_PIN脚的状态锁存
}
digitalWrite(STC_PIN,HIGH);//16个脚位的状态都写入后 将STC_PIN引脚拉高产生上升沿 将锁存数据显示并保持
delay(time_delay);//时间延迟 ms 显示此帧画面
}
//显示完数组内的内容后将16个控制引脚(D1.D2.D3....D16)拉高 停止显示
digitalWrite(STC_PIN,LOW);
for(int j=0;j<16;j++){
digitalWrite(SHC_PIN,LOW);
digitalWrite(DS_PIN,1);
digitalWrite(SHC_PIN,HIGH);
}
digitalWrite(STC_PIN,HIGH);
}
- 层控制
void Layer(int layer){//输入要显示的层数 输入0为都显示 当含有0~4之外的数字则不显示
switch(layer){
case 0:
digitalWrite(5,HIGH);//将开发板的GPIO5 (D1)引脚拉高
digitalWrite(4,HIGH);//GPIO4 (D2)引脚拉高
digitalWrite(0,HIGH);//GPIO0 (D3)引脚拉高
digitalWrite(15,HIGH);//GPIO15 (D8)引脚拉高
break;
case 1:
digitalWrite(5,HIGH);
digitalWrite(4,LOW);
digitalWrite(0,LOW);
digitalWrite(15,LOW);
break;
case 2:
digitalWrite(5,LOW);
digitalWrite(4,HIGH);
digitalWrite(0,LOW);
digitalWrite(15,LOW);
break;
case 3:
digitalWrite(5,LOW);
digitalWrite(4,LOW);
digitalWrite(0,HIGH);
digitalWrite(15,LOW);
break;
case 4:
digitalWrite(5,LOW);
digitalWrite(4,LOW);
digitalWrite(0,LOW);
digitalWrite(15,HIGH);
break;
case 12:
digitalWrite(5,HIGH);
digitalWrite(4,HIGH);
digitalWrite(0,LOW);
digitalWrite(15,LOW);
break;
case 21:
digitalWrite(5,HIGH);
digitalWrite(4,HIGH);
digitalWrite(0,LOW);
digitalWrite(15,LOW);
break;
case 13:
digitalWrite(5,HIGH);
digitalWrite(4,LOW);
digitalWrite(0,HIGH);
digitalWrite(15,LOW);
break;
case 31:
digitalWrite(5,HIGH);
digitalWrite(4,LOW);
digitalWrite(0,HIGH);
digitalWrite(15,LOW);
break;
case 14:
digitalWrite(5,HIGH);
digitalWrite(4,LOW);
digitalWrite(0,LOW);
digitalWrite(15,HIGH);
break;
case 41:
digitalWrite(5,HIGH);
digitalWrite(4,LOW);
digitalWrite(0,LOW);
digitalWrite(15,HIGH);
break;
case 23:
digitalWrite(5,LOW);
digitalWrite(4,HIGH);
digitalWrite(0,HIGH);
digitalWrite(15,LOW);
break;
case 32:
digitalWrite(5,LOW);
digitalWrite(4,HIGH);
digitalWrite(0,HIGH);
digitalWrite(15,LOW);
break;
case 24:
digitalWrite(5,LOW);
digitalWrite(4,HIGH);
digitalWrite(0,LOW);
digitalWrite(15,HIGH);
break;
case 42:
digitalWrite(5,LOW);
digitalWrite(4,HIGH);
digitalWrite(0,LOW);
digitalWrite(15,HIGH);
break;
case 34:
digitalWrite(5,LOW);
digitalWrite(4,LOW);
digitalWrite(0,HIGH);
digitalWrite(15,HIGH);
break;
case 43:
digitalWrite(5,LOW);
digitalWrite(4,LOW);
digitalWrite(0,HIGH);
digitalWrite(15,HIGH);
break;
case 123:
digitalWrite(5,HIGH);
digitalWrite(4,HIGH);
digitalWrite(0,HIGH);
digitalWrite(15,LOW);
break;
case 132:
digitalWrite(5,HIGH);
digitalWrite(4,HIGH);
digitalWrite(0,HIGH);
digitalWrite(15,LOW);
break;
case 213:
digitalWrite(5,HIGH);
digitalWrite(4,HIGH);
digitalWrite(0,HIGH);
digitalWrite(15,LOW);
break;
case 231:
digitalWrite(5,HIGH);
digitalWrite(4,HIGH);
digitalWrite(0,HIGH);
digitalWrite(15,LOW);
break;
case 321:
digitalWrite(5,HIGH);
digitalWrite(4,HIGH);
digitalWrite(0,HIGH);
digitalWrite(15,LOW);
break;
case 312:
digitalWrite(5,HIGH);
digitalWrite(4,HIGH);
digitalWrite(0,HIGH);
digitalWrite(15,LOW);
break;
case 124:
digitalWrite(5,HIGH);
digitalWrite(4,HIGH);
digitalWrite(0,LOW);
digitalWrite(15,HIGH);
break;
case 142:
digitalWrite(5,HIGH);
digitalWrite(4,HIGH);
digitalWrite(0,LOW);
digitalWrite(15,HIGH);
break;
case 241:
digitalWrite(5,HIGH);
digitalWrite(4,HIGH);
digitalWrite(0,LOW);
digitalWrite(15,HIGH);
break;
case 214:
digitalWrite(5,HIGH);
digitalWrite(4,HIGH);
digitalWrite(0,LOW);
digitalWrite(15,HIGH);
break;
case 412:
digitalWrite(5,HIGH);
digitalWrite(4,HIGH);
digitalWrite(0,LOW);
digitalWrite(15,HIGH);
break;
case 421:
digitalWrite(5,HIGH);
digitalWrite(4,HIGH);
digitalWrite(0,LOW);
digitalWrite(15,HIGH);
break;
case 234:
digitalWrite(5,LOW);
digitalWrite(4,HIGH);
digitalWrite(0,HIGH);
digitalWrite(15,HIGH);
break;
case 243:
digitalWrite(5,LOW);
digitalWrite(4,HIGH);
digitalWrite(0,HIGH);
digitalWrite(15,HIGH);
break;
case 324:
digitalWrite(5,LOW);
digitalWrite(4,HIGH);
digitalWrite(0,HIGH);
digitalWrite(15,HIGH);
break;
case 342:
digitalWrite(5,LOW);
digitalWrite(4,HIGH);
digitalWrite(0,HIGH);
digitalWrite(15,HIGH);
break;
case 423:
digitalWrite(5,LOW);
digitalWrite(4,HIGH);
digitalWrite(0,HIGH);
digitalWrite(15,HIGH);
break;
case 432:
digitalWrite(5,LOW);
digitalWrite(4,HIGH);
digitalWrite(0,HIGH);
digitalWrite(15,HIGH);
break;
default :
digitalWrite(5,LOW);
digitalWrite(4,LOW);
digitalWrite(0,LOW);
digitalWrite(15,LOW);
break;
}
}
完整示例程序
#define DS_PIN D5
#define STC_PIN D6
#define SHC_PIN D7
int S0to1_Length = 0;
int S0to1_array[]={//0到1方向 S型路线
1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,0,
1,1,1,1,1,1,1,1,1,1,1,1,1,1,0,1,
1,1,1,1,1,1,1,1,1,1,1,1,1,0,1,1,
1,1,1,1,1,1,1,1,1,1,1,1,0,1,1,1,
1,1,1,1,1,1,1,1,1,1,1,0,1,1,1,1,
1,1,1,1,1,1,1,1,1,1,0,1,1,1,1,1,
1,1,1,1,1,1,1,1,1,0,1,1,1,1,1,1,
1,1,1,1,1,1,1,1,0,1,1,1,1,1,1,1,
1,1,1,1,1,1,1,0,1,1,1,1,1,1,1,1,
1,1,1,1,1,1,0,1,1,1,1,1,1,1,1,1,
1,1,1,1,1,0,1,1,1,1,1,1,1,1,1,1,
1,1,1,1,0,1,1,1,1,1,1,1,1,1,1,1,
1,1,1,0,1,1,1,1,1,1,1,1,1,1,1,1,
1,1,0,1,1,1,1,1,1,1,1,1,1,1,1,1,
1,0,1,1,1,1,1,1,1,1,1,1,1,1,1,1,
0,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1
};
void DEMO_1(int time_delay){
int demo1[] = {0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0};//4
int demo2[] = {0,0,0,0,0,1,1,0,0,1,1,0,0,0,0,0};//34
int demo3[] = {0,0,0,0,0,1,1,0,0,1,1,0,0,0,0,0};//32
int demo4[] = {0,0,0,0,0,1,1,0,0,1,1,0,0,0,0,0};//21
int demo5[] = {0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0};//1
int demo6[] = {1,1,1,1,1,0,0,1,1,0,0,1,1,1,1,1};//12
int demo7[] = {1,1,1,1,1,0,0,1,1,0,0,1,1,1,1,1};//23
int demo8[] = {1,1,1,1,1,0,0,1,1,0,0,1,1,1,1,1};//34
Layer(4);
WriteArray(demo1,16,time_delay);
Layer(34);
WriteArray(demo2,16,time_delay);
Layer(32);
WriteArray(demo3,16,time_delay);
Layer(21);
WriteArray(demo4,16,time_delay);
Layer(1);
WriteArray(demo5,16,time_delay);
Layer(12);
WriteArray(demo6,16,time_delay);
Layer(23);
WriteArray(demo7,16,time_delay);
Layer(34);
WriteArray(demo8,16,time_delay);
}
void setup(){
InitPin();//引脚初始化
S0to1_Length = sizeof(S0to1_array) / sizeof(int);//计算数组长度
Layer(0);//点亮所有层
}
void loop(){
WriteArray(S0to1_array,S0to1_Length ,100);//每帧显示100ms
DEMO_1(125);
DEMO_1(125);
}
如过想要第一层的D2点亮而其余不亮,同时第二层D5点亮其余不亮。
void DEMO_2(){
int demo1[] = {1,0,1,1,1,1,1,1,1,1,1,1,1,1,1,1};//仅点亮D2
int demo2[] = {1,1,1,1,0,1,1,1,1,1,1,1,1,1,1,1};//仅点亮D5
Layer(5);
uint32_t tim = millis();
while(1){
Layer(1);//仅点亮第一层
WriteArray(demo1,16,8);//延迟8ms
Layer(2);//仅点亮第二层
WriteArray(demo2,16,8);//延迟8ms
if(millis() - tim >= 2000)break;//显示2s后跳出
}
}
完整的程序文件在群文件中531774127