极客工坊

 找回密码
 注册

QQ登录

只需一步,快速开始

查看: 20123|回复: 3

女神生日不知道送什么礼物,不如手工打造一颗arduino心愿球

[复制链接]
发表于 2019-3-29 17:39:33 | 显示全部楼层 |阅读模式
本帖最后由 arduinoxyz 于 2019-3-29 18:47 编辑

心愿球
由黄铜棒制成,采用自由球形态连接 18 颗发光 LED。

硬件材料
1*黄铜棒
18*贴片 LED
1*ATmega8L 芯片
1*CR2032 纽扣电池
1*开关
天体
主要挑战是用黄铜棒弯成圆形,看起来像一个天体。我用 6 根铜棒竖直排列(经度)和 3 根铜棒
水平排列(纬度)构建一个球。这样子就总共有 18 个交叉点用于焊接 LED。在球体的底部有一个
环形开口,为的是最终可以更好的放入芯片、电池等元器件。

首先,把铜棒弯成圆形。我最开始找到一个直径为 50 毫米的铁罐,可以在弯曲时用底盖固定铜
棒。弯曲铜棒后,把其剪断并把两端焊接在一起,形成一个漂亮的环。在一张纸上画出相同的形
状,可以帮助你匹配最完美的圆形。为了制作更小的圆环,我使用了其他直径的瓶。使用与你的
直径相匹配的东西,身边上到处都是圆形的东西!

接下来,我把 LED 焊接到三个 50mm 环上。我在一张纸上画了一个模板。我采用是黄色和红色
LED。黄色和红色,因为它比蓝色或白色更节能。

接着,我把带有 LED 的环焊接到基环上。我用一块胶带把基环固定在桌子上,修剪了垂直环的底
部并把它们焊接到环上,形成了一个皇冠。第一个环焊接成一体,第二个和第三个环切成两半,
形成球体的平顶。

最后一步是最让人沮丧和耗时的。把 LED 与弯曲杆相互连接以形成水平环。我把剩下的环一个一
个地切开,以适应垂直环之间的空间并求佛一样地焊接。

我想到一种放置 LED 的简单方法。 两个 LED 在邻近的垂直环(地面)上彼此面对,它们与一根弯
曲的杆连接,该杆是水平环(电源线)的一部分。最终得到 18 个 LED,分为 9 个部分。

温馨提醒:经常测试 LED 是否仍是好的,否则你需要在最后重做这件事,这是一种可怕的又振奋
人心的测试。
如果你只是希望它发光并且不关心任何动画。你可以立即停止阅读,把 CR2032 纽扣电池和开关放
入内部。通过 68Ω 限流电阻把 LED 与电池连接,就可以使其发光!把电池焊接到黄铜线时,请确
保不要过热,否则可能会导致电池过热。

如果你像我一样,爱 Arduino 并希望让它变得聪明并且有一点乐趣,让我们把微控制器放入其
中!我使用的是 ATmega8L 芯片——与 Arduino NANO 相同的封装,但内存更少,功耗更低。L 意
味着它具有 2.7 - 5V 的宽工作电压范围,这在使用 3V 纽扣电池时非常棒。另一方面,由于它是
TQF32 封装,因此焊接到铜棒上是一个不小的挑战,但外观和效果都很好。

原理图

源代码
  1. #define LEDS 9

  2. byte leds[] = {
  3.   5, 19, 17, // bottom
  4.   6, 1, 15, // middle
  5.   8, 21, 13 // top
  6. };

  7. #define ON true
  8. #define OFF false

  9. // variables for pattern timing
  10. unsigned long currentMillis = millis();
  11. unsigned long previousMillis = 0;
  12. unsigned long millisInterval = 3
  13. 00;

  14. // variables for software PWM
  15. unsigned long currentMicros = micros();
  16. unsigned long previousMicros = 0;
  17. // this is the frequency of the sw PWM
  18. // frequency = 1/(2 * microInterval)
  19. unsigned long microInterval = 250;

  20. const byte pwmMax = 100;

  21. // fading (for the timing)
  22. int fadeIncrement = 1;

  23. // typedef for properties of each sw pwm pin
  24. typedef struct pwmPins {
  25.   int pin;
  26.   int pwmValue;
  27.   bool pinState;
  28.   int pwmTickCount;
  29. } pwmPin;

  30. // create the sw pwm pins
  31. // these can be any I/O pin
  32. // that can be set to output!
  33. const int pinCount = 9;
  34. const byte pins[pinCount] = {
  35.   5, 19, 17, // bottom
  36.   6, 1, 15, // middle
  37.   8, 21, 13 // top
  38. };

  39. pwmPin myPWMpins[pinCount];

  40. // function to "setup" the sw pwm pin states
  41. // modify to suit your needs
  42. // this creates an alternating fade pattern
  43. void setupPWMpins() {
  44.   for (int index=0; index < pinCount; index++) {
  45.     myPWMpins[index].pin = pins[index];

  46.     // mix it up a little bit
  47.     // changes the starting pwmValue for odd and even
  48.     if (index % 2)
  49.       myPWMpins[index].pwmValue = 25;
  50.     else
  51.       myPWMpins[index].pwmValue = 75;

  52.     myPWMpins[index].pinState = ON;
  53.     myPWMpins[index].pwmTickCount = 0;

  54.     // unlike analogWrite(), this is necessary
  55.     pinMode(pins[index], OUTPUT);
  56.   }
  57. }

  58. void pwmFadePattern() {
  59.   // go through each sw pwm pin, and increase
  60.   // the pwm value. this would be like
  61.   // calling analogWrite() on each hw pwm pin
  62.   for (int index=0; index < pinCount; index++) {
  63.     myPWMpins[index].pwmValue += fadeIncrement;
  64.     if (myPWMpins[index].pwmValue > 100)
  65.       myPWMpins[index].pwmValue = 0;
  66.   }
  67. }

  68. void handlePWM() {
  69.   currentMicros = micros();
  70.   // check to see if we need to increment our PWM counters yet
  71.     if (currentMicros - previousMicros >= microInterval) {
  72.     // Increment each pin's counter
  73.     for (int index=0; index < pinCount; index++) {
  74.     // each pin has its own tickCounter
  75.       myPWMpins[index].pwmTickCount++;

  76.     // determine if we're counting on or off time
  77.       if (myPWMpins[index].pinState == ON) {
  78.         // see if we hit the desired on percentage
  79.         // not as precise as 255 or 1024, but easier to do math
  80.         if (myPWMpins[index].pwmTickCount >= myPWMpins[index].pwmValue) {
  81.           myPWMpins[index].pinState = OFF;
  82.         }
  83.       } else {
  84.         // if it isn't on, it is off
  85.         if (myPWMpins[index].pwmTickCount >= pwmMax) {
  86.           myPWMpins[index].pinState = ON;
  87.           myPWMpins[index].pwmTickCount = 0;
  88.         }
  89.       }
  90.       // could probably use some bitwise optimization here, digitalWrite()
  91.       // really slows things down after 10 pins.
  92.       digitalWrite(myPWMpins[index].pin, myPWMpins[index].pinState);
  93.     }
  94.     // reset the micros() tick counter.
  95.     digitalWrite(13, !digitalRead(13));
  96.     previousMicros = currentMicros;
  97.   }
  98. }

  99. void setup() {
  100.   setupPWMpins();
  101.   //pinMode(13, OUTPUT);
  102. }

  103. void loop() {
  104.   // this is the magic for sw pwm
  105.   // need to call this anytime you
  106.   // have a long operation
  107.   handlePWM();

  108.   // check timer for fading pattern
  109.   // this would be the same
  110.   // if we used analogWrite()
  111.   currentMillis = millis();
  112.   if (currentMillis - previousMillis >= millisInterval) {
  113.     // moved to own funciton for clarity
  114.     pwmFadePattern();

  115.     // setup clock for next tick
  116.     previousMillis = currentMillis;
  117.   }
  118. }
复制代码

本帖子中包含更多资源

您需要 登录 才可以下载或查看,没有帐号?注册

x
回复

使用道具 举报

发表于 2019-4-19 17:18:24 | 显示全部楼层
非常棒的设计!!谢谢分享
回复 支持 反对

使用道具 举报

发表于 2019-4-20 08:53:10 | 显示全部楼层
好漂亮啊 不错啊
回复 支持 反对

使用道具 举报

发表于 2019-9-23 16:02:03 | 显示全部楼层
楼主 您好!可以分享一下完整的代码吗?非常感谢
回复 支持 反对

使用道具 举报

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

本版积分规则 需要先绑定手机号

Archiver|联系我们|极客工坊

GMT+8, 2024-3-28 21:07 , Processed in 0.041962 second(s), 22 queries .

Powered by Discuz! X3.4 Licensed

Copyright © 2001-2021, Tencent Cloud.

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