Digispark ATtiny85 单片机点灯大师之圣诞节彩灯Merry Christmas

个人博客:https://www.djddb.top/
CSDN越来越恶心了,我为CSDN贡献了原创内容,一直没有收益,我想看别人的内容要么关注要么开VIP,越来越封闭咋回事?
既然这样我也封闭自己,大家可以去我的个人博客看看更多的内容,以后我会在个人博客更新。

前言

之前就答应过大家要把ATtiny85芯片玩出更多花样。用ATtiny85控制WS2812灯珠,我们可以玩出花来,甚至做成点阵屏幕都可以。
这一期主要是做一个圣诞节彩灯。显示Merry Christmas,用于圣诞节装(划掉)B装扮。
彩灯板的字母内部细节排列和整体布局,我参考了另一位大神的作品,这位大神是使用ESP32做的
https://mc.dfrobot.com.cn/thread-273244-1-1.html?tdsourcetag=s_pctim_aiomsg

一、硬件

1.材料与原理图

硬件包括:
电路板:
ATtiny85开发板,1个
滑动变阻器,2个
按动开关,1个
电阻5-10KΩ,1个
3针插座,1个
电容,1个
DC母头,1个

彩灯板:
亚克力板300mm*400mm,1块
WS2812灯珠,200个
0.6mm铜丝,10米
电容,规格随意,2个
得力502胶带点胶细管,1瓶

2.实物图参考

电路板正面
电路板背面
彩灯板子正面
彩灯板子背面

二、软件

1.软件说明

通过HSV2RGB来实现色彩的平滑过渡。
通过滑动变阻器ADC采集,控制色彩变幻的速度和灯珠亮度。
通过按键来切换闪烁模式。
不多说了,直接上源代码。

2.源代码

/******djddb制作******/
#include <WS2811.h>
//#include "DigiKeyboard.h"   //调试用的

#define NUM_LEDS 40       //你的灯珠数量
#define DATA_PIN 1        //RGB输出针脚
#define ADC_PIN1 1        //这里其实是ADC1编号, 而不是引脚号, 对应PB2引脚
#define ADC_PIN2 3        //这里其实是ADC3编号, 而不是引脚号, 对应PB3引脚
/*
ADC0-PB5
ADC1-PB2
ADC2-PB4
ADC3-PB3
*/

DEFINE_WS2811_FN(WS2811RGB, PORTB, 1)
RGB_t rgb[1]; //1 for 1 pixel

uint8_t g,r,b;
uint8_t i;
uint16_t Hueu = 0;
uint8_t satu = 100;
uint8_t mode = 0;           //初始化闪烁模式0
uint8_t pressStatus = 1;    //上一次按键的状态
uint8_t Brigthness = 20;    //初始化亮度20
uint16_t delayms = 300;     //初始化变幻延时300ms
uint8_t red[NUM_LEDS],green[NUM_LEDS],blue[NUM_LEDS];

void HSV2RGB(uint16_t hue, uint8_t saturation , uint8_t value)
{
  uint16_t hi = (hue / 60) % 6;
  uint16_t F = 100 * hue / 60 - 100 * hi;
  uint16_t P = value * (100 - saturation) / 100;
  uint16_t Q = (10000 - (F * saturation)) / 100;
  Q = value * Q / 100;                                      //得单独拿出来乘,不然的话Q值超过uint16的范围,结果会出错。可能是因为ATtiny85是8位单片机不支持uint32
  uint16_t T = (10000 - (saturation * (100 - F))) / 100;
  T = value * T / 100;                                      //同上

  switch (hi)
  {
    case 0:
      red[0] = value;
      green[0] = T;
      blue[0] = P;
      break;
    case 1:
      red[0] = Q;
      green[0] = value;
      blue[0] = P;
      break;
    case 2:
      red[0] = P;
      green[0] = value;
      blue[0] = T;
      break;
    case 3:
      red[0] = P;
      green[0] = Q;
      blue[0] = value;
      break;
    case 4:
      red[0] = T;
      green[0] = P;
      blue[0] = value;
      break;
    case 5:
      red[0] = value;
      green[0] = P;
      blue[0] = Q;
      break;
    default:
      red[0] = Brigthness;
      green[0] = Brigthness;
      blue[0] = Brigthness;
  }
  red[0] = red[0] * Brigthness / 100;               //如果不做brightness调节的话直接*255/100就行
  green[0] = green[0] * Brigthness / 100;
  blue[0] = blue[0] * Brigthness / 100;
  
  //DigiKeyboard.println(red[0],DEC);     //这里是调试用的
}

void setup() {
  pinMode(1,OUTPUT);        //P1脚是输出脚,接灯珠的DI
  pinMode(0,INPUT_PULLUP);  //P0脚是按键脚,监测按键状态切换闪烁模式
  delay(10);
  for(i = 0; i < NUM_LEDS; i++)
  {
    red[i] = Brigthness;
    green[i] = Brigthness;
    blue[i] = Brigthness;
  }
  for(i = 0; i < NUM_LEDS; i++) 
  {
    rgb[r].r = red[i];
    rgb[g].g = green[i];
    rgb[b].b = blue[i];
    WS2811RGB(rgb, ARRAYLEN(rgb));            //开机先显示全白色
  }

  //delay(1000);
  //DigiKeyboard.println("Hey, Merry Christmas!");
  delay(1000);
}

void loop() {
  for(i = NUM_LEDS-1; i > 0; i--)           //后一个灯珠延续前一个灯珠的颜色,做颜色滚动效果
  {
    red[i] = red[i-1];
    green[i] = green[i-1];
    blue[i] = blue[i-1];
  }
  
  HSV2RGB(Hueu, satu, 100);     //HSV中V值默认100,不做颜色明暗变化,只做色相和饱和度变化
  
  if (mode <= 1)
  {
    for(i = 0; i < NUM_LEDS; i++)         //0,1两种闪烁模式,每个灯珠颜色不同
    {
      rgb[r].r = red[i];
      rgb[g].g = green[i];
      rgb[b].b = blue[i];
      WS2811RGB(rgb, ARRAYLEN(rgb));     //WS2812B显示颜色
    }
  }
  else 
  {
    for(i = 0; i < NUM_LEDS; i++)        //2,3两种闪烁模式,所有灯珠颜色相同
    {
      rgb[r].r = red[0];
      rgb[g].g = green[0];
      rgb[b].b = blue[0];
      WS2811RGB(rgb, ARRAYLEN(rgb));          
    }
  }
  
  //0脚接切换开关,读取0脚状态决定颜色变化方式

  if (digitalRead(0) == LOW && pressStatus == 1)
  {
    delay(20);                                            //按键消抖
    if (digitalRead(0) == LOW && pressStatus == 1)
    {
      mode = mode + 1;
    }
  }
  pressStatus = digitalRead(0) == LOW?0:1;

  if (mode >3) 
  {mode = 0;}
  
  if (mode%2 == 1) {
    Hueu = random(0,360);                   //mode为奇数则P0脚高电平颜色随机变幻
    //DigiKeyboard.println("Hueu");
    //DigiKeyboard.println(Hueu,DEC);
  } else {                                  //mode为偶数则P0脚底电平颜色顺序变幻
    Hueu = Hueu + 3;
    if(Hueu > 359)
    {Hueu = 0;}
  }
  
  delayms = (1024-analogRead(ADC_PIN1))*5;        //用滑动电阻来调节灯光变幻频率
  Brigthness = (1024-analogRead(ADC_PIN2))/4;     //用滑动电阻来调节灯光亮度
  //DigiKeyboard.println("delayms");
  //DigiKeyboard.println(delayms,DEC);
  delay(delayms);
}

总结

效果图可以参考我的B站视频:
https://www.bilibili.com/video/bv1mD4y1Q78V
软件实现起来,还是很容易的,ATtiny85的flash和RAM也都够用,主要是硬件部分用502胶粘灯珠,然后一个一个焊接很耗时间,大家可以动手做起来,家里或者办公室都可以挂上,圣诞节人前显圣。

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值