Когда то давным давно, еще до эпохи РК86 и ZX-Spectrum, делом чести каждого начинающего радиолюбителя был собрать цветомузыку.
На транзисторах и тиристорах, с лапочками, крашеными цапонлаком и самодеятельными рассеивателями.
С тех пор интерес к созданию различных светодинамических установок остался, а возможности в эру светодиодов выросли многократно. Хочу посветить цикл статей светодиодам с пиксельной адресацией и что из них можно сотворить.
В данной статье речь пойдет о продукции китайской компании WORLDSEMI CO.,LIMITED — светодиодах с пиксельной адресацией.
Микросхема WS2811
Микросхема WS2811 представляют собой 3-х канальный контроллер/ШИМ драйвер с управлением по одному проводу.
Выпускаются WS2811 в корпусах DIP-8 и SOP-8
WS2811 подключаются последовательно друг за другом.
К каждой микросхеме подключается три светодиода
Либо 3 цепочки из светодиодов, если увеличить напряжение питания
На вход первой в цепочке микросхемы подается сигнал из прямоугольных импульсов частотой 400 или 800КГц. Импульсы, в зависимости от скважности, кодируют 0 или 1 для одного бита информации. Длинный (50мс) низкий уровень означает RESET или старт новой последовательности. Первая микросхема считывает 24 бита, в которых закодирован RGB сигнал по трем каналам светодиодов. Остальные импульсы пропускает на выходную шину. Следующие 24 бита достаются второй микросхеме и т.д. Всего каскадом может объединяться 1024 микросхем, информация в которых может обновляться 30 раз в секунду.
Подробнее изучить протокол управления микросхемами WS2811 можно изучить в даташите
- Описание микросхемы на английском языке на сайте производителя
- Даташит на WS2811 на английском языке (в архиве)
WS2812 и WS2812B
WS2812 представляет собой RGB светодиод в корпусе SMD5050 в корпус которого встроена микросхема WS281.1
WS2812 и WS2812B отличаются количеством ног. WS2812B их количество сократили до 4-х
Даташит на WS2812/WS2812S в корпусе SMD5050 с 6-ю контактами
Даташит на WS2812B в корпусе SMD5050 с 4-ми контактами
Готовые изделия на WS2811/WS2812
На сайте компании WORLDSEMI представлен большой выбор готовых устройств на базе светодиодов с пиксельной адресацией
Это гирлянды из различных модулей
Корпусные изделия
Светодиодные ленты
И даже матричный дисплей 16×16
Чем управлять
Компания WORLDSEMI выпускает также и контроллеры управления данными микросхемами и устройствами
Но покупать готовые контроллеры — не наш путь. Наш путь подключить WS2812 к Arduino при помощи библиотеки Adafruit_Neopixel
(можно и не Ардуино, но тогда это выходит за рамки тематики этого блога)
Покупка в интернете
Микросхемы WS2811/2812 и изделия из них можно купить в интернете. Цены в российских интернет магазинах на данные изделия очень уж завышенные.
На Алиэкспресс партией 100шт можно купить WS2812B по $0.13
Я заказал на TAOBAO.COM у этого продавца.
За эти же деньги можно их купить и на ТаоБао WS2812B (на сайте они почему то обозначены как WS2813-4). 200 штук через посредника с доставкой в Пермь обойдутся в $26 или $0.13 за штуку.
Поставляются светодиоды в специальной ленте, которую можно заряжать в устройство автоматического монтажа SMD компонентов
Светодиоды точно такие же как в даташите
Область применения
В основном, светодиоды с пиксельной адресацией используются для различных свето-динамических установок. Здесь собрана огромная коллекция реализации СДУ на WS2811/WS2812
Очень популярны они и при создании динамической подсветки дисплея, аналогичной Ambilight от Philips.
Я же решил сделать из них аналого-цифровые часы с возможностью превращения их в свето-динамическую установку.
Об изготовлении этого устройства я расскажу в следующих статьях.
Изготовление линейки из 10 светодиодов WS2812B
Изготовление дисплея на WS2812B
Цифро-аналоговые часы на WS2812B
А пока можно вместе с Тимофеем хорошо подумать и подготовится к этому
Интересная статья, даже не знал о таких светодиодах. Спасибо!
Хороший ресурс!
И кошак у вас классный)
Как купить на таобао уже голову сломал, через какого посредника или на прямую?
Для начала лучше через посредника.
Я чаще всего покупаю у http://www.mistertao.com/.
Там за небольшие посылки неплохая цена получается.
Вот ссылка на товар из обзора у МТ
http://www.mistertao.com/beta/pages/item/19005346058.html
Инструкций по работе с этим посредником навалом
Есть у них русскоязычная страница «В контакте»
http://vk.com/mistertao
Там представитель на русском отвечает на все вопросы
Почему то у него вот такая ошибка выскакивает
Dear Customer,
All products related to keywords «ds» are banned to sell.
Please try to search other products you like. Thank you!
Mistertao team.
Нажмите кнопку «Quick Order»
У МТ хитрые фильтры на бренды настроены
купил на ебей такие на подложке http://www.ebay.com/itm/161461052184?_trksid=p2060778.m2749.l2649&ssPageName=STRK%3AMEBIDX%3AIT
не подскажите где почитать про написание скетча под эти светодиоды(что-то типа уроков) ? Нужен скетч чтобы из 10 заданных мной цветов , светодиоды рандомно этими цветами переливались.
Ставите библиотеку NeoPixel
Там есть пример, показывающий несколько эффектов включая переливание радугой
На базе примера делаете то что нужно
Здесь народ собирает готовые проекты с такими светодиодами. Может сразу подберете то что нужно
почемуто у меня весь цикл огней из 10 светодиодов раза в 3 медленей чем у вас на видео.
Проверьте эту строчку
Adafruit_NeoPixel strip = Adafruit_NeoPixel(60, PIN, NEO_GRB + NEO_KHZ800);
число диодов должно соответствовать первому параметру и в последнем параметре частота должна быть 800КГц
Контроллер на 16МГц работает?
Скажите, пожалуйста, как может обновляться информация 30 раз в сек, если длительность RESET – 50 мс?
RESET около 50 мкс.
Какой максимальный ток у этих светодиодов? В даташите почему то не увидел.
20мА на каждый цвет
Хочу сделать подсветку типа ambilight….
Приобрел на Али 5 метров ленты на WS2812B..
Перед переклеиванием на телевизор(в ожидании Arduino Nano c FTDI) решил погонять ленту в качестве гирлянды с управлением от Arduino UnoR3… (питание брал только от Arduino подключенной к USB порту компьютера), если не считать зависаний ардуино из-за большой нагрузки, все работало замечательно(а если не включать ярко то и зависаний не случалось)!
Поправляя рукой провисание ленты, я статическим электричеством ударил один из диодов… В результате все диоды после «ударенного» перестали гореть…
я не отрезая ленту, пытался соединить DI и DO в обход «ударенного» диода, но диоды не горят…
Я сжег все диоды?
Нельзя запустить ленту в «обход» поврежденного диода не вырезав его «физически»?
Как поступить? для полного обклеивания телевизора, мне теперь не хватает 3-5 диодов…
Для начала прозвонить убитый диод. Может там короткое на массу или плюс и тогда вся шина дальше тоже может не работать. Я случайно при монтаже закоротил один вывод на массу и был подобный эффект.
Кстати, 5 диодов могу выслать, только пересылка не знаю сколько будет
Алексей спасибо, отрезан неработающую часть, и распределил на телевизоре оставшиеся диоды… хватило ровно впритык!
У меня, не знаю что произошло, но перестала работать лента из 60 диодов. При подключении к Ардуинке — просто моргнут все диоды и всё… Прозвонка ни чего не дала. Видимо не понял как это правильно сделать. Разрезал пополам. Половина работает — половина нет. Отрезал еще 10 от не работающей. 20 работают… и 10 тоже… Почесал репу…Взял соединил все куски другими концами, не так как отрезал. Включил всю ленту и… всё работает. Что было так и не понял… Китайцу, у которого покупал, показал видео с неработающей лентой, он погрустил но выслал мне новую. Вот теперь я обладатель резано-паянной, но рабочей и бесплатной ленты. Планирую собрать похожие и немного другие часы типа https://youtu.be/YErWfe0aTiQ. Посмотрим что получится. Кстати у меня похожий на вашего кот, только уши придавленные.
Знающие люди WS2811 и WS2812B по функционалу одинаковы т.е. WS2811 старая версия WS2812B новая версия, я правильно понимаю или как.
хотел заказать по цене одинаковы.
Друзья, с наступающими праздниками! Я к вам за срочной скорой помощью!!!
Срочно нужна помощь, совет. До нового года считанные дни, а у меня неполадки с гирляндами.
Купил на Али-Экспресс блок управления T1000S и 5 пиксельных гирлянд на 50 светодиодов каждая, получается в сумме на 250 светодиодов.
https://ru.aliexpress.com/item/original-T1000S-SD-card-for-WS2801-WS2811-LPD6803-led-pixel-controller-RGB-full-color-DMX512-2013/1132147162.html?spm=2114.13010608.0.0.jmzSLM&detailNewVersion=&categoryId=200001057
https://ru.aliexpress.com/item/12mm-WS2811-as-WS2801-led-pixel-module-IP68-waterproof-DC5V-full-color-RGB-50pcs-a-string/1022672558.html?spm=2114.13010608.0.0.jmzSLM&detailNewVersion=&categoryId=200001559
Покупал их поэтапно: сначала 3 гирлянды и блок управления, проверил — все работает. Через пару месяцев заказал еще две, тоже все работало. Все это еще по лету.
Где-то 10го декабря достал я эти запасы, подключил их все. На каждой гирлянде есть выход на доп.питание. Допаял разъемы, сделал на все это центральную жилу доп.питания, запустил — все отлично работает. Погонял ее, включал-выключал, менял программы, тестил, как мог — все было хорошо. Собрал, аккуратно убрал до появления елки.
Вчера развесили на елку всю эту красоту, включаем — НЕ РАБОТАЕТ!
Методом соединения-разъединения разъемов выяснили, что нижний ярус, первая по счету гирлянда, не работает. Все остальные четыре штуки — работают. Сняли нерабочую, подключили ее одну напрямик к блоку управления T1000S. Не горит. Прозвонили красный-зеленый провод, отвечающий за питания 5В, питание есть. Стали проверять белый провод, отвечающий за сигнал (DAT). Иглой с проводом подключились к блоку управления (к разъему DAT), и через каждый пиксель проверяли провод на пробой, так как мультиметром этот провод нельзя прозвонить на пробой, по той причине, что он проходит через микросхему WS2811 (это ШИМ-Контролер, отвечающий за адресацию светодиодных пикселей).
Получается, что с первого светодиода не идет сигнал ко второму и далее. Я в этом не силен, но впечатление, что микросхему на первом светодиоде просто выбило, из-за чего сигнал и не проходит, и гирлянда не горит.
Решил отрезать этот злополучный светодиод вместе с микросхемой, и оставить 49 пикселей. Сделал, подключил эту гирлянду напрямую к блоку управления — работает. Вернул на елку, подключил ее в цепь, включаю. Горит только эта гирлянда, все остальные — нет.
Методом подключения каждой гирлянды в отдельности к блоку управления, я понял, что из строя вышла вторая по порядку гирлянда. История та же, что и с первой.
Сижу и не знаю, что делать. Боюсь пожечь все микросхемы на гирляндах. Кромсать от балды я их больше не хочу. Есть какая-то причина, что пиксели выходят из строя, но я не могу ее определить и понять.
Простите, если не совсем внятно описал всю ситуацию, постарался все объяснить, как можно подробнее, дабы не упустить что-то важное, чего сам могу не учесть.
Может кто-то сталкивался с подобным или разбирается в таких вещах. Прошу помогите. Очень хотел устроить детям красоту, а получается все срывается. Да и денег вложено немерено!
Даже не знаю что предположить.
Ленты подключал десятками метров — все нормально.
Может с питанием что-то не так. БП 5В без пульсаций работает? Может не хватает его по току?
T1000 от него же запитан?
Если сгорает первый пиксель в цепочке, похоже с контроллера идет большой уровень.
Проблема! не могу подключить один светодиод ws2812B к ардуина мега 2560. Купила их несколько, решила потестить, запустить сначала один. Как это сделать нашла здесь: https://lesson.iarduino.ru/page/podklyuchaem-moduli-neopixel-na-baze-ws2812b-svetodiodov-k-arduino/
Данный код у меня работать отказался, исправила несколько строк в соответствие с описанием библиотеки: https://learn.adafruit.com/adafruit-neopixel-uberguide/arduino-library
Но все равно ничего не работает! Проверила, что идет на pin6 сигнал адекватный. В момент проверки светодиод зажегся, при том что был подключен лишь питанием, без входа. после перезагрузки дуйни он снова перестал работать и больше не зажигался. Что делать?
Библиотека NeoPixel работает без проблем. Нужно взять тестовый пример из нее, правильно выставить пин, к которому подключен WS2812 и количество.
Моргание светодиода может обуславливаться наличием помех на входе при включении питания. У меня такое бывает сплошь и рядом. И не только на первом диоде.
Добрый день.
Отличная штука. Спасибо за статью. А можно подробнее что нужно минимум купить чтобы можно было работать с этими светодиодами? Какая самая дешевая ардуинка. Какие кабели конец для прошивки и т.д. хочу изготовить несколько умных светильников. Сейчас комп рук и паяльной станции про ардуино ничего не знаю. Но очень хочу разобраться.
Берете Arduino Nano за пару долларов
http://ali.pub/1bxi0m
Еще вам понадобится кусочек ленты WS2812 и блок питание на 5В достаточной мощности
Не совсем пойму как сделать так чтоб почереди шли один за одним до последнего а потм опять сначала. Хочу попробовать данные ди оды поставить в качестве динамического поворотника.
Не подскажите как это реализовать.
На ваших снежинках вроде есть такое ток не могу понять какой кусок кода отвечает за это
В библиотеке NeoPoxel за управление определенным пиксельным диодом отвечает strop.setPixelColor(Номер, Цвет);
Где Номер — номер диода в цепочке, а цвет можно задать Цвет = strop.Color(R,G,B);
Посылаете команду первому светодиоду, затем гасите его, затем следующему.
Вот потренировался чуть, изменил готовый скетч. Может кому пригодится. сам искал — ничего не нашел
Для Ардуино Нано на ленту WS2812B на 43 пикселя (можно изменять)
#include
#define LED_COUNT 43
#define LED_PIN 6
// Parameter 1 = number of pixels in strip
// Parameter 2 = pin number
// Parameter 3 = pixel type flags, add together as needed:
// NEO_KHZ800 800 KHz bitstream (most NeoPixel products w/WS2812 LEDs)
Adafruit_NeoPixel strip = Adafruit_NeoPixel(LED_COUNT, LED_PIN, NEO_GRB + NEO_KHZ800);
void setup() {
strip.begin();
strip.show(); // Initialize all pixels to ‘off’
}
void loop() {
// Some example procedures showing how to display to the pixels:
colorWipe(strip.Color(255, 0, 0), 100); // Red
delay(500);
colorWipe(strip.Color(0, 255, 0), 100); // Green
delay(500);
colorWipe(strip.Color(0, 0, 255), 100); // Blue
delay(500);
colorWipe(strip.Color(127, 127, 127), 100); //wite
delay(10);
colorWipe(strip.Color(255, 0, 0), 100); // Red
delay(500);
colorWipe(strip.Color(0, 255, 0), 100); // Green
delay(500);
colorWipe(strip.Color(0, 0, 255), 100); // Blue
delay(500);
colorWipe(strip.Color(127, 127, 127), 100); // wite
delay(10);
colorWipe(strip.Color(255, 0, 0), 100); // Red
delay(500);
colorWipe(strip.Color(0, 255, 0), 100); // Green
delay(500);
colorWipe(strip.Color(0, 0, 255), 100); // Blue
delay(500);
colorWipe(strip.Color(127, 127, 127), 100); // wite
delay(10);
colorWipe(strip.Color(255, 0, 0), 100); // Red
delay(200);
colorWipe(strip.Color(0, 255, 0), 100); // Green
delay(200);
colorWipe(strip.Color(0, 0, 255), 100); // Blue
delay(200);
colorWipe(strip.Color(127, 127, 127), 100); // wite
delay(500);
// Send a theater pixel chase in…
theaterChase(strip.Color(127, 127, 127), 50); // White
theaterChase(strip.Color(127, 0, 0), 50); // Red
theaterChase(strip.Color( 0, 0, 127), 50); // Blue
theaterChase(strip.Color( 0, 127, 0), 50);
rainbowCycle(5);
rainbow(30);
theaterChaseRainbow(50);
}
// Fill the dots one after the other with a color
void colorWipe(uint32_t c, uint8_t wait) {
for(uint16_t i=0; i<strip.numPixels(); i++) {
strip.setPixelColor(i, c);
strip.show();
delay(50);
}
}
void rainbow(uint8_t wait) {
uint16_t i, j;
for(j=0; j<256*5; j++) {
for(i=0; i<strip.numPixels(); i++) {
strip.setPixelColor(i, Wheel((i+j) & 255));
}
strip.show();
delay(wait);
}
}
// This makes the rainbow equally distributed throughout
void rainbowCycle(uint8_t wait) {
uint16_t i, j;
for(j=0; j<256*10; j++) { // 5 cycles of all colors on wheel
for(i=0; i< strip.numPixels(); i++) {
strip.setPixelColor(i, Wheel(((i * 256 / strip.numPixels()) + j) & 255));
}
strip.show();
delay(wait);
}
}
//Theatre-style crawling light
void theaterChase(uint32_t c, uint8_t wait) {
for (int j=0; j<100; j++) { //do 10 cycles of chasing
for (int q=0; q < 3; q++) {
for (int i=0; i < strip.numPixels(); i=i+3) {
strip.setPixelColor(i+q, c); //turn every third pixel on
}
strip.show();
delay(wait);
for (int i=0; i < strip.numPixels(); i=i+3) {
strip.setPixelColor(i+q, 0); //turn every third pixel off
}
}
}
}
//Theatre-style crawling light with rainbow effect
void theaterChaseRainbow(uint8_t wait) {
for (int j=0; j < 256*5; j++) { // cycle all 256 colors in the wheel
for (int q=0; q < 3; q++) {
for (int i=0; i < strip.numPixels(); i=i+3) {
strip.setPixelColor(i+q, Wheel( (i+j) % 255)); //turn every third pixel on
}
strip.show();
delay(wait);
for (int i=0; i < strip.numPixels(); i=i+3) {
strip.setPixelColor(i+q, 0); //turn every third pixel off
}
}
}
}
// Input a value 0 to 255 to get a color value.
// The colours are a transition r — g — b — back to r.
uint32_t Wheel(byte WheelPos) {
if(WheelPos < 85) {
return strip.Color(WheelPos * 3, 255 — WheelPos * 3, 0);
} else if(WheelPos < 170) {
WheelPos -= 85;
return strip.Color(255 — WheelPos * 3, 0, WheelPos * 3);
} else {
WheelPos -= 170;
return strip.Color(0, WheelPos * 3, 255 — WheelPos * 3);
}
}
#include
#define LED_COUNT 43
#define LED_PIN 6
// Parameter 1 = number of pixels in strip
// Parameter 2 = pin number
// Parameter 3 = pixel type flags, add together as needed:
// NEO_KHZ800 800 KHz bitstream (most NeoPixel products w/WS2812 LEDs)
Adafruit_NeoPixel strip = Adafruit_NeoPixel(LED_COUNT, LED_PIN, NEO_GRB + NEO_KHZ800);
void setup() {
strip.begin();
strip.show(); // Initialize all pixels to ‘off’
}
void loop() {
// Some example procedures showing how to display to the pixels:
colorWipe(strip.Color(255, 0, 0), 100); // Red
delay(500);
colorWipe(strip.Color(0, 255, 0), 100); // Green
delay(500);
colorWipe(strip.Color(0, 0, 255), 100); // Blue
delay(500);
colorWipe(strip.Color(127, 127, 127), 100); //wite
delay(10);
colorWipe(strip.Color(255, 0, 0), 100); // Red
delay(500);
colorWipe(strip.Color(0, 255, 0), 100); // Green
delay(500);
colorWipe(strip.Color(0, 0, 255), 100); // Blue
delay(500);
colorWipe(strip.Color(127, 127, 127), 100); // wite
delay(10);
colorWipe(strip.Color(255, 0, 0), 100); // Red
delay(500);
colorWipe(strip.Color(0, 255, 0), 100); // Green
delay(500);
colorWipe(strip.Color(0, 0, 255), 100); // Blue
delay(500);
colorWipe(strip.Color(127, 127, 127), 100); // wite
delay(10);
colorWipe(strip.Color(255, 0, 0), 100); // Red
delay(200);
colorWipe(strip.Color(0, 255, 0), 100); // Green
delay(200);
colorWipe(strip.Color(0, 0, 255), 100); // Blue
delay(200);
colorWipe(strip.Color(127, 127, 127), 100); // wite
delay(500);
// Send a theater pixel chase in…
theaterChase(strip.Color(127, 127, 127), 50); // White
theaterChase(strip.Color(127, 0, 0), 50); // Red
theaterChase(strip.Color( 0, 0, 127), 50); // Blue
theaterChase(strip.Color( 0, 127, 0), 50);
rainbowCycle(5);
rainbow(30);
theaterChaseRainbow(50);
}
// Fill the dots one after the other with a color
void colorWipe(uint32_t c, uint8_t wait) {
for(uint16_t i=0; i<strip.numPixels(); i++) {
strip.setPixelColor(i, c);
strip.show();
delay(50);
}
}
void rainbow(uint8_t wait) {
uint16_t i, j;
for(j=0; j<256*5; j++) {
for(i=0; i<strip.numPixels(); i++) {
strip.setPixelColor(i, Wheel((i+j) & 255));
}
strip.show();
delay(wait);
}
}
// This makes the rainbow equally distributed throughout
void rainbowCycle(uint8_t wait) {
uint16_t i, j;
for(j=0; j<256*10; j++) { // 5 cycles of all colors on wheel
for(i=0; i< strip.numPixels(); i++) {
strip.setPixelColor(i, Wheel(((i * 256 / strip.numPixels()) + j) & 255));
}
strip.show();
delay(wait);
}
}
//Theatre-style crawling light
void theaterChase(uint32_t c, uint8_t wait) {
for (int j=0; j<100; j++) { //do 10 cycles of chasing
for (int q=0; q < 3; q++) {
for (int i=0; i < strip.numPixels(); i=i+3) {
strip.setPixelColor(i+q, c); //turn every third pixel on
}
strip.show();
delay(wait);
for (int i=0; i < strip.numPixels(); i=i+3) {
strip.setPixelColor(i+q, 0); //turn every third pixel off
}
}
}
}
//Theatre-style crawling light with rainbow effect
void theaterChaseRainbow(uint8_t wait) {
for (int j=0; j < 256*5; j++) { // cycle all 256 colors in the wheel
for (int q=0; q < 3; q++) {
for (int i=0; i < strip.numPixels(); i=i+3) {
strip.setPixelColor(i+q, Wheel( (i+j) % 255)); //turn every third pixel on
}
strip.show();
delay(wait);
for (int i=0; i < strip.numPixels(); i=i+3) {
strip.setPixelColor(i+q, 0); //turn every third pixel off
}
}
}
}
// Input a value 0 to 255 to get a color value.
// The colours are a transition r — g — b — back to r.
uint32_t Wheel(byte WheelPos) {
if(WheelPos < 85) {
return strip.Color(WheelPos * 3, 255 — WheelPos * 3, 0);
} else if(WheelPos < 170) {
WheelPos -= 85;
return strip.Color(255 — WheelPos * 3, 0, WheelPos * 3);
} else {
WheelPos -= 170;
return strip.Color(0, WheelPos * 3, 255 — WheelPos * 3);
}
}
Вы могли бы дать ссылку на осцилограмму с логического анализатора передачи данных в ленту? Надо полагать, что определяющими являются длительности импульсов высокого уровня, т.к. между посылками байтов будут задержки, т.е. длительность импульсов низкого уровня нет возможности жестко нормировать??
Ссылки на даташиты уже битые. Жаль.
Да
Ссылки умирают со временем
Даташиты легко ищутся поиском
https://www.google.ru/search?q=ws2812+datasheet
Как с вами связаться, для того чтобы предложить вам работу! необходимо написать программу для RGB светодиодной ленты!