Arduino 梦幻交互雪花 2019

梦幻雪花由30颗LED打造,分为17个独立的部分,由Arduino Nano控制。每组LED都可以用PWM调校,这样就可以创作出梦幻视觉效果。

首先打印一个漂亮而简单的雪花,记住要让它可以容纳Arduino Nano。

支撑结构也用于走线,由0.8mm黄铜棒与锡焊接而成。我总共使用了2米的黄铜棒。这是对你的耐心和技巧的一次考验。

首先,我通过弯曲一根黄铜棒并将两端焊接在一起来构建一个核心六边形。通过在六边形的顶部添加另外伸出6个黄铜棒,接地线完成,现在需要将LED的所有阴极引线焊接到其上以产生雪花图案。棘手的部分是添加贴片LED,不妨使用纸板和双面胶带制作的夹具。

接下来是在核心结构下加入Arduino Nano,在其间要留出足够的空间以满足3层黄铜棒接线,这将连接微控制器引脚到所有LED阳极引线。这同样需要极大的耐心。你不仅需要避免电线之间的短路,还要添加限流电阻并使其看起来不错。
叶片LED分别连接到最近的Arduino输出引脚。分支LED按两个分组并连接到PWM引脚。核心LED也按两个分组并连接到其余引脚。Arduino NANO只有18个输出引脚,我需要一个引脚用于触摸传感器,这只留下17个引脚,因此两对核心LED连接在一起形成一组4个。我使用220Ω电阻将每个引脚流过的电流限制在8mA左右。这意味着总共240mA,这对ATmega328芯片来说有点高,但它可以工作——安全最大值据说是200mA。

为了能够与雪花相互作用,我添加了另一个黄铜棒来制作电容式触摸传感器。

在焊接之前不要忘记随时检查所有二极管,如果开路或者反极性连接会很难更换它。

原理图

源代码

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
#include "SoftPWM.h"
#include <ADCTouchSensor.h>
 
byte edgeLedPins[] = {13, A4, A5, 2, 8, 12};
byte middleLedPins[] = {10, 6, 3, 5, 9, 11};
byte innerLedPins[] = {A2, A3, A1, 4, 7, A1};
 
ADCTouchSensor touchSensor = ADCTouchSensor(A0, 1);
 
void setup() {
  Serial.begin(115200);
  SoftPWMBegin();
}
 
byte animation = 0;
long touchAt = 0;
 
void loop() {
  switch (animation) {
    case 0:
      _fill(100);
      break;
    case 1:
      shinyAnimation();
      //fadingAnimation();
      break;
    case 2:
      circleAnimation();
      break;
    case 3:
      loopAnimation();
      break;
    case 4:
      fireworkAnimation();
      fireworkAnimation();
      fireworkAnimation();
      fireworkAnimation();
      fireworkAnimation();
      fireworkAnimation();
      animation ++;
      break;
    case 5:
      smileAnimation();
      break;
    default:
      animation = 0;
      break;
  }
  int touchValue = touchSensor.read();
  if (touchAt + 2000 < millis() && touchValue > 1000) {
    touchAt = millis(); // touch down, cold down timeout is 2s
    animation ++;
    _fill(0);
  }
}
 
void fireworkAnimation() {
  for (int i = 0; i < 4; i++) {
    SoftPWMSet(innerLedPins[i], 100);
    delay(100);
  }
  SoftPWMSet(innerLedPins[4], 100);
  for (int i = 0; i < 6; i++) {
    SoftPWMSet(middleLedPins[i], 255);
  }
  delay(50);
  for (int i = 0; i < 6; i++) {
    SoftPWMSet(innerLedPins[i], 0);
    SoftPWMSet(edgeLedPins[i], 255);
  }
  delay(50);
  for (int i = 0; i < 6; i++) {
    SoftPWMSet(middleLedPins[i], 0);
  }
  delay(50);
  _fill(0);
}
 
void smileAnimation() {
  SoftPWMSet(innerLedPins[1], 100);
  SoftPWMSet(innerLedPins[3], 100);
  SoftPWMSet(middleLedPins[0], 255);
  SoftPWMSet(middleLedPins[5], 255);
  SoftPWMSet(edgeLedPins[2], 255);
  SoftPWMSet(edgeLedPins[3], 255);
  delay(2000);
  SoftPWMSet(innerLedPins[1], 0);
  SoftPWMSet(innerLedPins[3], 0);
  delay(100);
  SoftPWMSet(innerLedPins[1], 100);
  SoftPWMSet(innerLedPins[3], 100);
  delay(100);
  SoftPWMSet(innerLedPins[1], 0);
  SoftPWMSet(innerLedPins[3], 0);
  delay(100);
}
 
byte circleState[] = {100, 55, 10};
byte circleStateAnimation[] = {1, 1, 1};
 
void circleAnimation() {
  for (int i = 0; i < 3; i++) {
    if (circleState[i] >= 100) {
      circleStateAnimation[i] = -1; // dim
    }
    else if (circleState[i] <= 10) {
      circleStateAnimation[i] = 1; // bright
    }
    circleState[i] += circleStateAnimation[i];
  }
  for (int i = 0; i < 6; i++) {
    SoftPWMSet(innerLedPins[i], circleState[0]);
    SoftPWMSet(middleLedPins[i], circleState[1]);
    SoftPWMSet(edgeLedPins[i], circleState[2]);
  }
  delay(5);
}
 
byte waveState[] = {100, 55, 10, 10, 55, 100};
byte waveStateAnimation[] = {1, 1, 1, -1, -1, -1};
 
void waveAnimation() {
  for (int i = 0; i < 6; i++) {
    if (waveState[i] >= 100) {
      waveStateAnimation[i] = -1; // dim
    }
    else if (waveState[i] <= 10) {
      waveStateAnimation[i] = 1; // bright
    }
    waveState[i] += waveStateAnimation[i];
  }
  for (int i = 0; i < 6; i+=2) {
    SoftPWMSet(innerLedPins[i], waveState[0]);
    SoftPWMSet(middleLedPins[i], waveState[1]);
    SoftPWMSet(edgeLedPins[i], waveState[2]);
    SoftPWMSet(innerLedPins[i + 1], waveState[3]);
    SoftPWMSet(middleLedPins[i + 1], waveState[4]);
    SoftPWMSet(edgeLedPins[i + 1], waveState[5]);
  }
  delay(10);
}
 
byte loopCounter = 0;
byte loopState = 150;
 
void loopAnimation() {
  SoftPWMSet(innerLedPins[loopCounter], loopState);
  SoftPWMSet(middleLedPins[loopCounter], loopState);
  SoftPWMSet(edgeLedPins[loopCounter], loopState);
 
  loopCounter = _nextIndex(loopCounter, 1);
  if (loopCounter == 0) {
    loopState = (loopState == 150 ? 0 : 150);
  }
  delay(100);
}
 
byte slowOnCounter = 0;
byte slowOnState = 150;
 
void slowOnAnimation() {
  byte randomLed = random(0, 18);
  if (randomLed < 6) {
    SoftPWMSet(innerLedPins[randomLed], slowOnState);
  }
  else if (randomLed < 12) {
    SoftPWMSet(middleLedPins[randomLed - 6], slowOnState);
  }
  else {
    SoftPWMSet(edgeLedPins[randomLed - 12], slowOnState);
  }
  slowOnCounter ++;
  if (slowOnCounter >= 50) {
    slowOnCounter = 0;
    slowOnState = (slowOnState == 150 ? 0 : 150);
  }
  delay(50);
}
 
byte shinyState[] = {0, 100, 0, 100, 0, 100};
byte shinyStateAnimation[] = {1, 1, 1, 1, 1, 1};
byte shinyCounter = 0;
 
void shinyAnimation() {
  for (int i = 0; i < 6; i++) {
    if (shinyState[i] >= 100) {
      shinyStateAnimation[i] = -1; // dim
    }
    else if (shinyState[i] <= 0) {
      shinyStateAnimation[i] = 1; // bright
    }
    shinyState[i] += shinyStateAnimation[i];
    SoftPWMSet(edgeLedPins[i], shinyState[i]);
  }
  shinyCounter ++;
  if (shinyCounter > 10) {
    shinyCounter = 0;
    for (byte r = random(1, 3); r > 0; r--) {
      byte randomLed = random(0, 12);
      if (randomLed < 6) {
        SoftPWMSet(innerLedPins[random(0, 6)], 255);
      }
      else {
        SoftPWMSet(middleLedPins[random(0, 6)], 255);
      }
    }
  }
  else {
    for (int i = 0; i < 6; i++) {
      SoftPWMSet(innerLedPins[i], 20);
      SoftPWMSet(middleLedPins[i], 20);
    }
  }
  delay(30);
}
 
byte fadingState[] = {0, 100, 0, 100, 0, 100};
byte fadingStateAnimation[] = {1, 1, 1, 1, 1, 1};
 
void fadingAnimation() {
  for (int i = 0; i < 6; i++) {
    if (fadingState[i] >= 100) {
      fadingStateAnimation[i] = -1; // dim
    }
    else if (fadingState[i] <= 0) {
      fadingStateAnimation[i] = 1; // bright
    }
    fadingState[i] += fadingStateAnimation[i];
    SoftPWMSet(edgeLedPins[i], fadingState[i]);
    SoftPWMSet(middleLedPins[_nextIndex(i, 1)], fadingState[i]);
    SoftPWMSet(innerLedPins[i], 50);
  }
  delay(20);
}
 
void _fill(byte value) {
  for (int i = 0; i < 6; i++) {
    SoftPWMSet(edgeLedPins[i], value);
    SoftPWMSet(middleLedPins[i], value);
    SoftPWMSet(innerLedPins[i], value);
  }
}
 
byte _prevIndex(short index, byte step) {
  index -= step;
  while (index < 0) {
    index += 6;
  }
  return index;
}
 
byte _nextIndex(short index, byte step) {
  index += step;
  while (index > 5) {
    index -= 6;
  }
  return index;
}

MAKER:Arduino
http://bbs.nxez.com/thread-456-1-1.html



坐沙发

发表评论