光序列创建器
组件和用品
| | × | 1 | |
| | × | 2 | |
| | × | 55 | |
| | × | 1 | |
| | × | 4 | |
| | × | 1 | |
| | × | 8 | |
| | × | 9 | |
| | × | 4 | |
关于这个项目
我一直在玩灯光和阵列,我想我会利用移位寄存器和 LCD 屏幕来创建一个程序,您可以在其中修改和显示您的灯光动画,而无需进入代码并手动创建动画每次。
有 4 个按钮,从左到右编号为 1 - 4。它们允许您导航菜单并更改变量。按钮 1 用于增加值和将灯的状态转为高。按钮 2 用于递减值,并将灯的状态转为低。按钮 3 可以在制作框架时向后移动光标,按钮 4 用作“后退”按钮。
该程序可以修改动画的速度和循环次数。我可能会发布另一个允许多个动画的版本。
您可以通过更改代码顶部的 ARR_SIZE 来更改帧
享受
代码
光序列器C/C++
插入此代码并运行它,如果接线正确,则应该没有问题!
享受#include #define ARR_SIZE 16 // 将此更改为任意数量的帧#define LIGHTS 8 // 控制游戏按钮输入const int btn1 =7, btn2 =8, btn3 =9, btn4 =10;//读取按钮状态的变量int bs1 =0, bs2 =0, bs3 =0, bs4 =0;//引脚连接到74HC595const的ST_CP int latchPin =11;//引脚连接到74HC595const的SH_CP int clockPin =13;// 引脚连接到 74HC595const 的 DS int dataPin =12;// 持有者你要传递字节数据的信息;// 用于读取 1 或 0bool ArrOne[ARR_SIZE][LIGHTS] ={false}; // 动画// 为寄存器翻译为bytesbyte lightArrOne[ARR_SIZE] ={0xFF};// 影响动画的变量int animSpeed =50; // 每帧之间的毫秒int loopCount =5; // 运行次数 // Controls LCD Valuesconst int rs =15, en =14, d4 =3, d5 =4, d6 =5, d7 =6;LiquidCrystal lcd(rs, en, d4, d5, d6 , d7);void setup(){ // 设置每个按钮向上 pinMode(btn1, INPUT_PULLUP); pinMode(btn2, INPUT_PULLUP); pinMode(btn3, INPUT_PULLUP); pinMode(btn4, INPUT_PULLUP); // 设置 LCD 的列数和行数:lcd.begin(16, 2); // 设置寄存器锁存 pinMode(latchPin, OUTPUT); PrintMenu();}void loop(){ bs1 =digitalRead(btn1); bs2 =数字读取(btn2); bs3 =digitalRead(btn3); bs4 =数字读取(btn4); // 播放动画 if(bs1 ==HIGH) { bs1 =LOW;// 只是用来防止坏/双输入延迟(150);玩(); // 修改动画 } else if(bs2 ==HIGH) { bs2 =LOW;延迟(150);创建(ArrOne); // 改变动画的速度 } else if(bs3 ==HIGH) { bs3 =LOW;延迟(150);设置速度(); // 改变动画播放的次数 } else if(bs4 ==HIGH) { bs4 =LOW;延迟(150);设置循环();打印菜单(); delay(150);}// 打印主菜单信息的函数void PrintMenu(){ ClearScreen(); lcd.print("1-Play 3-Speed"); lcd.setCursor(0, 1); lcd.print("2-Create 4-Loops");}// 用于打印创建框架的信息的函数void PrintCreate(bool Arr[][LIGHTS], int frame, int _bit){ ClearScreen(); lcd.print("框架:");液晶显示(帧+1); if(frame <9) lcd.print(" "); for(int j =0; j <_bit; j++) lcd.print(" ");液晶打印(“v”); lcd.setCursor(0, 1);液晶打印(“”); for(int j =0; j <8; j++) lcd.print(Arr[frame][j]);}// 打印设置速度信息的函数void PrintSetSpeed(){ ClearScreen(); lcd.print("设置速度(毫秒)"); lcd.setCursor(0, 1); lcd.print(animSpeed);}// 用于打印改变动画循环次数的信息的函数void PrintSetLoop(){ ClearScreen(); lcd.print("设置循环次数"); lcd.setCursor(0, 1); lcd.print(loopCount);}// 使用给定参数播放动画的函数void Play(){ // 动画 for(int count =0; count 0) { b =LIGHTS-1;框架 -; bs1 =digitalRead(btn1); bs2 =数字读取(btn2); bs3 =digitalRead(btn3); bs4 =数字读取(btn4);如果(bs1 ==HIGH){延迟(150); Arr[帧][b] =真; b++; } else if(bs2 ==HIGH) { 延迟(150); Arr[frame][b] =false; b++; } else if(bs3 ==HIGH) { 延迟(150);乙--; } else if(bs4 ==HIGH) { 延迟(150);离开 =真; } 延迟(10); } PrintCreate(Arr, frame, b); IntToHexToByte(Arr);延迟(500); }}// 函数将数组转换为字节供寄存器读取void IntToHexToByte(bool Arr[][LIGHTS]){ for(int row =0; row 1) animSpeed--; } // 提高速度 if(bs4 ==HIGH) { delay(150);离开 =真; } 延迟(30); }}// 改变动画循环次数的函数void SetLoop(){ bool leave =false;而(!离开){ PrintSetLoop(); bs1 =数字读取(btn1); bs2 =数字读取(btn2); bs3 =digitalRead(btn3); bs4 =数字读取(btn4);如果(bs1 ==HIGH){延迟(10);循环计数++; } if(bs2 ==HIGH) { 延迟(10); if(animSpeed> 1) loopCount--; } if(bs4 ==HIGH) { 延迟(150);离开 =真; } 延迟(30); }}// 实际移位寄存器中的位的函数void shiftOut(int myDataPin, int myClockPin, byte myDataOut){ // 这首先将 8 位移出 MSB, // 在时钟的上升沿, // 时钟空闲low //内部函数设置 int i =0; int pinState; pinMode(myClockPin,输出); pinMode(myDataPin,输出); //清除所有内容以防万一 //准备移位寄存器用于位移digitalWrite(myDataPin, 0);数字写入(myClockPin,0); // 字节 myDataOut 中的每一位 for (i =7; i>=0; i--) { digitalWrite(myClockPin, 0); if ( myDataOut &(1 <
示意图
仔细遵循这些行,由于程序中电阻器长度的限制,并且出于可读性目的,我无法像在实际构建中那样压缩它。构建完成后,我挑战您找到清理它的方法。