查看: 1017|回复: 8

[项目] 项目分享——arduino梦幻交互雪花2019

[复制链接]
  • TA的每日心情
    开心
    2019-8-19 13:48
  • 签到天数: 1 天

    [LV.1]初来乍到

    发表于 2019-4-4 00:29 | 显示全部楼层 |阅读模式
    本帖最后由 Arduino_xyz 于 2019-4-4 00:31 编辑

    雪花由30颗LED打造,分为17个独立的部分,由Arduino Nano控制。每组LED都可以用PWM调校,这样就可以创作出梦幻视觉效果。
    01.jpg
    首先打印一个漂亮而简单的雪花,记住要让它可以容纳Arduino Nano。
    02.jpg
    支撑结构也用于走线,由0.8mm黄铜棒与锡焊接而成。我总共使用了2米的黄铜棒。这是对你的耐心和技巧的一次考验。
    03.jpg
    首先,我通过弯曲一根黄铜棒并将两端焊接在一起来构建一个核心六边形。通过在六边形的顶部添加另外伸出6个黄铜棒,接地线完成,现在需要将LED的所有阴极引线焊接到其上以产生雪花图案。棘手的部分是添加贴片LED,不妨使用纸板和双面胶带制作的夹具。
    04.jpg
    接下来是在核心结构下加入Arduino Nano,在其间要留出足够的空间以满足3层黄铜棒接线,这将连接微控制器引脚到所有LED阳极引线。这同样需要极大的耐心。你不仅需要避免电线之间的短路,还要添加限流电阻并使其看起来不错。
    05.jpg
    叶片LED分别连接到最近的Arduino输出引脚。分支LED按两个分组并连接到PWM引脚。核心LED也按两个分组并连接到其余引脚。Arduino NANO只有18个输出引脚,我需要一个引脚用于触摸传感器,这只留下17个引脚,因此两对核心LED连接在一起形成一组4个。我使用220Ω电阻将每个引脚流过的电流限制在8mA左右。这意味着总共240mA,这对ATmega328芯片来说有点高,但它可以工作——安全最大值据说是200mA。
    为了能够与雪花相互作用,我添加了另一个黄铜棒来制作电容式触摸传感器。
    06.jpg
    在焊接之前不要忘记随时检查所有二极管,如果开路或者反极性连接会很难更换它。
    07.jpg
    原理图
    09.png
    源代码
    1. #include "SoftPWM.h"
    2. #include <ADCTouchSensor.h>

    3. byte edgeLedPins[] = {13, A4, A5, 2, 8, 12};
    4. byte middleLedPins[] = {10, 6, 3, 5, 9, 11};
    5. byte innerLedPins[] = {A2, A3, A1, 4, 7, A1};

    6. ADCTouchSensor touchSensor = ADCTouchSensor(A0, 1);

    7. void setup() {
    8.   Serial.begin(115200);
    9.   SoftPWMBegin();
    10. }

    11. byte animation = 0;
    12. long touchAt = 0;

    13. void loop() {
    14.   switch (animation) {
    15.     case 0:
    16.       _fill(100);
    17.       break;
    18.     case 1:
    19.       shinyAnimation();
    20.       //fadingAnimation();
    21.       break;
    22.     case 2:
    23.       circleAnimation();
    24.       break;
    25.     case 3:
    26.       loopAnimation();
    27.       break;
    28.     case 4:
    29.       fireworkAnimation();
    30.       fireworkAnimation();
    31.       fireworkAnimation();
    32.       fireworkAnimation();
    33.       fireworkAnimation();
    34.       fireworkAnimation();
    35.       animation ++;
    36.       break;
    37.     case 5:
    38.       smileAnimation();
    39.       break;
    40.     default:
    41.       animation = 0;
    42.       break;
    43.   }
    44.   int touchValue = touchSensor.read();
    45.   if (touchAt + 2000 < millis() && touchValue > 1000) {
    46.     touchAt = millis(); // touch down, cold down timeout is 2s
    47.     animation ++;
    48.     _fill(0);
    49.   }
    50. }

    51. void fireworkAnimation() {
    52.   for (int i = 0; i < 4; i++) {
    53.     SoftPWMSet(innerLedPins[i], 100);
    54.     delay(100);
    55.   }
    56.   SoftPWMSet(innerLedPins[4], 100);
    57.   for (int i = 0; i < 6; i++) {
    58.     SoftPWMSet(middleLedPins[i], 255);
    59.   }
    60.   delay(50);
    61.   for (int i = 0; i < 6; i++) {
    62.     SoftPWMSet(innerLedPins[i], 0);
    63.     SoftPWMSet(edgeLedPins[i], 255);
    64.   }
    65.   delay(50);
    66.   for (int i = 0; i < 6; i++) {
    67.     SoftPWMSet(middleLedPins[i], 0);
    68.   }
    69.   delay(50);
    70.   _fill(0);
    71. }

    72. void smileAnimation() {
    73.   SoftPWMSet(innerLedPins[1], 100);
    74.   SoftPWMSet(innerLedPins[3], 100);
    75.   SoftPWMSet(middleLedPins[0], 255);
    76.   SoftPWMSet(middleLedPins[5], 255);
    77.   SoftPWMSet(edgeLedPins[2], 255);
    78.   SoftPWMSet(edgeLedPins[3], 255);
    79.   delay(2000);
    80.   SoftPWMSet(innerLedPins[1], 0);
    81.   SoftPWMSet(innerLedPins[3], 0);
    82.   delay(100);
    83.   SoftPWMSet(innerLedPins[1], 100);
    84.   SoftPWMSet(innerLedPins[3], 100);
    85.   delay(100);
    86.   SoftPWMSet(innerLedPins[1], 0);
    87.   SoftPWMSet(innerLedPins[3], 0);
    88.   delay(100);
    89. }

    90. byte circleState[] = {100, 55, 10};
    91. byte circleStateAnimation[] = {1, 1, 1};

    92. void circleAnimation() {
    93.   for (int i = 0; i < 3; i++) {
    94.     if (circleState[i] >= 100) {
    95.       circleStateAnimation[i] = -1; // dim
    96.     }
    97.     else if (circleState[i] <= 10) {
    98.       circleStateAnimation[i] = 1; // bright
    99.     }
    100.     circleState[i] += circleStateAnimation[i];
    101.   }
    102.   for (int i = 0; i < 6; i++) {
    103.     SoftPWMSet(innerLedPins[i], circleState[0]);
    104.     SoftPWMSet(middleLedPins[i], circleState[1]);
    105.     SoftPWMSet(edgeLedPins[i], circleState[2]);
    106.   }
    107.   delay(5);
    108. }

    109. byte waveState[] = {100, 55, 10, 10, 55, 100};
    110. byte waveStateAnimation[] = {1, 1, 1, -1, -1, -1};

    111. void waveAnimation() {
    112.   for (int i = 0; i < 6; i++) {
    113.     if (waveState[i] >= 100) {
    114.       waveStateAnimation[i] = -1; // dim
    115.     }
    116.     else if (waveState[i] <= 10) {
    117.       waveStateAnimation[i] = 1; // bright
    118.     }
    119.     waveState[i] += waveStateAnimation[i];
    120.   }
    121.   for (int i = 0; i < 6; i+=2) {
    122.     SoftPWMSet(innerLedPins[i], waveState[0]);
    123.     SoftPWMSet(middleLedPins[i], waveState[1]);
    124.     SoftPWMSet(edgeLedPins[i], waveState[2]);
    125.     SoftPWMSet(innerLedPins[i + 1], waveState[3]);
    126.     SoftPWMSet(middleLedPins[i + 1], waveState[4]);
    127.     SoftPWMSet(edgeLedPins[i + 1], waveState[5]);
    128.   }
    129.   delay(10);
    130. }

    131. byte loopCounter = 0;
    132. byte loopState = 150;

    133. void loopAnimation() {
    134.   SoftPWMSet(innerLedPins[loopCounter], loopState);
    135.   SoftPWMSet(middleLedPins[loopCounter], loopState);
    136.   SoftPWMSet(edgeLedPins[loopCounter], loopState);

    137.   loopCounter = _nextIndex(loopCounter, 1);
    138.   if (loopCounter == 0) {
    139.     loopState = (loopState == 150 ? 0 : 150);
    140.   }
    141.   delay(100);
    142. }

    143. byte slowOnCounter = 0;
    144. byte slowOnState = 150;

    145. void slowOnAnimation() {
    146.   byte randomLed = random(0, 18);
    147.   if (randomLed < 6) {
    148.     SoftPWMSet(innerLedPins[randomLed], slowOnState);
    149.   }
    150.   else if (randomLed < 12) {
    151.     SoftPWMSet(middleLedPins[randomLed - 6], slowOnState);
    152.   }
    153.   else {
    154.     SoftPWMSet(edgeLedPins[randomLed - 12], slowOnState);
    155.   }
    156.   slowOnCounter ++;
    157.   if (slowOnCounter >= 50) {
    158.     slowOnCounter = 0;
    159.     slowOnState = (slowOnState == 150 ? 0 : 150);
    160.   }
    161.   delay(50);
    162. }

    163. byte shinyState[] = {0, 100, 0, 100, 0, 100};
    164. byte shinyStateAnimation[] = {1, 1, 1, 1, 1, 1};
    165. byte shinyCounter = 0;

    166. void shinyAnimation() {
    167.   for (int i = 0; i < 6; i++) {
    168.     if (shinyState[i] >= 100) {
    169.       shinyStateAnimation[i] = -1; // dim
    170.     }
    171.     else if (shinyState[i] <= 0) {
    172.       shinyStateAnimation[i] = 1; // bright
    173.     }
    174.     shinyState[i] += shinyStateAnimation[i];
    175.     SoftPWMSet(edgeLedPins[i], shinyState[i]);
    176.   }
    177.   shinyCounter ++;
    178.   if (shinyCounter > 10) {
    179.     shinyCounter = 0;
    180.     for (byte r = random(1, 3); r > 0; r--) {
    181.       byte randomLed = random(0, 12);
    182.       if (randomLed < 6) {
    183.         SoftPWMSet(innerLedPins[random(0, 6)], 255);
    184.       }
    185.       else {
    186.         SoftPWMSet(middleLedPins[random(0, 6)], 255);
    187.       }
    188.     }
    189.   }
    190.   else {
    191.     for (int i = 0; i < 6; i++) {
    192.       SoftPWMSet(innerLedPins[i], 20);
    193.       SoftPWMSet(middleLedPins[i], 20);
    194.     }
    195.   }
    196.   delay(30);
    197. }

    198. byte fadingState[] = {0, 100, 0, 100, 0, 100};
    199. byte fadingStateAnimation[] = {1, 1, 1, 1, 1, 1};

    200. void fadingAnimation() {
    201.   for (int i = 0; i < 6; i++) {
    202.     if (fadingState[i] >= 100) {
    203.       fadingStateAnimation[i] = -1; // dim
    204.     }
    205.     else if (fadingState[i] <= 0) {
    206.       fadingStateAnimation[i] = 1; // bright
    207.     }
    208.     fadingState[i] += fadingStateAnimation[i];
    209.     SoftPWMSet(edgeLedPins[i], fadingState[i]);
    210.     SoftPWMSet(middleLedPins[_nextIndex(i, 1)], fadingState[i]);
    211.     SoftPWMSet(innerLedPins[i], 50);
    212.   }
    213.   delay(20);
    214. }

    215. void _fill(byte value) {
    216.   for (int i = 0; i < 6; i++) {
    217.     SoftPWMSet(edgeLedPins[i], value);
    218.     SoftPWMSet(middleLedPins[i], value);
    219.     SoftPWMSet(innerLedPins[i], value);
    220.   }
    221. }

    222. byte _prevIndex(short index, byte step) {
    223.   index -= step;
    224.   while (index < 0) {
    225.     index += 6;
    226.   }
    227.   return index;
    228. }

    229. byte _nextIndex(short index, byte step) {
    230.   index += step;
    231.   while (index > 5) {
    232.     index -= 6;
    233.   }
    234.   return index;
    235. }
    复制代码

  • TA的每日心情
    开心
    2019-8-25 00:14
  • 签到天数: 70 天

    [LV.6]常住居民II

    发表于 2019-4-4 02:21 | 显示全部楼层
    哇  不错不错  要是有视频记的补发一下
  • TA的每日心情
    郁闷
    2018-12-6 22:21
  • 签到天数: 48 天

    [LV.5]常住居民I

    发表于 2019-4-4 10:53 | 显示全部楼层
    焊的真漂亮!上个视频吧
    如果以上内容对你有帮助,你可以通过打赏支持作者
  • TA的每日心情
    奋斗
    2019-6-9 21:59
  • 签到天数: 101 天

    [LV.6]常住居民II

    发表于 2019-4-5 11:30 | 显示全部楼层
    鼓励鼓励,上个视频演示下
  • TA的每日心情
    开心
    2019-8-19 13:48
  • 签到天数: 1 天

    [LV.1]初来乍到

     楼主| 发表于 2019-4-6 16:40 | 显示全部楼层
    本帖最后由 Arduino_xyz 于 2019-4-6 16:44 编辑

    PCB design for 梦幻雪花,你喜欢吗?视频上传不上来,感兴趣的可以留邮箱我发到你,并且分享免费的PDF格式教程和ino格式源码哦。
    03_1_01.png

    该用户从未签到

    发表于 2019-5-21 10:54 来自手机 | 显示全部楼层
    学习到了 留个邮箱 麻烦题主发下教程 万分感谢!1055315782@qq.com
  • TA的每日心情
    开心
    2019-8-19 13:48
  • 签到天数: 1 天

    [LV.1]初来乍到

     楼主| 发表于 2019-6-2 07:33 | 显示全部楼层
    Swifty 发表于 2019-5-21 10:54
    学习到了 留个邮箱 麻烦题主发下教程 万分感谢!1055315782@qq.com

    已发送,查收
  • TA的每日心情
    难过
    2019-8-24 00:33
  • 签到天数: 68 天

    [LV.6]常住居民II

    发表于 2019-6-2 14:33 | 显示全部楼层
    顶! 做的真漂亮!

    该用户从未签到

    发表于 2019-6-18 00:04 | 显示全部楼层
    想请教一下,黄铜线来做“电容式触摸传感器”,是什么原理呀
    您需要登录后才可以回帖 登录 | 立即注册  

    本版积分规则

    热门推荐

    arduino首次编译通过第二次编译必报错
    arduino首次编译通过第二
    如题: 刚打开ide 首次编译 上传都没问题 不管你改不改代码 直接进行 编译 或者上传
    【Arduino】108种传感器系列实验(06)---声音传感器模块
    【Arduino】108种传感器系
    37款传感器与模块的提法,在网络上广泛流传,其实Arduino能够兼容的传感器模块肯定是
    旧版本ide中 ino文件名不能以数字开头,不能有中文?
    旧版本ide中 ino文件名不
    最近下载了站长编著的ARDUINO程序设计基础一书的配套例程。发现用arduino ide打开 里
    用Blinker获取天气信息并用ArduinoJson6分析数据(arduino D1)
    用Blinker获取天气信息并
    在Blinker最新版本的库中我们看到它用了ArduinoJson6,图中的两个类是ArduinoJson6的类
    一波三折,分享我的esp32编译环境搭建arduino
    一波三折,分享我的esp32
    买了个esp-wroom32开发板,想用熟悉的arduino敲代码。 但是上网查遍了所有办法,要么
    Copyright   ©2015-2016  Arduino中文社区  Powered by©Discuz!   ( 蜀ICP备14017632号-3 )
    快速回复 返回顶部 返回列表