查看: 104|回复: 0

Digispark ATtiny85配合Prismatik软件DIY屏幕流光溢彩效果

[复制链接]
  • TA的每日心情
    开心
    2020-11-22 16:40
  • 签到天数: 1 天

    [LV.1]初来乍到

    发表于 2020-11-22 16:17 | 显示全部楼层 |阅读模式
    本帖最后由 djddb 于 2020-11-22 16:38 编辑

    CSDN上的帖子也是我的,如果下文有内容省略的地方,可以参考原文。
    链接如下:
    https://blog.csdn.net/qq_36151485/article/details/106884611

    一、硬件准备
    • 1.Digispark ATtiny85
    • 2.CH340 USB转TTL
    • 3.WS2812灯带
    二、开发环境与软件
    • 1.Arduino IDE安装
    • 2.添加开发板和驱动
    • 3.安装所需的库
    • 4.重刷ATtiny85的BootLoader
    三、程序编写
    • 1.ATtiny85点亮WS2812
    • 2.ATtiny85 SoftSerial
    • 3.Prismatik配置与数据结构
    • 4.ATtiny85通信Prismatik
    四、DIY成品
    • 1.硬件接连方法
    • 2.效果展示视频
    五、结语


    之前偶然间看到了飞利浦电视的流光溢彩效果,淘宝看了一下,最便宜都要一百多一套,懂单片机的我当然不会花这个冤枉钱。

    在CSDN搜索了一下,果然有好多大神用Arduino NANO DIY电脑显示器的流光溢彩效果,可是Arduino NANO十几块钱的价格对于我来说也很贵。

    手边只有一个Digispark ATtiny85,怎么办?反正都是在Arduino IDE里面搞开发,为了省钱,当然是要用Digispark ATtiny85 DIY流光溢彩效果啦。

    为了省下几块钱的预算,我们搞起。


    一、硬件准备

    使用的硬件包括:Digispark ATtiny85,CH340USB转TTL,WS2812灯带
    调试工具包括:另一个CH340USB转TTL


    1.Digispark ATtiny85

    ATtiny85是个非常好玩的芯片,体积小巧功能强悍,最开始是用来玩BadUSB的,后来发现功能很强悍,Arduino里面关于ATtiny85的例子也很多,正好有WS2812的例子,就拿过来做流光溢彩效果。

    Digispark ATtiny85在淘宝上非常便宜,一般价格都在6-8元还包邮,自行购买即可。我买的是左上角的那种,可以直接插电脑,不再需要USB线连接,做BadUSB拿出去装B携带方便。

    ATtiny85官方文档放在了最后的网盘里。



    2.CH340 USB转TTL

    CH340用于电脑与ATtiny85的串口通信,这个就不多赘述了,大家都常用。

    3.WS2812灯带

    WS2812灯带有30、60、144株/每米几种规格,价格分别为12、18、58元/米左右,推荐60株/每米的规格,既便宜,做出来效果的细腻程度也还可以。

    开发时用的是下面这个8灯珠的板子,价格大约2.8元/个,1米需要17个,换算后大概50元/米,136株/米,和买灯带价格差不多,并且有PCB板,可能更耐操一点。

    关于WS2812的文档,放在了最后的网盘里。




    二、开发环境与软件1.Arduino IDE安装
    2.添加开发板和驱动
    3.安装所需的库

    Arduino中开发板添加后,会显示Digistump的一些库,我们需要用到的有以下这些,添加开发板后就有了,不用额外安装库。
    #include <WS2811.h> //用于控制WS2812灯带
    #include <SoftSerial.h> //用于模拟串口通信
    #include <TinyPinChange.h> //用于定义引脚


    三、程序编写
    1.ATtiny85点亮WS2812

    Arduino点击文件–示例–WS2811–digispark,另存为一个文件。
    示例原代码如下:

    1. <font face="微软雅黑" color="#000000">#include <WS2811.h>
    2. DEFINE_WS2811_FN(WS2811RGB, PORTB, 1)
    3. RGB_t rgb[1]; //1 for 1 pixel

    4. void setup() {               

    5.   pinMode(1,OUTPUT);

    6. }

    7. void loop() {
    8.         setPixel(0,255,0,0); //set first pixel (zero indexed) to red
    9.         updatePixels(); //show the change
    10. }

    11. void setPixel(i,r,g,b){
    12.         rgb[r].r=r;
    13.     rgb[g].g=g;
    14.     rgb[b].b=b;
    15. }

    16. void updatePixels(){
    17.         WS2811RGB(rgb, ARRAYLEN(rgb));
    18. }</font>
    复制代码

    然后我们点击验证,发现报错如下。


    报错信息是i,r,g,b都没有定义,所以我觉得
    void setPixel(i,r,g,b)应该改为
    void setPixel(uint8_t i,uint8_t r,uint8_t g,uint8_t b)
    改完后确实编译通过了,问题解决。
    有兴趣的同学可以仔细看一下WS2811.h文件。


    阅读代码,我发现真正有用的只有:

    1句命令:WS2811RGB(rgb, ARRAYLEN(rgb));
    和3个值rgb[r].r,rgb[g].g,rgb.b
    所以我重新改了一下代码,让8个灯显示红橙黄绿青蓝紫白8个颜色:

    1. //LD
    2. #include <WS2811.h>
    3. DEFINE_WS2811_FN(WS2811RGB, PORTB, 1)
    4. RGB_t rgb[1]; //1 for 1 pixel
    5. uint8_t g;
    6. uint8_t r;
    7. uint8_t b;
    8. uint8_t i;
    9. uint8_t NUM_LEDS=8; //你的灯珠数量

    10. unsigned char red[] = { 255, 255, 255, 0, 0, 0, 150, 255};
    11. unsigned char green[] = { 0, 100, 255, 255, 255, 0, 0, 255};
    12. unsigned char blue[] = { 0, 0, 0, 0, 255, 255, 255, 255};

    13. void setup() {               
    14.   pinMode(1,OUTPUT);
    15.   delay(1000);
    16. }

    17. void loop() {
    18.    for(i = 0; i < NUM_LEDS; i++)
    19.   {
    20.     rgb[r].r = red[i];
    21.     rgb[g].g = green[i];
    22.     rgb[b].b = blue[i];
    23.     WS2811RGB(rgb, ARRAYLEN(rgb));// Shows new values
    24.   }
    25.   delay(100);//其实没必要放loop()中循环,WS2811会保持最后一次的颜色。
    26. }
    复制代码
    2.ATtiny85 SoftSerial

    同样,Digistump开发板下自带的SoftSerial示例程序如下,作用是在loop循环中,发送接收到的数据。但是实测下来,软件模拟的串口,波特率太高的话丢数据严重,可能9600波特率是比较稳定的。(这个涉及到晶振频率、波特率和丢包率之间的问题,感兴趣的同学可以深入学习。)

    1. /*
    2.   Software serial multiple serial test

    3. Receives from the hardware serial, sends to software serial.
    4. Receives from software serial, sends to hardware serial.

    5. The circuit:
    6. * RX is digital pin 2 (connect to TX of other device)
    7. * TX is digital pin 3 (connect to RX of other device)

    8. created back in the mists of time
    9. modified 9 Apr 2012
    10. by Tom Igoe
    11. based on Mikal Hart's example

    12. This example code is in the public domain.

    13. <SoftSerial> adapted from <SoftwareSerial> for <TinyPinChange> library which allows sharing the Pin Change Interrupt Vector.
    14. Single difference with <SoftwareSerial>: add #include <TinyPinChange.h>  at the top of your sketch.
    15. RC Navy (2012): http://p.loussouarn.free.fr

    16. */
    17. #include <SoftSerial.h>     /* Allows Pin Change Interrupt Vector Sharing */
    18. #include <TinyPinChange.h>  /* Ne pas oublier d'inclure la librairie <TinyPinChange> qui est utilisee par la librairie <RcSeq> */

    19. SoftSerial mySerial(2, 3); // RX, TX

    20. void setup()  
    21. {
    22. // Open serial communications and wait for port to open:
    23.   Serial.begin(57600);
    24.    while (!Serial) {
    25.     ; // wait for serial port to connect. Needed for Leonardo only
    26.   }

    27.   
    28.   Serial.println("Goodnight moon!");

    29.   // set the data rate for the SoftwareSerial port
    30.   mySerial.begin(4800);
    31.   mySerial.println("Hello, world?");
    32. }

    33. void loop() // run over and over
    34. {
    35.   if (mySerial.available())
    36.     Serial.write(mySerial.read());
    37.   if (Serial.available())
    38.     mySerial.write(Serial.read());
    39. }
    复制代码
    3.Prismatik配置与数据结构

    Prismatik软件的GitHub和下载地址如下,适用Windows,Ubuntu,OS,Android多种系统,Windows版本的安装包,文章最后的网盘里有一份。
    GitHub:
    https://github.com/psieg/Lightpack
    下载地址:
    https://lightpack.tv/pages/downloads


    之前看的最多的是用Arduino NANO做流光溢彩效果,有很多大神写的很详细,我主要参考的是下面这位大神的,包括所需的Prismatik最开始也是从这篇文章里得到的下载地址。
    链接:
    https://blog.csdn.net/u012963827/article/details/89640175


    但是,我用的是ATtiny85芯片+WS2811.h库,上面文章用的是Arduino NANO+FastLED.h库,所以只能理解代码后移植。

    为了详细了解数据结构,做了如下工作。


    先把CH340插到电脑上,找到对应的COM口,设置Prismatik。将CH340的TX脚接到另一个CH340的RX脚,并打开串口调试助手接收Prismatik发送出去的数据,在EXCEL整理数据结构如下。

    20200626213010854.png

    可以看到,开头是固定的Ada指令。
    随后的灯泡个数信息和校验码,我参考了上面提到的Arduino NANO的代码,其中一段如下:

    1.   // Hi, Lo, Checksum  
    2.   while (!mySerial.available()) ;;
    3.   hi=mySerial.read();
    4.   while (!mySerial.available()) ;;
    5.   lo=mySerial.read();
    6.   while (!mySerial.available()) ;;
    7.   chk=mySerial.read();

    8.   // If checksum does not match go back to wait
    9.   if (chk != ((hi ^ lo) ^ 0x55))
    10.   {
    11.     i=0;
    12.     goto waitLoop;
    13.   }
    复制代码

    所以0x00应该是灯珠个数高8位。正常情况下我们不会用到这位数据,因为低8位的0xFF就可以有256个灯珠数量了,我们DIY一般用不到这么多灯珠。

    再其后的0x07应该是灯珠个数的低8位,是因为我在Prismatik软件中把灯珠数量设置成了8个,所以这一位数据是0x07。
    0x52是校验码,
    0x52==(0x00 ^ 0x07) ^ 0x55

    再其后的0x16,0x16,0x00,0x16,0x16,0x00这些数据就是第1、2、3……个灯珠的R,G,B数值了。


    4.ATtiny85通信Prismatik

    有了上面的基础,我的代码如下:
    定义1脚发送WS2812的RGB数据。
    定义0、2脚为SoftSerial的RX, TX。
    loop命令中,循环等待并校验Ada命令。
    然后检验灯珠个数hi、lo、chk三个数据。
    随后把串口发过来的RGB数据放入缓存区。
    数据全部接收完毕后,用WS2811RGB(rgb, ARRAYLEN(rgb));指令发送给WS2812灯带。

    1. #include <WS2811.h>
    2. #include <SoftSerial.h>
    3. #include <TinyPinChange.h>

    4. #define DATA_PIN 1          //RGB输出针脚
    5. SoftSerial mySerial(0,2);   // RX, TX

    6. DEFINE_WS2811_FN(WS2811RGB, PORTB, 1)
    7. RGB_t rgb[1];               //1 for 1 pixel
    8. uint8_t prefix[] = {'A', 'd', 'a'}, hi, lo, chk;

    9. uint8_t g,r,b;
    10. uint8_t i,j;

    11. uint8_t Brightness=30;      //亮度30%
    12. uint8_t NUM_LEDS=24;        //你的灯珠数量
    13. uint8_t red[60],green[60],blue[60];

    14. void setup()
    15. {               
    16.   pinMode(1,OUTPUT);

    17.   //让灯珠闪一下表明单片机正常运行起来了
    18.   for(j=2;j>=1;j--)
    19.   {
    20.     rgb[r].r=100*(j-1)*Brightness/100;
    21.     rgb[g].g=100*(j-1)*Brightness/100;
    22.     rgb[b].b=100*(j-1)*Brightness/100;
    23.     for(i=0;i<NUM_LEDS;i++)
    24.     {WS2811RGB(rgb, ARRAYLEN(rgb));}
    25.    delay(500);
    26.   }

    27.   Serial.begin(9600);
    28.   Serial.println("Ada\n");
    29.   mySerial.begin(9600);
    30.   mySerial.println("Ada\n");
    31. }

    32. void loop()
    33. {
    34.   for(i = 0; i < sizeof prefix; ++i)
    35.   {
    36.     waitLoop: while (!mySerial.available()) ;;
    37.     if(prefix[i] == mySerial.read()) continue;
    38.     i = 0;
    39.     goto waitLoop;
    40.   }

    41.   // Hi, Lo, Checksum  
    42.   while (!mySerial.available()) ;;
    43.   hi=mySerial.read();
    44.   while (!mySerial.available()) ;;
    45.   lo=mySerial.read();
    46.   while (!mySerial.available()) ;;
    47.   chk=mySerial.read();

    48.   // If checksum does not match go back to wait
    49.   if (chk != ((hi ^ lo) ^ 0x55))
    50.   {
    51.     i=0;
    52.     goto waitLoop;
    53.   }

    54.   // Read the transmission data and set LED values
    55.   for(i = 0; i < NUM_LEDS; i++)
    56.   {
    57.     while(!mySerial.available());;
    58.     red[i] = mySerial.read();
    59.     while(!mySerial.available());;
    60.     green[i] = mySerial.read();
    61.     while(!mySerial.available());;
    62.     blue[i] = mySerial.read();
    63.   }

    64.   //hi和lo表示灯珠数量的高8位和低8位
    65.   //如果灯珠个数超过256个,需要把高8位的hi也算进来
    66.   NUM_LEDS=lo+1;

    67.   for(i = 0; i < NUM_LEDS; i++)
    68.   {
    69.     rgb[r].r = red[i];
    70.     rgb[g].g = green[i];
    71.     rgb[b].b = blue[i];
    72.     WS2811RGB(rgb, ARRAYLEN(rgb));// Shows new values
    73.   }
    74. }
    复制代码


    四、DIY成品
    1.硬件接连方法

    我的是笔记本电脑,背面的WS2812灯珠只有24个,实测最大不超过0.2A电流,可以用USB口直接供电。如果灯珠数量特别多,那么就需要额外的供电了,记得把灯带和ATtiny85共地。


    2.效果展示视频

    这个是我早期在B站发的的一个演示视频
    链接:
    https://www.bilibili.com/video/BV18J411P7L5/
    下面这个是近期刚录制的,播放是飞利浦官方的演示视频,网盘里也放了这个原视频。
    链接:
    https://www.bilibili.com/video/BV1ag4y1v787


    五、结语

    其实最终看来,Digispark ATtiny85的流光溢彩效果还可以,虽然只有10FPS但是足够用。后来我又咬咬牙买了Arduino NANO,虽然贵,但是真香,呵呵呵


    这是我第一次在CSDN发博客,之前只是自己玩玩单片机,直到有一个网友看了我的成果视频希望我出个教程,正好端午假期有空,就写了这个不算是教程的教程。我发现ATtiny85芯片真的足够好玩,以后有好的项目我还会在发出来与大家分享。


    文章的最后,我把一些用得到的文件、软件打包放网盘了,大家自行取阅。
    百度网盘:
    https://pan.baidu.com/s/1MIcNYL0Lk_GhttbfXHRu1A
    提取码:zfyc





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

    本版积分规则

    热门推荐

    万万nano不得买山寨版
    万万nano不得买山寨版
    arduino nano板子体积小,方便开发小型机器人。不过山寨版不得买,到时候后悔都来不及
    【干货分享】mega2560原理图PCB图纸altium designer18
    【干货分享】mega2560原理
    分享一下mega2560的板子 AD版本 **** 本内容被作者隐藏 **** ergo
    串口处理字符串输出指定统计信息
    串口处理字符串输出指定统
    设问串口接收一串字符串,要求打印出全部字符串,统计一共有几个整数,找出最大的整数
    【Arduino】168种传感器模块系列实验(104)---MAX30102手腕心率
    【Arduino】168种传感器模
    37款传感器与模块的提法,在网络上广泛流传,其实Arduino能够兼容的传感器模块肯定是
    【项目】基于Arduino Nano的多功能桌面感应垃圾桶
    【项目】基于Arduino Nano
    基于Arduino Nano的多功能桌面感应垃圾桶 (不知不觉中,自己已经步入大学第三年的时
    Copyright   ©2015-2016  Arduino中文社区  Powered by©Discuz!   
    快速回复 返回顶部 返回列表