转自:http://linyuhao.cc/2016/05/23/arduino1/

最近挺多小伙伴在问LED灯的问题,我在【骑行导航】【鹿岛夜灯】中都用到了全彩LED灯。
感觉特别的方便,只要使用1pin就能控制大量LED灯的颜色,控制的颜色多达16000万。价格也还好,0.4¥/个我也能接收,比自己用IC搭RGB LED合算多啦~
当然啦,缺点也是有的,比如不好在洞洞板上焊接~
下面来详细介绍下WS2812全彩LED灯的使用。

习惯性先看datasheet。
<h2>一、简介</h2>
WS2812B是一个集控制电路与发光电路于一体的LED灯。 外型嘛,和普通的5050LED灯珠一模一样。WS2812B内部包含了数据锁存信号整形放大驱动电路, 还有内部振荡器和电流控制部分。
 
<h2>二、引脚</h2>
引脚有4个,分别为VDD(5V),VSS(GND),DIN,DOUT。
 
<h2>三、数据通信</h2>
数据协议采用单线归零码的通信方式, 在上电复位以后, DIN端接受从控制器传输过来的数据。 首先送过来的24bit数据被第一个WS2812提取后,送到内部的数据锁存器。 剩余的数据经过内部整形处理电路放大后通过DOUT输出给下一个级联的WS2812。这样下来,每经过一个像素点的传输,信号减少24bit。
简单的说,就是发送一串数据,每经过一个WS2812就被截取一部分,剩下的继续发送~
波形有3种,分别是0、1、RESET:

ws2812波形

ws2812波形


其中,T0H、T0L、T1H、T1L的持续时间分别为0.4 µs、0.85µs、0.4 µs、0.85µs ± 150ns。所以感觉用树莓派驱动的话压力有点大,还是使用Arduino比较合适些~
发送数据的时候,需要先拉低DO至少50µs,之后按24bit的顺序发送控制信号就可以了。24bit的信号按GBR的顺序发送,高位先发~
典型电路图如下,基本就是DIN、DOUT级联,电源加个电容滤波下(如果级联个数不多的话,并不一定要加):
ws2812典型电路图

ws2812典型电路图


<span class="caption"> </span>
 
<h2>四、Arduino驱动</h2>
如果是在Arduino中使用的话,在Adafruit是有驱动的,直接调用就可以啦~
下面是结合github上的代码,翻译注释下:

<div class="c codecolorer"><span class="co2">#include <Adafruit_NeoPixel.h></span>
<span class="co1">// 定义控制引脚</span>
<span class="co2">#define PIN 6</span>
<span class="co1">// 连接WS2812的数量</span>
<span class="co2">#define NUMPIXELS 16</span>
<span class="co1">// 初始化</span>
Adafruit_NeoPixel pixels <span class="sy0">=</span> Adafruit_NeoPixel<span class="br0">(</span>NUMPIXELS<span class="sy0">,</span> PIN<span class="sy0">,</span> NEO_GRB <span class="sy0">+</span> NEO_KHZ800<span class="br0">)</span><span class="sy0">;</span>
<span class="kw4">int</span> delayval <span class="sy0">=</span> <span class="nu0">500</span><span class="sy0">;</span>
<span class="kw4">void</span> setup<span class="br0">(</span><span class="br0">)</span> <span class="br0">{</span>
<span class="co1">// This initializes the NeoPixel library.</span>
pixels.<span class="me1">begin</span><span class="br0">(</span><span class="br0">)</span><span class="sy0">;</span>
<span class="br0">}</span>
<span class="kw4">void</span> loop<span class="br0">(</span><span class="br0">)</span> <span class="br0">{</span>
<span class="kw1">for</span><span class="br0">(</span><span class="kw4">int</span> i <span class="sy0">=</span> <span class="nu0">0</span><span class="sy0">;</span> i <span class="sy0"><</span> NUMPIXELS<span class="sy0">;</span> i<span class="sy0">++</span><span class="br0">)</span> <span class="br0">{</span><span class="co1">// 设置第i个WS2812的RGB颜色</span>
pixels.<span class="me1">setPixelColor</span><span class="br0">(</span>i<span class="sy0">,</span> pixels.<span class="me1">Color</span><span class="br0">(</span><span class="nu0">0</span><span class="sy0">,</span><span class="nu0">150</span><span class="sy0">,</span><span class="nu0">0</span><span class="br0">)</span><span class="br0">)</span><span class="sy0">;</span>
<span class="co1">// 发送数据,WS2812发光</span>
pixels.<span class="me1">show</span><span class="br0">(</span><span class="br0">)</span><span class="sy0">;</span>
delay<span class="br0">(</span>delayval<span class="br0">)</span><span class="sy0">;</span>
<span class="br0">}</span>
<span class="br0">}</span>
</div>

<div class="c codecolorer">以上。</div>

分类: 未分类

0 条评论

发表评论

电子邮件地址不会被公开。 必填项已用*标注