灰阶光立方 最少硬件资源 程序可扩展-Arduino中文社区 - Powered by Discuz!

Arduino中文社区

 找回密码
 立即注册

QQ登录

只需一步,快速开始

查看: 2326|回复: 1

灰阶光立方 最少硬件资源 程序可扩展

[复制链接]
发表于 2020-7-10 11:24 | 显示全部楼层 |阅读模式
本帖最后由 createskyblue 于 2020-7-10 19:05 编辑

封面_压缩.jpg
说明
亮点1 多阶灰度模拟,用最少的资源做出灰阶光立方
亮点2 可以使用串口通讯通过光立方的密度、亮度、闪烁频率直观地显示出CPU占用率(可惜视频拍不出这个效果,想感受得自己做一个)
通过合理调整扫描间隔实现灰度显示,定时器不足采用软件模拟所以存在一定的缺陷:
缺陷1 更精细的灰阶需要牺牲刷新率换取
缺陷2 使用了所有可以用的io驱动,只可以周期性地进行串口通讯交换数据

视频演示


引脚定义


侧视图_压缩.jpg

程序

  1. /*
  2.   +创天蓝编写 1281702594@qq.com  采用CC协议
  3.   +关于串口通讯
  4.   -当需要时,光立方驱动程序会向上位机发送指令“get”,当上位机收到get后可开始传送cpu使用率(0-100)
  5.   -默认2000ms光立方发送一次刷新请求
  6.   -串口通讯超时默认为1500ms
  7.   -请求状态下向光立方发送串口指令"120"会软重启光立方
  8.   +倘若通讯超时 将清空显示,如果希望通讯超时后显示随机内容请把SerialReadCMD()函数中最后一处出现的"p=0;"改为"p=random(0,100);"即可
  9.   +支持更改光立方大小 默认大小4x4x4 把4改为你想要的即可
  10.   -如果光立方分辨率高于4x4x4需要修改LightCube()函数,因为arduino某些型号并不能直接驱动高于4x4x4的光立方
  11.   -不过不用担心,修改方式很简单,把IO控制的两行代码改成控制所需要的控制寄存器的代码就好
  12. */
  13. int cube[4][4][4];
  14. int layer[4] = {A5, A4, A3, A2}; //光立方的引脚
  15. int column[4][4] = {
  16.   A1, A0, 13, 12,
  17.   8,  9,  10, 11,
  18.   4,  5,  6,  7,
  19.   0,  1,  2,  3
  20. };

  21. byte LightCycle = 0;
  22. int p = 0;
  23. byte pw;
  24. unsigned long DisplayerTime = 0;
  25. unsigned long RandomCoolTime = 0;
  26. unsigned long SerialReadCMDTimeOut = 0;
  27. void (*resetFunc)(void) = 0;

  28. void BootLogo() {
  29.   cube[3][3][3]=255;

  30.   }

  31. void setup() {
  32.   randomSeed(analogRead(A0));
  33.   SetupCubePin();
  34.   CleanCube();
  35.   BootLogo();
  36.   LightCube();
  37.   //Serial.begin(115200);
  38. }

  39. void loop() {
  40.   DisplayerTime = millis();
  41.   //                                  ↓ 默认的请求刷新时间 单位ms
  42.   while (millis() < DisplayerTime + 1000) {
  43.     LightCube();
  44.     //选择闪烁模式
  45.     //byte RamTimePlusP = 100 - p + random(25, 75);  //CPU使用率低时闪得慢,使用率高时闪得快
  46.     byte RamTimePlusP = random(25, 85 + p); //CPU使用率高时闪得慢,使用率低时闪得快
  47.     while (millis() > RandomCoolTime + RamTimePlusP) {
  48.       RandomCube();
  49.       //PrintCube();
  50.       RandomCoolTime = millis();
  51.     }
  52.   }
  53.   //CleanCube();
  54.   LightCube();
  55.   p = 1000.0/(5.3*random(1, 100)+10);
  56.   //SerialReadCMD();
  57. }
  58. void SetupCubePin() {
  59.   //Serial.println("SetupCubePin");
  60.   for (byte z = 0; z < 4; z++) pinMode(layer[z], OUTPUT);
  61.   for (byte y = 0; y < 4; y++)
  62.     for (byte x = 0; x < 4; x++) pinMode(column[x][y], OUTPUT);
  63. }
  64. void CleanCube() {
  65.   //Serial.println("CleanCube");
  66.   for (byte z = 0; z < 4; z++)
  67.     for (byte y = 0; y < 4; y++)
  68.       for (byte x = 0; x < 4; x++) cube[x][y][z] = 0;
  69. }
  70. void PrintCube() {
  71.   Serial.println("PrintCube");
  72.   for (byte z = 0; z < 4; z++) {
  73.     for (byte y = 0; y < 4; y++) {
  74.       //Serial.println();
  75.       for (byte x = 0; x < 4; x++) Serial.print(cube[x][y][z] + String(" "));
  76.     }
  77.     Serial.println();
  78.   }
  79. }
  80. void RandomCube() {
  81.   //Serial.println("RandomCube");
  82.   //CleanCube();
  83.   int NewLight;
  84.   pw = 0;
  85.   for (byte t = 0; t < 2; t++)
  86.     for (byte z = 0; z < 4; z++)
  87.       for (byte y = 0; y < 4; y++)
  88.         for (byte x = 0; x < 4; x++) {
  89.           if (cube[x][y][z] > 0) cube[x][y][z] -= 10;
  90.           if (cube[x][y][z] < 0) cube[x][y][z] = 0;
  91.           if (random(0, 100) < abs(p - 100 * t)) {
  92.             NewLight = !t * random(15, 100) + cube[x][y][z];
  93.             if (NewLight < 256) cube[x][y][z] = NewLight; else NewLight = 255;
  94.           };
  95.           pw++;
  96.         }
  97.   //Serial.println(float(pw) / 64);
  98. }
  99. void LightCube() {
  100.   //Serial.println("LightCube");
  101.   for (byte z = 0; z < 4; z++) {
  102.     digitalWrite(layer[z], 0);
  103.     for (byte y = 0; y < 4; y++)
  104.       for (byte x = 0; x < 4; x++) {
  105.         if (LightCycle < cube[x][y][z]) digitalWrite(column[x][y], 1); else digitalWrite(column[x][y], 0);
  106.       }
  107.     digitalWrite(layer[z], 1);
  108.   }
  109.   LightCycle += 25;
  110. }
  111. void SerialReadCMD() {
  112.   pinMode(13, OUTPUT);
  113.   digitalWrite(13, 1);
  114.   Serial.begin(115200);
  115.   String inString = "";
  116.   SerialReadCMDTimeOut = millis();
  117.   delay(4);
  118.   while (1) {
  119.     //Serial.println("Get");
  120.     while (Serial.available() > 0) {
  121.       char inChar = Serial.read();
  122.       inString += (char)inChar;
  123.     }
  124.     if (inString != "" || millis() > SerialReadCMDTimeOut + 1500) break;  //收到数据或者连接超时

  125.   }
  126.   //p = 0; //通讯超时后清空光立方
  127.   p = random(1, 10); //通讯超时后开启随机展示模式
  128.   if (inString != "") p = inString.toInt();
  129.   if (p == 110) resetFunc();
  130.   Serial.println(p);
  131.   Serial.end();  //UNO IO不够通讯结束后防止显示异常必须关闭串口,如果你的串口IO与显示IO不是混用可以注释这一项
  132. }
复制代码

全部资料下载


您需要登录后才可以回帖 登录 | 立即注册

本版积分规则

小黑屋|Archiver|手机版|Arduino中文社区

GMT+8, 2024-11-28 11:42 , Processed in 0.134115 second(s), 18 queries .

Powered by Discuz! X3.4

Copyright © 2001-2021, Tencent Cloud.

快速回复 返回顶部 返回列表